ocpplab 0.1.1__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.
Files changed (118) hide show
  1. ocpplab-0.1.1/PKG-INFO +262 -0
  2. ocpplab-0.1.1/README.md +227 -0
  3. ocpplab-0.1.1/pyproject.toml +103 -0
  4. ocpplab-0.1.1/src/ocpplab/__init__.py +240 -0
  5. ocpplab-0.1.1/src/ocpplab/_default_clients.py +30 -0
  6. ocpplab-0.1.1/src/ocpplab/catalog/__init__.py +4 -0
  7. ocpplab-0.1.1/src/ocpplab/catalog/client.py +332 -0
  8. ocpplab-0.1.1/src/ocpplab/catalog/raw_client.py +657 -0
  9. ocpplab-0.1.1/src/ocpplab/charger_commands/__init__.py +4 -0
  10. ocpplab-0.1.1/src/ocpplab/charger_commands/client.py +1291 -0
  11. ocpplab-0.1.1/src/ocpplab/charger_commands/raw_client.py +2821 -0
  12. ocpplab-0.1.1/src/ocpplab/charger_configuration/__init__.py +4 -0
  13. ocpplab-0.1.1/src/ocpplab/charger_configuration/client.py +310 -0
  14. ocpplab-0.1.1/src/ocpplab/charger_configuration/raw_client.py +690 -0
  15. ocpplab-0.1.1/src/ocpplab/charger_deployments/__init__.py +4 -0
  16. ocpplab-0.1.1/src/ocpplab/charger_deployments/client.py +904 -0
  17. ocpplab-0.1.1/src/ocpplab/charger_deployments/raw_client.py +1850 -0
  18. ocpplab-0.1.1/src/ocpplab/charger_faults/__init__.py +4 -0
  19. ocpplab-0.1.1/src/ocpplab/charger_faults/client.py +266 -0
  20. ocpplab-0.1.1/src/ocpplab/charger_faults/raw_client.py +493 -0
  21. ocpplab-0.1.1/src/ocpplab/charger_local_authorization/__init__.py +4 -0
  22. ocpplab-0.1.1/src/ocpplab/charger_local_authorization/client.py +360 -0
  23. ocpplab-0.1.1/src/ocpplab/charger_local_authorization/raw_client.py +716 -0
  24. ocpplab-0.1.1/src/ocpplab/charger_logs/__init__.py +4 -0
  25. ocpplab-0.1.1/src/ocpplab/charger_logs/client.py +181 -0
  26. ocpplab-0.1.1/src/ocpplab/charger_logs/raw_client.py +266 -0
  27. ocpplab-0.1.1/src/ocpplab/client.py +500 -0
  28. ocpplab-0.1.1/src/ocpplab/core/__init__.py +127 -0
  29. ocpplab-0.1.1/src/ocpplab/core/api_error.py +23 -0
  30. ocpplab-0.1.1/src/ocpplab/core/client_wrapper.py +128 -0
  31. ocpplab-0.1.1/src/ocpplab/core/datetime_utils.py +70 -0
  32. ocpplab-0.1.1/src/ocpplab/core/file.py +67 -0
  33. ocpplab-0.1.1/src/ocpplab/core/force_multipart.py +18 -0
  34. ocpplab-0.1.1/src/ocpplab/core/http_client.py +840 -0
  35. ocpplab-0.1.1/src/ocpplab/core/http_response.py +59 -0
  36. ocpplab-0.1.1/src/ocpplab/core/http_sse/__init__.py +42 -0
  37. ocpplab-0.1.1/src/ocpplab/core/http_sse/_api.py +112 -0
  38. ocpplab-0.1.1/src/ocpplab/core/http_sse/_decoders.py +61 -0
  39. ocpplab-0.1.1/src/ocpplab/core/http_sse/_exceptions.py +7 -0
  40. ocpplab-0.1.1/src/ocpplab/core/http_sse/_models.py +17 -0
  41. ocpplab-0.1.1/src/ocpplab/core/jsonable_encoder.py +120 -0
  42. ocpplab-0.1.1/src/ocpplab/core/logging.py +107 -0
  43. ocpplab-0.1.1/src/ocpplab/core/parse_error.py +36 -0
  44. ocpplab-0.1.1/src/ocpplab/core/pydantic_utilities.py +634 -0
  45. ocpplab-0.1.1/src/ocpplab/core/query_encoder.py +58 -0
  46. ocpplab-0.1.1/src/ocpplab/core/remove_none_from_dict.py +11 -0
  47. ocpplab-0.1.1/src/ocpplab/core/request_options.py +35 -0
  48. ocpplab-0.1.1/src/ocpplab/core/serialization.py +276 -0
  49. ocpplab-0.1.1/src/ocpplab/errors/__init__.py +53 -0
  50. ocpplab-0.1.1/src/ocpplab/errors/bad_request_error.py +11 -0
  51. ocpplab-0.1.1/src/ocpplab/errors/forbidden_error.py +11 -0
  52. ocpplab-0.1.1/src/ocpplab/errors/internal_server_error.py +11 -0
  53. ocpplab-0.1.1/src/ocpplab/errors/not_found_error.py +11 -0
  54. ocpplab-0.1.1/src/ocpplab/errors/unauthorized_error.py +11 -0
  55. ocpplab-0.1.1/src/ocpplab/errors/unprocessable_entity_error.py +11 -0
  56. ocpplab-0.1.1/src/ocpplab/health/__init__.py +4 -0
  57. ocpplab-0.1.1/src/ocpplab/health/client.py +109 -0
  58. ocpplab-0.1.1/src/ocpplab/health/raw_client.py +155 -0
  59. ocpplab-0.1.1/src/ocpplab/location_charger_commands/__init__.py +4 -0
  60. ocpplab-0.1.1/src/ocpplab/location_charger_commands/client.py +1311 -0
  61. ocpplab-0.1.1/src/ocpplab/location_charger_commands/raw_client.py +2887 -0
  62. ocpplab-0.1.1/src/ocpplab/location_charger_faults/__init__.py +4 -0
  63. ocpplab-0.1.1/src/ocpplab/location_charger_faults/client.py +289 -0
  64. ocpplab-0.1.1/src/ocpplab/location_charger_faults/raw_client.py +563 -0
  65. ocpplab-0.1.1/src/ocpplab/location_charger_provisioning/__init__.py +4 -0
  66. ocpplab-0.1.1/src/ocpplab/location_charger_provisioning/client.py +797 -0
  67. ocpplab-0.1.1/src/ocpplab/location_charger_provisioning/raw_client.py +1712 -0
  68. ocpplab-0.1.1/src/ocpplab/locations/__init__.py +4 -0
  69. ocpplab-0.1.1/src/ocpplab/locations/client.py +633 -0
  70. ocpplab-0.1.1/src/ocpplab/locations/raw_client.py +1212 -0
  71. ocpplab-0.1.1/src/ocpplab/py.typed +0 -0
  72. ocpplab-0.1.1/src/ocpplab/raw_client.py +137 -0
  73. ocpplab-0.1.1/src/ocpplab/types/__init__.py +167 -0
  74. ocpplab-0.1.1/src/ocpplab/types/brand_list_response.py +27 -0
  75. ocpplab-0.1.1/src/ocpplab/types/brand_response.py +28 -0
  76. ocpplab-0.1.1/src/ocpplab/types/cache_reset_response.py +24 -0
  77. ocpplab-0.1.1/src/ocpplab/types/charger_lifecycle_request.py +8 -0
  78. ocpplab-0.1.1/src/ocpplab/types/charger_list_response.py +27 -0
  79. ocpplab-0.1.1/src/ocpplab/types/charger_log_entry.py +27 -0
  80. ocpplab-0.1.1/src/ocpplab/types/charger_log_list_response.py +27 -0
  81. ocpplab-0.1.1/src/ocpplab/types/charger_response.py +36 -0
  82. ocpplab-0.1.1/src/ocpplab/types/configuration_change_response.py +25 -0
  83. ocpplab-0.1.1/src/ocpplab/types/configuration_entry.py +24 -0
  84. ocpplab-0.1.1/src/ocpplab/types/configuration_response.py +24 -0
  85. ocpplab-0.1.1/src/ocpplab/types/configuration_update_request.py +8 -0
  86. ocpplab-0.1.1/src/ocpplab/types/connector_selection_request.py +24 -0
  87. ocpplab-0.1.1/src/ocpplab/types/coordinates.py +31 -0
  88. ocpplab-0.1.1/src/ocpplab/types/create_charger_request.py +42 -0
  89. ocpplab-0.1.1/src/ocpplab/types/create_location_chargers_response.py +28 -0
  90. ocpplab-0.1.1/src/ocpplab/types/delete_location_chargers_response.py +27 -0
  91. ocpplab-0.1.1/src/ocpplab/types/fault_operation_response.py +27 -0
  92. ocpplab-0.1.1/src/ocpplab/types/http_error_response.py +26 -0
  93. ocpplab-0.1.1/src/ocpplab/types/http_validation_error.py +20 -0
  94. ocpplab-0.1.1/src/ocpplab/types/local_auth_list_entry.py +26 -0
  95. ocpplab-0.1.1/src/ocpplab/types/local_authorization_list_response.py +27 -0
  96. ocpplab-0.1.1/src/ocpplab/types/local_list_mutation_response.py +27 -0
  97. ocpplab-0.1.1/src/ocpplab/types/location_command_failure.py +24 -0
  98. ocpplab-0.1.1/src/ocpplab/types/location_command_response.py +29 -0
  99. ocpplab-0.1.1/src/ocpplab/types/location_create_charger_failure.py +24 -0
  100. ocpplab-0.1.1/src/ocpplab/types/location_delete_charger_failure.py +24 -0
  101. ocpplab-0.1.1/src/ocpplab/types/location_fault_response.py +29 -0
  102. ocpplab-0.1.1/src/ocpplab/types/location_fault_result.py +26 -0
  103. ocpplab-0.1.1/src/ocpplab/types/location_lifecycle_request.py +23 -0
  104. ocpplab-0.1.1/src/ocpplab/types/location_list_response.py +27 -0
  105. ocpplab-0.1.1/src/ocpplab/types/location_queued_command_result.py +26 -0
  106. ocpplab-0.1.1/src/ocpplab/types/location_response.py +37 -0
  107. ocpplab-0.1.1/src/ocpplab/types/location_response_coordinates.py +7 -0
  108. ocpplab-0.1.1/src/ocpplab/types/location_update_charger_failure.py +24 -0
  109. ocpplab-0.1.1/src/ocpplab/types/model_list_response.py +27 -0
  110. ocpplab-0.1.1/src/ocpplab/types/model_response.py +34 -0
  111. ocpplab-0.1.1/src/ocpplab/types/proxy_action.py +27 -0
  112. ocpplab-0.1.1/src/ocpplab/types/proxy_ocpp_version.py +5 -0
  113. ocpplab-0.1.1/src/ocpplab/types/queued_command_response.py +29 -0
  114. ocpplab-0.1.1/src/ocpplab/types/update_location_charger_item.py +30 -0
  115. ocpplab-0.1.1/src/ocpplab/types/update_location_chargers_response.py +28 -0
  116. ocpplab-0.1.1/src/ocpplab/types/validation_error.py +24 -0
  117. ocpplab-0.1.1/src/ocpplab/types/validation_error_loc_item.py +5 -0
  118. ocpplab-0.1.1/src/ocpplab/version.py +3 -0
ocpplab-0.1.1/PKG-INFO ADDED
@@ -0,0 +1,262 @@
1
+ Metadata-Version: 2.1
2
+ Name: ocpplab
3
+ Version: 0.1.1
4
+ Summary:
5
+ Keywords: ev,ocpp,sdk,api,charging
6
+ Requires-Python: >=3.10,<4.0
7
+ Classifier: Intended Audience :: Developers
8
+ Classifier: Operating System :: MacOS
9
+ Classifier: Operating System :: Microsoft :: Windows
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Operating System :: POSIX
12
+ Classifier: Operating System :: POSIX :: Linux
13
+ Classifier: Programming Language :: Python
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Classifier: Programming Language :: Python :: 3.15
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Classifier: Typing :: Typed
23
+ Provides-Extra: aiohttp
24
+ Requires-Dist: aiohttp (>=3.10.0,<4) ; extra == "aiohttp"
25
+ Requires-Dist: httpx (>=0.21.2)
26
+ Requires-Dist: httpx-aiohttp (==0.1.8) ; extra == "aiohttp"
27
+ Requires-Dist: pydantic (>=1.9.2)
28
+ Requires-Dist: pydantic-core (>=2.18.2,<2.44.0)
29
+ Requires-Dist: typing_extensions (>=4.0.0)
30
+ Project-URL: Documentation, https://github.com/ev-cloudx/ocpplab-sdk
31
+ Project-URL: Homepage, https://github.com/ev-cloudx/ocpplab-sdk
32
+ Project-URL: Repository, https://github.com/ev-cloudx/ocpplab-sdk
33
+ Description-Content-Type: text/markdown
34
+
35
+ # Ocpplab Python Library
36
+
37
+ [![fern shield](https://img.shields.io/badge/%F0%9F%8C%BF-Built%20with%20Fern-brightgreen)](https://buildwithfern.com?utm_source=github&utm_medium=github&utm_campaign=readme&utm_source=https%3A%2F%2Fgithub.com%2Fev-cloudx%2Focpplab-sdk)
38
+ [![pypi](https://img.shields.io/pypi/v/ocpplab)](https://pypi.python.org/pypi/ocpplab)
39
+
40
+ The Ocpplab Python library provides convenient access to the Ocpplab APIs from Python.
41
+
42
+ ## Table of Contents
43
+
44
+ - [Run](#run)
45
+ - [Contract](#contract)
46
+ - [Client Generation](#client-generation)
47
+ - [Notes](#notes)
48
+ - [Seed Scripts](#seed-scripts)
49
+ - [Installation](#installation)
50
+ - [Reference](#reference)
51
+ - [Usage](#usage)
52
+ - [Async Client](#async-client)
53
+ - [Exception Handling](#exception-handling)
54
+ - [Advanced](#advanced)
55
+ - [Access Raw Response Data](#access-raw-response-data)
56
+ - [Retries](#retries)
57
+ - [Timeouts](#timeouts)
58
+ - [Custom Client](#custom-client)
59
+ - [Contributing](#contributing)
60
+
61
+ ## Run
62
+
63
+ Start the API locally with:
64
+
65
+ ```bash
66
+ uvicorn src.main:app --reload --host 0.0.0.0 --port 8000
67
+ ```
68
+
69
+ ## Contract
70
+
71
+ - Runtime OpenAPI JSON: `/openapi.json`
72
+ - Checked-in spec: [`openapi.yaml`](/Users/yacine-elazrak/OCPPLAB/OCPP/ocpplab-sdk/openapi.yaml)
73
+ - Regenerate artifacts: `make openapi`
74
+
75
+ The checked-in OpenAPI files are generated from the current FastAPI app with runtime dependencies disabled, so the exported contract does not depend on Supabase or Temporal startup.
76
+
77
+ ## Client Generation
78
+
79
+ Generate your preferred client directly from `/openapi.json` or the checked-in
80
+ OpenAPI artifacts.
81
+
82
+ ## Notes
83
+
84
+ - Tenant-scoped endpoints require the `X-Organization-Id` header.
85
+ - Pydantic API schemas live under `src/schemas/`.
86
+ - Queue producers and consumers live under `src/messaging/`.
87
+
88
+ ## Seed Scripts
89
+
90
+ This repo also contains TypeScript data seeding files for local or sandbox database setup:
91
+
92
+ - [seed.ts](/Users/yacine-elazrak/OCPPLAB/OCPP/ocpplab-sdk/seed.ts): uses Snaplet Seed to reset and populate the `brands`, `models`, `locations`, and `deployments` tables with demo data.
93
+ - [seed.config.ts](/Users/yacine-elazrak/OCPPLAB/OCPP/ocpplab-sdk/seed.config.ts): defines the Postgres adapter and target schema selection used by the seeding tool.
94
+
95
+ Prerequisites:
96
+
97
+ - Node.js installed
98
+ - project dependencies installed with your preferred JS package manager
99
+ - access to the target Postgres database configured for Snaplet Seed
100
+
101
+ ## Installation
102
+
103
+ ```sh
104
+ pip install ocpplab
105
+ ```
106
+
107
+ ## Reference
108
+
109
+ A full reference for this library is available [here](https://github.com/ev-cloudx/ocpplab-sdk/blob/HEAD/./reference.md).
110
+
111
+ ## Usage
112
+
113
+ Instantiate and use the client with the following:
114
+
115
+ ```python
116
+ from ocpplab import OcpplabApi
117
+
118
+ client = OcpplabApi(
119
+ token="<token>",
120
+ base_url="https://yourhost.com/path/to/api",
121
+ )
122
+
123
+ client.charger_deployments.create_charger(
124
+ identity="CP-TEST-001",
125
+ brand_slug="wallbox",
126
+ model_slug="wallbox-pulsar-plus",
127
+ connector_type="Type2",
128
+ ws_url="wss://ocpp-toolkit-api.monta.app",
129
+ ocpp_version="OCPP1.6",
130
+ charge_point_name="Bay A01",
131
+ location_id="4090477f-a416-4515-a302-97aa344a0a2a",
132
+ location_name="La Defense Charging Hub",
133
+ )
134
+ ```
135
+
136
+ ## Async Client
137
+
138
+ The SDK also exports an `async` client so that you can make non-blocking calls to our API. Note that if you are constructing an Async httpx client class to pass into this client, use `httpx.AsyncClient()` instead of `httpx.Client()` (e.g. for the `httpx_client` parameter of this client).
139
+
140
+ ```python
141
+ import asyncio
142
+
143
+ from ocpplab import AsyncOcpplabApi
144
+
145
+ client = AsyncOcpplabApi(
146
+ token="<token>",
147
+ base_url="https://yourhost.com/path/to/api",
148
+ )
149
+
150
+
151
+ async def main() -> None:
152
+ await client.charger_deployments.create_charger(
153
+ identity="CP-TEST-001",
154
+ brand_slug="wallbox",
155
+ model_slug="wallbox-pulsar-plus",
156
+ connector_type="Type2",
157
+ ws_url="wss://ocpp-toolkit-api.monta.app",
158
+ ocpp_version="OCPP1.6",
159
+ charge_point_name="Bay A01",
160
+ location_id="4090477f-a416-4515-a302-97aa344a0a2a",
161
+ location_name="La Defense Charging Hub",
162
+ )
163
+
164
+
165
+ asyncio.run(main())
166
+ ```
167
+
168
+ ## Exception Handling
169
+
170
+ When the API returns a non-success status code (4xx or 5xx response), a subclass of the following error
171
+ will be thrown.
172
+
173
+ ```python
174
+ from ocpplab.core.api_error import ApiError
175
+
176
+ try:
177
+ client.charger_deployments.create_charger(...)
178
+ except ApiError as e:
179
+ print(e.status_code)
180
+ print(e.body)
181
+ ```
182
+
183
+ ## Advanced
184
+
185
+ ### Access Raw Response Data
186
+
187
+ The SDK provides access to raw response data, including headers, through the `.with_raw_response` property.
188
+ The `.with_raw_response` property returns a "raw" client that can be used to access the `.headers` and `.data` attributes.
189
+
190
+ ```python
191
+ from ocpplab import OcpplabApi
192
+
193
+ client = OcpplabApi(...)
194
+ response = client.charger_deployments.with_raw_response.create_charger(...)
195
+ print(response.headers) # access the response headers
196
+ print(response.status_code) # access the response status code
197
+ print(response.data) # access the underlying object
198
+ ```
199
+
200
+ ### Retries
201
+
202
+ The SDK is instrumented with automatic retries with exponential backoff. A request will be retried as long
203
+ as the request is deemed retryable and the number of retry attempts has not grown larger than the configured
204
+ retry limit (default: 2).
205
+
206
+ A request is deemed retryable when any of the following HTTP status codes is returned:
207
+
208
+ - [408](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/408) (Timeout)
209
+ - [429](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429) (Too Many Requests)
210
+ - [5XX](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500) (Internal Server Errors)
211
+
212
+ Use the `max_retries` request option to configure this behavior.
213
+
214
+ ```python
215
+ client.charger_deployments.create_charger(..., request_options={
216
+ "max_retries": 1
217
+ })
218
+ ```
219
+
220
+ ### Timeouts
221
+
222
+ The SDK defaults to a 60 second timeout. You can configure this with a timeout option at the client or request level.
223
+
224
+ ```python
225
+ from ocpplab import OcpplabApi
226
+
227
+ client = OcpplabApi(..., timeout=20.0)
228
+
229
+ # Override timeout for a specific method
230
+ client.charger_deployments.create_charger(..., request_options={
231
+ "timeout_in_seconds": 1
232
+ })
233
+ ```
234
+
235
+ ### Custom Client
236
+
237
+ You can override the `httpx` client to customize it for your use-case. Some common use-cases include support for proxies
238
+ and transports.
239
+
240
+ ```python
241
+ import httpx
242
+ from ocpplab import OcpplabApi
243
+
244
+ client = OcpplabApi(
245
+ ...,
246
+ httpx_client=httpx.Client(
247
+ proxy="http://my.test.proxy.example.com",
248
+ transport=httpx.HTTPTransport(local_address="0.0.0.0"),
249
+ ),
250
+ )
251
+ ```
252
+
253
+ ## Contributing
254
+
255
+ While we value open-source contributions to this SDK, this library is generated programmatically.
256
+ Additions made directly to this library would have to be moved over to our generation code,
257
+ otherwise they would be overwritten upon the next generated release. Feel free to open a PR as
258
+ a proof of concept, but know that we will not be able to merge it as-is. We suggest opening
259
+ an issue first to discuss with us!
260
+
261
+ On the other hand, contributions to the README are always very welcome!
262
+
@@ -0,0 +1,227 @@
1
+ # Ocpplab Python Library
2
+
3
+ [![fern shield](https://img.shields.io/badge/%F0%9F%8C%BF-Built%20with%20Fern-brightgreen)](https://buildwithfern.com?utm_source=github&utm_medium=github&utm_campaign=readme&utm_source=https%3A%2F%2Fgithub.com%2Fev-cloudx%2Focpplab-sdk)
4
+ [![pypi](https://img.shields.io/pypi/v/ocpplab)](https://pypi.python.org/pypi/ocpplab)
5
+
6
+ The Ocpplab Python library provides convenient access to the Ocpplab APIs from Python.
7
+
8
+ ## Table of Contents
9
+
10
+ - [Run](#run)
11
+ - [Contract](#contract)
12
+ - [Client Generation](#client-generation)
13
+ - [Notes](#notes)
14
+ - [Seed Scripts](#seed-scripts)
15
+ - [Installation](#installation)
16
+ - [Reference](#reference)
17
+ - [Usage](#usage)
18
+ - [Async Client](#async-client)
19
+ - [Exception Handling](#exception-handling)
20
+ - [Advanced](#advanced)
21
+ - [Access Raw Response Data](#access-raw-response-data)
22
+ - [Retries](#retries)
23
+ - [Timeouts](#timeouts)
24
+ - [Custom Client](#custom-client)
25
+ - [Contributing](#contributing)
26
+
27
+ ## Run
28
+
29
+ Start the API locally with:
30
+
31
+ ```bash
32
+ uvicorn src.main:app --reload --host 0.0.0.0 --port 8000
33
+ ```
34
+
35
+ ## Contract
36
+
37
+ - Runtime OpenAPI JSON: `/openapi.json`
38
+ - Checked-in spec: [`openapi.yaml`](/Users/yacine-elazrak/OCPPLAB/OCPP/ocpplab-sdk/openapi.yaml)
39
+ - Regenerate artifacts: `make openapi`
40
+
41
+ The checked-in OpenAPI files are generated from the current FastAPI app with runtime dependencies disabled, so the exported contract does not depend on Supabase or Temporal startup.
42
+
43
+ ## Client Generation
44
+
45
+ Generate your preferred client directly from `/openapi.json` or the checked-in
46
+ OpenAPI artifacts.
47
+
48
+ ## Notes
49
+
50
+ - Tenant-scoped endpoints require the `X-Organization-Id` header.
51
+ - Pydantic API schemas live under `src/schemas/`.
52
+ - Queue producers and consumers live under `src/messaging/`.
53
+
54
+ ## Seed Scripts
55
+
56
+ This repo also contains TypeScript data seeding files for local or sandbox database setup:
57
+
58
+ - [seed.ts](/Users/yacine-elazrak/OCPPLAB/OCPP/ocpplab-sdk/seed.ts): uses Snaplet Seed to reset and populate the `brands`, `models`, `locations`, and `deployments` tables with demo data.
59
+ - [seed.config.ts](/Users/yacine-elazrak/OCPPLAB/OCPP/ocpplab-sdk/seed.config.ts): defines the Postgres adapter and target schema selection used by the seeding tool.
60
+
61
+ Prerequisites:
62
+
63
+ - Node.js installed
64
+ - project dependencies installed with your preferred JS package manager
65
+ - access to the target Postgres database configured for Snaplet Seed
66
+
67
+ ## Installation
68
+
69
+ ```sh
70
+ pip install ocpplab
71
+ ```
72
+
73
+ ## Reference
74
+
75
+ A full reference for this library is available [here](https://github.com/ev-cloudx/ocpplab-sdk/blob/HEAD/./reference.md).
76
+
77
+ ## Usage
78
+
79
+ Instantiate and use the client with the following:
80
+
81
+ ```python
82
+ from ocpplab import OcpplabApi
83
+
84
+ client = OcpplabApi(
85
+ token="<token>",
86
+ base_url="https://yourhost.com/path/to/api",
87
+ )
88
+
89
+ client.charger_deployments.create_charger(
90
+ identity="CP-TEST-001",
91
+ brand_slug="wallbox",
92
+ model_slug="wallbox-pulsar-plus",
93
+ connector_type="Type2",
94
+ ws_url="wss://ocpp-toolkit-api.monta.app",
95
+ ocpp_version="OCPP1.6",
96
+ charge_point_name="Bay A01",
97
+ location_id="4090477f-a416-4515-a302-97aa344a0a2a",
98
+ location_name="La Defense Charging Hub",
99
+ )
100
+ ```
101
+
102
+ ## Async Client
103
+
104
+ The SDK also exports an `async` client so that you can make non-blocking calls to our API. Note that if you are constructing an Async httpx client class to pass into this client, use `httpx.AsyncClient()` instead of `httpx.Client()` (e.g. for the `httpx_client` parameter of this client).
105
+
106
+ ```python
107
+ import asyncio
108
+
109
+ from ocpplab import AsyncOcpplabApi
110
+
111
+ client = AsyncOcpplabApi(
112
+ token="<token>",
113
+ base_url="https://yourhost.com/path/to/api",
114
+ )
115
+
116
+
117
+ async def main() -> None:
118
+ await client.charger_deployments.create_charger(
119
+ identity="CP-TEST-001",
120
+ brand_slug="wallbox",
121
+ model_slug="wallbox-pulsar-plus",
122
+ connector_type="Type2",
123
+ ws_url="wss://ocpp-toolkit-api.monta.app",
124
+ ocpp_version="OCPP1.6",
125
+ charge_point_name="Bay A01",
126
+ location_id="4090477f-a416-4515-a302-97aa344a0a2a",
127
+ location_name="La Defense Charging Hub",
128
+ )
129
+
130
+
131
+ asyncio.run(main())
132
+ ```
133
+
134
+ ## Exception Handling
135
+
136
+ When the API returns a non-success status code (4xx or 5xx response), a subclass of the following error
137
+ will be thrown.
138
+
139
+ ```python
140
+ from ocpplab.core.api_error import ApiError
141
+
142
+ try:
143
+ client.charger_deployments.create_charger(...)
144
+ except ApiError as e:
145
+ print(e.status_code)
146
+ print(e.body)
147
+ ```
148
+
149
+ ## Advanced
150
+
151
+ ### Access Raw Response Data
152
+
153
+ The SDK provides access to raw response data, including headers, through the `.with_raw_response` property.
154
+ The `.with_raw_response` property returns a "raw" client that can be used to access the `.headers` and `.data` attributes.
155
+
156
+ ```python
157
+ from ocpplab import OcpplabApi
158
+
159
+ client = OcpplabApi(...)
160
+ response = client.charger_deployments.with_raw_response.create_charger(...)
161
+ print(response.headers) # access the response headers
162
+ print(response.status_code) # access the response status code
163
+ print(response.data) # access the underlying object
164
+ ```
165
+
166
+ ### Retries
167
+
168
+ The SDK is instrumented with automatic retries with exponential backoff. A request will be retried as long
169
+ as the request is deemed retryable and the number of retry attempts has not grown larger than the configured
170
+ retry limit (default: 2).
171
+
172
+ A request is deemed retryable when any of the following HTTP status codes is returned:
173
+
174
+ - [408](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/408) (Timeout)
175
+ - [429](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429) (Too Many Requests)
176
+ - [5XX](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500) (Internal Server Errors)
177
+
178
+ Use the `max_retries` request option to configure this behavior.
179
+
180
+ ```python
181
+ client.charger_deployments.create_charger(..., request_options={
182
+ "max_retries": 1
183
+ })
184
+ ```
185
+
186
+ ### Timeouts
187
+
188
+ The SDK defaults to a 60 second timeout. You can configure this with a timeout option at the client or request level.
189
+
190
+ ```python
191
+ from ocpplab import OcpplabApi
192
+
193
+ client = OcpplabApi(..., timeout=20.0)
194
+
195
+ # Override timeout for a specific method
196
+ client.charger_deployments.create_charger(..., request_options={
197
+ "timeout_in_seconds": 1
198
+ })
199
+ ```
200
+
201
+ ### Custom Client
202
+
203
+ You can override the `httpx` client to customize it for your use-case. Some common use-cases include support for proxies
204
+ and transports.
205
+
206
+ ```python
207
+ import httpx
208
+ from ocpplab import OcpplabApi
209
+
210
+ client = OcpplabApi(
211
+ ...,
212
+ httpx_client=httpx.Client(
213
+ proxy="http://my.test.proxy.example.com",
214
+ transport=httpx.HTTPTransport(local_address="0.0.0.0"),
215
+ ),
216
+ )
217
+ ```
218
+
219
+ ## Contributing
220
+
221
+ While we value open-source contributions to this SDK, this library is generated programmatically.
222
+ Additions made directly to this library would have to be moved over to our generation code,
223
+ otherwise they would be overwritten upon the next generated release. Feel free to open a PR as
224
+ a proof of concept, but know that we will not be able to merge it as-is. We suggest opening
225
+ an issue first to discuss with us!
226
+
227
+ On the other hand, contributions to the README are always very welcome!
@@ -0,0 +1,103 @@
1
+ [project]
2
+ name = "ocpplab"
3
+ dynamic = ["version"]
4
+
5
+ [tool.poetry]
6
+ name = "ocpplab"
7
+ version = "0.1.1"
8
+ description = ""
9
+ readme = "README.md"
10
+ authors = []
11
+ keywords = [
12
+ "ev",
13
+ "ocpp",
14
+ "sdk",
15
+ "api",
16
+ "charging"
17
+ ]
18
+
19
+ classifiers = [
20
+ "Intended Audience :: Developers",
21
+ "Programming Language :: Python",
22
+ "Programming Language :: Python :: 3",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.11",
25
+ "Programming Language :: Python :: 3.12",
26
+ "Programming Language :: Python :: 3.13",
27
+ "Programming Language :: Python :: 3.14",
28
+ "Programming Language :: Python :: 3.15",
29
+ "Operating System :: OS Independent",
30
+ "Operating System :: POSIX",
31
+ "Operating System :: MacOS",
32
+ "Operating System :: POSIX :: Linux",
33
+ "Operating System :: Microsoft :: Windows",
34
+ "Topic :: Software Development :: Libraries :: Python Modules",
35
+ "Typing :: Typed"
36
+ ]
37
+ packages = [
38
+ { include = "ocpplab", from = "src"}
39
+ ]
40
+
41
+ [tool.poetry.urls]
42
+ Documentation = 'https://github.com/ev-cloudx/ocpplab-sdk'
43
+ Homepage = 'https://github.com/ev-cloudx/ocpplab-sdk'
44
+ Repository = 'https://github.com/ev-cloudx/ocpplab-sdk'
45
+
46
+ [tool.poetry.dependencies]
47
+ python = "^3.10"
48
+ aiohttp = { version = ">=3.10.0,<4", optional = true}
49
+ httpx = ">=0.21.2"
50
+ httpx-aiohttp = { version = "0.1.8", optional = true}
51
+ pydantic = ">= 1.9.2"
52
+ pydantic-core = ">=2.18.2,<2.44.0"
53
+ typing_extensions = ">= 4.0.0"
54
+
55
+ [tool.poetry.group.dev.dependencies]
56
+ mypy = "==1.13.0"
57
+ pytest = "^8.2.0"
58
+ pytest-asyncio = "^1.0.0"
59
+ pytest-xdist = "^3.6.1"
60
+ python-dateutil = "^2.9.0"
61
+ types-python-dateutil = "^2.9.0.20240316"
62
+ ruff = "==0.11.5"
63
+
64
+ [tool.pytest.ini_options]
65
+ testpaths = [ "tests" ]
66
+ asyncio_mode = "auto"
67
+ markers = [
68
+ "aiohttp: tests that require httpx_aiohttp to be installed",
69
+ ]
70
+
71
+ [tool.mypy]
72
+ plugins = ["pydantic.mypy"]
73
+
74
+ [tool.ruff]
75
+ line-length = 120
76
+
77
+ [tool.ruff.lint]
78
+ select = [
79
+ "E", # pycodestyle errors
80
+ "F", # pyflakes
81
+ "I", # isort
82
+ ]
83
+ ignore = [
84
+ "E402", # Module level import not at top of file
85
+ "E501", # Line too long
86
+ "E711", # Comparison to `None` should be `cond is not None`
87
+ "E712", # Avoid equality comparisons to `True`; use `if ...:` checks
88
+ "E721", # Use `is` and `is not` for type comparisons, or `isinstance()` for insinstance checks
89
+ "E722", # Do not use bare `except`
90
+ "E731", # Do not assign a `lambda` expression, use a `def`
91
+ "F821", # Undefined name
92
+ "F841" # Local variable ... is assigned to but never used
93
+ ]
94
+
95
+ [tool.ruff.lint.isort]
96
+ section-order = ["future", "standard-library", "third-party", "first-party"]
97
+
98
+ [build-system]
99
+ requires = ["poetry-core"]
100
+ build-backend = "poetry.core.masonry.api"
101
+
102
+ [tool.poetry.extras]
103
+ aiohttp=["aiohttp", "httpx-aiohttp"]