dpp-sdk 0.2.1__tar.gz → 0.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. dpp_sdk-0.4.0/.gitignore +38 -0
  2. dpp_sdk-0.4.0/CHANGELOG.md +96 -0
  3. dpp_sdk-0.4.0/PKG-INFO +338 -0
  4. dpp_sdk-0.4.0/README.md +307 -0
  5. {dpp_sdk-0.2.1 → dpp_sdk-0.4.0}/pyproject.toml +29 -6
  6. {dpp_sdk-0.2.1 → dpp_sdk-0.4.0}/src/dpp_sdk/__init__.py +2 -2
  7. dpp_sdk-0.4.0/src/dpp_sdk/clients/README.md +318 -0
  8. {dpp_sdk-0.2.1 → dpp_sdk-0.4.0}/src/dpp_sdk/clients/__init__.py +1 -2
  9. {dpp_sdk-0.2.1 → dpp_sdk-0.4.0}/src/dpp_sdk/clients/_http.py +9 -3
  10. {dpp_sdk-0.2.1 → dpp_sdk-0.4.0}/src/dpp_sdk/clients/endpoints.py +1 -3
  11. {dpp_sdk-0.2.1 → dpp_sdk-0.4.0}/src/dpp_sdk/clients/payloads.py +38 -6
  12. dpp_sdk-0.4.0/src/dpp_sdk/clients/registry.py +83 -0
  13. {dpp_sdk-0.2.1 → dpp_sdk-0.4.0}/src/dpp_sdk/clients/repo.py +121 -23
  14. dpp_sdk-0.4.0/src/dpp_sdk/core/README.md +132 -0
  15. {dpp_sdk-0.2.1 → dpp_sdk-0.4.0}/src/dpp_sdk/core/__init__.py +1 -1
  16. dpp_sdk-0.4.0/src/dpp_sdk/core/_text.py +41 -0
  17. {dpp_sdk-0.2.1 → dpp_sdk-0.4.0}/src/dpp_sdk/core/model.py +11 -5
  18. {dpp_sdk-0.2.1 → dpp_sdk-0.4.0}/src/dpp_sdk/core/validation.py +4 -5
  19. dpp_sdk-0.4.0/src/dpp_sdk/dpp4fun/README.md +132 -0
  20. {dpp_sdk-0.2.1 → dpp_sdk-0.4.0}/src/dpp_sdk/dpp4fun/__init__.py +1 -1
  21. {dpp_sdk-0.2.1 → dpp_sdk-0.4.0}/src/dpp_sdk/dpp4fun/model.py +8 -8
  22. {dpp_sdk-0.2.1 → dpp_sdk-0.4.0}/src/dpp_sdk/dpp4fun/transport.py +18 -6
  23. {dpp_sdk-0.2.1 → dpp_sdk-0.4.0}/src/dpp_sdk/dpp4fun/validation.py +35 -22
  24. {dpp_sdk-0.2.1 → dpp_sdk-0.4.0}/tests/conftest.py +27 -0
  25. dpp_sdk-0.4.0/tests/fixtures/java-contract/README.md +12 -0
  26. dpp_sdk-0.4.0/tests/fixtures/java-contract/canonical-java-output.json +1 -0
  27. dpp_sdk-0.4.0/tests/fixtures/java-contract/fixture-metadata.json +161 -0
  28. dpp_sdk-0.4.0/tests/fixtures/java-contract/invalid-cross-object-rule.json +1 -0
  29. dpp_sdk-0.4.0/tests/fixtures/java-contract/invalid-missing-required-field.json +1 -0
  30. dpp_sdk-0.4.0/tests/fixtures/java-contract/invalid-semantic-rule.json +1 -0
  31. dpp_sdk-0.4.0/tests/fixtures/java-contract/legacy-blocker-placeholders.json +15 -0
  32. dpp_sdk-0.4.0/tests/fixtures/java-contract/malformed-json.txt +1 -0
  33. dpp_sdk-0.4.0/tests/fixtures/java-contract/valid-complete-dpp.json +1 -0
  34. dpp_sdk-0.4.0/tests/fixtures/java-contract/valid-flat-input.json +1 -0
  35. dpp_sdk-0.4.0/tests/fixtures/java-contract/valid-minimal-dpp.json +1 -0
  36. dpp_sdk-0.4.0/tests/fixtures/java-contract/valid-nested-input.json +1 -0
  37. dpp_sdk-0.4.0/tests/installed_wheel_integration.py +258 -0
  38. dpp_sdk-0.4.0/tests/test_clients.py +1207 -0
  39. dpp_sdk-0.4.0/tests/test_core_model.py +400 -0
  40. dpp_sdk-0.4.0/tests/test_core_validation.py +484 -0
  41. dpp_sdk-0.4.0/tests/test_documentation.py +451 -0
  42. dpp_sdk-0.4.0/tests/test_dpp4fun_model.py +301 -0
  43. dpp_sdk-0.4.0/tests/test_dpp4fun_validation.py +501 -0
  44. dpp_sdk-0.4.0/tests/test_end_to_end.py +84 -0
  45. {dpp_sdk-0.2.1 → dpp_sdk-0.4.0}/tests/test_integration_live.py +21 -27
  46. dpp_sdk-0.4.0/tests/test_java_contract_fixtures.py +82 -0
  47. dpp_sdk-0.4.0/tests/test_live_test_gating.py +230 -0
  48. dpp_sdk-0.4.0/tests/test_parity_evidence_tooling.py +21 -0
  49. dpp_sdk-0.4.0/tests/test_python_only_extensions.py +180 -0
  50. dpp_sdk-0.4.0/tests/test_readme_examples.py +119 -0
  51. dpp_sdk-0.4.0/tests/test_release_validation.py +209 -0
  52. dpp_sdk-0.4.0/tests/test_smoke.py +116 -0
  53. dpp_sdk-0.4.0/tests/test_transport_roundtrip.py +166 -0
  54. dpp_sdk-0.2.1/.gitignore +0 -25
  55. dpp_sdk-0.2.1/CHANGELOG.md +0 -42
  56. dpp_sdk-0.2.1/PKG-INFO +0 -234
  57. dpp_sdk-0.2.1/README.md +0 -204
  58. dpp_sdk-0.2.1/src/dpp_sdk/clients/registry.py +0 -46
  59. dpp_sdk-0.2.1/tests/test_clients.py +0 -160
  60. dpp_sdk-0.2.1/tests/test_core_model.py +0 -93
  61. dpp_sdk-0.2.1/tests/test_core_validation.py +0 -93
  62. dpp_sdk-0.2.1/tests/test_dpp4fun_validation.py +0 -95
  63. dpp_sdk-0.2.1/tests/test_end_to_end.py +0 -24
  64. dpp_sdk-0.2.1/tests/test_smoke.py +0 -18
  65. dpp_sdk-0.2.1/tests/test_transport_roundtrip.py +0 -66
  66. {dpp_sdk-0.2.1 → dpp_sdk-0.4.0}/LICENSE +0 -0
  67. {dpp_sdk-0.2.1 → dpp_sdk-0.4.0}/src/dpp_sdk/clients/errors.py +0 -0
  68. {dpp_sdk-0.2.1 → dpp_sdk-0.4.0}/src/dpp_sdk/core/errors.py +0 -0
  69. {dpp_sdk-0.2.1 → dpp_sdk-0.4.0}/src/dpp_sdk/py.typed +0 -0
  70. {dpp_sdk-0.2.1 → dpp_sdk-0.4.0}/tests/__init__.py +0 -0
@@ -0,0 +1,38 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .eggs/
6
+ build/
7
+ dist/
8
+ /artifacts/
9
+ verification-report.json
10
+ legacy-verification-report.json
11
+ .venv/
12
+ venv/
13
+ .mock-services-demo-venv/
14
+ site-packages/
15
+ dist-packages/
16
+ pyvenv.cfg
17
+ .env
18
+
19
+ # Tooling caches
20
+ .pytest_cache/
21
+ .mypy_cache/
22
+ .ruff_cache/
23
+ .coverage
24
+ htmlcov/
25
+ coverage.xml
26
+
27
+ # Editor / OS
28
+ .idea/
29
+ .vscode/
30
+ .DS_Store
31
+
32
+ # Documents
33
+ /docs-internal
34
+
35
+ # Local agent instructions and retained agent state (at any depth)
36
+ **/AGENTS.md
37
+ **/CLAUDE.md
38
+ **/.codex/
@@ -0,0 +1,96 @@
1
+ # Changelog
2
+
3
+ All notable changes to `dpp-sdk` are documented here. The format is based on
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this project adheres to
5
+ [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [0.4.0] - Synchronisation with java-dpp-sdk
8
+
9
+ ### Added
10
+ - An isolated `examples/mock-services-demo` consumer project with reproducible Mock image
11
+ profiles, pull-only memory-mode Compose infrastructure, SDK-01 through SDK-17, complete public
12
+ repository/registry interoperability scenarios, controlled edge contracts, installed-import
13
+ proof, dynamic image identity evidence, and retained verification reports.
14
+ - A fresh-installed-wheel cross-component proof covering validated immutable updates,
15
+ DPP4Fun codec round-trips, captured repository/registry requests, and client error
16
+ translation without source-tree imports.
17
+ - Python-only local-endpoint helpers and factories, with explicit `base_url` and
18
+ environment overrides (`DPP_REPO_BASE_URL` / `DPP_REGISTRY_BASE_URL`). They do
19
+ not provide or operate any service.
20
+ - `health_check()` on both clients (probes `GET /health`).
21
+ - Default endpoint constants and helpers exported from `dpp_sdk.clients`:
22
+ `DEFAULT_REPO_BASE_URL`, `DEFAULT_REGISTRY_BASE_URL`, `DEFAULT_REPO_PORT`,
23
+ `DEFAULT_REGISTRY_PORT`, `local_repo_base_url()`, `local_registry_base_url()`.
24
+ - `integration` pytest marker and opt-in live conformance tests for an
25
+ externally supplied endpoint.
26
+
27
+ ### Fixed
28
+ - The installed Mock-services demo's SDK-only modes now defer service-profile loading, so `sdk`
29
+ and `sdk --json` run from an installed nested wheel without a checkout or `env/pinned.env`.
30
+ - Mock-services demo configuration tests now isolate service environment variables, so documented
31
+ alternate host-port overrides cannot contaminate profile/default assertions.
32
+ - Bill-of-materials validation now rejects null material, component, and part members
33
+ with fail-fast indexed `DppValidationError` paths instead of leaking `AttributeError`.
34
+ - History reads now normalize timezone-aware datetimes to the Mock-compatible canonical UTC
35
+ `Z` query wire, including Mock-compatible fractional-second precision.
36
+ - Repository identifiers and element paths now use exact dynamic-segment percent encoding,
37
+ preserving literal `*` while encoding `~`, `%`, `?`, and `#`.
38
+ - Repository and registry clients now reject null response payloads, null codec results, and
39
+ invalid registry requests through causal `DppMappingClientError` failures before invalid
40
+ values or raw implementation exceptions can escape.
41
+ - Contracted text fields use an explicit frozen Unicode White_Space table in construction,
42
+ semantic validation, duplicate comparison, and cross-object comparison.
43
+ - Contracted floating-point values are finite and non-negative; strict JSON mapping rejects
44
+ non-finite input, overflow, and output with preserved causes.
45
+ - Standalone codec roots and null string-list members follow the approved structural mapping
46
+ boundary, while direct defensive validators retain indexed semantic errors.
47
+
48
+ ### Changed
49
+ - Active model guidance and contract tests consistently use `with_updates()` as the
50
+ revalidating immutable-edit seam; intentional Pydantic bypass probes remain internal.
51
+ - `README.md`: full lifecycle Quickstart (build → validate → store → register → read → update →
52
+ delete) now uses application-provided endpoints and no-network examples.
53
+ - Domain models expose `with_updates()` for revalidated immutable updates; contracted collections
54
+ are immutable tuples in memory and continue to serialize as JSON arrays.
55
+ - Validation documentation now describes the tested fail-fast behavior rather than aggregation.
56
+ - Canonical repository and registry documentation uses `/v1` routes, canonical registration
57
+ fields and `registrationId`, compressed/versioned reads, direct data-element JSON bodies, and
58
+ distinct client error categories.
59
+ - Both SDK clients support explicit `close()` and context-manager cleanup for SDK-owned HTTPX
60
+ resources; caller-supplied clients remain caller-owned.
61
+ - Aggregate validators document and test their supported public boundary and fail-fast order;
62
+ arbitrary `model_construct()` corruption is not a public compatibility contract.
63
+ - Root and module READMEs now use plain-language entry points, explain Python client payload models,
64
+ distinguish optional Mock-demo prerequisites, and include focused Mermaid diagrams with captions.
65
+
66
+ ### Compatibility
67
+ - `UpdateDataElementRequest` remains importable only as a compatibility DTO; it does not affect
68
+ canonical direct data-element PATCH bodies.
69
+ - Legacy registry aliases and the unversioned product-ID history route are retained compatibility
70
+ surfaces only. New integrations should use canonical field names and versioned routes.
71
+
72
+ ## [0.2.1] — Previous package baseline
73
+
74
+ - Package metadata and `dpp_sdk.__version__` identified the preceding checkout as `0.2.1`.
75
+ - This repository checkout contains no local release tag for `0.2.1`; commit history remains
76
+ the provenance source for changes predating the current unreleased section.
77
+
78
+ ## [0.1.1]
79
+
80
+ ### Changed
81
+ - Documentation update: streamlined `README.md` and project metadata.
82
+
83
+ ## [0.1.0] — Initial release
84
+
85
+ First public release of the Python port of the Mock DPP SDK.
86
+
87
+ ### Added
88
+ - `dpp_sdk.core` — core DPP model, validation, and identifiers (Pydantic v2).
89
+ - `dpp_sdk.dpp4fun` — furniture-specific DPP aggregate, validation, and flat/nested JSON transport.
90
+ - `dpp_sdk.clients` — `httpx`-based HTTP clients for the DPP repository and registry APIs.
91
+ - Packaging: PEP 621 `pyproject.toml`, `src/` layout, `py.typed` marker, sdist + wheel build.
92
+
93
+ [Unreleased]: https://github.com/CIR4FUN-EU/dpp-sdk-python/compare/v0.4.0...HEAD
94
+ [0.4.0]: https://github.com/CIR4FUN-EU/dpp-sdk-python/releases/tag/v0.4.0
95
+ [0.1.1]: https://github.com/CIR4FUN-EU/dpp-sdk-python/compare/v0.1.0...v0.1.1
96
+ [0.1.0]: https://github.com/CIR4FUN-EU/dpp-sdk-python/releases/tag/v0.1.0
dpp_sdk-0.4.0/PKG-INFO ADDED
@@ -0,0 +1,338 @@
1
+ Metadata-Version: 2.5
2
+ Name: dpp-sdk
3
+ Version: 0.4.0
4
+ Summary: Python SDK for interacting with Digital Product Passport (DPP) System Infrastructure
5
+ Project-URL: Homepage, https://gitlab.cc-asp.fraunhofer.de/ipk-gfm/digital-product-passport-sdk/dpp-python-sdk
6
+ Project-URL: Repository, https://gitlab.cc-asp.fraunhofer.de/ipk-gfm/digital-product-passport-sdk/dpp-python-sdk
7
+ Project-URL: Issues, https://gitlab.cc-asp.fraunhofer.de/ipk-gfm/digital-product-passport-sdk/dpp-python-sdk/-/issues
8
+ Project-URL: Changelog, https://gitlab.cc-asp.fraunhofer.de/ipk-gfm/digital-product-passport-sdk/dpp-python-sdk/-/blob/main/CHANGELOG.md
9
+ Project-URL: Reference, https://gitlab.cc-asp.fraunhofer.de/ipk-gfm/digital-product-passport-sdk/dpp-sdk-platform
10
+ Author: Enno Mueller
11
+ License-Expression: Apache-2.0
12
+ License-File: LICENSE
13
+ Keywords: digital-product-passport,dpp,prEN-18222,sustainability
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Typing :: Typed
18
+ Requires-Python: >=3.11
19
+ Requires-Dist: httpx>=0.27
20
+ Requires-Dist: pydantic>=2.6
21
+ Provides-Extra: dev
22
+ Requires-Dist: mypy>=1.9; extra == 'dev'
23
+ Requires-Dist: pytest-cov>=5.0; extra == 'dev'
24
+ Requires-Dist: pytest-sugar>=1.1.1; extra == 'dev'
25
+ Requires-Dist: pytest>=8.0; extra == 'dev'
26
+ Requires-Dist: ruff>=0.4; extra == 'dev'
27
+ Provides-Extra: release
28
+ Requires-Dist: build>=1.2; extra == 'release'
29
+ Requires-Dist: twine>=5.1; extra == 'release'
30
+ Description-Content-Type: text/markdown
31
+
32
+ # dpp-sdk (Python)
33
+
34
+ `dpp-sdk` helps Python applications work with Digital Product Passports (DPPs). You can use it
35
+ to describe a passport, check it, turn it into JSON, and call a DPP repository or registry API.
36
+
37
+ It is a client library, not a service. It does not run a repository or registry, store data, or
38
+ provide Docker, Spring, EDC, or dataspace features. The Mock-services demo is a separate optional
39
+ consumer of this SDK.
40
+
41
+ ## Architecture at a glance
42
+
43
+ ![Python SDK architecture](docs/architecture/python-sdk-overview.svg)
44
+
45
+ `dpp_sdk.core` contains reusable DPP models and validation. `dpp_sdk.dpp4fun` builds its furniture
46
+ model, validation, and JSON mapping on Core, while `dpp_sdk.clients` stays model-independent and
47
+ performs the HTTP calls. The Mock-services demo is optional: it uses the installed SDK and public
48
+ clients against Java repository and registry images.
49
+
50
+
51
+ ## Standards alignment
52
+
53
+ **EN 18222:2026:** The SDK implements selected public DPP repository and registry API shapes
54
+ alongside the project DPP4Fun model, validation, and JSON rules. It is not a formal compliance implementation. It also makes no certification, legal-conformity, or production-readiness claim.
55
+
56
+ Some API contracts were designed using confidential external technical specifications that cannot
57
+ be published here. This documentation describes only the behavior implemented by this project.
58
+
59
+ ### What the SDK supports
60
+
61
+ - Create, read, update, read historical versions of, and delete repository passports.
62
+ - Register passport metadata with a registry.
63
+ - Read a compressed passport as an untyped JSON value when the service provides one.
64
+
65
+ ## Known standards limitations
66
+
67
+ - The registry request has no backup-operator field or backup-operator operation.
68
+ - Compressed passports use a project-defined format. The SDK does not turn them into a typed
69
+ `Dpp4Fun` value automatically.
70
+ - Partial updates and element paths are only partly implemented. The SDK sends the documented
71
+ requests, but it does not provide a complete generic implementation of RFC 7396 JSON Merge Patch
72
+ or a complete implementation of RFC 9535 JSONPath.
73
+ - The Python SDK does not record lifecycle events or keep a lifecycle-event history.
74
+ - Authentication, backup/recovery, retries, persistence, and other production operations are not
75
+ provided.
76
+ - The SDK calls public `/v1/...` service routes. Mock demo `/internal/...` routes are not Python
77
+ client methods.
78
+ - No real EU registry integration, production security hardening, or production-operational
79
+ guarantee is provided.
80
+
81
+
82
+ ## Start here
83
+
84
+ Choose the smallest part that matches your job:
85
+
86
+ | If you want to… | Start with… |
87
+ | --- | --- |
88
+ | describe reusable passport details | [Core module](src/dpp_sdk/core/README.md) |
89
+ | work with furniture passports | [DPP4Fun module](src/dpp_sdk/dpp4fun/README.md) |
90
+ | call a repository or registry API | [Clients module](src/dpp_sdk/clients/README.md) |
91
+ | see a complete consumer walkthrough | [SDK usage](docs/usage.md) |
92
+ | understand package boundaries | [SDK overview](docs/overview.md) |
93
+ | look up model fields and JSON/null semantics | [Model guide](docs/model-guide.md) |
94
+ | look up semantic validation rules | [Validation rules](docs/validation-rules.md) |
95
+ | try disposable mock services locally | [Mock-services demo](examples/mock-services-demo/README.md) |
96
+ | prepare a package release | [Release guide](RELEASING.md) |
97
+ | review changes or licensing | [Changelog](CHANGELOG.md) · [License](LICENSE) |
98
+
99
+
100
+ ## Prerequisites
101
+
102
+ - **All SDK users:** Python 3.11 or newer.
103
+ - **Only for the optional live Mock-services demo:** Docker Engine with Compose v2, Docker Buildx
104
+ for the demo's image-identity check, and access to the public GHCR image references.
105
+
106
+ You do not need Docker, Compose, Buildx, or GHCR access to install the SDK, use its models, or run
107
+ the SDK-only demo checks.
108
+
109
+ ## Install
110
+
111
+ **Purpose:** install the published SDK for an application. **Run from:** any directory; these
112
+ commands are directory-independent because pip downloads a named published distribution rather
113
+ than reading this checkout. **Prerequisites:** Python 3.11 or newer on `PATH` and access to the
114
+ selected package index.
115
+
116
+ Choose the source deliberately:
117
+
118
+ | Need | Install choice | Why |
119
+ | --- | --- | --- |
120
+ | ordinary application use | latest published `dpp-sdk` | uses the newest released distribution; no checkout is required |
121
+ | repeatable deployment or compatibility testing | an exact published version such as `dpp-sdk==0.4.0` | prevents a later release from changing the installed SDK |
122
+ | updates within one released minor line | a compatible version range such as `dpp-sdk~=0.4.0` | accepts compatible `0.4.x` fixes but not `0.5.0` |
123
+ | contribution, an unreleased fix, or reproducing checkout state | install this local checkout | uses the source currently in this repository; it is not a substitute for a released package in production |
124
+
125
+ Release tags are named `v<major>.<minor>.<patch>` (for example, `v0.4.0`), while pip version
126
+ selectors omit the `v` (for example, `dpp-sdk==0.4.0`).
127
+
128
+ ### PowerShell
129
+
130
+ ```powershell
131
+ python -m pip install dpp-sdk
132
+ ```
133
+
134
+ ### Linux/macOS
135
+
136
+ ```bash
137
+ python -m pip install dpp-sdk
138
+ ```
139
+
140
+ ### Install a selected published release
141
+
142
+ Use an exact version when deployment must be reproducible. Use `~=` only when your application
143
+ has tested the compatible release line and can accept later patch releases.
144
+
145
+ #### PowerShell
146
+
147
+ ```powershell
148
+ python -m pip install "dpp-sdk==0.4.0"
149
+ python -m pip install "dpp-sdk~=0.4.0"
150
+ ```
151
+
152
+ #### Linux/macOS
153
+
154
+ ```bash
155
+ python -m pip install "dpp-sdk==0.4.0"
156
+ python -m pip install "dpp-sdk~=0.4.0"
157
+ ```
158
+
159
+ ### Install this local checkout
160
+
161
+ Use this only when you need the un-released source in this checkout, are contributing, or are
162
+ reproducing a source-state issue. Create the repository-local `.venv` once when it is absent; it is
163
+ local developer state and must not be committed.
164
+
165
+ #### Create the development environment
166
+
167
+ **Purpose:** create an isolated checkout environment with development and release tools.
168
+ **Run from:** the Python repository root, the directory containing `pyproject.toml`.
169
+ **Prerequisites:** Python 3.11 or newer on `PATH`.
170
+
171
+ ##### PowerShell
172
+
173
+ ```powershell
174
+ python -m venv .venv
175
+ .\.venv\Scripts\python.exe -m pip install -e ".[dev,release]"
176
+ ```
177
+
178
+ ##### Linux/macOS
179
+
180
+ ```bash
181
+ python -m venv .venv
182
+ .venv/bin/python -m pip install -e ".[dev,release]"
183
+ ```
184
+
185
+ **Expected result:** `.venv` contains an isolated editable SDK install plus the configured test,
186
+ lint, type-check, build, and package-check tools. **Cleanup:** remove `.venv` only when you no
187
+ longer need this checkout environment.
188
+
189
+ #### PowerShell
190
+
191
+ ```powershell
192
+ .\.venv\Scripts\python.exe -m pip install .
193
+ ```
194
+
195
+ #### Linux/macOS
196
+
197
+ ```bash
198
+ .venv/bin/python -m pip install .
199
+ ```
200
+
201
+ `dpp-sdk` is the single package that contains the core, DPP4Fun, clients, and public payload
202
+ models. The separately installed `dpp-sdk-mock-services-demo` package is reference/demo code, not
203
+ a dependency that ordinary SDK users need.
204
+
205
+ **Expected result:** the same interpreter imports the intended SDK:
206
+
207
+ ```powershell
208
+ .\.venv\Scripts\python.exe -c "import dpp_sdk; print(dpp_sdk.__version__)"
209
+ ```
210
+
211
+ ```bash
212
+ .venv/bin/python -c "import dpp_sdk; print(dpp_sdk.__version__)"
213
+ ```
214
+
215
+ **Cleanup:** none.
216
+
217
+ ## First use from this checkout
218
+
219
+ All local commands in this section run from the repository root, the directory containing
220
+ `pyproject.toml`.
221
+
222
+ 1. Choose a published install above, or create `.venv` and install this checkout.
223
+ 2. Run the import probe above, then use the small SDK example below.
224
+ 3. Run the SDK-only educational walkthrough after following the isolated-wheel setup in the
225
+ [Mock-services demo guide](examples/mock-services-demo/README.md#quick-start):
226
+ `./.mock-services-demo-venv/Scripts/python.exe -m dpp_mock_services_demo sdk` on PowerShell, or
227
+ `./.mock-services-demo-venv/bin/python -m dpp_mock_services_demo sdk` on Linux/macOS. Use
228
+ `--summary` for compact verification or `--json` for machine-readable evidence.
229
+ 4. Run SDK tests with the development interpreter; focused core, validation, client, and
230
+ documentation commands are owned by the [release guide](RELEASING.md).
231
+ 5. Only when you need live interoperability, follow the [Mock-services demo guide]
232
+ (examples/mock-services-demo/README.md) to start a uniquely named disposable project, run
233
+ `demo`, `full`, or `verify`, inspect its report/logs, and tear down only that project.
234
+
235
+ The demo guide owns its longer service commands and troubleshooting. Docker is never required for
236
+ the installation, SDK example, or SDK-only demo.
237
+
238
+ ## A small useful example
239
+
240
+ Parse a furniture passport, check it, and turn it back into JSON:
241
+
242
+ ```python
243
+ from dpp_sdk import from_json, to_json, validate_dpp4fun
244
+
245
+
246
+ def check_passport(raw_json: str) -> str:
247
+ passport = from_json(raw_json)
248
+ validate_dpp4fun(passport)
249
+ return to_json(passport)
250
+ ```
251
+
252
+ `from_json()` checks that the JSON has the right shape. `validate_dpp4fun()` checks the extra
253
+ business rules. Run validation before relying on a passport or sending it to a service.
254
+
255
+ ## Store and read a passport
256
+
257
+ Once you have a valid `Dpp4Fun` value and a repository URL, the generic client can store and read
258
+ it. The same pattern works with your own model when you provide a codec and validator.
259
+
260
+ ```python
261
+ from dpp_sdk import Dpp4Fun, Dpp4FunJsonCodec, validate_dpp4fun
262
+ from dpp_sdk.clients import DppRepoClient
263
+
264
+
265
+ def store_and_read(dpp: Dpp4Fun, repository_url: str) -> Dpp4Fun:
266
+ with DppRepoClient(
267
+ repository_url,
268
+ codec=Dpp4FunJsonCodec(),
269
+ validator=validate_dpp4fun,
270
+ ) as repository:
271
+ created = repository.create_dpp(dpp)
272
+ return repository.read_dpp_by_id(created.dppId)
273
+ ```
274
+
275
+ For all operations, request and response payloads, errors, partial updates, and resource ownership,
276
+ see the [clients module guide](src/dpp_sdk/clients/README.md).
277
+
278
+
279
+ ### Technical details
280
+
281
+ Repository creation uses `POST /v1/dpps`; registry registration uses `POST /v1/registerDPP`. A
282
+ registration request identifies its repository with `dppApiEndpoint="https://repo.example.com"`.
283
+ Full reads use a typed model; compressed and fine-grained reads return the JSON value supplied by
284
+ the service. The typed compressed-read method is `read_compressed_dpp_by_id()`.
285
+
286
+ `UpdateDataElementRequest` remains importable for compatibility, while the normal fine-grained
287
+ update sends its value directly. The client guide explains exact JSON field names, error types, and
288
+ supported paths.
289
+
290
+ `read_dpp_version_by_product_id_and_date()` remains a legacy compatibility only route. New code
291
+ should use `read_dpp_version_by_id_and_date()` with a DPP ID.
292
+
293
+ Semantic validation is fail-fast. Models use immutable tuples for contracted collections; use
294
+ `with_updates()` to make a checked replacement instead of changing a model in place. Mapping
295
+ failures in client code use `DppMappingClientError`; an HTTPX client you provide stays caller-owned.
296
+
297
+ ## Optional Mock-services demo
298
+
299
+ Use Docker Compose to start the disposable repository and registry services, run the connected demo,
300
+ then stop and remove the project. **Run from:** the Python repository root.
301
+
302
+ ```powershell
303
+ $demoDir = (Resolve-Path .\examples\mock-services-demo).Path
304
+ $envFile = Join-Path $demoDir ".env"
305
+ if (-not (Test-Path -LiteralPath $envFile)) {
306
+ Copy-Item (Join-Path $demoDir ".env.example") $envFile
307
+ }
308
+ $composeFile = Join-Path $demoDir "compose.yaml"
309
+ $project = "dpp-mock-services-demo-local"
310
+ docker compose --env-file $envFile -f $composeFile -p $project up -d --wait
311
+ & .\.venv\Scripts\python.exe -m dpp_mock_services_demo demo --env-file $envFile
312
+ docker compose --env-file $envFile -f $composeFile -p $project down -v
313
+ ```
314
+
315
+ ## Linux/macOS
316
+
317
+ ```bash
318
+ demo_dir="$(cd ./examples/mock-services-demo && pwd)"
319
+ env_file="$demo_dir/.env"
320
+ [ -f "$env_file" ] || cp "$demo_dir/.env.example" "$env_file"
321
+ docker compose --env-file "$env_file" -f "$demo_dir/compose.yaml" -p dpp-mock-services-demo-local up -d --wait
322
+ .venv/bin/python -m dpp_mock_services_demo demo --env-file "$env_file"
323
+ docker compose --env-file "$env_file" -f "$demo_dir/compose.yaml" -p dpp-mock-services-demo-local down -v
324
+ ```
325
+
326
+ For tests, alternate configuration, logs, and troubleshooting, see the
327
+ [Mock-services demo guide](examples/mock-services-demo/README.md) and
328
+ [ADVANCED_OPERATIONS.md](examples/mock-services-demo/ADVANCED_OPERATIONS.md).
329
+
330
+ ## Documentation and next steps
331
+
332
+ For a first integration, follow the [SDK usage guide](docs/usage.md). Use the [SDK overview]
333
+ (docs/overview.md) to understand package boundaries, the [model guide](docs/model-guide.md) for
334
+ field/default/null behavior, the [validation guide](docs/validation-guide.md) and
335
+ [validation-rule reference](docs/validation-rules.md) for validation and codec behavior, and the
336
+ [clients guide](src/dpp_sdk/clients/README.md) for every public HTTP operation and payload. The
337
+ [release guide](RELEASING.md) owns development and release validation; the separate
338
+ [Mock-services demo](examples/mock-services-demo/README.md) owns its optional service lifecycle.