pybluecurrent 0.1.0__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.
- pybluecurrent-0.2.0/.github/workflows/publish.yaml +52 -0
- pybluecurrent-0.2.0/.github/workflows/test.yaml +51 -0
- {pybluecurrent-0.1.0 → pybluecurrent-0.2.0}/.gitignore +3 -0
- {pybluecurrent-0.1.0 → pybluecurrent-0.2.0}/.pre-commit-config.yaml +7 -16
- pybluecurrent-0.2.0/CHANGELOG.md +40 -0
- {pybluecurrent-0.1.0 → pybluecurrent-0.2.0}/PKG-INFO +30 -2
- {pybluecurrent-0.1.0 → pybluecurrent-0.2.0}/README.md +29 -1
- {pybluecurrent-0.1.0 → pybluecurrent-0.2.0}/pyproject.toml +6 -7
- pybluecurrent-0.2.0/src/pybluecurrent/_version.py +24 -0
- {pybluecurrent-0.1.0 → pybluecurrent-0.2.0}/src/pybluecurrent/client.py +132 -61
- pybluecurrent-0.2.0/src/pybluecurrent/utilities.py +51 -0
- {pybluecurrent-0.1.0 → pybluecurrent-0.2.0}/src/pybluecurrent.egg-info/PKG-INFO +30 -2
- {pybluecurrent-0.1.0 → pybluecurrent-0.2.0}/src/pybluecurrent.egg-info/SOURCES.txt +13 -1
- pybluecurrent-0.2.0/src/pybluecurrent.egg-info/scm_file_list.json +29 -0
- pybluecurrent-0.2.0/src/pybluecurrent.egg-info/scm_version.json +8 -0
- {pybluecurrent-0.1.0 → pybluecurrent-0.2.0}/tests/conftest.py +16 -1
- pybluecurrent-0.2.0/tests/fake_socket.py +130 -0
- pybluecurrent-0.2.0/tests/fixtures/account.json +12 -0
- pybluecurrent-0.2.0/tests/fixtures/charge_cards.json +15 -0
- pybluecurrent-0.2.0/tests/fixtures/charge_point_settings.json +50 -0
- pybluecurrent-0.2.0/tests/fixtures/charge_points.json +75 -0
- pybluecurrent-0.2.0/tests/fixtures/error_forbidden.json +5 -0
- pybluecurrent-0.2.0/tests/fixtures/grid_status.json +11 -0
- pybluecurrent-0.2.0/tests/fixtures/sustainability_status.json +5 -0
- {pybluecurrent-0.1.0 → pybluecurrent-0.2.0}/tests/test_client.py +16 -2
- pybluecurrent-0.2.0/tests/test_offline.py +225 -0
- {pybluecurrent-0.1.0 → pybluecurrent-0.2.0}/tests/test_utilities.py +12 -0
- pybluecurrent-0.1.0/.github/workflows/publish.yaml +0 -32
- pybluecurrent-0.1.0/.github/workflows/test.yaml +0 -31
- pybluecurrent-0.1.0/src/pybluecurrent/_version.py +0 -34
- pybluecurrent-0.1.0/src/pybluecurrent/utilities.py +0 -36
- {pybluecurrent-0.1.0 → pybluecurrent-0.2.0}/LICENSE +0 -0
- {pybluecurrent-0.1.0 → pybluecurrent-0.2.0}/setup.cfg +0 -0
- {pybluecurrent-0.1.0 → pybluecurrent-0.2.0}/src/pybluecurrent/__init__.py +0 -0
- {pybluecurrent-0.1.0 → pybluecurrent-0.2.0}/src/pybluecurrent/exceptions.py +0 -0
- {pybluecurrent-0.1.0 → pybluecurrent-0.2.0}/src/pybluecurrent/py.typed +0 -0
- {pybluecurrent-0.1.0 → pybluecurrent-0.2.0}/src/pybluecurrent.egg-info/dependency_links.txt +0 -0
- {pybluecurrent-0.1.0 → pybluecurrent-0.2.0}/src/pybluecurrent.egg-info/requires.txt +0 -0
- {pybluecurrent-0.1.0 → pybluecurrent-0.2.0}/src/pybluecurrent.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
name: Build and Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
release:
|
|
8
|
+
types: [published]
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
build:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
timeout-minutes: 10
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- name: Set up Python
|
|
19
|
+
uses: actions/setup-python@v5
|
|
20
|
+
with:
|
|
21
|
+
python-version: "3.x"
|
|
22
|
+
|
|
23
|
+
- name: Build
|
|
24
|
+
run: |
|
|
25
|
+
pip3 install build
|
|
26
|
+
python3 -m build
|
|
27
|
+
|
|
28
|
+
publish:
|
|
29
|
+
needs: build
|
|
30
|
+
if: startsWith(github.ref, 'refs/tags')
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
timeout-minutes: 10
|
|
33
|
+
environment: pypi
|
|
34
|
+
permissions:
|
|
35
|
+
id-token: write
|
|
36
|
+
contents: read
|
|
37
|
+
|
|
38
|
+
steps:
|
|
39
|
+
- uses: actions/checkout@v4
|
|
40
|
+
|
|
41
|
+
- name: Set up Python
|
|
42
|
+
uses: actions/setup-python@v5
|
|
43
|
+
with:
|
|
44
|
+
python-version: "3.x"
|
|
45
|
+
|
|
46
|
+
- name: Build
|
|
47
|
+
run: |
|
|
48
|
+
pip3 install build
|
|
49
|
+
python3 -m build
|
|
50
|
+
|
|
51
|
+
- name: Publish to PyPI
|
|
52
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
name: Continuous Integration
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
pull_request:
|
|
6
|
+
push:
|
|
7
|
+
branches:
|
|
8
|
+
- main
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
lint:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
timeout-minutes: 10
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- name: Set up Python
|
|
19
|
+
uses: actions/setup-python@v5
|
|
20
|
+
with:
|
|
21
|
+
python-version: "3.x"
|
|
22
|
+
|
|
23
|
+
- name: Install Dependencies
|
|
24
|
+
run: |
|
|
25
|
+
pip3 install -e ".[dev]"
|
|
26
|
+
|
|
27
|
+
- name: Run pre-commit
|
|
28
|
+
run: pre-commit run --all-files
|
|
29
|
+
|
|
30
|
+
test:
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
timeout-minutes: 10
|
|
33
|
+
strategy:
|
|
34
|
+
fail-fast: false
|
|
35
|
+
matrix:
|
|
36
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
37
|
+
|
|
38
|
+
steps:
|
|
39
|
+
- uses: actions/checkout@v4
|
|
40
|
+
|
|
41
|
+
- name: Set up Python
|
|
42
|
+
uses: actions/setup-python@v5
|
|
43
|
+
with:
|
|
44
|
+
python-version: ${{ matrix.python-version }}
|
|
45
|
+
|
|
46
|
+
- name: Install Dependencies
|
|
47
|
+
run: |
|
|
48
|
+
pip3 install -e ".[dev]"
|
|
49
|
+
|
|
50
|
+
- name: Run Pytest
|
|
51
|
+
run: pytest
|
|
@@ -13,22 +13,13 @@ repos:
|
|
|
13
13
|
- id: check-json
|
|
14
14
|
- id: pretty-format-json
|
|
15
15
|
args: [--autofix]
|
|
16
|
-
- repo: https://github.com/ambv/black
|
|
17
|
-
rev: 23.3.0
|
|
18
|
-
hooks:
|
|
19
|
-
- id: black
|
|
20
16
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
21
|
-
rev: v0.
|
|
22
|
-
hooks:
|
|
23
|
-
- id: ruff
|
|
24
|
-
- repo: https://github.com/pycqa/isort
|
|
25
|
-
rev: 5.12.0
|
|
17
|
+
rev: v0.15.20
|
|
26
18
|
hooks:
|
|
27
|
-
- id:
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
19
|
+
- id: ruff-check
|
|
20
|
+
args: [--fix]
|
|
21
|
+
- id: ruff-format
|
|
22
|
+
- repo: https://github.com/astral-sh/ty-pre-commit
|
|
23
|
+
rev: v0.0.56
|
|
31
24
|
hooks:
|
|
32
|
-
|
|
33
|
-
additional_dependencies:
|
|
34
|
-
- types-requests
|
|
25
|
+
- id: ty
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
6
|
+
This project is pre-1.0: breaking changes may land in minor releases.
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.2.0] - 2026-07-11
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- API-token authentication: construct the client with `BlueCurrentClient(api_token=...)` instead of a username and password.
|
|
15
|
+
- `get_api_token()` and `generate_api_token()` to fetch or rotate your account's API token (home automation key).
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- REST calls now use `api.bluecurrent.nl` instead of the legacy `bo.bluecurrent.nl` backoffice host (same `bc_api` v2.0 API and response shapes).
|
|
20
|
+
- REST requests now use a 30-second timeout instead of httpx's 5-second default, so occasional slow backend responses no longer raise `httpx.ReadTimeout`; override with the `http_timeout` attribute.
|
|
21
|
+
- Internal: added an offline websocket test harness (fake socket + recorded fixtures) so the auth/`_send`/`_receive`/`_handler` logic runs in CI without live credentials.
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- Concurrent websocket calls are now safe: calls awaiting the same response type are serialized so overlapping same-type calls can no longer receive each other's replies (different-type calls still run concurrently). Errors the backend tags with a request id are routed to the originating call rather than failing every in-flight call.
|
|
26
|
+
|
|
27
|
+
## [0.1.1] - 2026-07-04
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
|
|
31
|
+
- `get_account` no longer raises a `ValueError` on BlueCurrent's current date format; `first_login_app` now parses both the legacy (`01-JAN-20`) and ISO (`2020-01-15T13:33:52`) formats.
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
|
|
35
|
+
- `get_account` returns `first_login_app` as a `datetime` (previously a `date`).
|
|
36
|
+
- Internal: switched tooling to Ruff and ty, added a Python 3.10–3.13 CI matrix, and moved to PyPI trusted publishing (OIDC).
|
|
37
|
+
|
|
38
|
+
[Unreleased]: https://github.com/rogiervandergeer/pybluecurrent/compare/0.2.0...HEAD
|
|
39
|
+
[0.2.0]: https://github.com/rogiervandergeer/pybluecurrent/compare/0.1.1...0.2.0
|
|
40
|
+
[0.1.1]: https://github.com/rogiervandergeer/pybluecurrent/compare/0.1.0...0.1.1
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pybluecurrent
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Python client for BlueCurrent charge points.
|
|
5
5
|
Author-email: Rogier van der Geer <rogier@vander-geer.nl>
|
|
6
6
|
License: MIT
|
|
@@ -52,6 +52,8 @@ async with client:
|
|
|
52
52
|
The `BlueCurrentClient` exposes the following methods:
|
|
53
53
|
|
|
54
54
|
- [`get_account`](#getaccount---get-your-account-information)
|
|
55
|
+
- [`get_api_token`](#getapitoken---get-your-api-token)
|
|
56
|
+
- [`generate_api_token`](#generateapitoken---generate-a-new-api-token)
|
|
55
57
|
- [`get_charge_cards`](#getchargecards---get-your-charge-cards)
|
|
56
58
|
- [`get_charge_points`](#getchargepoints---get-your-charge-points)
|
|
57
59
|
- [`get_charge_point_settings`](#getchargepointsettings---get-the-settings-of-a-charge-point)
|
|
@@ -76,6 +78,14 @@ async with client:
|
|
|
76
78
|
```
|
|
77
79
|
Entering the async context will automatically login.
|
|
78
80
|
|
|
81
|
+
Instead of a username and password, you can authenticate with an API token:
|
|
82
|
+
```python
|
|
83
|
+
client = BlueCurrentClient(api_token="your_api_token")
|
|
84
|
+
```
|
|
85
|
+
Retrieve or rotate the token with [`get_api_token`](#getapitoken---get-your-api-token) and
|
|
86
|
+
[`generate_api_token`](#generateapitoken---generate-a-new-api-token), or from the
|
|
87
|
+
[BlueCurrent website](https://my.bluecurrent.nl).
|
|
88
|
+
|
|
79
89
|
#### `get_account` - Get your account information.
|
|
80
90
|
|
|
81
91
|
```python
|
|
@@ -94,11 +104,29 @@ A dictionary describing your account:
|
|
|
94
104
|
"developer_mode_enabled": False,
|
|
95
105
|
"tel": "",
|
|
96
106
|
"marketing_target": "bluecurrent",
|
|
97
|
-
"first_login_app":
|
|
107
|
+
"first_login_app": datetime(2020, 1, 15, 13, 33, 52),
|
|
98
108
|
"hubspot_user_identity": "a_very_long_string"
|
|
99
109
|
}
|
|
100
110
|
```
|
|
101
111
|
|
|
112
|
+
#### `get_api_token` - Get your API token.
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
async def get_api_token(self) -> str
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Returns the API token (home automation key) for your account. This token can be used to authenticate
|
|
119
|
+
instead of a username and password, by constructing the client with `BlueCurrentClient(api_token=...)`.
|
|
120
|
+
|
|
121
|
+
#### `generate_api_token` - Generate a new API token.
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
async def generate_api_token(self) -> str
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Generates a new API token and returns it. **Warning:** this rotates the token — any previously issued
|
|
128
|
+
token is invalidated, which will break anything still using the old one (for example a Home Assistant integration).
|
|
129
|
+
|
|
102
130
|
#### `get_charge_cards` - Get your charge cards.
|
|
103
131
|
|
|
104
132
|
```python
|
|
@@ -25,6 +25,8 @@ async with client:
|
|
|
25
25
|
The `BlueCurrentClient` exposes the following methods:
|
|
26
26
|
|
|
27
27
|
- [`get_account`](#getaccount---get-your-account-information)
|
|
28
|
+
- [`get_api_token`](#getapitoken---get-your-api-token)
|
|
29
|
+
- [`generate_api_token`](#generateapitoken---generate-a-new-api-token)
|
|
28
30
|
- [`get_charge_cards`](#getchargecards---get-your-charge-cards)
|
|
29
31
|
- [`get_charge_points`](#getchargepoints---get-your-charge-points)
|
|
30
32
|
- [`get_charge_point_settings`](#getchargepointsettings---get-the-settings-of-a-charge-point)
|
|
@@ -49,6 +51,14 @@ async with client:
|
|
|
49
51
|
```
|
|
50
52
|
Entering the async context will automatically login.
|
|
51
53
|
|
|
54
|
+
Instead of a username and password, you can authenticate with an API token:
|
|
55
|
+
```python
|
|
56
|
+
client = BlueCurrentClient(api_token="your_api_token")
|
|
57
|
+
```
|
|
58
|
+
Retrieve or rotate the token with [`get_api_token`](#getapitoken---get-your-api-token) and
|
|
59
|
+
[`generate_api_token`](#generateapitoken---generate-a-new-api-token), or from the
|
|
60
|
+
[BlueCurrent website](https://my.bluecurrent.nl).
|
|
61
|
+
|
|
52
62
|
#### `get_account` - Get your account information.
|
|
53
63
|
|
|
54
64
|
```python
|
|
@@ -67,11 +77,29 @@ A dictionary describing your account:
|
|
|
67
77
|
"developer_mode_enabled": False,
|
|
68
78
|
"tel": "",
|
|
69
79
|
"marketing_target": "bluecurrent",
|
|
70
|
-
"first_login_app":
|
|
80
|
+
"first_login_app": datetime(2020, 1, 15, 13, 33, 52),
|
|
71
81
|
"hubspot_user_identity": "a_very_long_string"
|
|
72
82
|
}
|
|
73
83
|
```
|
|
74
84
|
|
|
85
|
+
#### `get_api_token` - Get your API token.
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
async def get_api_token(self) -> str
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Returns the API token (home automation key) for your account. This token can be used to authenticate
|
|
92
|
+
instead of a username and password, by constructing the client with `BlueCurrentClient(api_token=...)`.
|
|
93
|
+
|
|
94
|
+
#### `generate_api_token` - Generate a new API token.
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
async def generate_api_token(self) -> str
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Generates a new API token and returns it. **Warning:** this rotates the token — any previously issued
|
|
101
|
+
token is invalidated, which will break anything still using the old one (for example a Home Assistant integration).
|
|
102
|
+
|
|
75
103
|
#### `get_charge_cards` - Get your charge cards.
|
|
76
104
|
|
|
77
105
|
```python
|
|
@@ -43,17 +43,16 @@ pybluecurrent = ["py.typed"]
|
|
|
43
43
|
[tool.setuptools_scm]
|
|
44
44
|
write_to = "src/pybluecurrent/_version.py"
|
|
45
45
|
|
|
46
|
-
[tool.black]
|
|
47
|
-
line-length = 120
|
|
48
|
-
target-version = ["py310"]
|
|
49
|
-
|
|
50
|
-
[tool.isort]
|
|
51
|
-
profile = "black"
|
|
52
|
-
|
|
53
46
|
[tool.ruff]
|
|
54
47
|
line-length = 120
|
|
55
48
|
target-version = "py310"
|
|
56
49
|
|
|
50
|
+
[tool.ruff.lint]
|
|
51
|
+
select = ["E", "F", "I"]
|
|
52
|
+
|
|
53
|
+
[tool.ty.src]
|
|
54
|
+
include = ["src"]
|
|
55
|
+
|
|
57
56
|
[tool.pytest.ini_options]
|
|
58
57
|
asyncio_mode = "auto"
|
|
59
58
|
asyncio_default_fixture_loop_scope = "session"
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# file generated by vcs-versioning
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"__version__",
|
|
7
|
+
"__version_tuple__",
|
|
8
|
+
"version",
|
|
9
|
+
"version_tuple",
|
|
10
|
+
"__commit_id__",
|
|
11
|
+
"commit_id",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
version: str
|
|
15
|
+
__version__: str
|
|
16
|
+
__version_tuple__: tuple[int | str, ...]
|
|
17
|
+
version_tuple: tuple[int | str, ...]
|
|
18
|
+
commit_id: str | None
|
|
19
|
+
__commit_id__: str | None
|
|
20
|
+
|
|
21
|
+
__version__ = version = '0.2.0'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 2, 0)
|
|
23
|
+
|
|
24
|
+
__commit_id__ = commit_id = 'ge8d24aba3'
|