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.
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/CHANGELOG.md +35 -0
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/PKG-INFO +64 -43
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/README.md +61 -41
- lib_shopware6_api_base-4.0.0/example.env +48 -0
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/pyproject.toml +5 -2
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/src/lib_shopware6_api_base/__init__conf__.py +1 -1
- lib_shopware6_api_base-4.0.0/src/lib_shopware6_api_base/conf_shopware6_api_base_classes.py +143 -0
- lib_shopware6_api_base-4.0.0/src/lib_shopware6_api_base/config.py +50 -0
- lib_shopware6_api_base-4.0.0/src/lib_shopware6_api_base/defaultconfig.d/10-logging.toml +26 -0
- lib_shopware6_api_base-4.0.0/src/lib_shopware6_api_base/defaultconfig.d/20-shopware.toml +40 -0
- lib_shopware6_api_base-4.0.0/src/lib_shopware6_api_base/defaultconfig.toml +25 -0
- {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
- lib_shopware6_api_base-4.0.0/src/lib_shopware6_api_base/logging_setup.py +58 -0
- lib_shopware6_api_base-4.0.0/tests/conf_test_docker.py +27 -0
- lib_shopware6_api_base-4.0.0/tests/test_config.py +131 -0
- lib_shopware6_api_base-4.0.0/tests/test_logging_config.py +49 -0
- lib_shopware6_api_base-3.1.2/example.env +0 -103
- lib_shopware6_api_base-3.1.2/src/lib_shopware6_api_base/conf_shopware6_api_base_classes.py +0 -382
- lib_shopware6_api_base-3.1.2/tests/conf_test_docker.py +0 -21
- lib_shopware6_api_base-3.1.2/tests/docker.env +0 -94
- lib_shopware6_api_base-3.1.2/tests/test_config.py +0 -363
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/.devcontainer/devcontainer.json +0 -0
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/.devcontainer/settings.json +0 -0
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/.github/actions/extract-metadata/action.yml +0 -0
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/.github/dependabot.yml +0 -0
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/.github/workflows/cicd_docker.yml +0 -0
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/.github/workflows/codeql-analysis.yml +0 -0
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/.github/workflows/default_release_public.yml +0 -0
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/.gitignore +0 -0
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/CODE_OF_CONDUCT.md +0 -0
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/CONTRIBUTING.md +0 -0
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/INSTALL.md +0 -0
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/ISSUE_TEMPLATE.md +0 -0
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/LICENSE +0 -0
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/Makefile +0 -0
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/PULL_REQUEST_TEMPLATE.md +0 -0
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/notebooks/Quickstart.ipynb +0 -0
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/src/lib_shopware6_api_base/.gitignore +0 -0
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/src/lib_shopware6_api_base/__init__.py +0 -0
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/src/lib_shopware6_api_base/__main__.py +0 -0
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/src/lib_shopware6_api_base/_compat.py +0 -0
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/src/lib_shopware6_api_base/_http_common.py +0 -0
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/src/lib_shopware6_api_base/exit_codes.py +0 -0
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/src/lib_shopware6_api_base/py.typed +0 -0
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/tests/conftest.py +0 -0
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/tests/test_api_base.py +0 -0
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/tests/test_cli.py +0 -0
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/tests/test_conf_classes.py +0 -0
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/tests/test_criteria.py +0 -0
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/tests/test_criteria_aggregation.py +0 -0
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/tests/test_criteria_filter.py +0 -0
- {lib_shopware6_api_base-3.1.2 → lib_shopware6_api_base-4.0.0}/tests/test_criteria_sorting.py +0 -0
- {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
|
+
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
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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
|
-
|
|
137
|
-
|
|
155
|
+
SHOPWARE__ADMIN_API_URL="https://shop.example.com/api"
|
|
156
|
+
SHOPWARE__STOREFRONT_API_URL="https://shop.example.com/store-api"
|
|
138
157
|
|
|
139
|
-
#
|
|
140
|
-
|
|
158
|
+
# Transport (set to "1" only for local HTTP development)
|
|
159
|
+
SHOPWARE__INSECURE_TRANSPORT="0"
|
|
141
160
|
|
|
142
|
-
# User
|
|
143
|
-
|
|
144
|
-
|
|
161
|
+
# User-Credentials grant (interactive apps with refresh tokens)
|
|
162
|
+
SHOPWARE__USERNAME="admin@example.com"
|
|
163
|
+
SHOPWARE__PASSWORD="your-password"
|
|
145
164
|
|
|
146
|
-
# Resource
|
|
147
|
-
|
|
148
|
-
|
|
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
|
-
|
|
170
|
+
SHOPWARE__GRANT_TYPE="RESOURCE_OWNER"
|
|
152
171
|
|
|
153
172
|
# Storefront API access key (from Sales Channel settings)
|
|
154
|
-
|
|
173
|
+
SHOPWARE__STORE_API_SW_ACCESS_KEY="SWSCXXXXXXXXXXXXXXXXXX"
|
|
155
174
|
```
|
|
156
175
|
|
|
157
|
-
####
|
|
176
|
+
#### `[shopware]` Settings Reference
|
|
158
177
|
|
|
159
|
-
|
|
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
|
-
|
|
|
162
|
-
|
|
163
|
-
| `
|
|
164
|
-
| `
|
|
165
|
-
| `
|
|
166
|
-
| `
|
|
167
|
-
| `
|
|
168
|
-
| `
|
|
169
|
-
| `
|
|
170
|
-
| `
|
|
171
|
-
| `
|
|
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
|
|
262
|
-
|
|
263
|
-
| `request_url`
|
|
264
|
-
| `payload`
|
|
265
|
-
| `update_header_fields` | `dict[str, str] \| None`
|
|
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
|
|
270
|
-
|
|
271
|
-
| `content_type`
|
|
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
|
|
446
|
-
|
|
466
|
+
| Exception | When Raised |
|
|
467
|
+
|----------------------|-------------------------------------------------|
|
|
447
468
|
| `ConfigurationError` | Missing .env file, invalid configuration values |
|
|
448
|
-
| `ShopwareAPIError`
|
|
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
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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
|
-
|
|
84
|
-
|
|
101
|
+
SHOPWARE__ADMIN_API_URL="https://shop.example.com/api"
|
|
102
|
+
SHOPWARE__STOREFRONT_API_URL="https://shop.example.com/store-api"
|
|
85
103
|
|
|
86
|
-
#
|
|
87
|
-
|
|
104
|
+
# Transport (set to "1" only for local HTTP development)
|
|
105
|
+
SHOPWARE__INSECURE_TRANSPORT="0"
|
|
88
106
|
|
|
89
|
-
# User
|
|
90
|
-
|
|
91
|
-
|
|
107
|
+
# User-Credentials grant (interactive apps with refresh tokens)
|
|
108
|
+
SHOPWARE__USERNAME="admin@example.com"
|
|
109
|
+
SHOPWARE__PASSWORD="your-password"
|
|
92
110
|
|
|
93
|
-
# Resource
|
|
94
|
-
|
|
95
|
-
|
|
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
|
-
|
|
116
|
+
SHOPWARE__GRANT_TYPE="RESOURCE_OWNER"
|
|
99
117
|
|
|
100
118
|
# Storefront API access key (from Sales Channel settings)
|
|
101
|
-
|
|
119
|
+
SHOPWARE__STORE_API_SW_ACCESS_KEY="SWSCXXXXXXXXXXXXXXXXXX"
|
|
102
120
|
```
|
|
103
121
|
|
|
104
|
-
####
|
|
122
|
+
#### `[shopware]` Settings Reference
|
|
105
123
|
|
|
106
|
-
|
|
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
|
-
|
|
|
109
|
-
|
|
110
|
-
| `
|
|
111
|
-
| `
|
|
112
|
-
| `
|
|
113
|
-
| `
|
|
114
|
-
| `
|
|
115
|
-
| `
|
|
116
|
-
| `
|
|
117
|
-
| `
|
|
118
|
-
| `
|
|
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
|
|
209
|
-
|
|
210
|
-
| `request_url`
|
|
211
|
-
| `payload`
|
|
212
|
-
| `update_header_fields` | `dict[str, str] \| None`
|
|
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
|
|
217
|
-
|
|
218
|
-
| `content_type`
|
|
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
|
|
393
|
-
|
|
412
|
+
| Exception | When Raised |
|
|
413
|
+
|----------------------|-------------------------------------------------|
|
|
394
414
|
| `ConfigurationError` | Missing .env file, invalid configuration values |
|
|
395
|
-
| `ShopwareAPIError`
|
|
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
|
+
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
|
-
"
|
|
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 = "
|
|
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"
|