Skip to content
Closed
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ __pycache__/
*$py.class

.venv/
.sdk-build.*
venv/
env/
ENV/
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ from zero_friction.core.sdk_client import SDKClient
config = ZeroFrictionConfig()
sdk = SDKClient(config=config)

contract = sdk.masterdata_client.contracts_api.get_contracts_contractuuid(
contract = sdk.masterdata_client.default_api.get_contracts_contractuuid(
contractuuid="fc77b9c6-42bc-4fe7-b0a2-0f0309449a98",
**config.as_kwargs(),
)
Expand Down Expand Up @@ -76,3 +76,6 @@ from root-package lint/type-check coverage settings.

See `docs/quickstart.md` and the documents under `docs/` for the development,
secret-management, dependency, quality, and devcontainer workflows.

See `docs/sdk-regeneration.md` when refreshing the bundled OpenAPI
specifications or regenerating the clients under `sdk/`.
103 changes: 103 additions & 0 deletions docs/sdk-regeneration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# SDK regeneration

The eight clients under `sdk/` are generated from the specifications under
`openapi_specs/`. Do not edit generated models or API modules by hand.

## Specification source

The specifications were exported from the Zero Friction developer portal on
2026-09-10. The portal exposes Azure API Management's data API at:

```text
https://zf-apim-heat-prd-int-we-001.data.azure-api.net
```

Each specification was retrieved from:

```text
/apis/{API_ID}?api-version=2022-04-01-preview&export=true
```

with this required request header:

```text
Accept: application/vnd.oai.openapi
```

The API IDs match the specification filenames: `Attachments-1-0`,
`Billing-1-0`, `Communication-1-0`, `Configuration-1-0`,
`Forecasting-1-0`, `Masterdata-1-0`, `Metering-1-0`, and
`RegionalRegulations-1-0`.

For example, refresh the Configuration specification with:

```bash
curl --fail --silent --show-error \
--header 'Accept: application/vnd.oai.openapi' \
'https://zf-apim-heat-prd-int-we-001.data.azure-api.net/apis/Configuration-1-0?api-version=2022-04-01-preview&export=true' \
--output openapi_specs/Configuration-1-0.yaml
```

The checked-in files have trailing whitespace removed. Their SHA-256 hashes
are:

| Specification | SHA-256 |
| --- | --- |
| Attachments | `effeef83bd6eeebaf8e3b5b57f7a7d42a6c3404aedb51016137e002f377761f1` |
| Billing | `39885bb75a5010827ffaae9daea0758e08231bf4ed703544f2ca0b055d23d6c1` |
| Communication | `0f91a3533a1b80e82b4890ecafd24ae6884b62f8d3914ae9ad8c2df7d736ffc6` |
| Configuration | `a8fe1c335f7ed58031c6fed653b27a1ecdbefa67f47af89096ecf98fd591ea9f` |
| Forecasting | `07bba645bd9ccbcdc5b031123fbf7ba226aa5dcee3b69cff59e9c3f29b6baef1` |
| Masterdata | `bc85fb7015d1490f856878167e9977b8f1831aa74811d9820b58716be031a2be` |
| Metering | `a40322204f4dca1a011e72d5bb845324d05d1bf049491cb7976c007d418427bc` |
| RegionalRegulations | `bfa99915cafe8284b6bcb139d107905c10b25565a9a8c2189be693597f353948` |

Placeholder password and private-key values in vendor examples carry
detect-secrets allowlist comments; they contain the literal value `string`,
not credentials.

## Generate the clients

Docker, `rsync`, and `uv` are required. From the repository root, run:

```bash
./scripts/generate-sdk.sh
```

The script uses OpenAPI Generator 7.13.0 pinned by image digest, stages all
eight clients, applies the repository's API-version compatibility behavior,
normalizes generated text, and then replaces `sdk/` only after every client
has generated successfully.

The vendor Masterdata specification repeats the `Name` and `Id` query
parameters on the two bulk service-context filter operations. Generation
therefore skips OpenAPI Generator's validation for that client only. The
generator de-duplicates those parameters in the generated method signatures.

## Compatibility notes

The current vendor exports group operations under the `Default` tag. Generated
API modules are consequently exposed as `default_api` instead of the previous
resource-specific modules such as `contracts_api` and `customers_api`. This is
a breaking public API change for callers that use the generated clients or the
unified client's dynamically attached API attributes.

The refreshed schema also resolves two local workarounds:

- `CultureInfo` is now a string, so values such as `nl-NL` work without a
generated-model patch.
- Customer lookup is now generated with the documented query parameter, and
billing calculation parameter subtypes are present in the schema. Their
runtime patches were removed.

The permissive country-code compatibility patch remains in
`zero_friction/patches/` because the vendor schema still publishes a closed
country-code enum.

No live API requests are part of generation or verification. Run the offline
checks with:

```bash
uv run --frozen pytest
uv run pre-commit run --all-files
```
25 changes: 25 additions & 0 deletions docs/superpowers/plans/2026-09-10-sdk-refresh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# SDK specification refresh implementation plan

> **For agentic workers:** Use techletes-superpowers:subagent-driven-development to implement and review this plan task by task.

**Goal:** Implement #12 by refreshing vendor specifications and reproducibly regenerating existing SDK clients.

**Architecture:** Retain OpenAPI Generator 7.13.0 and the eight existing Python package names. Store vendor specifications and provenance, provide a repeatable generation command, and retain compatibility patches in `zero_friction/patches/`.

**Tech stack:** Python 3.9+, uv, Docker, OpenAPI Generator 7.13.0.

## Global constraints

- Preserve the public package name, Python 3.9+ compatibility, and SDK client package structure.
- No tariff workflows, raw-JSON workaround, live tariff writes, or scheduled automation.
- Do not manually edit generated models; resolve generation issues at the source or generator configuration.
- Use existing dependencies and targeted runnable checks.

## Tasks

- [x] Recover generator settings from existing metadata/history and compare a baseline generation against checked-in clients.
- [x] Retrieve complete vendor specifications for all eight clients into `openapi_specs/`; reject empty/incomplete exports and record source, date, version, and content hashes.
- [x] Add `scripts/generate-sdk.sh` with the pinned generator and existing package naming. Generate into temporary directories before updating `sdk/`, preserving existing non-generated compatibility code.
- [x] Review endpoint/model differences and wrapper imports. Add a focused offline check under `tests/` that loads repository clients rather than the Git versions installed by the root package.
- [x] Document provenance, generation commands, compatibility changes, and validation limits in `docs/sdk-regeneration.md`, linked from README.
- [x] Run `uv run --frozen pytest`, `uv run pre-commit run --all-files`, and generation reproducibility comparison. Obtain independent review, resolve findings, and prepare a PR closing #12.
Loading
Loading