plentymarkets-api-client 0.1.2__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.
- plentymarkets_api_client-0.1.2/.claude/CLAUDE.md +72 -0
- plentymarkets_api_client-0.1.2/.forgejo/workflows/release.yml +105 -0
- plentymarkets_api_client-0.1.2/.gitignore +10 -0
- plentymarkets_api_client-0.1.2/.pre-commit-config.yaml +6 -0
- plentymarkets_api_client-0.1.2/.python-version +1 -0
- plentymarkets_api_client-0.1.2/CHANGELOG.md +42 -0
- plentymarkets_api_client-0.1.2/LICENSE +21 -0
- plentymarkets_api_client-0.1.2/PKG-INFO +153 -0
- plentymarkets_api_client-0.1.2/README.md +99 -0
- plentymarkets_api_client-0.1.2/ROADMAP.md +60 -0
- plentymarkets_api_client-0.1.2/docs/superpowers/plans/2026-06-30-pyPlentyAPI-initial-implementation.md +2106 -0
- plentymarkets_api_client-0.1.2/docs/superpowers/plans/2026-06-30-pyPlentyAPI.md +2503 -0
- plentymarkets_api_client-0.1.2/docs/superpowers/specs/2026-06-30-pyPlentyAPI-design.md +164 -0
- plentymarkets_api_client-0.1.2/pyproject.toml +60 -0
- plentymarkets_api_client-0.1.2/scripts/bump_changelog.py +33 -0
- plentymarkets_api_client-0.1.2/src/plentymarkets/__init__.py +19 -0
- plentymarkets_api_client-0.1.2/src/plentymarkets/_exceptions.py +31 -0
- plentymarkets_api_client-0.1.2/src/plentymarkets/_session.py +240 -0
- plentymarkets_api_client-0.1.2/src/plentymarkets/_types.py +277 -0
- plentymarkets_api_client-0.1.2/src/plentymarkets/client.py +96 -0
- plentymarkets_api_client-0.1.2/src/plentymarkets/modules/__init__.py +0 -0
- plentymarkets_api_client-0.1.2/src/plentymarkets/modules/contacts.py +230 -0
- plentymarkets_api_client-0.1.2/src/plentymarkets/modules/items.py +179 -0
- plentymarkets_api_client-0.1.2/src/plentymarkets/modules/orders.py +203 -0
- plentymarkets_api_client-0.1.2/src/plentymarkets/modules/stock.py +119 -0
- plentymarkets_api_client-0.1.2/src/plentymarkets/py.typed +0 -0
- plentymarkets_api_client-0.1.2/tests/__init__.py +0 -0
- plentymarkets_api_client-0.1.2/tests/conftest.py +9 -0
- plentymarkets_api_client-0.1.2/tests/test_client.py +58 -0
- plentymarkets_api_client-0.1.2/tests/test_contacts.py +87 -0
- plentymarkets_api_client-0.1.2/tests/test_exceptions.py +32 -0
- plentymarkets_api_client-0.1.2/tests/test_items.py +87 -0
- plentymarkets_api_client-0.1.2/tests/test_orders.py +110 -0
- plentymarkets_api_client-0.1.2/tests/test_session.py +324 -0
- plentymarkets_api_client-0.1.2/tests/test_stock.py +78 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# pyPlentyAPI — Claude Guide
|
|
2
|
+
|
|
3
|
+
## Project
|
|
4
|
+
Async Python client for the PlentyMarkets REST API. NOT PlentyBase.
|
|
5
|
+
Package name: `plentymarkets`. Entry point: `PlentyClient`.
|
|
6
|
+
|
|
7
|
+
## API Docs
|
|
8
|
+
- REST API reference: https://developers.plentymarkets.com/en-gb/plentymarkets-rest-api/index.html
|
|
9
|
+
- OpenAPI spec (JSON): https://raw.githubusercontent.com/plentymarkets/api-doc/master/plentymarkets/openApiV3/openApiV3.json
|
|
10
|
+
|
|
11
|
+
## Setup
|
|
12
|
+
```bash
|
|
13
|
+
uv sync --extra dev
|
|
14
|
+
uv run pre-commit install --hook-type commit-msg
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Running tests
|
|
18
|
+
```bash
|
|
19
|
+
uv run pytest # unit tests only
|
|
20
|
+
uv run pytest -m integration # requires live credentials
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Conventions
|
|
24
|
+
- Conventional commits enforced via commitizen (`feat:`, `fix:`, `docs:`, `chore:`, `test:`, `refactor:`)
|
|
25
|
+
- Google-style docstrings on ALL public methods; document every response dict key
|
|
26
|
+
- CHANGELOG.md: only ever write to `[Unreleased]` — never add a release section
|
|
27
|
+
- CHANGELOG.md: Group changes by module. Use the same prefix as in commit messages.
|
|
28
|
+
- Small focused commits, one logical change each
|
|
29
|
+
- **Branch workflow:** All changes must branch off `staging` and be merged back into `staging`. `main` is protected and only updated via merges from `staging`.
|
|
30
|
+
|
|
31
|
+
## Package structure
|
|
32
|
+
```
|
|
33
|
+
src/plentymarkets/
|
|
34
|
+
__init__.py # exports PlentyClient + all TypedDicts
|
|
35
|
+
client.py # PlentyClient
|
|
36
|
+
_session.py # HTTP session, auth lifecycle
|
|
37
|
+
_exceptions.py # exception hierarchy
|
|
38
|
+
_types.py # TypedDict payload definitions for all write operations
|
|
39
|
+
modules/
|
|
40
|
+
orders.py # OrdersModule → /rest/orders
|
|
41
|
+
items.py # ItemsModule → /rest/items
|
|
42
|
+
stock.py # StockModule → /rest/stock
|
|
43
|
+
contacts.py # ContactsModule → /rest/accounts/contacts
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## TypedDicts
|
|
47
|
+
`_types.py` holds `TypedDict` definitions for every method that accepts a `data` dict.
|
|
48
|
+
Import them for IDE autocomplete and static type checking — at runtime they are plain dicts.
|
|
49
|
+
|
|
50
|
+
| TypedDict | Used by |
|
|
51
|
+
|---|---|
|
|
52
|
+
| `OrderCreatePayload` | `client.orders.create(data)` |
|
|
53
|
+
| `ItemCreatePayload` | `client.items.create(data)` |
|
|
54
|
+
| `ItemUpdatePayload` | `client.items.update(item_id, data)` |
|
|
55
|
+
| `StockCorrectionPayload` | `client.stock.correct(warehouse_id, data)` |
|
|
56
|
+
| `ContactCreatePayload` | `client.contacts.create(data)` |
|
|
57
|
+
| `ContactUpdatePayload` | `client.contacts.update(contact_id, data)` |
|
|
58
|
+
|
|
59
|
+
All six are exported from `plentymarkets` directly:
|
|
60
|
+
```python
|
|
61
|
+
from plentymarkets import OrderCreatePayload, PlentyClient
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
When adding a new module method that accepts a payload dict, add a matching TypedDict
|
|
65
|
+
to `_types.py` and export it from `__init__.py`.
|
|
66
|
+
|
|
67
|
+
## Auth
|
|
68
|
+
POST /rest/login with username+password → accessToken + expiresIn (seconds).
|
|
69
|
+
Token sent as `Authorization: Bearer <token>` on every request.
|
|
70
|
+
Auto-refreshed when within 60 s of expiry. 401 mid-session → re-login once → retry.
|
|
71
|
+
```
|
|
72
|
+
```
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
release:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
permissions:
|
|
12
|
+
contents: write
|
|
13
|
+
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- name: Install uv
|
|
18
|
+
run: |
|
|
19
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
20
|
+
echo "$HOME/.local/bin" >> $GITHUB_PATH
|
|
21
|
+
|
|
22
|
+
- name: Install dependencies
|
|
23
|
+
run: uv sync --extra dev
|
|
24
|
+
|
|
25
|
+
- name: Run tests
|
|
26
|
+
run: uv run pytest
|
|
27
|
+
|
|
28
|
+
- name: Extract version
|
|
29
|
+
id: version
|
|
30
|
+
run: |
|
|
31
|
+
VERSION=$(grep '^version' pyproject.toml | head -1 | cut -d'"' -f2)
|
|
32
|
+
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
33
|
+
echo "tag=v$VERSION" >> $GITHUB_OUTPUT
|
|
34
|
+
|
|
35
|
+
- name: Build distribution
|
|
36
|
+
run: uv build
|
|
37
|
+
|
|
38
|
+
- name: Publish to PyPI
|
|
39
|
+
env:
|
|
40
|
+
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_TOKEN }}
|
|
41
|
+
run: uv publish
|
|
42
|
+
|
|
43
|
+
- name: Extract changelog entry
|
|
44
|
+
id: changelog
|
|
45
|
+
run: |
|
|
46
|
+
python3 - "${{ steps.version.outputs.version }}" <<'EOF'
|
|
47
|
+
import re
|
|
48
|
+
import sys
|
|
49
|
+
|
|
50
|
+
version = sys.argv[1]
|
|
51
|
+
content = open("CHANGELOG.md").read()
|
|
52
|
+
pattern = rf"## \[{re.escape(version)}\][^\n]*\n(.*?)(?=\n## \[|\Z)"
|
|
53
|
+
match = re.search(pattern, content, re.DOTALL)
|
|
54
|
+
entry = match.group(1).strip() if match else ""
|
|
55
|
+
open("changelog_entry.md", "w").write(entry)
|
|
56
|
+
EOF
|
|
57
|
+
|
|
58
|
+
- name: Create release and upload artifacts
|
|
59
|
+
env:
|
|
60
|
+
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
|
61
|
+
run: |
|
|
62
|
+
set -e
|
|
63
|
+
REPO="${{ github.repository }}"
|
|
64
|
+
TAG="${{ steps.version.outputs.tag }}"
|
|
65
|
+
|
|
66
|
+
STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
|
|
67
|
+
-H "Authorization: token $GITEA_TOKEN" \
|
|
68
|
+
"https://codeberg.org/api/v1/repos/$REPO/releases/tags/$TAG")
|
|
69
|
+
|
|
70
|
+
if [ "$STATUS" != "200" ]; then
|
|
71
|
+
python3 - "$TAG" "${{ github.sha }}" <<'EOF' > release_payload.json
|
|
72
|
+
import json
|
|
73
|
+
import sys
|
|
74
|
+
|
|
75
|
+
tag, sha = sys.argv[1], sys.argv[2]
|
|
76
|
+
body = open("changelog_entry.md").read()
|
|
77
|
+
print(json.dumps({
|
|
78
|
+
"tag_name": tag,
|
|
79
|
+
"target_commitish": sha,
|
|
80
|
+
"name": tag,
|
|
81
|
+
"body": body,
|
|
82
|
+
"draft": False,
|
|
83
|
+
"prerelease": False,
|
|
84
|
+
}))
|
|
85
|
+
EOF
|
|
86
|
+
|
|
87
|
+
curl -X POST \
|
|
88
|
+
-H "Authorization: token $GITEA_TOKEN" \
|
|
89
|
+
-H "Content-Type: application/json" \
|
|
90
|
+
--data-binary @release_payload.json \
|
|
91
|
+
"https://codeberg.org/api/v1/repos/$REPO/releases"
|
|
92
|
+
fi
|
|
93
|
+
|
|
94
|
+
RELEASE_ID=$(curl -s \
|
|
95
|
+
-H "Authorization: token $GITEA_TOKEN" \
|
|
96
|
+
"https://codeberg.org/api/v1/repos/$REPO/releases/tags/$TAG" \
|
|
97
|
+
| python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")
|
|
98
|
+
|
|
99
|
+
for file in dist/*; do
|
|
100
|
+
[ -f "$file" ] || continue
|
|
101
|
+
curl -X POST \
|
|
102
|
+
-H "Authorization: token $GITEA_TOKEN" \
|
|
103
|
+
-F "attachment=@$file" \
|
|
104
|
+
"https://codeberg.org/api/v1/repos/$REPO/releases/$RELEASE_ID/assets"
|
|
105
|
+
done
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [0.1.2] - 2026-06-30
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
- `pyproject`: rename PyPI distribution from `plentymarkets` to `plentymarkets-api-client` — the import package stays `plentymarkets` (`from plentymarkets import PlentyClient`)
|
|
13
|
+
- `pyproject`: add full PyPI metadata — `readme`, `license`, `authors`, `keywords`, `classifiers`, `project.urls` (Homepage, Repository, Issues, Changelog)
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
- `plentymarkets`: PEP 561 `py.typed` marker so downstream type checkers pick up the package's type hints
|
|
17
|
+
|
|
18
|
+
## [0.1.1] - 2026-06-30
|
|
19
|
+
|
|
20
|
+
### CI
|
|
21
|
+
- `release`: publish built distributions to PyPI via `uv publish` after the Codeberg release build ([`c450759`](https://codeberg.org/ZanderHammer/pyPlentyAPI/commit/c450759))
|
|
22
|
+
- `release`: use the matching `CHANGELOG.md` `## [VERSION]` section as the Codeberg release body instead of a generic link ([`07730aa`](https://codeberg.org/ZanderHammer/pyPlentyAPI/commit/07730aa))
|
|
23
|
+
|
|
24
|
+
### Chore
|
|
25
|
+
- `commitizen`: add `scripts/bump_changelog.py` as a `pre_bump_hook` to version the `[Unreleased]` section into `## [VERSION] - DATE` automatically on `cz bump` ([`bc4728c`](https://codeberg.org/ZanderHammer/pyPlentyAPI/commit/bc4728c))
|
|
26
|
+
|
|
27
|
+
## [0.1.0] - 2026-06-30
|
|
28
|
+
|
|
29
|
+
### Added
|
|
30
|
+
- Exception hierarchy: `PlentyError`, `AuthError`, `NotFoundError`, `RateLimitError`, `ServerError`, `ConnectionError`
|
|
31
|
+
- `_Session`: async HTTP client with login, token auto-refresh, 401 re-login, and error mapping
|
|
32
|
+
- `PlentyClient`: async context manager with lazy `orders`, `items`, `stock`, `contacts` module properties
|
|
33
|
+
- `OrdersModule`: `get`, `list`, `create`, `update_status`, `paginate_orders` (`/rest/orders`)
|
|
34
|
+
- `ItemsModule`: `get`, `list`, `create`, `update`, `paginate_items` (`/rest/items`)
|
|
35
|
+
- `StockModule`: `get_by_warehouse`, `correct`, `paginate_stock` (`/rest/stock/warehouses`)
|
|
36
|
+
- `ContactsModule`: `get`, `list`, `create`, `update`, `paginate_contacts` (`/rest/accounts/contacts`)
|
|
37
|
+
- `_types`: `TypedDict` payload definitions for all write operations — `OrderCreatePayload`, `ItemCreatePayload`, `ItemUpdatePayload`, `StockCorrectionPayload`, `ContactCreatePayload`, `ContactUpdatePayload`; all exported from `plentymarkets` top-level
|
|
38
|
+
- `PlentyClient`, `OrdersModule`, `ItemsModule`, `StockModule`, `ContactsModule`: `__repr__` for readable debug output ([`5ad0e94`](https://codeberg.org/ZanderHammer/pyPlentyAPI/commit/5ad0e94))
|
|
39
|
+
|
|
40
|
+
### Fixed
|
|
41
|
+
- `_session`: raise `ValueError` when `base_url` contains `/rest`, preventing a silent `JSONDecodeError` from doubled path segments ([`731ff44`](https://codeberg.org/ZanderHammer/pyPlentyAPI/commit/731ff44))
|
|
42
|
+
- All modules, `_session`: replace bare `dict` return annotations with `dict[str, Any]`, resolving `Unknown` type hints in Pylance ([`a47534d`](https://codeberg.org/ZanderHammer/pyPlentyAPI/commit/a47534d))
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Alexander Hammer
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: plentymarkets-api-client
|
|
3
|
+
Version: 0.1.2
|
|
4
|
+
Summary: Async Python client for the PlentyMarkets REST API
|
|
5
|
+
Project-URL: Homepage, https://codeberg.org/ZanderHammer/pyPlentyAPI
|
|
6
|
+
Project-URL: Repository, https://codeberg.org/ZanderHammer/pyPlentyAPI
|
|
7
|
+
Project-URL: Issues, https://codeberg.org/ZanderHammer/pyPlentyAPI/issues
|
|
8
|
+
Project-URL: Changelog, https://codeberg.org/ZanderHammer/pyPlentyAPI/src/branch/main/CHANGELOG.md
|
|
9
|
+
Author-email: Alexander Hammer <acj259@gmail.com>
|
|
10
|
+
License: MIT License
|
|
11
|
+
|
|
12
|
+
Copyright (c) 2026 Alexander Hammer
|
|
13
|
+
|
|
14
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
15
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
16
|
+
in the Software without restriction, including without limitation the rights
|
|
17
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
18
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
19
|
+
furnished to do so, subject to the following conditions:
|
|
20
|
+
|
|
21
|
+
The above copyright notice and this permission notice shall be included in all
|
|
22
|
+
copies or substantial portions of the Software.
|
|
23
|
+
|
|
24
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
25
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
26
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
27
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
28
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
29
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
30
|
+
SOFTWARE.
|
|
31
|
+
License-File: LICENSE
|
|
32
|
+
Keywords: async,ecommerce,httpx,plentymarkets,rest-api
|
|
33
|
+
Classifier: Development Status :: 3 - Alpha
|
|
34
|
+
Classifier: Intended Audience :: Developers
|
|
35
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
36
|
+
Classifier: Operating System :: OS Independent
|
|
37
|
+
Classifier: Programming Language :: Python :: 3
|
|
38
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
39
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
40
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
41
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
42
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
43
|
+
Classifier: Typing :: Typed
|
|
44
|
+
Requires-Python: >=3.11
|
|
45
|
+
Requires-Dist: httpx>=0.27
|
|
46
|
+
Provides-Extra: dev
|
|
47
|
+
Requires-Dist: commitizen>=3.29; extra == 'dev'
|
|
48
|
+
Requires-Dist: hatchling>=1.25; extra == 'dev'
|
|
49
|
+
Requires-Dist: pre-commit>=3.7; extra == 'dev'
|
|
50
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
51
|
+
Requires-Dist: pytest-httpx>=0.30; extra == 'dev'
|
|
52
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
53
|
+
Description-Content-Type: text/markdown
|
|
54
|
+
|
|
55
|
+
# pyPlentyAPI
|
|
56
|
+
|
|
57
|
+
[](https://opensource.org/licenses/MIT)
|
|
58
|
+
[](https://www.python.org/downloads/)
|
|
59
|
+
[](https://github.com/astral-sh/uv)
|
|
60
|
+
[](https://docs.pytest.org/)
|
|
61
|
+
|
|
62
|
+
Async Python client for the [PlentyMarkets REST API](https://developers.plentymarkets.com/en-gb/plentymarkets-rest-api/index.html).
|
|
63
|
+
|
|
64
|
+
## Features
|
|
65
|
+
- **Async-first**: Built on `httpx.AsyncClient` for high-performance async/await support.
|
|
66
|
+
- **Lazy-loaded modules**: Access `orders`, `items`, `stock`, and `contacts` as properties of `PlentyClient`.
|
|
67
|
+
- **Auto-refreshing auth**: Tokens are refreshed automatically when within 60 seconds of expiry.
|
|
68
|
+
- **Comprehensive error handling**: Custom exceptions for HTTP status codes (e.g., `NotFoundError`, `RateLimitError`).
|
|
69
|
+
- **Pagination support**: Async generators for iterating across all pages of results.
|
|
70
|
+
- **Type hints**: Full type annotations for IDE support and static analysis.
|
|
71
|
+
|
|
72
|
+
## Installation
|
|
73
|
+
```bash
|
|
74
|
+
pip install plentymarkets-api-client
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Or with `uv`:
|
|
78
|
+
```bash
|
|
79
|
+
uv add plentymarkets-api-client
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Quickstart
|
|
83
|
+
```python
|
|
84
|
+
import asyncio
|
|
85
|
+
from plentymarkets import PlentyClient
|
|
86
|
+
|
|
87
|
+
async def main():
|
|
88
|
+
async with PlentyClient(username="your_username", password="your_password") as client:
|
|
89
|
+
# Fetch an order by ID
|
|
90
|
+
order = await client.orders.get(123)
|
|
91
|
+
print(order)
|
|
92
|
+
|
|
93
|
+
# List all items (paginated)
|
|
94
|
+
async for item in client.items.paginate_items():
|
|
95
|
+
print(item)
|
|
96
|
+
|
|
97
|
+
asyncio.run(main())
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Modules
|
|
101
|
+
| Module | Description | Key Methods |
|
|
102
|
+
|-----------|--------------------------------------|-------------------------------------------------------------------------------------------------|
|
|
103
|
+
| **Orders** | Manage orders and order statuses. | `get()`, `list()`, `create()`, `update_status()`, `paginate_orders()` |
|
|
104
|
+
| **Items** | Manage items and item variants. | `get()`, `list()`, `create()`, `update()`, `paginate_items()` |
|
|
105
|
+
| **Stock** | Manage stock across warehouses. | `get_by_warehouse()`, `correct()`, `paginate_stock()` |
|
|
106
|
+
| **Contacts** | Manage customer and supplier data. | `get()`, `list()`, `create()`, `update()`, `paginate_contacts()` |
|
|
107
|
+
|
|
108
|
+
## Authentication
|
|
109
|
+
1. Initialize `PlentyClient` with your PlentyMarkets username and password.
|
|
110
|
+
2. The client automatically logs in and manages the `accessToken` lifecycle.
|
|
111
|
+
3. Tokens are sent as `Authorization: Bearer <token>` in all requests.
|
|
112
|
+
4. If a 401 error occurs, the client attempts to re-login once before failing.
|
|
113
|
+
|
|
114
|
+
## Error Handling
|
|
115
|
+
Custom exceptions are raised for HTTP errors:
|
|
116
|
+
- `AuthError`: 401 Unauthorized
|
|
117
|
+
- `NotFoundError`: 404 Not Found
|
|
118
|
+
- `RateLimitError`: 429 Too Many Requests
|
|
119
|
+
- `ServerError`: 5xx Server Errors
|
|
120
|
+
- `ConnectionError`: Network failures
|
|
121
|
+
|
|
122
|
+
Example:
|
|
123
|
+
```python
|
|
124
|
+
try:
|
|
125
|
+
order = await client.orders.get(99999)
|
|
126
|
+
except plentymarkets.NotFoundError:
|
|
127
|
+
print("Order not found")
|
|
128
|
+
except plentymarkets.RateLimitError:
|
|
129
|
+
print("Rate limit exceeded")
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Pagination
|
|
133
|
+
Use async generators to iterate across all pages:
|
|
134
|
+
```python
|
|
135
|
+
async for order in client.orders.paginate_orders():
|
|
136
|
+
print(order)
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Development
|
|
140
|
+
### Setup
|
|
141
|
+
```bash
|
|
142
|
+
uv sync --extra dev
|
|
143
|
+
uv run pre-commit install --hook-type commit-msg
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Running Tests
|
|
147
|
+
```bash
|
|
148
|
+
uv run pytest # Unit tests
|
|
149
|
+
uv run pytest -m integration # Integration tests (requires live credentials)
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## License
|
|
153
|
+
MIT
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# pyPlentyAPI
|
|
2
|
+
|
|
3
|
+
[](https://opensource.org/licenses/MIT)
|
|
4
|
+
[](https://www.python.org/downloads/)
|
|
5
|
+
[](https://github.com/astral-sh/uv)
|
|
6
|
+
[](https://docs.pytest.org/)
|
|
7
|
+
|
|
8
|
+
Async Python client for the [PlentyMarkets REST API](https://developers.plentymarkets.com/en-gb/plentymarkets-rest-api/index.html).
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
- **Async-first**: Built on `httpx.AsyncClient` for high-performance async/await support.
|
|
12
|
+
- **Lazy-loaded modules**: Access `orders`, `items`, `stock`, and `contacts` as properties of `PlentyClient`.
|
|
13
|
+
- **Auto-refreshing auth**: Tokens are refreshed automatically when within 60 seconds of expiry.
|
|
14
|
+
- **Comprehensive error handling**: Custom exceptions for HTTP status codes (e.g., `NotFoundError`, `RateLimitError`).
|
|
15
|
+
- **Pagination support**: Async generators for iterating across all pages of results.
|
|
16
|
+
- **Type hints**: Full type annotations for IDE support and static analysis.
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
```bash
|
|
20
|
+
pip install plentymarkets-api-client
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Or with `uv`:
|
|
24
|
+
```bash
|
|
25
|
+
uv add plentymarkets-api-client
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Quickstart
|
|
29
|
+
```python
|
|
30
|
+
import asyncio
|
|
31
|
+
from plentymarkets import PlentyClient
|
|
32
|
+
|
|
33
|
+
async def main():
|
|
34
|
+
async with PlentyClient(username="your_username", password="your_password") as client:
|
|
35
|
+
# Fetch an order by ID
|
|
36
|
+
order = await client.orders.get(123)
|
|
37
|
+
print(order)
|
|
38
|
+
|
|
39
|
+
# List all items (paginated)
|
|
40
|
+
async for item in client.items.paginate_items():
|
|
41
|
+
print(item)
|
|
42
|
+
|
|
43
|
+
asyncio.run(main())
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Modules
|
|
47
|
+
| Module | Description | Key Methods |
|
|
48
|
+
|-----------|--------------------------------------|-------------------------------------------------------------------------------------------------|
|
|
49
|
+
| **Orders** | Manage orders and order statuses. | `get()`, `list()`, `create()`, `update_status()`, `paginate_orders()` |
|
|
50
|
+
| **Items** | Manage items and item variants. | `get()`, `list()`, `create()`, `update()`, `paginate_items()` |
|
|
51
|
+
| **Stock** | Manage stock across warehouses. | `get_by_warehouse()`, `correct()`, `paginate_stock()` |
|
|
52
|
+
| **Contacts** | Manage customer and supplier data. | `get()`, `list()`, `create()`, `update()`, `paginate_contacts()` |
|
|
53
|
+
|
|
54
|
+
## Authentication
|
|
55
|
+
1. Initialize `PlentyClient` with your PlentyMarkets username and password.
|
|
56
|
+
2. The client automatically logs in and manages the `accessToken` lifecycle.
|
|
57
|
+
3. Tokens are sent as `Authorization: Bearer <token>` in all requests.
|
|
58
|
+
4. If a 401 error occurs, the client attempts to re-login once before failing.
|
|
59
|
+
|
|
60
|
+
## Error Handling
|
|
61
|
+
Custom exceptions are raised for HTTP errors:
|
|
62
|
+
- `AuthError`: 401 Unauthorized
|
|
63
|
+
- `NotFoundError`: 404 Not Found
|
|
64
|
+
- `RateLimitError`: 429 Too Many Requests
|
|
65
|
+
- `ServerError`: 5xx Server Errors
|
|
66
|
+
- `ConnectionError`: Network failures
|
|
67
|
+
|
|
68
|
+
Example:
|
|
69
|
+
```python
|
|
70
|
+
try:
|
|
71
|
+
order = await client.orders.get(99999)
|
|
72
|
+
except plentymarkets.NotFoundError:
|
|
73
|
+
print("Order not found")
|
|
74
|
+
except plentymarkets.RateLimitError:
|
|
75
|
+
print("Rate limit exceeded")
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Pagination
|
|
79
|
+
Use async generators to iterate across all pages:
|
|
80
|
+
```python
|
|
81
|
+
async for order in client.orders.paginate_orders():
|
|
82
|
+
print(order)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Development
|
|
86
|
+
### Setup
|
|
87
|
+
```bash
|
|
88
|
+
uv sync --extra dev
|
|
89
|
+
uv run pre-commit install --hook-type commit-msg
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Running Tests
|
|
93
|
+
```bash
|
|
94
|
+
uv run pytest # Unit tests
|
|
95
|
+
uv run pytest -m integration # Integration tests (requires live credentials)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## License
|
|
99
|
+
MIT
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Roadmap
|
|
2
|
+
|
|
3
|
+
All 53 modules available in the PlentyMarkets REST API. Modules marked **[core]** are in the
|
|
4
|
+
initial implementation scope. All others are planned for future incremental additions.
|
|
5
|
+
|
|
6
|
+
| API Tag | Description | Status |
|
|
7
|
+
|---|---|---|
|
|
8
|
+
| `Account` | Customer accounts and contacts — addresses, contact data, bank details | **[core]** |
|
|
9
|
+
| `Accounting` | VAT configurations, financial accounts, revenue bookings | planned |
|
|
10
|
+
| `AddressDesign` | Address label templates and print format settings | planned |
|
|
11
|
+
| `AuditLog` | Change history and audit trail for system actions | planned |
|
|
12
|
+
| `Authentication` | Login/logout and token management | internal (used by `_session.py`) |
|
|
13
|
+
| `Authorization` | User roles, permissions, and access rights | planned |
|
|
14
|
+
| `BI` | Business intelligence — reports and analytics data | planned |
|
|
15
|
+
| `Basket` | Shopping cart / basket management for webshop visitors | planned |
|
|
16
|
+
| `Batch` | Batch processing and bulk operations across resources | planned |
|
|
17
|
+
| `Blog` | Blog posts and categories published in the webshop | planned |
|
|
18
|
+
| `Board` | Task boards (Kanban-style) for internal team workflows | planned |
|
|
19
|
+
| `Boards` | Board management — creating and configuring boards | planned |
|
|
20
|
+
| `Catalog` | Data catalogues for flexible export/import field mappings | planned |
|
|
21
|
+
| `Category` | Product and content categories used in webshop and items | planned |
|
|
22
|
+
| `Cloud` | Cloud storage and file management | planned |
|
|
23
|
+
| `Comment` | Comments attachable to orders, contacts, and tickets | planned |
|
|
24
|
+
| `Configuration` | System-wide settings and global configuration values | planned |
|
|
25
|
+
| `Document` | Order documents — invoices, delivery notes, return slips | planned |
|
|
26
|
+
| `ElasticSync` | Data import/sync mappings (Data Exchange / ElasticSync) | planned |
|
|
27
|
+
| `Export` | Data export formats, fields, and export jobs | planned |
|
|
28
|
+
| `ExportSettings` | Settings and saved configurations for exports | planned |
|
|
29
|
+
| `Feedback` | Customer product reviews and ratings | planned |
|
|
30
|
+
| `Fulfillment` | Shipping labels, package tracking, shipping service providers | planned |
|
|
31
|
+
| `Item` | Product catalogue — items, variations, images, attributes, prices | **[core]** |
|
|
32
|
+
| `LegalInformation` | Legal texts — terms of service, privacy policy, cancellation rights | planned |
|
|
33
|
+
| `Listing` | eBay/marketplace listing templates and active listings | planned |
|
|
34
|
+
| `Log` | System log entries and error/debug logs | planned |
|
|
35
|
+
| `MailTemplates` | Email templates for automated system notifications | planned |
|
|
36
|
+
| `Market` | Marketplace integrations — Amazon, eBay, Otto, etc. | planned |
|
|
37
|
+
| `Messenger` | Internal messaging between system users | planned |
|
|
38
|
+
| `Newsletter` | Newsletter recipient lists and subscription management | planned |
|
|
39
|
+
| `Order` | Orders, order items, order properties, and status management | **[core]** |
|
|
40
|
+
| `OrderSummary` | Aggregated order statistics and revenue summaries | planned |
|
|
41
|
+
| `Payment` | Payments, payment methods, and booking payments to orders | planned |
|
|
42
|
+
| `Pim` | Product Information Management — PIM-specific item operations | planned |
|
|
43
|
+
| `PluginMultilingualism` | Plugin translation strings and multilingual content | planned |
|
|
44
|
+
| `PluginSet` | Plugin set management and deployment to clients | planned |
|
|
45
|
+
| `Plugins` | Plugin installation, configuration, and lifecycle | planned |
|
|
46
|
+
| `Property` | Item and contact properties — property groups and values | planned |
|
|
47
|
+
| `Returns` | Return orders, return reasons, and return processing | planned |
|
|
48
|
+
| `ShopBuilder` | Webshop layout and drag-and-drop page builder configuration | planned |
|
|
49
|
+
| `Stock` | Item stock levels, stock movements, and manual corrections | **[core]** |
|
|
50
|
+
| `StockManagement` | Warehouse-level stock redistribution and incoming goods | planned |
|
|
51
|
+
| `Sync` | Data synchronisation jobs and field mapping configuration | planned |
|
|
52
|
+
| `Tag` | Tags for labelling orders, contacts, variations, etc. | planned |
|
|
53
|
+
| `Ticket` | Support tickets and helpdesk case management | planned |
|
|
54
|
+
| `TicketMessage` | Messages and replies within support tickets | planned |
|
|
55
|
+
| `Todo` | Internal to-do tasks and user assignments | planned |
|
|
56
|
+
| `User` | System users, user accounts, and preferences | planned |
|
|
57
|
+
| `Warehouse` | Warehouse configuration, storage locations, rack management | planned |
|
|
58
|
+
| `Webstore` | Webshop settings, themes, plugins, and client configuration | planned |
|
|
59
|
+
| `Wizard` | Setup wizards for guided first-time configuration | planned |
|
|
60
|
+
| `plentyMarketplace` | plentyMarkets plugin marketplace integration | planned |
|