pyardent 1.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.
- pyardent-1.0.0/LICENSE.md +21 -0
- pyardent-1.0.0/PKG-INFO +125 -0
- pyardent-1.0.0/README.md +105 -0
- pyardent-1.0.0/pyproject.toml +42 -0
- pyardent-1.0.0/src/pyardent/__init__.py +10 -0
- pyardent-1.0.0/src/pyardent/client.py +95 -0
- pyardent-1.0.0/src/pyardent/exceptions.py +56 -0
- pyardent-1.0.0/src/pyardent/models/__init__.py +7 -0
- pyardent-1.0.0/src/pyardent/models/commodity.py +320 -0
- pyardent-1.0.0/src/pyardent/models/market.py +82 -0
- pyardent-1.0.0/src/pyardent/models/meta.py +137 -0
- pyardent-1.0.0/src/pyardent/models/station.py +218 -0
- pyardent-1.0.0/src/pyardent/models/system.py +376 -0
- pyardent-1.0.0/src/pyardent/modules/__init__.py +6 -0
- pyardent-1.0.0/src/pyardent/modules/commodity.py +67 -0
- pyardent-1.0.0/src/pyardent/modules/meta.py +65 -0
- pyardent-1.0.0/src/pyardent/modules/station.py +69 -0
- pyardent-1.0.0/src/pyardent/modules/system.py +96 -0
- pyardent-1.0.0/src/pyardent/py.typed +0 -0
- pyardent-1.0.0/src/pyardent/types.py +29 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ProsD03
|
|
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.
|
pyardent-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyardent
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Python client for the Ardent Insight API (Elite Dangerous trade/system data)
|
|
5
|
+
Author: ProsD
|
|
6
|
+
Author-email: ProsD <me@prosd.dev>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
License-File: LICENSE.md
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Typing :: Typed
|
|
14
|
+
Requires-Dist: httpx>=0.28.1
|
|
15
|
+
Requires-Dist: pydantic==2.13.5
|
|
16
|
+
Requires-Python: >=3.12
|
|
17
|
+
Project-URL: Issues, https://github.com/ProsD03/pyardent/issues
|
|
18
|
+
Project-URL: Repository, https://github.com/ProsD03/pyardent
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
|
|
21
|
+
# pyardent
|
|
22
|
+
|
|
23
|
+
[](https://badge.fury.io/py/pyardent)
|
|
24
|
+
[](LICENSE.md)
|
|
25
|
+
[](pyproject.toml)
|
|
26
|
+
[](https://github.com/ProsD03/pyardent/actions/workflows/type_check.yml)
|
|
27
|
+
[](https://github.com/ProsD03/pyardent/actions/workflows/tests.yml)
|
|
28
|
+
[](https://github.com/ProsD03/pyardent/tree/python-coverage-comment-action-data)
|
|
29
|
+
|
|
30
|
+
A Python client for the [Ardent Insight](https://ardent-insight.com) API: trade and system data for Elite Dangerous.
|
|
31
|
+
|
|
32
|
+
Built on `httpx` and `pydantic`, fully type-hinted (ships a `py.typed` marker), with zero runtime dependencies beyond those two.
|
|
33
|
+
|
|
34
|
+
## Installation
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pip install pyardent
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Requires Python 3.12+.
|
|
41
|
+
|
|
42
|
+
## Quickstart
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
from pyardent import ArdentClient
|
|
46
|
+
|
|
47
|
+
client = ArdentClient()
|
|
48
|
+
|
|
49
|
+
gold = client.commodity.get_by_name("gold")
|
|
50
|
+
print(gold)
|
|
51
|
+
#> commodity_name='gold' rare=False rare_station_id=None rare_max_count=None min_buy_price=3800 ...
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
sol = client.system.get_by_name("Sol")
|
|
55
|
+
stations = sol.get_stations()
|
|
56
|
+
lincoln = next(s for s in stations if s.station_name == "Abraham Lincoln")
|
|
57
|
+
print(lincoln)
|
|
58
|
+
#> system_address=10477373803 station_id=128016896 station_name='Abraham Lincoln' ...
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Why pyardent
|
|
62
|
+
|
|
63
|
+
Models aren't flat DTOs: they carry a reference back to the client, so you can traverse straight from one resource to another without manually threading IDs through further calls:
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
gold = client.commodity.get_by_name("gold")
|
|
67
|
+
|
|
68
|
+
# Where can I sell gold for at least 50,000 credits, near Sol?
|
|
69
|
+
sol = client.system.get_by_name("Sol")
|
|
70
|
+
buyers = gold.get_nearby_importers(sol, min_price=50_000, max_distance=50)
|
|
71
|
+
|
|
72
|
+
for order in buyers:
|
|
73
|
+
station = order.get_station() # one more hop, still through the same client
|
|
74
|
+
print(station.station_name, order.sell_price)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
This graph-traversal pattern is consistent across the library: `System.get_stations()`, `Station.get_full_details()`, `Commodity.get_exporters()`, `CommodityMarket.get_station()`, and more.
|
|
78
|
+
|
|
79
|
+
## Error handling
|
|
80
|
+
|
|
81
|
+
Failed requests raise a typed exception instead of a bare `httpx.HTTPStatusError`:
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
from pyardent import ArdentClient, SystemNotFoundError
|
|
85
|
+
|
|
86
|
+
client = ArdentClient()
|
|
87
|
+
|
|
88
|
+
try:
|
|
89
|
+
client.system.get_by_name("Not A Real System")
|
|
90
|
+
except SystemNotFoundError:
|
|
91
|
+
...
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
All exceptions inherit from `PyArdentError`; more specific subclasses (`CommodityNotFoundError`, `ServiceNotFoundError`, `ResourceNotFoundError`) are raised where the API's error response is specific enough to tell them apart.
|
|
95
|
+
|
|
96
|
+
## Features
|
|
97
|
+
|
|
98
|
+
- Full pydantic models for every major resource: `System`, `Station`, `Commodity`, `CommodityMarket`
|
|
99
|
+
- Graph-traversal methods to move between related resources without re-fetching by hand
|
|
100
|
+
- A typed exception hierarchy instead of raw HTTP errors
|
|
101
|
+
- Custom `base_url` support, for pointing at a self-hosted or staging Ardent deployment
|
|
102
|
+
- Fully typed public API (`py.typed` included, so your type checker sees real types, not `Any`)
|
|
103
|
+
|
|
104
|
+
## Development
|
|
105
|
+
|
|
106
|
+
This project uses [`uv`](https://docs.astral.sh/uv/) for dependency management.
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
uv sync # install dependencies
|
|
110
|
+
uv run pytest # run tests
|
|
111
|
+
uv run pytest --cov=src/pyardent --cov-report=term-missing # run tests with coverage
|
|
112
|
+
uv run mypy src # type check
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Contributions are welcome. Please make sure the commands above are clean before opening a pull request.
|
|
116
|
+
|
|
117
|
+
## AI Usage Disclosure
|
|
118
|
+
|
|
119
|
+
AI assistance (Claude Code) was used for parts of this project: documentation, the test suite, and general bug fixing.
|
|
120
|
+
|
|
121
|
+
The research into Ardent Insight's documented and undocumented API surface, the overall structure of the library, and most of the core implementation were written by hand.
|
|
122
|
+
|
|
123
|
+
## License
|
|
124
|
+
|
|
125
|
+
MIT. See [LICENSE.md](LICENSE.md) for details.
|
pyardent-1.0.0/README.md
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# pyardent
|
|
2
|
+
|
|
3
|
+
[](https://badge.fury.io/py/pyardent)
|
|
4
|
+
[](LICENSE.md)
|
|
5
|
+
[](pyproject.toml)
|
|
6
|
+
[](https://github.com/ProsD03/pyardent/actions/workflows/type_check.yml)
|
|
7
|
+
[](https://github.com/ProsD03/pyardent/actions/workflows/tests.yml)
|
|
8
|
+
[](https://github.com/ProsD03/pyardent/tree/python-coverage-comment-action-data)
|
|
9
|
+
|
|
10
|
+
A Python client for the [Ardent Insight](https://ardent-insight.com) API: trade and system data for Elite Dangerous.
|
|
11
|
+
|
|
12
|
+
Built on `httpx` and `pydantic`, fully type-hinted (ships a `py.typed` marker), with zero runtime dependencies beyond those two.
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pip install pyardent
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Requires Python 3.12+.
|
|
21
|
+
|
|
22
|
+
## Quickstart
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
from pyardent import ArdentClient
|
|
26
|
+
|
|
27
|
+
client = ArdentClient()
|
|
28
|
+
|
|
29
|
+
gold = client.commodity.get_by_name("gold")
|
|
30
|
+
print(gold)
|
|
31
|
+
#> commodity_name='gold' rare=False rare_station_id=None rare_max_count=None min_buy_price=3800 ...
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
sol = client.system.get_by_name("Sol")
|
|
35
|
+
stations = sol.get_stations()
|
|
36
|
+
lincoln = next(s for s in stations if s.station_name == "Abraham Lincoln")
|
|
37
|
+
print(lincoln)
|
|
38
|
+
#> system_address=10477373803 station_id=128016896 station_name='Abraham Lincoln' ...
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Why pyardent
|
|
42
|
+
|
|
43
|
+
Models aren't flat DTOs: they carry a reference back to the client, so you can traverse straight from one resource to another without manually threading IDs through further calls:
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
gold = client.commodity.get_by_name("gold")
|
|
47
|
+
|
|
48
|
+
# Where can I sell gold for at least 50,000 credits, near Sol?
|
|
49
|
+
sol = client.system.get_by_name("Sol")
|
|
50
|
+
buyers = gold.get_nearby_importers(sol, min_price=50_000, max_distance=50)
|
|
51
|
+
|
|
52
|
+
for order in buyers:
|
|
53
|
+
station = order.get_station() # one more hop, still through the same client
|
|
54
|
+
print(station.station_name, order.sell_price)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
This graph-traversal pattern is consistent across the library: `System.get_stations()`, `Station.get_full_details()`, `Commodity.get_exporters()`, `CommodityMarket.get_station()`, and more.
|
|
58
|
+
|
|
59
|
+
## Error handling
|
|
60
|
+
|
|
61
|
+
Failed requests raise a typed exception instead of a bare `httpx.HTTPStatusError`:
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
from pyardent import ArdentClient, SystemNotFoundError
|
|
65
|
+
|
|
66
|
+
client = ArdentClient()
|
|
67
|
+
|
|
68
|
+
try:
|
|
69
|
+
client.system.get_by_name("Not A Real System")
|
|
70
|
+
except SystemNotFoundError:
|
|
71
|
+
...
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
All exceptions inherit from `PyArdentError`; more specific subclasses (`CommodityNotFoundError`, `ServiceNotFoundError`, `ResourceNotFoundError`) are raised where the API's error response is specific enough to tell them apart.
|
|
75
|
+
|
|
76
|
+
## Features
|
|
77
|
+
|
|
78
|
+
- Full pydantic models for every major resource: `System`, `Station`, `Commodity`, `CommodityMarket`
|
|
79
|
+
- Graph-traversal methods to move between related resources without re-fetching by hand
|
|
80
|
+
- A typed exception hierarchy instead of raw HTTP errors
|
|
81
|
+
- Custom `base_url` support, for pointing at a self-hosted or staging Ardent deployment
|
|
82
|
+
- Fully typed public API (`py.typed` included, so your type checker sees real types, not `Any`)
|
|
83
|
+
|
|
84
|
+
## Development
|
|
85
|
+
|
|
86
|
+
This project uses [`uv`](https://docs.astral.sh/uv/) for dependency management.
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
uv sync # install dependencies
|
|
90
|
+
uv run pytest # run tests
|
|
91
|
+
uv run pytest --cov=src/pyardent --cov-report=term-missing # run tests with coverage
|
|
92
|
+
uv run mypy src # type check
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Contributions are welcome. Please make sure the commands above are clean before opening a pull request.
|
|
96
|
+
|
|
97
|
+
## AI Usage Disclosure
|
|
98
|
+
|
|
99
|
+
AI assistance (Claude Code) was used for parts of this project: documentation, the test suite, and general bug fixing.
|
|
100
|
+
|
|
101
|
+
The research into Ardent Insight's documented and undocumented API surface, the overall structure of the library, and most of the core implementation were written by hand.
|
|
102
|
+
|
|
103
|
+
## License
|
|
104
|
+
|
|
105
|
+
MIT. See [LICENSE.md](LICENSE.md) for details.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "pyardent"
|
|
3
|
+
version = "1.0.0"
|
|
4
|
+
description = "Python client for the Ardent Insight API (Elite Dangerous trade/system data)"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
license-files = ["LICENSE.md"]
|
|
8
|
+
authors = [
|
|
9
|
+
{ name = "ProsD", email = "me@prosd.dev" }
|
|
10
|
+
]
|
|
11
|
+
requires-python = ">=3.12"
|
|
12
|
+
classifiers = [
|
|
13
|
+
"Development Status :: 3 - Alpha",
|
|
14
|
+
"Intended Audience :: Developers",
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"Programming Language :: Python :: 3.12",
|
|
17
|
+
"Typing :: Typed",
|
|
18
|
+
]
|
|
19
|
+
dependencies = [
|
|
20
|
+
"httpx>=0.28.1",
|
|
21
|
+
"pydantic==2.13.5",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
[project.urls]
|
|
25
|
+
Repository = "https://github.com/ProsD03/pyardent"
|
|
26
|
+
Issues = "https://github.com/ProsD03/pyardent/issues"
|
|
27
|
+
|
|
28
|
+
[build-system]
|
|
29
|
+
requires = ["uv_build>=0.8.12,<0.9.0"]
|
|
30
|
+
build-backend = "uv_build"
|
|
31
|
+
|
|
32
|
+
[dependency-groups]
|
|
33
|
+
dev = [
|
|
34
|
+
"mypy>=2.1.0",
|
|
35
|
+
"pytest>=9.0.3",
|
|
36
|
+
"pytest-asyncio>=1.4.0",
|
|
37
|
+
"pytest-cov>=7.1.0",
|
|
38
|
+
"respx>=0.23.1",
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
[tool.coverage.run]
|
|
42
|
+
relative_files = true
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
from .client import ArdentClient
|
|
4
|
+
from .exceptions import PyArdentError, ResourceNotFoundError, CommodityNotFoundError, SystemNotFoundError, ServiceNotFoundError
|
|
5
|
+
from .types import StationServices, LandingPad
|
|
6
|
+
from .models import System, Station, Commodity, CommodityMarket
|
|
7
|
+
|
|
8
|
+
logging.getLogger("pyardent").addHandler(logging.NullHandler())
|
|
9
|
+
|
|
10
|
+
__all__ = ['ArdentClient', 'ResourceNotFoundError', 'CommodityNotFoundError', 'SystemNotFoundError', 'ServiceNotFoundError', 'PyArdentError', "StationServices", "LandingPad", "System", "Station", "Commodity", "CommodityMarket"]
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"""Top-level client for the Ardent Insight API.
|
|
2
|
+
|
|
3
|
+
Wires up an `httpx.Client` shared by all `*Module` instances and installs the
|
|
4
|
+
response hook that translates HTTP error responses into `PyArdentError`
|
|
5
|
+
subclasses.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
|
|
10
|
+
import httpx
|
|
11
|
+
from .modules import MetaModule, CommodityModule, SystemModule
|
|
12
|
+
from .exceptions import PyArdentError, ResourceNotFoundError, CommodityNotFoundError, SystemNotFoundError, \
|
|
13
|
+
ServiceNotFoundError
|
|
14
|
+
from .modules.station import StationModule
|
|
15
|
+
|
|
16
|
+
logger = logging.getLogger("pyardent.client")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _handle_response_errors(response: httpx.Response):
|
|
20
|
+
"""Translate failed HTTP responses into `PyArdentError` subclasses.
|
|
21
|
+
|
|
22
|
+
Registered as an `httpx.Client` "response" event hook, so it runs on
|
|
23
|
+
every request made through `ArdentClient`. Successful responses pass
|
|
24
|
+
through unchanged.
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
response: The `httpx.Response` returned by the underlying request.
|
|
28
|
+
|
|
29
|
+
Raises:
|
|
30
|
+
CommodityNotFoundError: On a 404 whose API error message mentions a commodity.
|
|
31
|
+
SystemNotFoundError: On a 404 whose API error message mentions a system.
|
|
32
|
+
ServiceNotFoundError: On a 404 whose API error message mentions a service.
|
|
33
|
+
ResourceNotFoundError: On a 404 with no recognizable error message.
|
|
34
|
+
PyArdentError: On any other HTTP error status, a 404 with an
|
|
35
|
+
unrecognized message, or a network-level error.
|
|
36
|
+
"""
|
|
37
|
+
response.read()
|
|
38
|
+
try:
|
|
39
|
+
response.raise_for_status()
|
|
40
|
+
except httpx.HTTPStatusError as e:
|
|
41
|
+
|
|
42
|
+
logger.error(f"HTTP error {e.response.status_code} for URL: {response.url}")
|
|
43
|
+
|
|
44
|
+
if e.response.status_code == 404:
|
|
45
|
+
error_payload = e.response.json()
|
|
46
|
+
api_msg = error_payload.get("message")
|
|
47
|
+
if api_msg:
|
|
48
|
+
if "commodity" in api_msg.lower():
|
|
49
|
+
raise CommodityNotFoundError(str(response.url)) from e
|
|
50
|
+
elif "system" in api_msg.lower():
|
|
51
|
+
raise SystemNotFoundError(str(response.url)) from e
|
|
52
|
+
elif "service" in api_msg.lower():
|
|
53
|
+
raise ServiceNotFoundError(str(response.url)) from e
|
|
54
|
+
else:
|
|
55
|
+
raise PyArdentError(api_msg) from e
|
|
56
|
+
raise ResourceNotFoundError(str(response.url)) from e
|
|
57
|
+
else:
|
|
58
|
+
raise PyArdentError(f"HTTP error {e.response.status_code} for URL: {response.url}") from e
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class ArdentClient:
|
|
62
|
+
"""Entry point for the Ardent Insight API client.
|
|
63
|
+
|
|
64
|
+
Holds the shared `httpx.Client` and exposes one module per API resource
|
|
65
|
+
area (`meta`, `commodity`, `system`, `station`). Methods on those modules
|
|
66
|
+
return rich pydantic models (e.g. `System`, `Station`, `Commodity`,
|
|
67
|
+
`CommodityMarket`) that carry a reference back to this client so they can
|
|
68
|
+
make further API calls themselves (e.g. `system.get_stations()`).
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
DEFAULT_BASE_URL = "https://api.ardent-insight.com/v2"
|
|
72
|
+
_client: httpx.Client
|
|
73
|
+
|
|
74
|
+
meta: MetaModule
|
|
75
|
+
commodity: CommodityModule
|
|
76
|
+
system: SystemModule
|
|
77
|
+
station: StationModule
|
|
78
|
+
|
|
79
|
+
def __init__(self, base_url: str | None = None):
|
|
80
|
+
"""Create a client and its underlying HTTP session.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
base_url: Override for the API base URL. Defaults to
|
|
84
|
+
`ArdentClient.DEFAULT_BASE_URL` when omitted.
|
|
85
|
+
"""
|
|
86
|
+
self._base_url = base_url or self.DEFAULT_BASE_URL
|
|
87
|
+
|
|
88
|
+
self._client = httpx.Client(base_url=self._base_url, event_hooks={"response": [_handle_response_errors, ]})
|
|
89
|
+
|
|
90
|
+
self.meta = MetaModule(self._client)
|
|
91
|
+
self.commodity = CommodityModule(self._client)
|
|
92
|
+
self.system = SystemModule(self._client)
|
|
93
|
+
self.station = StationModule(self._client)
|
|
94
|
+
|
|
95
|
+
logger.info(f"Initialized ArdentClient pointing to {self._base_url}")
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""Exception hierarchy raised by pyardent.
|
|
2
|
+
|
|
3
|
+
All errors raised by the client are `PyArdentError` or one of its subclasses
|
|
4
|
+
below, translated from HTTP responses by `client._handle_response_errors`.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class PyArdentError(Exception):
|
|
9
|
+
"""Base class for all errors raised by this library.
|
|
10
|
+
|
|
11
|
+
Args:
|
|
12
|
+
message: Human-readable description of the failure.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
def __init__(self, message: str):
|
|
16
|
+
super().__init__(message)
|
|
17
|
+
|
|
18
|
+
class ResourceNotFoundError(PyArdentError):
|
|
19
|
+
"""Raised on a 404 whose API error message didn't match a more specific case.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
url: The request URL that returned the 404.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
def __init__(self, url: str):
|
|
26
|
+
super().__init__(f"Resource not found at endpoint: {url}")
|
|
27
|
+
|
|
28
|
+
class CommodityNotFoundError(PyArdentError):
|
|
29
|
+
"""Raised when the requested commodity does not exist.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
url: The request URL that returned the 404.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
def __init__(self, url: str):
|
|
36
|
+
super().__init__(f"Commodity does not exist. Endpoint: {url}")
|
|
37
|
+
|
|
38
|
+
class SystemNotFoundError(PyArdentError):
|
|
39
|
+
"""Raised when the requested system does not exist.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
url: The request URL that returned the 404.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
def __init__(self, url: str):
|
|
46
|
+
super().__init__(f"System does not exist. Endpoint: {url}")
|
|
47
|
+
|
|
48
|
+
class ServiceNotFoundError(PyArdentError):
|
|
49
|
+
"""Raised when the requested station service type is unknown to the API.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
url: The request URL that returned the 404.
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
def __init__(self, url: str):
|
|
56
|
+
super().__init__(f"Service does not exist. Endpoint: {url}")
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
from .meta import APIVersion, APIStats, APIEconomies, APIStations
|
|
2
|
+
from .commodity import Commodity
|
|
3
|
+
from .system import System
|
|
4
|
+
from .station import Station
|
|
5
|
+
from .market import CommodityMarket
|
|
6
|
+
|
|
7
|
+
__all__ = ["APIVersion", "APIStats", "APIEconomies", "APIStations", "Commodity", "System", "Station", "CommodityMarket"]
|