Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 14 additions & 9 deletions robosystems_client/clients/ledger_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,7 @@
"jsonld": "JSONLD",
"holon-jsonld": "HOLON_JSONLD",
"xbrl-2.1": "XBRL_2_1",
"tavi": "TAVI",
}


Expand Down Expand Up @@ -2216,22 +2217,24 @@ def download_report_bundle(
to: str | Path | None = None,
expires_in: int = 300,
) -> ReportBundleDownload:
"""Download a published Report's serialization bundle (JSON-LD or XBRL 2.1).
"""Download a published Report's serialization bundle.

A download is a read, so the presigned URL is resolved through the
GraphQL ``reportDownloadUrl`` field (the REST download route was
retired). Every flavor resolves to a short-lived presigned S3 URL —
JSON-LD is stamped at publish time; XBRL is materialized + cached on
first request. The client follows the URL and pulls the bytes.
JSON-LD is stamped at publish time; XBRL, the holon and the Tavi
model are materialized + cached on first request. The client follows
the URL and pulls the bytes.

Args:
graph_id: Graph identifier owning the Report.
report_id: Report identifier (``rpt_``-prefixed ULID).
format: Serialization flavor — ``"jsonld"`` (default, the flat
canonical bundle), ``"holon-jsonld"`` (the dataset-form
scene/boundary/projection holon), or ``"xbrl-2.1"``. The enum
names ``"JSONLD"`` / ``"HOLON_JSONLD"`` / ``"XBRL_2_1"`` are
also accepted.
scene/boundary/projection holon), ``"xbrl-2.1"``, or
``"tavi"`` (the Project Tavi compiled model, compact JSON).
The enum names ``"JSONLD"`` / ``"HOLON_JSONLD"`` /
``"XBRL_2_1"`` / ``"TAVI"`` are also accepted.
to: Optional file path to write the bytes to. When set, the
returned ``ReportBundleDownload.path`` points at the
written file.
Expand Down Expand Up @@ -2275,9 +2278,11 @@ def download_report_bundle(
)

generation_count = info.generation_count
default_ext = {"XBRL_2_1": "zip", "HOLON_JSONLD": "holon.jsonld"}.get(
gql_format, "jsonld"
)
default_ext = {
"XBRL_2_1": "zip",
"HOLON_JSONLD": "holon.jsonld",
"TAVI": "tavi.json",
}.get(gql_format, "jsonld")
filename = (
_parse_filename(artifact.headers.get("content-disposition", ""))
or f"{report_id}-g{generation_count or 1}.{default_ext}"
Expand Down
1 change: 1 addition & 0 deletions robosystems_client/graphql/generated/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ class ReportDownloadFormat(str, Enum):
JSONLD = "JSONLD"
HOLON_JSONLD = "HOLON_JSONLD"
XBRL_2_1 = "XBRL_2_1"
TAVI = "TAVI"
3 changes: 2 additions & 1 deletion robosystems_client/graphql/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -2153,7 +2153,7 @@ type ReportBundleDownload {
generationCount: Int!

"""
Content the Report carries that this flavor does not. ``disclosure_notes``: the XBRL 2.1 zip ships statements only — tenant-authored disclosure notes render on screen and ride the JSON-LD and holon flavors, but are excluded from this file.
Content the Report carries that this flavor does not. ``disclosure_notes``: the XBRL 2.1 zip ships statements only — tenant-authored disclosure notes render on screen and ride the JSON-LD and holon flavors, but are excluded from this file. The Tavi compiled model carries the statements and notes but has no home for ``ib_envelopes`` (the per-Network Information Block payloads), ``definition_links`` (equivalence, general-special, essence-alias and mapping arcs), ``reporting_style``, ``framework_pins``, ``fact_sets`` (the FactSet partition and each fact's structure pin) or ``filing_lifecycle`` (filing status, supersession, share provenance); all of it rides the JSON-LD and holon flavors.
"""
omittedContent: [String!]!
}
Expand All @@ -2162,6 +2162,7 @@ enum ReportDownloadFormat {
JSONLD
HOLON_JSONLD
XBRL_2_1
TAVI
}

"""
Expand Down
23 changes: 23 additions & 0 deletions tests/test_ledger_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2162,6 +2162,29 @@ def test_xbrl_download_follows_presigned_url(
assert result.generation_count == 3
assert mock_query.call_args.args[2]["format"] == "XBRL_2_1"

@patch("robosystems_client.clients.ledger_client.httpx.Client")
def test_tavi_download_maps_the_alias_and_names_the_file(
self, mock_client_cls, mock_config, graph_id
):
"""Tavi: ``"tavi"`` maps to ``TAVI``; without a content-disposition the
filename falls back to ``{report}-g{n}.tavi.json``."""
artifact = self._mock_artifact(b'{"documentInfo":{}}', "unused")
artifact.headers = {}
self._patch_httpx(mock_client_cls, artifact)
with patch.object(
LedgerClient,
"_query",
return_value=self._gql_data("application/json", "tavi", gen=4),
) as mock_query:
result = LedgerClient(mock_config).download_report_bundle(
graph_id, "rpt_01", format="tavi"
)

assert result.filename == "rpt_01-g4.tavi.json"
assert result.format == "tavi"
assert result.content_type == "application/json"
assert mock_query.call_args.args[2]["format"] == "TAVI"

@patch("robosystems_client.clients.ledger_client.httpx.Client")
def test_to_arg_writes_bytes_to_disk(
self, mock_client_cls, mock_config, graph_id, tmp_path
Expand Down