lib-shopware6-api-base 3.1.2__tar.gz → 4.0.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 (61) hide show
  1. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/CHANGELOG.md +35 -0
  2. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/PKG-INFO +64 -43
  3. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/README.md +61 -41
  4. lib_shopware6_api_base-4.0.0/example.env +48 -0
  5. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/pyproject.toml +5 -2
  6. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/src/lib_shopware6_api_base/__init__conf__.py +1 -1
  7. lib_shopware6_api_base-4.0.0/src/lib_shopware6_api_base/conf_shopware6_api_base_classes.py +143 -0
  8. lib_shopware6_api_base-4.0.0/src/lib_shopware6_api_base/config.py +50 -0
  9. lib_shopware6_api_base-4.0.0/src/lib_shopware6_api_base/defaultconfig.d/10-logging.toml +26 -0
  10. lib_shopware6_api_base-4.0.0/src/lib_shopware6_api_base/defaultconfig.d/20-shopware.toml +40 -0
  11. lib_shopware6_api_base-4.0.0/src/lib_shopware6_api_base/defaultconfig.toml +25 -0
  12. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/src/lib_shopware6_api_base/lib_shopware6_api_base_cli.py +11 -6
  13. lib_shopware6_api_base-4.0.0/src/lib_shopware6_api_base/logging_setup.py +58 -0
  14. lib_shopware6_api_base-4.0.0/tests/conf_test_docker.py +27 -0
  15. lib_shopware6_api_base-4.0.0/tests/test_config.py +131 -0
  16. lib_shopware6_api_base-4.0.0/tests/test_logging_config.py +49 -0
  17. lib_shopware6_api_base-3.1.2/example.env +0 -103
  18. lib_shopware6_api_base-3.1.2/src/lib_shopware6_api_base/conf_shopware6_api_base_classes.py +0 -382
  19. lib_shopware6_api_base-3.1.2/tests/conf_test_docker.py +0 -21
  20. lib_shopware6_api_base-3.1.2/tests/docker.env +0 -94
  21. lib_shopware6_api_base-3.1.2/tests/test_config.py +0 -363
  22. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/.devcontainer/devcontainer.json +0 -0
  23. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/.devcontainer/settings.json +0 -0
  24. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/.github/actions/extract-metadata/action.yml +0 -0
  25. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/.github/dependabot.yml +0 -0
  26. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/.github/workflows/cicd_docker.yml +0 -0
  27. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/.github/workflows/codeql-analysis.yml +0 -0
  28. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/.github/workflows/default_release_public.yml +0 -0
  29. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/.gitignore +0 -0
  30. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/CODE_OF_CONDUCT.md +0 -0
  31. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/CONTRIBUTING.md +0 -0
  32. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/INSTALL.md +0 -0
  33. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/ISSUE_TEMPLATE.md +0 -0
  34. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/LICENSE +0 -0
  35. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/Makefile +0 -0
  36. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/PULL_REQUEST_TEMPLATE.md +0 -0
  37. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/notebooks/Quickstart.ipynb +0 -0
  38. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/src/lib_shopware6_api_base/.gitignore +0 -0
  39. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/src/lib_shopware6_api_base/__init__.py +0 -0
  40. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/src/lib_shopware6_api_base/__main__.py +0 -0
  41. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/src/lib_shopware6_api_base/_compat.py +0 -0
  42. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/src/lib_shopware6_api_base/_http_common.py +0 -0
  43. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/src/lib_shopware6_api_base/exit_codes.py +0 -0
  44. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/src/lib_shopware6_api_base/lib_shopware6_admin_client.py +0 -0
  45. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/src/lib_shopware6_api_base/lib_shopware6_api_base.py +0 -0
  46. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/src/lib_shopware6_api_base/lib_shopware6_api_base_criteria.py +0 -0
  47. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/src/lib_shopware6_api_base/lib_shopware6_api_base_criteria_aggregation.py +0 -0
  48. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/src/lib_shopware6_api_base/lib_shopware6_api_base_criteria_filter.py +0 -0
  49. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/src/lib_shopware6_api_base/lib_shopware6_api_base_criteria_sorting.py +0 -0
  50. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/src/lib_shopware6_api_base/lib_shopware6_api_base_helpers.py +0 -0
  51. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/src/lib_shopware6_api_base/lib_shopware6_storefront_client.py +0 -0
  52. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/src/lib_shopware6_api_base/py.typed +0 -0
  53. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/tests/conftest.py +0 -0
  54. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/tests/test_api_base.py +0 -0
  55. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/tests/test_cli.py +0 -0
  56. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/tests/test_conf_classes.py +0 -0
  57. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/tests/test_criteria.py +0 -0
  58. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/tests/test_criteria_aggregation.py +0 -0
  59. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/tests/test_criteria_filter.py +0 -0
  60. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/tests/test_criteria_sorting.py +0 -0
  61. {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/tests/test_helpers.py +0 -0
@@ -5,6 +5,41 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [4.0.0] - 2026-06-08
9
+
10
+ ### Breaking Changes
11
+
12
+ - **Configuration is now loaded through `lib_layered_config`.** All settings — the
13
+ `[shopware]` connection settings and the `[lib_log_rich]` logging settings — are merged
14
+ across bundled defaults → app → host → user → `.env` → environment variables.
15
+ - **Environment variables renamed.** The old single-underscore `SHOPWARE_*` variables are
16
+ no longer read. Use `SHOPWARE__<KEY>` in a `.env` file, or
17
+ `LIB_SHOPWARE6_API_BASE___SHOPWARE__<KEY>` as a real environment variable. See the README
18
+ migration table.
19
+ - `ConfShopware6ApiBase` is now a plain Pydantic `BaseModel` (no longer `pydantic-settings`
20
+ `BaseSettings`); the removed helpers `from_env_file` / `from_env_vars` are gone.
21
+ `load_config_from_env()` / `require_config_from_env()` remain and now take no arguments.
22
+ - The `OAUTHLIB_INSECURE_TRANSPORT` side effect was removed (authlib is no longer a
23
+ dependency); `insecure_transport` is still accepted as a config field.
24
+
25
+ ### Added
26
+
27
+ - `lib_log_rich` structured logging, configured via the `[lib_log_rich]` config section and
28
+ initialized by the CLI (`logging_setup.py`). Library modules continue to use stdlib
29
+ `logging`, which is bridged into `lib_log_rich`.
30
+ - Bundled `defaultconfig.toml` + `defaultconfig.d/{10-logging,20-shopware}.toml` shipped with
31
+ the package as the lowest-precedence config layer.
32
+
33
+ ### Removed
34
+
35
+ - `pydantic-settings` dependency.
36
+
37
+ ## [3.1.3] - 2026-06-08
38
+
39
+ ### Fixed
40
+
41
+ - Docs: reformatted README markdown tables for consistent column alignment (cosmetic; no content change).
42
+
8
43
  ## [3.1.2] - 2026-06-08
9
44
 
10
45
  ### Changed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lib_shopware6_api_base
3
- Version: 3.1.2
3
+ Version: 4.0.0
4
4
  Summary: python3 base API client for shopware6
5
5
  Project-URL: Homepage, https://github.com/bitranox/lib_shopware6_api_base
6
6
  Project-URL: Documentation, https://github.com/bitranox/lib_shopware6_api_base/blob/master/README.md
@@ -24,8 +24,9 @@ Classifier: Typing :: Typed
24
24
  Requires-Python: >=3.10
25
25
  Requires-Dist: httpx2>=2.3.0
26
26
  Requires-Dist: lib-cli-exit-tools>=2.3.1
27
+ Requires-Dist: lib-layered-config>=5.5.1
28
+ Requires-Dist: lib-log-rich>=6.3.4
27
29
  Requires-Dist: orjson
28
- Requires-Dist: pydantic-settings>=2.14.1
29
30
  Requires-Dist: pydantic>=2.13.4
30
31
  Requires-Dist: rich-click
31
32
  Provides-Extra: dev
@@ -122,10 +123,28 @@ This is the base abstraction layer. For higher-level functions, see [lib_shopwar
122
123
 
123
124
  ## Configuration
124
125
 
125
- Configuration is managed via the `ConfShopware6ApiBase` class (Pydantic-based) which can load settings from:
126
- 1. Environment variables
127
- 2. A `.env` file
128
- 3. Direct instantiation
126
+ Configuration is managed via the `ConfShopware6ApiBase` class (Pydantic) and loaded
127
+ through [`lib_layered_config`](https://github.com/bitranox/lib_layered_config), which
128
+ merges, in increasing precedence:
129
+
130
+ ```
131
+ bundled defaults -> app -> host -> user -> .env -> environment variables
132
+ ```
133
+
134
+ You can also instantiate `ConfShopware6ApiBase(...)` directly with keyword arguments.
135
+
136
+ > **⚠️ Breaking change in 4.0.0 — env vars renamed.** Configuration moved to
137
+ > `lib_layered_config`, so the old single-underscore `SHOPWARE_*` variables are **no
138
+ > longer read**. Rename them to the `[shopware]` section form:
139
+ >
140
+ > | Old (≤ 3.x) | New — `.env` file | New — environment variable |
141
+ > |------------------------------------|--------------------------------|---------------------------------------------------------|
142
+ > | `SHOPWARE_ADMIN_API_URL` | `SHOPWARE__ADMIN_API_URL` | `LIB_SHOPWARE6_API_BASE___SHOPWARE__ADMIN_API_URL` |
143
+ > | `SHOPWARE_STOREFRONT_API_URL` | `SHOPWARE__STOREFRONT_API_URL` | `LIB_SHOPWARE6_API_BASE___SHOPWARE__STOREFRONT_API_URL` |
144
+ > | `SHOPWARE_<NAME>` | `SHOPWARE__<NAME>` | `LIB_SHOPWARE6_API_BASE___SHOPWARE__<NAME>` |
145
+ >
146
+ > i.e. in a `.env` file replace the single `_` after `SHOPWARE` with `__`; as a real
147
+ > environment variable also add the `LIB_SHOPWARE6_API_BASE___` slug prefix.
129
148
 
130
149
  ### Environment File (.env)
131
150
 
@@ -133,42 +152,44 @@ Copy `example.env` to `.env` and adjust values for your shop:
133
152
 
134
153
  ```bash
135
154
  # API Endpoints
136
- SHOPWARE_ADMIN_API_URL="https://shop.example.com/api"
137
- SHOPWARE_STOREFRONT_API_URL="https://shop.example.com/store-api"
155
+ SHOPWARE__ADMIN_API_URL="https://shop.example.com/api"
156
+ SHOPWARE__STOREFRONT_API_URL="https://shop.example.com/store-api"
138
157
 
139
- # OAuth2 Security (set to "1" only for local HTTP development)
140
- SHOPWARE_INSECURE_TRANSPORT="0"
158
+ # Transport (set to "1" only for local HTTP development)
159
+ SHOPWARE__INSECURE_TRANSPORT="0"
141
160
 
142
- # User Credentials Grant (for interactive apps with refresh tokens)
143
- SHOPWARE_USERNAME="admin@example.com"
144
- SHOPWARE_PASSWORD="your-password"
161
+ # User-Credentials grant (interactive apps with refresh tokens)
162
+ SHOPWARE__USERNAME="admin@example.com"
163
+ SHOPWARE__PASSWORD="your-password"
145
164
 
146
- # Resource Owner Grant (for automation/CLI - no refresh tokens)
147
- SHOPWARE_CLIENT_ID="SWIAXXXXXXXXXXXXXXXXXXXX"
148
- SHOPWARE_CLIENT_SECRET="your-integration-secret"
165
+ # Resource-Owner grant (automation/CLI - no refresh tokens)
166
+ SHOPWARE__CLIENT_ID="SWIAXXXXXXXXXXXXXXXXXXXX"
167
+ SHOPWARE__CLIENT_SECRET="your-integration-secret"
149
168
 
150
169
  # Grant type: USER_CREDENTIALS or RESOURCE_OWNER
151
- SHOPWARE_GRANT_TYPE="RESOURCE_OWNER"
170
+ SHOPWARE__GRANT_TYPE="RESOURCE_OWNER"
152
171
 
153
172
  # Storefront API access key (from Sales Channel settings)
154
- SHOPWARE_STORE_API_SW_ACCESS_KEY="SWSCXXXXXXXXXXXXXXXXXX"
173
+ SHOPWARE__STORE_API_SW_ACCESS_KEY="SWSCXXXXXXXXXXXXXXXXXX"
155
174
  ```
156
175
 
157
- #### .env Settings Reference
176
+ #### `[shopware]` Settings Reference
158
177
 
159
- All environment variables use the `SHOPWARE_` prefix to avoid collision with system variables.
178
+ In a `.env` file use the `SHOPWARE__<KEY>` form; as a real environment variable prefix
179
+ with `LIB_SHOPWARE6_API_BASE___`. The same keys can be set in a TOML config file under
180
+ `[shopware]` (dropping the `SHOPWARE__` prefix).
160
181
 
161
- | Variable | Description | Example |
162
- |----------|---------------------------------------------------------------|---------|
163
- | `SHOPWARE_ADMIN_API_URL` | Admin API endpoint | `https://shop.example.com/api` |
164
- | `SHOPWARE_STOREFRONT_API_URL` | Storefront API endpoint | `https://shop.example.com/store-api` |
165
- | `SHOPWARE_INSECURE_TRANSPORT` | Allow HTTP (dev only) | `0` (production) or `1` (dev) |
166
- | `SHOPWARE_USERNAME` | Admin user email | `admin@example.com` |
167
- | `SHOPWARE_PASSWORD` | Admin user password | `secret` |
168
- | `SHOPWARE_CLIENT_ID` | Integration Access ID | `SWIA...` |
169
- | `SHOPWARE_CLIENT_SECRET` | Integration Secret | `...` |
170
- | `SHOPWARE_GRANT_TYPE` | Auth method | `USER_CREDENTIALS` or `RESOURCE_OWNER` |
171
- | `SHOPWARE_STORE_API_SW_ACCESS_KEY` | Storefront access key | `SWSC...` |
182
+ | `.env` key | Description | Example |
183
+ |------------------------------------|-------------------------|----------------------------------------|
184
+ | `SHOPWARE__ADMIN_API_URL` | Admin API endpoint | `https://shop.example.com/api` |
185
+ | `SHOPWARE__STOREFRONT_API_URL` | Storefront API endpoint | `https://shop.example.com/store-api` |
186
+ | `SHOPWARE__INSECURE_TRANSPORT` | Allow HTTP (dev only) | `0` (production) or `1` (dev) |
187
+ | `SHOPWARE__USERNAME` | Admin user email | `admin@example.com` |
188
+ | `SHOPWARE__PASSWORD` | Admin user password | `secret` |
189
+ | `SHOPWARE__CLIENT_ID` | Integration Access ID | `SWIA...` |
190
+ | `SHOPWARE__CLIENT_SECRET` | Integration Secret | `...` |
191
+ | `SHOPWARE__GRANT_TYPE` | Auth method | `USER_CREDENTIALS` or `RESOURCE_OWNER` |
192
+ | `SHOPWARE__STORE_API_SW_ACCESS_KEY`| Storefront access key | `SWSC...` |
172
193
 
173
194
  ### Loading Configuration
174
195
 
@@ -258,18 +279,18 @@ products = client.request_post("product", payload=criteria)
258
279
 
259
280
  All request methods accept these parameters:
260
281
 
261
- | Parameter | Type | Description |
262
- |-----------|------|-------------|
263
- | `request_url` | `str` | API endpoint (without base URL) |
264
- | `payload` | `dict \| Criteria \| None` | Request body |
265
- | `update_header_fields` | `dict[str, str] \| None` | Custom headers |
282
+ | Parameter | Type | Description |
283
+ |------------------------|----------------------------|---------------------------------|
284
+ | `request_url` | `str` | API endpoint (without base URL) |
285
+ | `payload` | `dict \| Criteria \| None` | Request body |
286
+ | `update_header_fields` | `dict[str, str] \| None` | Custom headers |
266
287
 
267
288
  Admin API methods also support:
268
289
 
269
- | Parameter | Type | Description |
270
- |-----------|------|-------------|
271
- | `content_type` | `str` | Content type (`json`, `octet-stream`) |
272
- | `additional_query_params` | `dict` | URL query parameters |
290
+ | Parameter | Type | Description |
291
+ |---------------------------|--------|---------------------------------------|
292
+ | `content_type` | `str` | Content type (`json`, `octet-stream`) |
293
+ | `additional_query_params` | `dict` | URL query parameters |
273
294
 
274
295
  ### Custom Headers
275
296
 
@@ -442,10 +463,10 @@ except ShopwareAPIError as e:
442
463
 
443
464
  ### Exception Types
444
465
 
445
- | Exception | When Raised |
446
- |-----------|-------------|
466
+ | Exception | When Raised |
467
+ |----------------------|-------------------------------------------------|
447
468
  | `ConfigurationError` | Missing .env file, invalid configuration values |
448
- | `ShopwareAPIError` | HTTP errors from the API (4xx, 5xx responses) |
469
+ | `ShopwareAPIError` | HTTP errors from the API (4xx, 5xx responses) |
449
470
 
450
471
  ---
451
472
 
@@ -69,10 +69,28 @@ This is the base abstraction layer. For higher-level functions, see [lib_shopwar
69
69
 
70
70
  ## Configuration
71
71
 
72
- Configuration is managed via the `ConfShopware6ApiBase` class (Pydantic-based) which can load settings from:
73
- 1. Environment variables
74
- 2. A `.env` file
75
- 3. Direct instantiation
72
+ Configuration is managed via the `ConfShopware6ApiBase` class (Pydantic) and loaded
73
+ through [`lib_layered_config`](https://github.com/bitranox/lib_layered_config), which
74
+ merges, in increasing precedence:
75
+
76
+ ```
77
+ bundled defaults -> app -> host -> user -> .env -> environment variables
78
+ ```
79
+
80
+ You can also instantiate `ConfShopware6ApiBase(...)` directly with keyword arguments.
81
+
82
+ > **⚠️ Breaking change in 4.0.0 — env vars renamed.** Configuration moved to
83
+ > `lib_layered_config`, so the old single-underscore `SHOPWARE_*` variables are **no
84
+ > longer read**. Rename them to the `[shopware]` section form:
85
+ >
86
+ > | Old (≤ 3.x) | New — `.env` file | New — environment variable |
87
+ > |------------------------------------|--------------------------------|---------------------------------------------------------|
88
+ > | `SHOPWARE_ADMIN_API_URL` | `SHOPWARE__ADMIN_API_URL` | `LIB_SHOPWARE6_API_BASE___SHOPWARE__ADMIN_API_URL` |
89
+ > | `SHOPWARE_STOREFRONT_API_URL` | `SHOPWARE__STOREFRONT_API_URL` | `LIB_SHOPWARE6_API_BASE___SHOPWARE__STOREFRONT_API_URL` |
90
+ > | `SHOPWARE_<NAME>` | `SHOPWARE__<NAME>` | `LIB_SHOPWARE6_API_BASE___SHOPWARE__<NAME>` |
91
+ >
92
+ > i.e. in a `.env` file replace the single `_` after `SHOPWARE` with `__`; as a real
93
+ > environment variable also add the `LIB_SHOPWARE6_API_BASE___` slug prefix.
76
94
 
77
95
  ### Environment File (.env)
78
96
 
@@ -80,42 +98,44 @@ Copy `example.env` to `.env` and adjust values for your shop:
80
98
 
81
99
  ```bash
82
100
  # API Endpoints
83
- SHOPWARE_ADMIN_API_URL="https://shop.example.com/api"
84
- SHOPWARE_STOREFRONT_API_URL="https://shop.example.com/store-api"
101
+ SHOPWARE__ADMIN_API_URL="https://shop.example.com/api"
102
+ SHOPWARE__STOREFRONT_API_URL="https://shop.example.com/store-api"
85
103
 
86
- # OAuth2 Security (set to "1" only for local HTTP development)
87
- SHOPWARE_INSECURE_TRANSPORT="0"
104
+ # Transport (set to "1" only for local HTTP development)
105
+ SHOPWARE__INSECURE_TRANSPORT="0"
88
106
 
89
- # User Credentials Grant (for interactive apps with refresh tokens)
90
- SHOPWARE_USERNAME="admin@example.com"
91
- SHOPWARE_PASSWORD="your-password"
107
+ # User-Credentials grant (interactive apps with refresh tokens)
108
+ SHOPWARE__USERNAME="admin@example.com"
109
+ SHOPWARE__PASSWORD="your-password"
92
110
 
93
- # Resource Owner Grant (for automation/CLI - no refresh tokens)
94
- SHOPWARE_CLIENT_ID="SWIAXXXXXXXXXXXXXXXXXXXX"
95
- SHOPWARE_CLIENT_SECRET="your-integration-secret"
111
+ # Resource-Owner grant (automation/CLI - no refresh tokens)
112
+ SHOPWARE__CLIENT_ID="SWIAXXXXXXXXXXXXXXXXXXXX"
113
+ SHOPWARE__CLIENT_SECRET="your-integration-secret"
96
114
 
97
115
  # Grant type: USER_CREDENTIALS or RESOURCE_OWNER
98
- SHOPWARE_GRANT_TYPE="RESOURCE_OWNER"
116
+ SHOPWARE__GRANT_TYPE="RESOURCE_OWNER"
99
117
 
100
118
  # Storefront API access key (from Sales Channel settings)
101
- SHOPWARE_STORE_API_SW_ACCESS_KEY="SWSCXXXXXXXXXXXXXXXXXX"
119
+ SHOPWARE__STORE_API_SW_ACCESS_KEY="SWSCXXXXXXXXXXXXXXXXXX"
102
120
  ```
103
121
 
104
- #### .env Settings Reference
122
+ #### `[shopware]` Settings Reference
105
123
 
106
- All environment variables use the `SHOPWARE_` prefix to avoid collision with system variables.
124
+ In a `.env` file use the `SHOPWARE__<KEY>` form; as a real environment variable prefix
125
+ with `LIB_SHOPWARE6_API_BASE___`. The same keys can be set in a TOML config file under
126
+ `[shopware]` (dropping the `SHOPWARE__` prefix).
107
127
 
108
- | Variable | Description | Example |
109
- |----------|---------------------------------------------------------------|---------|
110
- | `SHOPWARE_ADMIN_API_URL` | Admin API endpoint | `https://shop.example.com/api` |
111
- | `SHOPWARE_STOREFRONT_API_URL` | Storefront API endpoint | `https://shop.example.com/store-api` |
112
- | `SHOPWARE_INSECURE_TRANSPORT` | Allow HTTP (dev only) | `0` (production) or `1` (dev) |
113
- | `SHOPWARE_USERNAME` | Admin user email | `admin@example.com` |
114
- | `SHOPWARE_PASSWORD` | Admin user password | `secret` |
115
- | `SHOPWARE_CLIENT_ID` | Integration Access ID | `SWIA...` |
116
- | `SHOPWARE_CLIENT_SECRET` | Integration Secret | `...` |
117
- | `SHOPWARE_GRANT_TYPE` | Auth method | `USER_CREDENTIALS` or `RESOURCE_OWNER` |
118
- | `SHOPWARE_STORE_API_SW_ACCESS_KEY` | Storefront access key | `SWSC...` |
128
+ | `.env` key | Description | Example |
129
+ |------------------------------------|-------------------------|----------------------------------------|
130
+ | `SHOPWARE__ADMIN_API_URL` | Admin API endpoint | `https://shop.example.com/api` |
131
+ | `SHOPWARE__STOREFRONT_API_URL` | Storefront API endpoint | `https://shop.example.com/store-api` |
132
+ | `SHOPWARE__INSECURE_TRANSPORT` | Allow HTTP (dev only) | `0` (production) or `1` (dev) |
133
+ | `SHOPWARE__USERNAME` | Admin user email | `admin@example.com` |
134
+ | `SHOPWARE__PASSWORD` | Admin user password | `secret` |
135
+ | `SHOPWARE__CLIENT_ID` | Integration Access ID | `SWIA...` |
136
+ | `SHOPWARE__CLIENT_SECRET` | Integration Secret | `...` |
137
+ | `SHOPWARE__GRANT_TYPE` | Auth method | `USER_CREDENTIALS` or `RESOURCE_OWNER` |
138
+ | `SHOPWARE__STORE_API_SW_ACCESS_KEY`| Storefront access key | `SWSC...` |
119
139
 
120
140
  ### Loading Configuration
121
141
 
@@ -205,18 +225,18 @@ products = client.request_post("product", payload=criteria)
205
225
 
206
226
  All request methods accept these parameters:
207
227
 
208
- | Parameter | Type | Description |
209
- |-----------|------|-------------|
210
- | `request_url` | `str` | API endpoint (without base URL) |
211
- | `payload` | `dict \| Criteria \| None` | Request body |
212
- | `update_header_fields` | `dict[str, str] \| None` | Custom headers |
228
+ | Parameter | Type | Description |
229
+ |------------------------|----------------------------|---------------------------------|
230
+ | `request_url` | `str` | API endpoint (without base URL) |
231
+ | `payload` | `dict \| Criteria \| None` | Request body |
232
+ | `update_header_fields` | `dict[str, str] \| None` | Custom headers |
213
233
 
214
234
  Admin API methods also support:
215
235
 
216
- | Parameter | Type | Description |
217
- |-----------|------|-------------|
218
- | `content_type` | `str` | Content type (`json`, `octet-stream`) |
219
- | `additional_query_params` | `dict` | URL query parameters |
236
+ | Parameter | Type | Description |
237
+ |---------------------------|--------|---------------------------------------|
238
+ | `content_type` | `str` | Content type (`json`, `octet-stream`) |
239
+ | `additional_query_params` | `dict` | URL query parameters |
220
240
 
221
241
  ### Custom Headers
222
242
 
@@ -389,10 +409,10 @@ except ShopwareAPIError as e:
389
409
 
390
410
  ### Exception Types
391
411
 
392
- | Exception | When Raised |
393
- |-----------|-------------|
412
+ | Exception | When Raised |
413
+ |----------------------|-------------------------------------------------|
394
414
  | `ConfigurationError` | Missing .env file, invalid configuration values |
395
- | `ShopwareAPIError` | HTTP errors from the API (4xx, 5xx responses) |
415
+ | `ShopwareAPIError` | HTTP errors from the API (4xx, 5xx responses) |
396
416
 
397
417
  ---
398
418
 
@@ -0,0 +1,48 @@
1
+ # =============================================================================
2
+ # Shopware 6 API Configuration - Example .env
3
+ # =============================================================================
4
+ #
5
+ # Copy this file to .env and adjust the values for your shop.
6
+ #
7
+ # Configuration is loaded through lib_layered_config and merged in increasing
8
+ # precedence: bundled defaults -> app -> host -> user -> .env -> environment.
9
+ #
10
+ # Naming convention (IMPORTANT — changed in 4.0.0):
11
+ # - In a .env file, use the SECTION__KEY form (double underscore), no prefix:
12
+ # SHOPWARE__ADMIN_API_URL=...
13
+ # LIB_LOG_RICH__CONSOLE_LEVEL=DEBUG
14
+ # - As a real environment variable, prefix with the slug:
15
+ # LIB_SHOPWARE6_API_BASE___SHOPWARE__ADMIN_API_URL=...
16
+ #
17
+ # Migration from <=3.x: the old single-underscore SHOPWARE_* variables
18
+ # (e.g. SHOPWARE_ADMIN_API_URL) are NO LONGER read. Rename them to the
19
+ # [shopware] section form above (SHOPWARE__ADMIN_API_URL, ...).
20
+ # =============================================================================
21
+
22
+ # --- API Endpoints --------------------------------------------------------
23
+ SHOPWARE__ADMIN_API_URL="https://shop.example.com/api"
24
+ SHOPWARE__STOREFRONT_API_URL="https://shop.example.com/store-api"
25
+
26
+ # --- Transport ------------------------------------------------------------
27
+ # Allow plain HTTP (HTTP instead of HTTPS). "0" in production; "1" only for local dev.
28
+ SHOPWARE__INSECURE_TRANSPORT="0"
29
+
30
+ # --- Authentication: User-Credentials grant (interactive; refresh tokens) -
31
+ # Setup: Admin Panel > Settings > System > Users
32
+ SHOPWARE__USERNAME="api-user@example.com"
33
+ SHOPWARE__PASSWORD="your-secure-password-here"
34
+
35
+ # --- Authentication: Resource-Owner / Integration grant (automation) ------
36
+ # Setup: Admin Panel > Settings > System > Integrations
37
+ SHOPWARE__CLIENT_ID="SWIAXXXXXXXXXXXXXXXXXXXX"
38
+ SHOPWARE__CLIENT_SECRET="your-integration-secret-key-here"
39
+
40
+ # --- Grant type: USER_CREDENTIALS or RESOURCE_OWNER -----------------------
41
+ SHOPWARE__GRANT_TYPE="RESOURCE_OWNER"
42
+
43
+ # --- Store API access key (sw-access-key from the Sales Channel) ----------
44
+ SHOPWARE__STORE_API_SW_ACCESS_KEY="SWSCXXXXXXXXXXXXXXXXXX"
45
+
46
+ # --- Logging (lib_log_rich) — optional overrides --------------------------
47
+ # LIB_LOG_RICH__CONSOLE_LEVEL=INFO
48
+ # LIB_LOG_RICH__ENVIRONMENT=prod
@@ -1,12 +1,13 @@
1
1
  [project]
2
2
  name = "lib_shopware6_api_base"
3
- version = "3.1.2"
3
+ version = "4.0.0"
4
4
  description = "python3 base API client for shopware6"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
7
7
  dependencies = [
8
8
  "pydantic>=2.13.4",
9
- "pydantic-settings>=2.14.1",
9
+ "lib_layered_config>=5.5.1",
10
+ "lib_log_rich>=6.3.4",
10
11
  "lib_cli_exit_tools>=2.3.1",
11
12
  "rich-click",
12
13
  "orjson",
@@ -71,6 +72,8 @@ build-backend = "hatchling.build"
71
72
  packages = ["src/lib_shopware6_api_base"]
72
73
  include = [
73
74
  "src/lib_shopware6_api_base/py.typed",
75
+ "src/lib_shopware6_api_base/defaultconfig.toml",
76
+ "src/lib_shopware6_api_base/defaultconfig.d/*.toml",
74
77
  ]
75
78
 
76
79
  [tool.ruff]
@@ -26,7 +26,7 @@ name = "lib_shopware6_api_base"
26
26
  #: Human-readable summary shown in CLI help output.
27
27
  title = "python3 base API client for shopware6"
28
28
  #: Current release version pulled from ``pyproject.toml`` by automation.
29
- version = "3.1.2"
29
+ version = "4.0.0"
30
30
  #: Repository homepage presented to users.
31
31
  homepage = "https://github.com/bitranox/lib_shopware6_api_base"
32
32
  #: Author attribution surfaced in CLI output.
@@ -0,0 +1,143 @@
1
+ # STDLIB
2
+ from enum import Enum
3
+ from typing import Any
4
+
5
+ # EXT
6
+ from pydantic import AliasChoices, BaseModel, ConfigDict, Field, field_validator
7
+
8
+ # PROJ
9
+ from .config import get_config
10
+
11
+ __all__ = [
12
+ "GrantType",
13
+ "HttpMethod",
14
+ "ShopwareAPIError",
15
+ "ConfigurationError",
16
+ "ConfShopware6ApiBase",
17
+ "load_config_from_env",
18
+ "require_config_from_env",
19
+ ]
20
+
21
+
22
+ class GrantType(str, Enum):
23
+ """OAuth2 grant type for Shopware6 API authentication."""
24
+
25
+ USER_CREDENTIALS = "user_credentials"
26
+ RESOURCE_OWNER = "resource_owner"
27
+
28
+
29
+ class HttpMethod(str, Enum):
30
+ """HTTP methods supported by the Shopware6 API."""
31
+
32
+ GET = "get"
33
+ PATCH = "patch"
34
+ POST = "post"
35
+ PUT = "put"
36
+ DELETE = "delete"
37
+
38
+
39
+ class ShopwareAPIError(Exception):
40
+ """Exception raised for Shopware API errors."""
41
+
42
+
43
+ class ConfigurationError(Exception):
44
+ """Exception raised for configuration errors."""
45
+
46
+
47
+ class ConfShopware6ApiBase(BaseModel):
48
+ """Configuration for a Shopware6 API connection.
49
+
50
+ The values are loaded through ``lib_layered_config`` from the ``[shopware]``
51
+ section (bundled defaults -> app -> host -> user -> ``.env`` -> environment),
52
+ but the model may also be instantiated directly with keyword arguments.
53
+
54
+ Environment variables use the ``lib_layered_config`` scheme, e.g.::
55
+
56
+ LIB_SHOPWARE6_API_BASE___SHOPWARE__ADMIN_API_URL=https://shop.example.com/api
57
+
58
+ or, inside a ``.env`` file (no slug prefix)::
59
+
60
+ SHOPWARE__ADMIN_API_URL=https://shop.example.com/api
61
+ """
62
+
63
+ model_config = ConfigDict(populate_by_name=True, validate_assignment=True, extra="ignore")
64
+
65
+ # API Endpoints (TOML keys drop the redundant ``shopware_`` prefix).
66
+ shopware_admin_api_url: str = Field(default="", validation_alias=AliasChoices("admin_api_url", "shopware_admin_api_url"))
67
+ shopware_storefront_api_url: str = Field(
68
+ default="", validation_alias=AliasChoices("storefront_api_url", "shopware_storefront_api_url")
69
+ )
70
+
71
+ # User-Credentials grant (with refresh token).
72
+ username: str = ""
73
+ password: str = ""
74
+
75
+ # Resource-Owner / Integration grant (no refresh token).
76
+ client_id: str = ""
77
+ client_secret: str = ""
78
+
79
+ # Grant type selection.
80
+ grant_type: GrantType = GrantType.USER_CREDENTIALS
81
+
82
+ # Storefront API access key.
83
+ store_api_sw_access_key: str = ""
84
+
85
+ # Allow plain HTTP (development only); "1" enables it.
86
+ insecure_transport: str = "0"
87
+
88
+ # Follow HTTP redirects (may expose auth tokens to redirect targets).
89
+ follow_redirects: bool = False
90
+
91
+ # Emit debug logging of all HTTP requests/responses (may expose secrets).
92
+ enable_request_logging: bool = False
93
+
94
+ @field_validator("grant_type", mode="before")
95
+ @classmethod
96
+ def parse_grant_type(cls, v: str | GrantType) -> GrantType:
97
+ """Parse grant_type from a string ("USER_CREDENTIALS"/"user_credentials") or enum."""
98
+ if isinstance(v, GrantType):
99
+ return v
100
+ v_upper = v.upper()
101
+ if v_upper in ("USER_CREDENTIALS", "RESOURCE_OWNER"):
102
+ return GrantType(v.lower())
103
+ try:
104
+ return GrantType(v.lower())
105
+ except ValueError:
106
+ pass
107
+ raise ValueError(f"Invalid grant_type: {v!r}. Must be 'USER_CREDENTIALS' or 'RESOURCE_OWNER'")
108
+
109
+
110
+ def _load_shopware_section() -> dict[str, Any]:
111
+ """Return the merged ``[shopware]`` configuration section as a plain dict."""
112
+ raw: Any = get_config().get("shopware", default={})
113
+ return dict(raw) if raw else {}
114
+
115
+
116
+ def load_config_from_env() -> ConfShopware6ApiBase:
117
+ """Load the Shopware configuration via ``lib_layered_config``.
118
+
119
+ Reads the ``[shopware]`` section merged across all configuration layers
120
+ (bundled defaults, app/host/user config files, ``.env``, environment).
121
+
122
+ Returns:
123
+ ConfShopware6ApiBase: the loaded configuration (fields default to empty
124
+ when nothing is configured).
125
+ """
126
+ return ConfShopware6ApiBase(**_load_shopware_section())
127
+
128
+
129
+ def require_config_from_env() -> ConfShopware6ApiBase:
130
+ """Load the configuration, raising if no Shopware endpoint is configured.
131
+
132
+ Raises:
133
+ ConfigurationError: if neither the admin nor the storefront API URL is set.
134
+ """
135
+ config = load_config_from_env()
136
+ if not (config.shopware_admin_api_url or config.shopware_storefront_api_url):
137
+ raise ConfigurationError(
138
+ "No Shopware configuration found.\n\n"
139
+ "Provide a [shopware] section via a config file, a .env file, or environment\n"
140
+ "variables (e.g. LIB_SHOPWARE6_API_BASE___SHOPWARE__ADMIN_API_URL=...).\n"
141
+ "See example.env / the README for the full list of settings."
142
+ )
143
+ return config
@@ -0,0 +1,50 @@
1
+ """Layered configuration loading via ``lib_layered_config``.
2
+
3
+ All configuration for this package — both the Shopware connection settings
4
+ (``[shopware]``) and logging (``[lib_log_rich]``) — is loaded through
5
+ ``lib_layered_config``, which merges, in increasing precedence:
6
+
7
+ defaults (bundled) → app → host → user → ``.env`` → environment variables
8
+
9
+ The vendor / app / slug identifiers (see :mod:`__init__conf__`) determine the
10
+ platform-specific config file locations and the environment-variable prefix.
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ from functools import lru_cache
16
+ from pathlib import Path
17
+
18
+ from lib_layered_config import Config, read_config
19
+
20
+ from . import __init__conf__
21
+
22
+ __all__ = ["get_config", "get_default_config_path"]
23
+
24
+
25
+ def get_default_config_path() -> Path:
26
+ """Return the path to the bundled ``defaultconfig.toml`` shipped with the package."""
27
+ return Path(__file__).parent / "defaultconfig.toml"
28
+
29
+
30
+ @lru_cache(maxsize=4)
31
+ def get_config(*, profile: str | None = None, start_dir: str | None = None) -> Config:
32
+ """Load the merged, layered configuration.
33
+
34
+ Args:
35
+ profile: Optional profile name for environment isolation (inserts a
36
+ ``profile/<name>/`` subdirectory into all config paths).
37
+ start_dir: Optional directory that seeds ``.env`` discovery (defaults to cwd).
38
+
39
+ Returns:
40
+ An immutable :class:`lib_layered_config.Config`. Sections are read with
41
+ ``config.get("<section>", default={})``.
42
+ """
43
+ return read_config(
44
+ vendor=__init__conf__.LAYEREDCONF_VENDOR,
45
+ app=__init__conf__.LAYEREDCONF_APP,
46
+ slug=__init__conf__.LAYEREDCONF_SLUG,
47
+ profile=profile,
48
+ default_file=get_default_config_path(),
49
+ start_dir=start_dir,
50
+ )
@@ -0,0 +1,26 @@
1
+ # ==============================================================================
2
+ # [lib_log_rich] — Rich-powered structured logging
3
+ # ==============================================================================
4
+ #
5
+ # Loaded via lib_layered_config and passed to lib_log_rich.runtime.RuntimeConfig.
6
+ # Override via host/user config, a .env file, or environment variables:
7
+ #
8
+ # .env: LIB_LOG_RICH__CONSOLE_LEVEL=DEBUG
9
+ # environment: LIB_SHOPWARE6_API_BASE___LIB_LOG_RICH__CONSOLE_LEVEL=DEBUG
10
+ #
11
+ # Only the most common keys are listed here; every RuntimeConfig field is
12
+ # accepted. See https://github.com/bitranox/lib_log_rich for the full reference.
13
+ #
14
+ [lib_log_rich]
15
+
16
+ # Logical service name recorded on each log event.
17
+ service = "lib_shopware6_api_base"
18
+
19
+ # Deployment environment label (dev, staging, prod, local, ...).
20
+ environment = "prod"
21
+
22
+ # Minimum console severity: DEBUG, INFO, WARNING, ERROR, CRITICAL.
23
+ console_level = "INFO"
24
+
25
+ # Minimum severity for backend adapters (journald / Windows Event Log).
26
+ backend_level = "WARNING"