python-sendparcel-inpost 0.1.1__tar.gz → 0.2.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.
- python_sendparcel_inpost-0.2.0/.github/workflows/ci.yml +28 -0
- python_sendparcel_inpost-0.2.0/.github/workflows/release.yml +23 -0
- python_sendparcel_inpost-0.2.0/LICENSE +10 -0
- python_sendparcel_inpost-0.2.0/PKG-INFO +106 -0
- python_sendparcel_inpost-0.2.0/README.md +72 -0
- {python_sendparcel_inpost-0.1.1 → python_sendparcel_inpost-0.2.0}/docs/configuration.md +6 -6
- {python_sendparcel_inpost-0.1.1 → python_sendparcel_inpost-0.2.0}/pyproject.toml +10 -2
- {python_sendparcel_inpost-0.1.1 → python_sendparcel_inpost-0.2.0}/src/sendparcel_inpost/__init__.py +3 -1
- python_sendparcel_inpost-0.2.0/src/sendparcel_inpost/client.py +751 -0
- {python_sendparcel_inpost-0.1.1 → python_sendparcel_inpost-0.2.0}/src/sendparcel_inpost/exceptions.py +27 -0
- {python_sendparcel_inpost-0.1.1 → python_sendparcel_inpost-0.2.0}/src/sendparcel_inpost/providers/__init__.py +6 -1
- python_sendparcel_inpost-0.2.0/src/sendparcel_inpost/providers/base.py +368 -0
- python_sendparcel_inpost-0.2.0/src/sendparcel_inpost/providers/courier.py +93 -0
- python_sendparcel_inpost-0.2.0/src/sendparcel_inpost/providers/locker.py +103 -0
- {python_sendparcel_inpost-0.1.1 → python_sendparcel_inpost-0.2.0}/src/sendparcel_inpost/status_mapping.py +17 -0
- python_sendparcel_inpost-0.2.0/tests/__init__.py +0 -0
- python_sendparcel_inpost-0.2.0/tests/test_client.py +506 -0
- {python_sendparcel_inpost-0.1.1 → python_sendparcel_inpost-0.2.0}/tests/test_courier_provider.py +64 -60
- {python_sendparcel_inpost-0.1.1 → python_sendparcel_inpost-0.2.0}/tests/test_enums.py +11 -5
- {python_sendparcel_inpost-0.1.1 → python_sendparcel_inpost-0.2.0}/tests/test_locker_provider.py +181 -87
- {python_sendparcel_inpost-0.1.1 → python_sendparcel_inpost-0.2.0}/tests/test_status_mapping.py +31 -0
- python_sendparcel_inpost-0.1.1/PKG-INFO +0 -371
- python_sendparcel_inpost-0.1.1/README.md +0 -343
- python_sendparcel_inpost-0.1.1/src/sendparcel_inpost/client.py +0 -177
- python_sendparcel_inpost-0.1.1/src/sendparcel_inpost/providers/courier.py +0 -305
- python_sendparcel_inpost-0.1.1/src/sendparcel_inpost/providers/locker.py +0 -320
- python_sendparcel_inpost-0.1.1/tests/test_client.py +0 -233
- {python_sendparcel_inpost-0.1.1 → python_sendparcel_inpost-0.2.0}/.gitignore +0 -0
- {python_sendparcel_inpost-0.1.1 → python_sendparcel_inpost-0.2.0}/CHANGELOG.md +0 -0
- {python_sendparcel_inpost-0.1.1 → python_sendparcel_inpost-0.2.0}/CONTRIBUTING.md +0 -0
- {python_sendparcel_inpost-0.1.1 → python_sendparcel_inpost-0.2.0}/docs/api.md +0 -0
- {python_sendparcel_inpost-0.1.1 → python_sendparcel_inpost-0.2.0}/docs/index.md +0 -0
- {python_sendparcel_inpost-0.1.1 → python_sendparcel_inpost-0.2.0}/docs/quickstart.md +0 -0
- {python_sendparcel_inpost-0.1.1 → python_sendparcel_inpost-0.2.0}/src/sendparcel_inpost/enums.py +0 -0
- /python_sendparcel_inpost-0.1.1/tests/__init__.py → /python_sendparcel_inpost-0.2.0/src/sendparcel_inpost/py.typed +0 -0
- {python_sendparcel_inpost-0.1.1 → python_sendparcel_inpost-0.2.0}/src/sendparcel_inpost/types.py +0 -0
- {python_sendparcel_inpost-0.1.1 → python_sendparcel_inpost-0.2.0}/tests/conftest.py +0 -0
- {python_sendparcel_inpost-0.1.1 → python_sendparcel_inpost-0.2.0}/tests/test_config_schema.py +0 -0
- {python_sendparcel_inpost-0.1.1 → python_sendparcel_inpost-0.2.0}/tests/test_entry_points.py +0 -0
- {python_sendparcel_inpost-0.1.1 → python_sendparcel_inpost-0.2.0}/tests/test_exceptions.py +0 -0
- {python_sendparcel_inpost-0.1.1 → python_sendparcel_inpost-0.2.0}/tests/test_types.py +0 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
lint:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
- uses: astral-sh/setup-uv@v5
|
|
14
|
+
with:
|
|
15
|
+
enable-cache: true
|
|
16
|
+
- run: uv sync --extra dev
|
|
17
|
+
- run: uv run ruff check .
|
|
18
|
+
- run: uv run ruff format --check .
|
|
19
|
+
|
|
20
|
+
test:
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
- uses: astral-sh/setup-uv@v5
|
|
25
|
+
with:
|
|
26
|
+
enable-cache: true
|
|
27
|
+
- run: uv sync --extra dev
|
|
28
|
+
- run: uv run pytest tests/ --cov=sendparcel_inpost --cov-report=xml -v
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
id-token: write
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
release:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
environment: release
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: astral-sh/setup-uv@v5
|
|
18
|
+
with:
|
|
19
|
+
enable-cache: true
|
|
20
|
+
- name: Build package
|
|
21
|
+
run: uv build
|
|
22
|
+
- name: Publish to PyPI
|
|
23
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
|
|
2
|
+
MIT License
|
|
3
|
+
|
|
4
|
+
Copyright (c) 2025, Dominik Kozaczko
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
7
|
+
|
|
8
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
9
|
+
|
|
10
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: python-sendparcel-inpost
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: InPost ShipX provider for python-sendparcel.
|
|
5
|
+
Project-URL: Homepage, https://github.com/python-sendparcel/python-sendparcel-inpost
|
|
6
|
+
Project-URL: Repository, https://github.com/python-sendparcel/python-sendparcel-inpost
|
|
7
|
+
Project-URL: Changelog, https://github.com/python-sendparcel/python-sendparcel-inpost/blob/main/CHANGELOG.md
|
|
8
|
+
Project-URL: Issue Tracker, https://github.com/python-sendparcel/python-sendparcel-inpost/issues
|
|
9
|
+
Author-email: Dominik Kozaczko <dominik@kozaczko.info>
|
|
10
|
+
License: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: inpost,parcel,sendparcel,shipping,shipx
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Natural Language :: English
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
|
+
Classifier: Typing :: Typed
|
|
22
|
+
Requires-Python: >=3.12
|
|
23
|
+
Requires-Dist: anyio>=4.0
|
|
24
|
+
Requires-Dist: httpx>=0.27.0
|
|
25
|
+
Requires-Dist: python-sendparcel>=0.1.1
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
|
|
28
|
+
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
|
|
29
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
30
|
+
Requires-Dist: respx>=0.22.0; extra == 'dev'
|
|
31
|
+
Requires-Dist: ruff>=0.9.0; extra == 'dev'
|
|
32
|
+
Requires-Dist: ty>=0.0.1a11; extra == 'dev'
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
|
|
35
|
+
# python-sendparcel-inpost
|
|
36
|
+
|
|
37
|
+
InPost ShipX provider package for the `python-sendparcel` ecosystem.
|
|
38
|
+
|
|
39
|
+
> Alpha notice: this package tracks the still-changing `python-sendparcel` core.
|
|
40
|
+
|
|
41
|
+
## What it provides
|
|
42
|
+
|
|
43
|
+
- `InPostLockerProvider` for locker shipments
|
|
44
|
+
- `InPostCourierProvider` for courier shipments
|
|
45
|
+
- `ShipXClient` for direct async ShipX API access
|
|
46
|
+
- ShipX-to-sendparcel status normalization helpers
|
|
47
|
+
|
|
48
|
+
## Contract
|
|
49
|
+
|
|
50
|
+
This package follows the cleaned core contract:
|
|
51
|
+
|
|
52
|
+
- `create_shipment(...) -> ShipmentCreateResult`
|
|
53
|
+
- `create_label(...) -> LabelInfo`
|
|
54
|
+
- `handle_callback(...) -> ShipmentUpdateResult`
|
|
55
|
+
- `fetch_shipment_status(...) -> ShipmentUpdateResult`
|
|
56
|
+
- `cancel_shipment(...) -> bool`
|
|
57
|
+
|
|
58
|
+
Providers do not mutate shipment state directly. They translate ShipX responses into normalized results that the core flow applies.
|
|
59
|
+
|
|
60
|
+
## Installation
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
uv add python-sendparcel-inpost
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
or:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
pip install python-sendparcel-inpost
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Configuration
|
|
73
|
+
|
|
74
|
+
| Key | Type | Description |
|
|
75
|
+
|---|---|---|
|
|
76
|
+
| `token` | `str` | ShipX API bearer token |
|
|
77
|
+
| `organization_id` | `int` | ShipX organization ID |
|
|
78
|
+
| `sandbox` | `bool` | Use sandbox API |
|
|
79
|
+
| `base_url` | `str` | Optional API base override |
|
|
80
|
+
| `timeout` | `float` | Request timeout in seconds |
|
|
81
|
+
|
|
82
|
+
## Status normalization
|
|
83
|
+
|
|
84
|
+
ShipX statuses are normalized to sendparcel shipment statuses.
|
|
85
|
+
|
|
86
|
+
- recognized ShipX statuses produce `{"status": ...}`
|
|
87
|
+
- tracking numbers are included when available
|
|
88
|
+
- unknown ShipX statuses do not invent fake sendparcel statuses
|
|
89
|
+
|
|
90
|
+
That means callback and polling updates can safely return only tracking data when ShipX introduces a new status the mapper does not know yet.
|
|
91
|
+
|
|
92
|
+
## Labels
|
|
93
|
+
|
|
94
|
+
Labels are returned as payloads.
|
|
95
|
+
|
|
96
|
+
- PDF labels are returned as base64 content in `LabelInfo["content_base64"]`
|
|
97
|
+
- no label URL is persisted by the core contract
|
|
98
|
+
|
|
99
|
+
## Development
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
uv sync --extra dev
|
|
103
|
+
uv run pytest
|
|
104
|
+
uv run ruff check src tests
|
|
105
|
+
uv run mypy src tests
|
|
106
|
+
```
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# python-sendparcel-inpost
|
|
2
|
+
|
|
3
|
+
InPost ShipX provider package for the `python-sendparcel` ecosystem.
|
|
4
|
+
|
|
5
|
+
> Alpha notice: this package tracks the still-changing `python-sendparcel` core.
|
|
6
|
+
|
|
7
|
+
## What it provides
|
|
8
|
+
|
|
9
|
+
- `InPostLockerProvider` for locker shipments
|
|
10
|
+
- `InPostCourierProvider` for courier shipments
|
|
11
|
+
- `ShipXClient` for direct async ShipX API access
|
|
12
|
+
- ShipX-to-sendparcel status normalization helpers
|
|
13
|
+
|
|
14
|
+
## Contract
|
|
15
|
+
|
|
16
|
+
This package follows the cleaned core contract:
|
|
17
|
+
|
|
18
|
+
- `create_shipment(...) -> ShipmentCreateResult`
|
|
19
|
+
- `create_label(...) -> LabelInfo`
|
|
20
|
+
- `handle_callback(...) -> ShipmentUpdateResult`
|
|
21
|
+
- `fetch_shipment_status(...) -> ShipmentUpdateResult`
|
|
22
|
+
- `cancel_shipment(...) -> bool`
|
|
23
|
+
|
|
24
|
+
Providers do not mutate shipment state directly. They translate ShipX responses into normalized results that the core flow applies.
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
uv add python-sendparcel-inpost
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
or:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pip install python-sendparcel-inpost
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Configuration
|
|
39
|
+
|
|
40
|
+
| Key | Type | Description |
|
|
41
|
+
|---|---|---|
|
|
42
|
+
| `token` | `str` | ShipX API bearer token |
|
|
43
|
+
| `organization_id` | `int` | ShipX organization ID |
|
|
44
|
+
| `sandbox` | `bool` | Use sandbox API |
|
|
45
|
+
| `base_url` | `str` | Optional API base override |
|
|
46
|
+
| `timeout` | `float` | Request timeout in seconds |
|
|
47
|
+
|
|
48
|
+
## Status normalization
|
|
49
|
+
|
|
50
|
+
ShipX statuses are normalized to sendparcel shipment statuses.
|
|
51
|
+
|
|
52
|
+
- recognized ShipX statuses produce `{"status": ...}`
|
|
53
|
+
- tracking numbers are included when available
|
|
54
|
+
- unknown ShipX statuses do not invent fake sendparcel statuses
|
|
55
|
+
|
|
56
|
+
That means callback and polling updates can safely return only tracking data when ShipX introduces a new status the mapper does not know yet.
|
|
57
|
+
|
|
58
|
+
## Labels
|
|
59
|
+
|
|
60
|
+
Labels are returned as payloads.
|
|
61
|
+
|
|
62
|
+
- PDF labels are returned as base64 content in `LabelInfo["content_base64"]`
|
|
63
|
+
- no label URL is persisted by the core contract
|
|
64
|
+
|
|
65
|
+
## Development
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
uv sync --extra dev
|
|
69
|
+
uv run pytest
|
|
70
|
+
uv run ruff check src tests
|
|
71
|
+
uv run mypy src tests
|
|
72
|
+
```
|
|
@@ -80,10 +80,10 @@ Both providers implement the full `BaseProvider` interface:
|
|
|
80
80
|
|---|---|
|
|
81
81
|
| `create_shipment(**kwargs)` | Create a shipment in ShipX |
|
|
82
82
|
| `create_label(**kwargs)` | Download shipping label (PDF by default) |
|
|
83
|
-
| `fetch_shipment_status(**kwargs)` | Poll ShipX API
|
|
83
|
+
| `fetch_shipment_status(**kwargs)` | Poll ShipX API and return `ShipmentUpdateResult` |
|
|
84
84
|
| `cancel_shipment(**kwargs)` | Cancel the shipment (returns `True`/`False`) |
|
|
85
85
|
| `verify_callback(data, headers, **kwargs)` | Verify webhook source IP |
|
|
86
|
-
| `handle_callback(data, headers, **kwargs)` |
|
|
86
|
+
| `handle_callback(data, headers, **kwargs)` | Normalize webhook payload into `ShipmentUpdateResult` |
|
|
87
87
|
|
|
88
88
|
## ShipXClient
|
|
89
89
|
|
|
@@ -173,7 +173,8 @@ ShipX uses 24 internal statuses. These are mapped to 8 sendparcel statuses:
|
|
|
173
173
|
| `RETURNED` | `returned_to_sender` |
|
|
174
174
|
| `FAILED` | `rejected_by_receiver`, `undelivered`, `oversized`, `missing`, `claim_created` |
|
|
175
175
|
|
|
176
|
-
Unrecognized statuses return `None` from `map_shipx_status()`.
|
|
176
|
+
Unrecognized statuses return `None` from `map_shipx_status()`. Use
|
|
177
|
+
`build_shipment_update()` to keep tracking data even when a status is unknown.
|
|
177
178
|
|
|
178
179
|
## Error handling
|
|
179
180
|
|
|
@@ -206,9 +207,8 @@ the `X-Forwarded-For` header (first entry). Invalid or missing IPs raise
|
|
|
206
207
|
}
|
|
207
208
|
```
|
|
208
209
|
|
|
209
|
-
The `handle_callback` method
|
|
210
|
-
|
|
211
|
-
`ShipmentFlow`.
|
|
210
|
+
The `handle_callback` method normalizes ShipX payloads into
|
|
211
|
+
`ShipmentUpdateResult`. The core flow applies transitions.
|
|
212
212
|
|
|
213
213
|
## Enums
|
|
214
214
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "python-sendparcel-inpost"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.2.0"
|
|
4
4
|
description = "InPost ShipX provider for python-sendparcel."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = { text = "MIT" }
|
|
@@ -18,7 +18,7 @@ classifiers = [
|
|
|
18
18
|
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
19
19
|
"Typing :: Typed",
|
|
20
20
|
]
|
|
21
|
-
dependencies = ["python-sendparcel>=0.1.
|
|
21
|
+
dependencies = ["python-sendparcel>=0.1.1", "httpx>=0.27.0", "anyio>=4.0"]
|
|
22
22
|
|
|
23
23
|
[project.optional-dependencies]
|
|
24
24
|
dev = [
|
|
@@ -27,8 +27,16 @@ dev = [
|
|
|
27
27
|
"pytest-cov>=5.0",
|
|
28
28
|
"respx>=0.22.0",
|
|
29
29
|
"ruff>=0.9.0",
|
|
30
|
+
"ty>=0.0.1a11",
|
|
30
31
|
]
|
|
31
32
|
|
|
33
|
+
[project.urls]
|
|
34
|
+
Homepage = "https://github.com/python-sendparcel/python-sendparcel-inpost"
|
|
35
|
+
# Documentation = "https://python-sendparcel-inpost.readthedocs.io/"
|
|
36
|
+
Repository = "https://github.com/python-sendparcel/python-sendparcel-inpost"
|
|
37
|
+
Changelog = "https://github.com/python-sendparcel/python-sendparcel-inpost/blob/main/CHANGELOG.md"
|
|
38
|
+
"Issue Tracker" = "https://github.com/python-sendparcel/python-sendparcel-inpost/issues"
|
|
39
|
+
|
|
32
40
|
[project.entry-points."sendparcel.providers"]
|
|
33
41
|
inpost_locker = "sendparcel_inpost.providers.locker:InPostLockerProvider"
|
|
34
42
|
inpost_courier = "sendparcel_inpost.providers.courier:InPostCourierProvider"
|
{python_sendparcel_inpost-0.1.1 → python_sendparcel_inpost-0.2.0}/src/sendparcel_inpost/__init__.py
RENAMED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
"""InPost ShipX provider for python-sendparcel."""
|
|
2
2
|
|
|
3
|
-
__version__ = "0.
|
|
3
|
+
__version__ = "0.2.0"
|
|
4
4
|
|
|
5
5
|
from sendparcel_inpost.client import ShipXClient
|
|
6
|
+
from sendparcel_inpost.exceptions import CircuitBreakerError
|
|
6
7
|
from sendparcel_inpost.providers.courier import InPostCourierProvider
|
|
7
8
|
from sendparcel_inpost.providers.locker import InPostLockerProvider
|
|
8
9
|
|
|
9
10
|
__all__ = [
|
|
11
|
+
"CircuitBreakerError",
|
|
10
12
|
"InPostCourierProvider",
|
|
11
13
|
"InPostLockerProvider",
|
|
12
14
|
"ShipXClient",
|