python-eveonline 0.2.0__tar.gz → 0.2.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.
- python_eveonline-0.2.2/PKG-INFO +144 -0
- python_eveonline-0.2.2/README.md +112 -0
- {python_eveonline-0.2.0 → python_eveonline-0.2.2}/pyproject.toml +1 -1
- {python_eveonline-0.2.0 → python_eveonline-0.2.2}/src/eveonline/__init__.py +10 -1
- {python_eveonline-0.2.0 → python_eveonline-0.2.2}/src/eveonline/client.py +23 -9
- {python_eveonline-0.2.0 → python_eveonline-0.2.2}/src/eveonline/const.py +4 -2
- {python_eveonline-0.2.0 → python_eveonline-0.2.2}/src/eveonline/exceptions.py +14 -2
- python_eveonline-0.2.2/src/eveonline/models.py +305 -0
- python_eveonline-0.2.2/src/python_eveonline.egg-info/PKG-INFO +144 -0
- {python_eveonline-0.2.0 → python_eveonline-0.2.2}/tests/test_client_authenticated.py +16 -1
- {python_eveonline-0.2.0 → python_eveonline-0.2.2}/tests/test_client_public.py +66 -0
- {python_eveonline-0.2.0 → python_eveonline-0.2.2}/tests/test_const.py +3 -3
- {python_eveonline-0.2.0 → python_eveonline-0.2.2}/tests/test_exceptions.py +10 -0
- {python_eveonline-0.2.0 → python_eveonline-0.2.2}/tests/test_models.py +37 -2
- python_eveonline-0.2.0/PKG-INFO +0 -71
- python_eveonline-0.2.0/README.md +0 -39
- python_eveonline-0.2.0/src/eveonline/models.py +0 -178
- python_eveonline-0.2.0/src/python_eveonline.egg-info/PKG-INFO +0 -71
- {python_eveonline-0.2.0 → python_eveonline-0.2.2}/LICENSE +0 -0
- {python_eveonline-0.2.0 → python_eveonline-0.2.2}/setup.cfg +0 -0
- {python_eveonline-0.2.0 → python_eveonline-0.2.2}/src/eveonline/auth.py +0 -0
- {python_eveonline-0.2.0 → python_eveonline-0.2.2}/src/eveonline/py.typed +0 -0
- {python_eveonline-0.2.0 → python_eveonline-0.2.2}/src/python_eveonline.egg-info/SOURCES.txt +0 -0
- {python_eveonline-0.2.0 → python_eveonline-0.2.2}/src/python_eveonline.egg-info/dependency_links.txt +0 -0
- {python_eveonline-0.2.0 → python_eveonline-0.2.2}/src/python_eveonline.egg-info/requires.txt +0 -0
- {python_eveonline-0.2.0 → python_eveonline-0.2.2}/src/python_eveonline.egg-info/top_level.txt +0 -0
- {python_eveonline-0.2.0 → python_eveonline-0.2.2}/tests/test_auth.py +0 -0
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: python-eveonline
|
|
3
|
+
Version: 0.2.2
|
|
4
|
+
Summary: Async Python client for the Eve Online ESI API
|
|
5
|
+
Author: Ronald van der Meer
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/ronaldvdmeer/python-eveonline
|
|
8
|
+
Project-URL: Repository, https://github.com/ronaldvdmeer/python-eveonline
|
|
9
|
+
Project-URL: Issues, https://github.com/ronaldvdmeer/python-eveonline/issues
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Topic :: Games/Entertainment
|
|
17
|
+
Classifier: Typing :: Typed
|
|
18
|
+
Classifier: Framework :: AsyncIO
|
|
19
|
+
Requires-Python: >=3.11
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: aiohttp>=3.9.0
|
|
23
|
+
Provides-Extra: dev
|
|
24
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
25
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
|
|
26
|
+
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
27
|
+
Requires-Dist: aioresponses>=0.7; extra == "dev"
|
|
28
|
+
Requires-Dist: mypy>=1.8; extra == "dev"
|
|
29
|
+
Requires-Dist: pylint>=3.0; extra == "dev"
|
|
30
|
+
Requires-Dist: ruff>=0.3; extra == "dev"
|
|
31
|
+
Dynamic: license-file
|
|
32
|
+
|
|
33
|
+
# python-eveonline
|
|
34
|
+
|
|
35
|
+
[](https://pypi.org/project/python-eveonline/)
|
|
36
|
+
[](https://pypi.org/project/python-eveonline/)
|
|
37
|
+
[](https://github.com/ronaldvdmeer/python-eveonline/blob/main/LICENSE)
|
|
38
|
+
[](https://github.com/ronaldvdmeer/python-eveonline/releases)
|
|
39
|
+
|
|
40
|
+
Async Python client library for the [Eve Online ESI API](https://esi.evetech.net/ui/).
|
|
41
|
+
|
|
42
|
+
Built for use with [Home Assistant](https://www.home-assistant.io/) but can be used standalone in any async Python project.
|
|
43
|
+
|
|
44
|
+
## Features
|
|
45
|
+
|
|
46
|
+
- **Fully async** — built on [aiohttp](https://docs.aiohttp.org/)
|
|
47
|
+
- **Typed models** — all API responses are frozen dataclasses
|
|
48
|
+
- **Public endpoints** — server status, character info, corporation info, portraits, universe name resolution
|
|
49
|
+
- **Authenticated endpoints** — online status, location, ship, wallet, skills, skill queue, mail, industry jobs, market orders, jump fatigue
|
|
50
|
+
- **Abstract auth** — implement `AbstractAuth` to provide your own token management (e.g. Home Assistant OAuth2)
|
|
51
|
+
- **Type-safe** — PEP 561 compatible (`py.typed`), strict mypy configuration
|
|
52
|
+
- **Tested** — 100% test coverage
|
|
53
|
+
|
|
54
|
+
## Installation
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pip install python-eveonline
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Quick start
|
|
61
|
+
|
|
62
|
+
### Public endpoints (no authentication required)
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
import asyncio
|
|
66
|
+
import aiohttp
|
|
67
|
+
from eveonline import EveOnlineClient
|
|
68
|
+
|
|
69
|
+
async def main():
|
|
70
|
+
async with aiohttp.ClientSession() as session:
|
|
71
|
+
client = EveOnlineClient(session=session)
|
|
72
|
+
status = await client.async_get_server_status()
|
|
73
|
+
print(f"{status.players} players online (version {status.server_version})")
|
|
74
|
+
|
|
75
|
+
asyncio.run(main())
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Authenticated endpoints
|
|
79
|
+
|
|
80
|
+
To access character-specific data, implement the `AbstractAuth` class with your own token management:
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
from eveonline import EveOnlineClient
|
|
84
|
+
from eveonline.auth import AbstractAuth
|
|
85
|
+
|
|
86
|
+
class MyAuth(AbstractAuth):
|
|
87
|
+
async def async_get_access_token(self) -> str:
|
|
88
|
+
return "your-access-token"
|
|
89
|
+
|
|
90
|
+
auth = MyAuth(websession)
|
|
91
|
+
client = EveOnlineClient(auth=auth)
|
|
92
|
+
|
|
93
|
+
online = await client.async_get_character_online(character_id)
|
|
94
|
+
wallet = await client.async_get_wallet_balance(character_id)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Available endpoints
|
|
98
|
+
|
|
99
|
+
| Method | Scope required | Returns |
|
|
100
|
+
|--------|---------------|---------|
|
|
101
|
+
| `async_get_server_status()` | — | `ServerStatus` |
|
|
102
|
+
| `async_get_character_public(id)` | — | `CharacterPublicInfo` |
|
|
103
|
+
| `async_get_character_portrait(id)` | — | `CharacterPortrait` |
|
|
104
|
+
| `async_get_corporation_public(id)` | — | `CorporationPublicInfo` |
|
|
105
|
+
| `async_resolve_names(ids)` | — | `list[UniverseName]` |
|
|
106
|
+
| `async_get_character_online(id)` | `esi-location.read_online.v1` | `CharacterOnlineStatus` |
|
|
107
|
+
| `async_get_character_location(id)` | `esi-location.read_location.v1` | `CharacterLocation` |
|
|
108
|
+
| `async_get_character_ship(id)` | `esi-location.read_ship_type.v1` | `CharacterShip` |
|
|
109
|
+
| `async_get_wallet_balance(id)` | `esi-wallet.read_character_wallet.v1` | `WalletBalance` |
|
|
110
|
+
| `async_get_skills(id)` | `esi-skills.read_skills.v1` | `CharacterSkillsSummary` |
|
|
111
|
+
| `async_get_skill_queue(id)` | `esi-skills.read_skillqueue.v1` | `list[SkillQueueEntry]` |
|
|
112
|
+
| `async_get_mail_labels(id)` | `esi-mail.read_mail.v1` | `MailLabelsSummary` |
|
|
113
|
+
| `async_get_industry_jobs(id)` | `esi-industry.read_character_jobs.v1` | `list[IndustryJob]` |
|
|
114
|
+
| `async_get_market_orders(id)` | `esi-markets.read_character_orders.v1` | `list[MarketOrder]` |
|
|
115
|
+
| `async_get_jump_fatigue(id)` | `esi-characters.read_fatigue.v1` | `JumpFatigue` |
|
|
116
|
+
|
|
117
|
+
## Error handling
|
|
118
|
+
|
|
119
|
+
All exceptions inherit from `EveOnlineError`:
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
from eveonline import EveOnlineClient, EveOnlineError
|
|
123
|
+
from eveonline.exceptions import (
|
|
124
|
+
EveOnlineAuthenticationError, # 401/403 or missing auth
|
|
125
|
+
EveOnlineConnectionError, # Network/connection failures
|
|
126
|
+
EveOnlineRateLimitError, # 429 with optional retry_after
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
try:
|
|
130
|
+
status = await client.async_get_server_status()
|
|
131
|
+
except EveOnlineAuthenticationError:
|
|
132
|
+
# Token expired or invalid
|
|
133
|
+
...
|
|
134
|
+
except EveOnlineRateLimitError as err:
|
|
135
|
+
# Back off for err.retry_after seconds
|
|
136
|
+
...
|
|
137
|
+
except EveOnlineError:
|
|
138
|
+
# Any other ESI error
|
|
139
|
+
...
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## License
|
|
143
|
+
|
|
144
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# python-eveonline
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/python-eveonline/)
|
|
4
|
+
[](https://pypi.org/project/python-eveonline/)
|
|
5
|
+
[](https://github.com/ronaldvdmeer/python-eveonline/blob/main/LICENSE)
|
|
6
|
+
[](https://github.com/ronaldvdmeer/python-eveonline/releases)
|
|
7
|
+
|
|
8
|
+
Async Python client library for the [Eve Online ESI API](https://esi.evetech.net/ui/).
|
|
9
|
+
|
|
10
|
+
Built for use with [Home Assistant](https://www.home-assistant.io/) but can be used standalone in any async Python project.
|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
- **Fully async** — built on [aiohttp](https://docs.aiohttp.org/)
|
|
15
|
+
- **Typed models** — all API responses are frozen dataclasses
|
|
16
|
+
- **Public endpoints** — server status, character info, corporation info, portraits, universe name resolution
|
|
17
|
+
- **Authenticated endpoints** — online status, location, ship, wallet, skills, skill queue, mail, industry jobs, market orders, jump fatigue
|
|
18
|
+
- **Abstract auth** — implement `AbstractAuth` to provide your own token management (e.g. Home Assistant OAuth2)
|
|
19
|
+
- **Type-safe** — PEP 561 compatible (`py.typed`), strict mypy configuration
|
|
20
|
+
- **Tested** — 100% test coverage
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install python-eveonline
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Quick start
|
|
29
|
+
|
|
30
|
+
### Public endpoints (no authentication required)
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
import asyncio
|
|
34
|
+
import aiohttp
|
|
35
|
+
from eveonline import EveOnlineClient
|
|
36
|
+
|
|
37
|
+
async def main():
|
|
38
|
+
async with aiohttp.ClientSession() as session:
|
|
39
|
+
client = EveOnlineClient(session=session)
|
|
40
|
+
status = await client.async_get_server_status()
|
|
41
|
+
print(f"{status.players} players online (version {status.server_version})")
|
|
42
|
+
|
|
43
|
+
asyncio.run(main())
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Authenticated endpoints
|
|
47
|
+
|
|
48
|
+
To access character-specific data, implement the `AbstractAuth` class with your own token management:
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
from eveonline import EveOnlineClient
|
|
52
|
+
from eveonline.auth import AbstractAuth
|
|
53
|
+
|
|
54
|
+
class MyAuth(AbstractAuth):
|
|
55
|
+
async def async_get_access_token(self) -> str:
|
|
56
|
+
return "your-access-token"
|
|
57
|
+
|
|
58
|
+
auth = MyAuth(websession)
|
|
59
|
+
client = EveOnlineClient(auth=auth)
|
|
60
|
+
|
|
61
|
+
online = await client.async_get_character_online(character_id)
|
|
62
|
+
wallet = await client.async_get_wallet_balance(character_id)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Available endpoints
|
|
66
|
+
|
|
67
|
+
| Method | Scope required | Returns |
|
|
68
|
+
|--------|---------------|---------|
|
|
69
|
+
| `async_get_server_status()` | — | `ServerStatus` |
|
|
70
|
+
| `async_get_character_public(id)` | — | `CharacterPublicInfo` |
|
|
71
|
+
| `async_get_character_portrait(id)` | — | `CharacterPortrait` |
|
|
72
|
+
| `async_get_corporation_public(id)` | — | `CorporationPublicInfo` |
|
|
73
|
+
| `async_resolve_names(ids)` | — | `list[UniverseName]` |
|
|
74
|
+
| `async_get_character_online(id)` | `esi-location.read_online.v1` | `CharacterOnlineStatus` |
|
|
75
|
+
| `async_get_character_location(id)` | `esi-location.read_location.v1` | `CharacterLocation` |
|
|
76
|
+
| `async_get_character_ship(id)` | `esi-location.read_ship_type.v1` | `CharacterShip` |
|
|
77
|
+
| `async_get_wallet_balance(id)` | `esi-wallet.read_character_wallet.v1` | `WalletBalance` |
|
|
78
|
+
| `async_get_skills(id)` | `esi-skills.read_skills.v1` | `CharacterSkillsSummary` |
|
|
79
|
+
| `async_get_skill_queue(id)` | `esi-skills.read_skillqueue.v1` | `list[SkillQueueEntry]` |
|
|
80
|
+
| `async_get_mail_labels(id)` | `esi-mail.read_mail.v1` | `MailLabelsSummary` |
|
|
81
|
+
| `async_get_industry_jobs(id)` | `esi-industry.read_character_jobs.v1` | `list[IndustryJob]` |
|
|
82
|
+
| `async_get_market_orders(id)` | `esi-markets.read_character_orders.v1` | `list[MarketOrder]` |
|
|
83
|
+
| `async_get_jump_fatigue(id)` | `esi-characters.read_fatigue.v1` | `JumpFatigue` |
|
|
84
|
+
|
|
85
|
+
## Error handling
|
|
86
|
+
|
|
87
|
+
All exceptions inherit from `EveOnlineError`:
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
from eveonline import EveOnlineClient, EveOnlineError
|
|
91
|
+
from eveonline.exceptions import (
|
|
92
|
+
EveOnlineAuthenticationError, # 401/403 or missing auth
|
|
93
|
+
EveOnlineConnectionError, # Network/connection failures
|
|
94
|
+
EveOnlineRateLimitError, # 429 with optional retry_after
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
try:
|
|
98
|
+
status = await client.async_get_server_status()
|
|
99
|
+
except EveOnlineAuthenticationError:
|
|
100
|
+
# Token expired or invalid
|
|
101
|
+
...
|
|
102
|
+
except EveOnlineRateLimitError as err:
|
|
103
|
+
# Back off for err.retry_after seconds
|
|
104
|
+
...
|
|
105
|
+
except EveOnlineError:
|
|
106
|
+
# Any other ESI error
|
|
107
|
+
...
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## License
|
|
111
|
+
|
|
112
|
+
[MIT](LICENSE)
|
|
@@ -1,15 +1,23 @@
|
|
|
1
1
|
"""Async Python client for the Eve Online ESI API."""
|
|
2
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
6
|
+
|
|
3
7
|
from .auth import AbstractAuth
|
|
4
8
|
from .client import EveOnlineClient
|
|
5
9
|
from .exceptions import (
|
|
6
10
|
EveOnlineAuthenticationError,
|
|
7
11
|
EveOnlineConnectionError,
|
|
8
12
|
EveOnlineError,
|
|
13
|
+
EveOnlineNotFoundError,
|
|
9
14
|
EveOnlineRateLimitError,
|
|
10
15
|
)
|
|
11
16
|
|
|
12
|
-
|
|
17
|
+
try:
|
|
18
|
+
__version__ = version("python-eveonline")
|
|
19
|
+
except PackageNotFoundError:
|
|
20
|
+
__version__ = "0.0.0"
|
|
13
21
|
|
|
14
22
|
__all__ = [
|
|
15
23
|
"AbstractAuth",
|
|
@@ -17,6 +25,7 @@ __all__ = [
|
|
|
17
25
|
"EveOnlineClient",
|
|
18
26
|
"EveOnlineConnectionError",
|
|
19
27
|
"EveOnlineError",
|
|
28
|
+
"EveOnlineNotFoundError",
|
|
20
29
|
"EveOnlineRateLimitError",
|
|
21
30
|
"__version__",
|
|
22
31
|
]
|
|
@@ -145,7 +145,13 @@ class EveOnlineClient:
|
|
|
145
145
|
|
|
146
146
|
if response.status in (420, 429):
|
|
147
147
|
retry_after = response.headers.get("Retry-After")
|
|
148
|
-
|
|
148
|
+
retry_after_seconds: int | None = None
|
|
149
|
+
if retry_after is not None:
|
|
150
|
+
try:
|
|
151
|
+
retry_after_seconds = int(retry_after)
|
|
152
|
+
except ValueError:
|
|
153
|
+
retry_after_seconds = None
|
|
154
|
+
raise EveOnlineRateLimitError(retry_after=retry_after_seconds)
|
|
149
155
|
|
|
150
156
|
if response.status >= 400:
|
|
151
157
|
text = await response.text()
|
|
@@ -156,11 +162,19 @@ class EveOnlineClient:
|
|
|
156
162
|
|
|
157
163
|
@staticmethod
|
|
158
164
|
def _parse_datetime(value: str | None) -> datetime | None:
|
|
159
|
-
"""Parse an
|
|
165
|
+
"""Parse an ISO 8601 datetime string from ESI.
|
|
166
|
+
|
|
167
|
+
Args:
|
|
168
|
+
value: An ISO 8601 string (e.g. ``"2025-01-15T12:34:56Z"``) or
|
|
169
|
+
``None``.
|
|
170
|
+
|
|
171
|
+
Returns:
|
|
172
|
+
A timezone-aware :class:`~datetime.datetime`, or ``None`` when
|
|
173
|
+
*value* is ``None``.
|
|
174
|
+
"""
|
|
160
175
|
if value is None:
|
|
161
176
|
return None
|
|
162
|
-
|
|
163
|
-
return datetime.fromisoformat(value.replace("Z", "+00:00"))
|
|
177
|
+
return datetime.fromisoformat(value)
|
|
164
178
|
|
|
165
179
|
# -------------------------------------------------------------------------
|
|
166
180
|
# Public endpoints (no auth required)
|
|
@@ -176,7 +190,7 @@ class EveOnlineClient:
|
|
|
176
190
|
return ServerStatus(
|
|
177
191
|
players=data["players"],
|
|
178
192
|
server_version=data["server_version"],
|
|
179
|
-
start_time=datetime.fromisoformat(data["start_time"]
|
|
193
|
+
start_time=datetime.fromisoformat(data["start_time"]),
|
|
180
194
|
vip=data.get("vip"),
|
|
181
195
|
)
|
|
182
196
|
|
|
@@ -194,7 +208,7 @@ class EveOnlineClient:
|
|
|
194
208
|
character_id=character_id,
|
|
195
209
|
name=data["name"],
|
|
196
210
|
corporation_id=data["corporation_id"],
|
|
197
|
-
birthday=datetime.fromisoformat(data["birthday"]
|
|
211
|
+
birthday=datetime.fromisoformat(data["birthday"]),
|
|
198
212
|
gender=data["gender"],
|
|
199
213
|
race_id=data["race_id"],
|
|
200
214
|
bloodline_id=data["bloodline_id"],
|
|
@@ -424,8 +438,8 @@ class EveOnlineClient:
|
|
|
424
438
|
job_id=entry["job_id"],
|
|
425
439
|
activity_id=entry["activity_id"],
|
|
426
440
|
status=entry["status"],
|
|
427
|
-
start_date=datetime.fromisoformat(entry["start_date"]
|
|
428
|
-
end_date=datetime.fromisoformat(entry["end_date"]
|
|
441
|
+
start_date=datetime.fromisoformat(entry["start_date"]),
|
|
442
|
+
end_date=datetime.fromisoformat(entry["end_date"]),
|
|
429
443
|
blueprint_type_id=entry["blueprint_type_id"],
|
|
430
444
|
output_location_id=entry["output_location_id"],
|
|
431
445
|
runs=entry["runs"],
|
|
@@ -458,7 +472,7 @@ class EveOnlineClient:
|
|
|
458
472
|
volume_total=entry["volume_total"],
|
|
459
473
|
location_id=entry["location_id"],
|
|
460
474
|
region_id=entry["region_id"],
|
|
461
|
-
issued=datetime.fromisoformat(entry["issued"]
|
|
475
|
+
issued=datetime.fromisoformat(entry["issued"]),
|
|
462
476
|
duration=entry["duration"],
|
|
463
477
|
range=entry["range"],
|
|
464
478
|
min_volume=entry.get("min_volume"),
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"""Constants for the Eve Online ESI API."""
|
|
2
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
3
5
|
from typing import Final
|
|
4
6
|
|
|
5
7
|
# ESI API
|
|
@@ -28,7 +30,7 @@ SCOPE_READ_INDUSTRY_JOBS: Final = "esi-industry.read_character_jobs.v1"
|
|
|
28
30
|
SCOPE_READ_MARKET_ORDERS: Final = "esi-markets.read_character_orders.v1"
|
|
29
31
|
|
|
30
32
|
# Default scopes for a typical Home Assistant integration
|
|
31
|
-
DEFAULT_SCOPES: Final =
|
|
33
|
+
DEFAULT_SCOPES: Final = (
|
|
32
34
|
SCOPE_READ_ONLINE,
|
|
33
35
|
SCOPE_READ_LOCATION,
|
|
34
36
|
SCOPE_READ_SHIP_TYPE,
|
|
@@ -39,4 +41,4 @@ DEFAULT_SCOPES: Final = [
|
|
|
39
41
|
SCOPE_READ_MAIL,
|
|
40
42
|
SCOPE_READ_INDUSTRY_JOBS,
|
|
41
43
|
SCOPE_READ_MARKET_ORDERS,
|
|
42
|
-
|
|
44
|
+
)
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"""Exceptions for the Eve Online ESI client."""
|
|
2
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
3
5
|
|
|
4
6
|
class EveOnlineError(Exception):
|
|
5
7
|
"""Base exception for Eve Online ESI errors."""
|
|
@@ -14,10 +16,20 @@ class EveOnlineAuthenticationError(EveOnlineError):
|
|
|
14
16
|
|
|
15
17
|
|
|
16
18
|
class EveOnlineRateLimitError(EveOnlineError):
|
|
17
|
-
"""Exception raised when the ESI rate limit is exceeded.
|
|
19
|
+
"""Exception raised when the ESI rate limit is exceeded.
|
|
20
|
+
|
|
21
|
+
Attributes:
|
|
22
|
+
retry_after: Seconds to wait before retrying, or ``None`` if the
|
|
23
|
+
server did not provide the header.
|
|
24
|
+
"""
|
|
18
25
|
|
|
19
26
|
def __init__(self, retry_after: int | None = None) -> None:
|
|
20
|
-
"""Initialize the rate limit error.
|
|
27
|
+
"""Initialize the rate limit error.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
retry_after: Optional number of seconds the server asks us to
|
|
31
|
+
wait before retrying.
|
|
32
|
+
"""
|
|
21
33
|
self.retry_after = retry_after
|
|
22
34
|
message = "ESI rate limit exceeded"
|
|
23
35
|
if retry_after is not None:
|