Skip to content

[bot] Merge master/c226287e into rel/dev - #1925

Merged
yenkins-admin merged 1 commit into
rel/devfrom
snapshot-master-c226287e-to-rel/dev
Nov 6, 2026
Merged

yenkins-admin merged 1 commit into
rel/devfrom
snapshot-master-c226287e-to-rel/dev

Conversation

@yenkins-admin

Copy link
Copy Markdown
Contributor

🚀 Automated PR to perform merge from master into rel/dev with changes up to c226287 (created by https://github.com/gooddata/gooddata-python-sdk/actions/runs/42228460311).

* chore(gooddata-api-client): regenerate against staging

Regenerate the client from the staging specs, which carry the
backend's Publisher document permission and layout changes.

- CREATE_DOCUMENT joins every workspace permission enum that has
  CREATE_VISUALIZATION, including the declarative single-workspace
  and hierarchy permissions.
- DeclarativePublisherDocument gains created_at, created_by,
  modified_at and modified_by. The document template and page
  template layout types have no author fields.

The same download brings unrelated backend changes: a required
restrictedCount on ChangeAnalysisResult, a required storages list
(ObjectStorageRef) on DatabaseInstance, the MODEL_STATISTICS explain
type, relationships on JsonApiPublisherDocumentOut, and the removal
of AmplitudeService. No package's source uses the changed or removed
models.

jira: LX-3447
risk: low
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(gooddata-sdk): read CREATE_DOCUMENT permission assignments

Assert that a declarative single-workspace permission and a
workspace hierarchy permission named CREATE_DOCUMENT survive the
round trip: from_dict reads the assignment, to_api builds the client
model, and to_dict gives back the input. The regenerated client
allows the value, and the validation tests would otherwise only
cover it through the enum sweep, without a typed read of the
assignment.

The shared declarative_workspace_permissions.json fixture stays as
it is: the recorded PUT tests replay it, and adding the value there
would change their cassettes and the permission counts they assert.

jira: LX-3447
risk: nonprod
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(gooddata-api-client): resolve discriminated oneOf via python names

Building a model whose property is a discriminated oneOf, such as the
Publisher document layout node, failed when the input used python
names: `PublisherDocumentColumn._from_openapi_data() missing 1 required
positional argument: 'children'`, whatever the node's `type` was.

In python-name mode (`_spec_property_naming=False`)
`get_possible_classes` replaced a discriminated composed model by all
its members without reading the discriminator. `attempt_convert_item`
then tried them in order, and the first member missing a required
argument raised a plain `TypeError`, which it does not catch. With JSON
names the composed class stays the only candidate and
`_new_from_openapi_data` dispatches on the discriminator.

`Base.to_api()` in the SDK builds client models with `camel_case=False`
(python names), so a discriminated composed model must resolve through
its discriminator in that mode too. `get_possible_classes` now keeps
such a model as the single candidate in both modes. Discriminated
`ModelNormal` classes and undiscriminated unions are unchanged, and a
member instance is still accepted, since `is_valid_type` already walks
the discriminator map.

jira: LX-3447
risk: low
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(gooddata-sdk): write keyword attributes under client names

The generated client names an attribute whose API name is a Python
keyword with a leading underscore (`from` becomes `_from`), while an
attrs class can only spell it with a trailing one (`from_`).
`Base._get_snake_dict` used `attrs.asdict`, which keeps the attrs
name, so the client took `from_` as an unknown extra property and the
request body silently lacked `from`.

`_get_snake_dict` now walks attrs fields itself and writes `<kw>_`
under `_<kw>` at every depth, keeping the old filtering of None and
private attributes. Only attrs field names are renamed: keys inside a
`dict` value, such as an analytics object's opaque `content`, are user
JSON and pass untouched. `to_dict`, `to_api` and the workspace
layout's `to_api(include_nested_structures)` all go through it.

No SDK attribute is named this way yet; the publisher document period
is the first.

jira: LX-3447
risk: low
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(gooddata-sdk): model publisher documents in the analytics layer

Add CatalogDeclarativePublisherDocument,
CatalogDeclarativePublisherDocumentTemplate and
CatalogDeclarativePublisherDocumentPageTemplate, exported from
gooddata_sdk, and the documents, document_templates and page_templates
lists on CatalogDeclarativeAnalyticsLayer. A layout read from the API
or a dict now keeps its Publisher documents, document templates and
page templates through to_api() instead of dropping them.

A document's period is the typed CatalogPublisherDocumentPeriod, a
union of CatalogAbsolutePublisherDocumentPeriod (ISO dates) and
CatalogRelativePublisherDocumentPeriod (offsets in granularity units),
all three exported from gooddata_sdk. A structure hook on the global
converter dispatches on type, the way dashboard permissions do, so
nested reads through the analytics and workspace layouts are typed
too. Without it, a read handed back the generated client's names and
types (_from, datetime.date). The keyword field is from_, which Base
writes as the client's _from, so the request body carries from.
Content stays an opaque dict, so keys the SDK does not model survive
the round trip.

The document carries the created/modified author fields through
CatalogAnalyticsBaseMeta, like memory items. The templates carry no
author fields, because the layout API exposes none on them.

reports, reportTemplates, reportPageLayouts and computedAttributes are
still not modelled in the analytics layer, until LX-3244.

jira: LX-3447
risk: low
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(gooddata-sdk): store and load publisher documents on disk

The analytics layer carries publisher documents, document templates
and page templates, but store_to_disk and load_from_disk ignored them,
so a layout written to disk and read back lost all three.

store_to_disk now writes them to three folders directly under
analytics_model/: documents/, document_templates/ and
page_templates/, one <id>.yaml per object, the same way as metrics
or parameters. load_from_disk reads them back. A folder stored before
this change, without the three folders, still loads, with the three
lists empty; a document YAML without the author fields loads with
them unset.

jira: LX-3447
risk: low
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* build(gooddata-sdk): require gooddata-code-convertors 11.66.0

11.66.0 is the first stable release of gooddata-code-convertors with
the v2 publisher convertors for documents, document templates and
page templates, which Analytics-as-Code needs to clone and deploy
them. uv lock moves only the convertor entry, from 11.57.0 to
11.66.0, with the same dependencies.

On py314 in freshly built tox envs, the 27 existing AaC tests
(-k aac) pass, and the gooddata-eval suite, the other consumer of
the convertors, passes unchanged (2542 passed, 1 skipped by design).

jira: LX-3447
risk: low
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(gooddata-sdk): clone and deploy publisher documents as code

gdc clone writes Publisher documents, document templates and page
templates to documents/, documentTemplates/ and pageTemplates/, and
gdc deploy sends them back, through the v2 publisher convertors of
gooddata-code-convertors.

The AaC form carries no author fields, so a clone then deploy
re-stamps the creator to the deploying user.

An object whose version is not "2" raises a ValueError naming its
type, id and version, on store and on load; so does any other refusal
by the convertor. Store converts all three types before it creates
the target folder, so refusing one of them writes nothing.

The folder names follow the layout keys until the gd CLI decides its
own (LX-3096).

jira: LX-3447
risk: low
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(gooddata-eval): write dates in the generate snapshot

An absolute-period Publisher document puts datetime.date values into
the declarative layer the snapshot is taken from, and json.dumps
refused them, so --snapshot-out failed on any workspace holding such
a document. The write now turns date and datetime values into ISO
strings and raises TypeError on any other value JSON cannot hold, so
a replayed snapshot never carries a silently stringified value.
Snapshots saved from now on carry documents.

jira: LX-3447
risk: low
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* test(gooddata-sdk): cover documents in the analytics layout round trip

The new service test seeds a workspace with one document, carrying
an absolute period and author fields, one document template and one
page template. It then reads, stores, loads and puts the analytics
model and checks that all three survive, the document with its four
author fields unchanged. The same scenario run against the SDK
before the document models leaves the workspace with no documents.

The backend omits documents, documentTemplates and pageTemplates
from layout responses when they are empty, while the SDK always
emits them. The two tests comparing the SDK dictionary with the raw
layout fill those keys on the raw side through one helper, and stay
exact on every other key. The expected layouts gain the three lists.

upload_demo_layout.py, which make load-staging runs, now treats a
201 from user creation as success, the status the backend returns
for it now; before, the layout load crashed on it.

jira: LX-3447
risk: nonprod
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(gooddata-sdk): record layout cassettes with publisher documents

The SDK now sends documents, documentTemplates and pageTemplates in
every analytics layout it puts, and the backend returns them, so the
15 cassettes that replay a layout read or put no longer matched. They
are re-recorded, and the document round-trip test gets its own
cassette.

All 16 were recorded on the python-sdk-dex staging environment with
ENABLE_METRIC_PERMISSIONS and ENABLE_VISUALIZATION_PERMISSIONS off,
and are committed as recorded, unedited. With those flags on, the
backend adds grants on metrics and visualization objects and the
metricExtensions and visualizationObjectExtensions lists, which the
SDK does not model yet (PSDK-236), and the raw-layout tests fail on
them. Dashboard grants are recorded as returned.

A separate recording on a local stack agrees with these on every
interaction and on everything the tests assert. It differs only in
values no test reads: the organization's region, dataCenter and
allowedOrigins fields, the content type and type field of not-found
errors, and the content-length header.

jira: LX-3447
risk: nonprod
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(gooddata-sdk): type client model fields as Catalog classes

Record for the next contributor the rule the publisher document
period settled: a field the generated client types as a model gets
its own Catalog class, because a plain dict read through the client
comes back with the client's Python names and value types. The entry
names the pattern (a Union behind a global_converter structure hook,
a keyword field spelled from_), the one exception by convention (an
analytics object's content stays an opaque dict), and the check to
run after regenerating the client, since a regeneration once typed
Automation.metadata without anyone noticing.

jira: LX-3447
risk: nonprod
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@yenkins-admin
yenkins-admin merged commit d75ed7e into rel/dev Nov 6, 2026
3 checks passed
@yenkins-admin
yenkins-admin deleted the snapshot-master-c226287e-to-rel/dev branch November 6, 2026 13:49
@coderabbitai

coderabbitai Bot commented Nov 6, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: dded78ea-9307-4b2c-a1b7-f09724219a37

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

@codecov

codecov Bot commented Nov 6, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.90110% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.15%. Comparing base (b765e4b) to head (c226287).
⚠️ Report is 637 commits behind head on rel/dev.

Files with missing lines Patch % Lines
...model/workspace/analytics_model/analytics_model.py 98.14% 2 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           rel/dev    #1925      +/-   ##
===========================================
+ Coverage    86.03%   86.15%   +0.11%     
===========================================
  Files          344      344              
  Lines        25698    25874     +176     
===========================================
+ Hits         22110    22291     +181     
+ Misses        3588     3583       -5     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants