pydiagral 1.5.0b2__tar.gz → 1.5.0b5__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.
- pydiagral-1.5.0b5/CHANGELOG.md +40 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/PKG-INFO +1 -1
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/example_code.py +3 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/src/pydiagral/api.py +61 -23
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/src/pydiagral/exceptions.py +8 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/tests/test_pydiagral_api.py +21 -16
- pydiagral-1.5.0b2/CHANGELOG.md +0 -19
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/.devcontainer/Dockerfile.dev +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/.devcontainer/devcontainer.json +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/.github/FUNDING.yml +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/.github/copilot-commit-message-instructions.md +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/.github/dependabot.yml +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/.github/labels.yml +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/.github/workflows/labeler.yml +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/.github/workflows/lint.yaml +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/.github/workflows/lock.yml +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/.github/workflows/pytest.yaml +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/.github/workflows/release_and_doc.yaml +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/.github/workflows/semantic-prs.yml +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/.gitignore +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/.releaserc +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/.vscode/extensions.json +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/.vscode/settings.json +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/LICENSE +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/README.md +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/docs/api.md +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/docs/exceptions.md +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/docs/how-to-find-diagral-serial.png +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/docs/index.md +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/docs/models.md +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/docs/pydiagral-Logo.png +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/mkdocs.yml +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/pyproject.toml +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/src/pydiagral/__init__.py +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/src/pydiagral/constants.py +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/src/pydiagral/models.py +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/src/pydiagral/utils.py +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/tests/__init__.py +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/tests/data/configuration_sample.json +0 -0
- {pydiagral-1.5.0b2 → pydiagral-1.5.0b5}/tests/data/system_details_sample.json +0 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
# [1.5.0-beta.5](https://github.com/mguyard/pydiagral/compare/v1.5.0-beta.4...v1.5.0-beta.5) (2025-03-01)
|
2
|
+
|
3
|
+
|
4
|
+
### Bug Fixes
|
5
|
+
|
6
|
+
* **api:** 🔧 Refactor API key handling and introduce new exceptions ([b1f6d06](https://github.com/mguyard/pydiagral/commit/b1f6d060e52c0c660e760c1dc86c5fa75613e4b2))
|
7
|
+
|
8
|
+
# [1.5.0-beta.4](https://github.com/mguyard/pydiagral/compare/v1.5.0-beta.3...v1.5.0-beta.4) (2025-02-28)
|
9
|
+
|
10
|
+
|
11
|
+
### Bug Fixes
|
12
|
+
|
13
|
+
* **api:** 🔧 Update log message for alarm name retrieval ([fca40e4](https://github.com/mguyard/pydiagral/commit/fca40e44bccd59f6399ae2b89a29c2b4fcc80172))
|
14
|
+
|
15
|
+
# [1.5.0-beta.3](https://github.com/mguyard/pydiagral/compare/v1.5.0-beta.2...v1.5.0-beta.3) (2025-02-28)
|
16
|
+
|
17
|
+
|
18
|
+
### Features
|
19
|
+
|
20
|
+
* **api:** 🚀 Add `get_alarm_name` method and log alarm name in tests ([96e727f](https://github.com/mguyard/pydiagral/commit/96e727fe851a1086d8689c6fb7204efdb702938d))
|
21
|
+
|
22
|
+
# [1.5.0-beta.2](https://github.com/mguyard/pydiagral/compare/v1.5.0-beta.1...v1.5.0-beta.2) (2025-02-28)
|
23
|
+
|
24
|
+
|
25
|
+
### Features
|
26
|
+
|
27
|
+
* **api:** 🚀 Add connection testing functionality with result handling ([a07bbfc](https://github.com/mguyard/pydiagral/commit/a07bbfc22a1f41418dad0347394cadcab31685e8))
|
28
|
+
|
29
|
+
# [1.5.0-beta.1](https://github.com/mguyard/pydiagral/compare/v1.4.0...v1.5.0-beta.1) (2025-02-28)
|
30
|
+
|
31
|
+
|
32
|
+
### Features
|
33
|
+
|
34
|
+
* **api:** 🚀 Add testing connection feature ([53981f6](https://github.com/mguyard/pydiagral/commit/53981f6bdb8b797b7f4408fbaf2264b66a58ab38))
|
35
|
+
|
36
|
+
# 1.4.0 (2025-02-23)
|
37
|
+
|
38
|
+
### Features
|
39
|
+
|
40
|
+
- Initial Public release
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: pydiagral
|
3
|
-
Version: 1.5.
|
3
|
+
Version: 1.5.0b5
|
4
4
|
Summary: A Python library for interacting with Diagral systems
|
5
5
|
Project-URL: Homepage, https://github.com/mguyard/pydiagral
|
6
6
|
Project-URL: Documentation, https://github.com/mguyard/pydiagral
|
@@ -239,6 +239,9 @@ async def test_diagral_api() -> None: # noqa: D103,C901
|
|
239
239
|
stop_result = await alarm.stop_system()
|
240
240
|
_LOGGER.info("Stop System with result: %s", stop_result)
|
241
241
|
|
242
|
+
alarm_name: str = await alarm.get_alarm_name() # Get the alarm name
|
243
|
+
_LOGGER.info("Alarm Name is: %s", alarm_name)
|
244
|
+
|
242
245
|
if (
|
243
246
|
APIKEY_DELETION and APIKEY_CREATION
|
244
247
|
): # Only when the API key has been created
|
@@ -16,6 +16,8 @@ import aiohttp
|
|
16
16
|
|
17
17
|
from .constants import API_VERSION, BASE_URL
|
18
18
|
from .exceptions import (
|
19
|
+
APIKeyCreationError,
|
20
|
+
APIValidationError,
|
19
21
|
AuthenticationError,
|
20
22
|
ClientError,
|
21
23
|
ConfigurationError,
|
@@ -266,7 +268,8 @@ class DiagralAPI:
|
|
266
268
|
ApiKeyWithSecret: An instance of ApiKeyWithSecret containing the created API key and secret key.
|
267
269
|
|
268
270
|
Raises:
|
269
|
-
|
271
|
+
APIKeyCreationError: If the API key creation fails.
|
272
|
+
APIValidationError: If the API key validation fails.
|
270
273
|
|
271
274
|
"""
|
272
275
|
|
@@ -285,16 +288,16 @@ class DiagralAPI:
|
|
285
288
|
set_apikey_response: ApiKeyWithSecret = ApiKeyWithSecret.from_dict(
|
286
289
|
response_data
|
287
290
|
)
|
288
|
-
self.__apikey = set_apikey_response.api_key
|
291
|
+
self.__apikey: str = set_apikey_response.api_key
|
289
292
|
if not self.__apikey:
|
290
293
|
error_msg = "API key not found in response"
|
291
294
|
_LOGGER.error(error_msg)
|
292
|
-
raise
|
293
|
-
self.__secret_key = set_apikey_response.secret_key
|
295
|
+
raise APIKeyCreationError(error_msg)
|
296
|
+
self.__secret_key: str = set_apikey_response.secret_key
|
294
297
|
if not self.__secret_key:
|
295
298
|
error_msg = "Secret key not found in response"
|
296
299
|
_LOGGER.error(error_msg)
|
297
|
-
raise
|
300
|
+
raise APIKeyCreationError(error_msg)
|
298
301
|
|
299
302
|
_LOGGER.info("Successfully created new API key: ...%s", self.__apikey[-4:])
|
300
303
|
# Verify if the API key is valid
|
@@ -303,14 +306,14 @@ class DiagralAPI:
|
|
303
306
|
_LOGGER.info(
|
304
307
|
"Successfully verified new API key: ...%s", self.__apikey[-4:]
|
305
308
|
)
|
306
|
-
except
|
309
|
+
except APIValidationError as e:
|
307
310
|
_LOGGER.error("Created API key failed validation: %s", e)
|
308
311
|
self.__apikey = None
|
309
312
|
raise
|
310
313
|
except DiagralAPIError as e:
|
311
314
|
error_msg: str = f"Failed to create API key: {e!s}"
|
312
315
|
_LOGGER.error(error_msg)
|
313
|
-
raise
|
316
|
+
raise APIKeyCreationError(error_msg) from e
|
314
317
|
|
315
318
|
return ApiKeyWithSecret(api_key=self.__apikey, secret_key=self.__secret_key)
|
316
319
|
|
@@ -329,6 +332,7 @@ class DiagralAPI:
|
|
329
332
|
|
330
333
|
Raises:
|
331
334
|
ConfigurationError: If no API key is provided or if the API key is invalid.
|
335
|
+
APIValidationError: If the API key is invalid or not found in the list of valid keys.
|
332
336
|
|
333
337
|
"""
|
334
338
|
|
@@ -357,7 +361,7 @@ class DiagralAPI:
|
|
357
361
|
if is_valid:
|
358
362
|
_LOGGER.info("API key successfully validated")
|
359
363
|
else:
|
360
|
-
raise
|
364
|
+
raise APIValidationError(
|
361
365
|
"API key is invalid or not found in the list of valid keys"
|
362
366
|
)
|
363
367
|
|
@@ -400,7 +404,7 @@ class DiagralAPI:
|
|
400
404
|
self.__apikey = None
|
401
405
|
self.__secret_key = None
|
402
406
|
|
403
|
-
async def try_connection(self, ephemeral: bool = True) ->
|
407
|
+
async def try_connection(self, ephemeral: bool = True) -> TryConnectResult:
|
404
408
|
"""Test connection with the Diagral system.
|
405
409
|
|
406
410
|
This method tests the connection by either using provided API credentials or generating
|
@@ -415,7 +419,14 @@ class DiagralAPI:
|
|
415
419
|
if non-ephemeral temporary keys were generated.
|
416
420
|
|
417
421
|
Raises:
|
418
|
-
|
422
|
+
APIKeyCreationError: If creation of temporary API keys fails
|
423
|
+
APIValidationError: If API key validation fails
|
424
|
+
SessionError: If the session is not initialized.
|
425
|
+
DiagralAPIError: If the request results in a 400 status code or other API errors.
|
426
|
+
AuthenticationError: If authentication fails or request results in a 401 or 403 status code.
|
427
|
+
ValidationError: If the request results in a 422 status code.
|
428
|
+
ServerError: If the request results in a 500 or 503 status code.
|
429
|
+
ClientError: If there is a network error.
|
419
430
|
|
420
431
|
Note:
|
421
432
|
If API credentials are not provided during client initialization, temporary
|
@@ -427,20 +438,25 @@ class DiagralAPI:
|
|
427
438
|
|
428
439
|
result: TryConnectResult = TryConnectResult()
|
429
440
|
api_keys_provided = bool(self.__apikey and self.__secret_key)
|
430
|
-
try:
|
431
|
-
# If API keys are not provided, generate temporary keys
|
432
|
-
if not api_keys_provided:
|
433
|
-
api_key_response: ApiKeyWithSecret = await self.set_apikey()
|
434
441
|
|
435
|
-
|
442
|
+
# If API keys are not provided, generate temporary keys
|
443
|
+
if not api_keys_provided:
|
444
|
+
api_key_response: ApiKeyWithSecret = await self.set_apikey()
|
445
|
+
|
446
|
+
# Retrieve system status to validate connection
|
447
|
+
try:
|
436
448
|
await self.get_system_status()
|
437
|
-
|
449
|
+
except DiagralAPIError:
|
438
450
|
if ephemeral and not api_keys_provided:
|
439
451
|
await self.delete_apikey(apikey=self.__apikey)
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
452
|
+
raise
|
453
|
+
|
454
|
+
# If connection is successful, clean up temporary keys if requested (ephemeral)
|
455
|
+
if ephemeral and not api_keys_provided:
|
456
|
+
await self.delete_apikey(apikey=self.__apikey)
|
457
|
+
elif not ephemeral and not api_keys_provided:
|
458
|
+
result.keys = api_key_response
|
459
|
+
|
444
460
|
result.result = True
|
445
461
|
return result
|
446
462
|
|
@@ -489,6 +505,28 @@ class DiagralAPI:
|
|
489
505
|
)
|
490
506
|
return self.alarm_configuration
|
491
507
|
|
508
|
+
async def get_alarm_name(self) -> str:
|
509
|
+
"""Get the name of the alarm from the configuration.
|
510
|
+
|
511
|
+
Returns:
|
512
|
+
str: The name of the alarm from the configuration.
|
513
|
+
|
514
|
+
Raises:
|
515
|
+
ConfigurationError: If unable to retrieve the alarm configuration.
|
516
|
+
|
517
|
+
Note:
|
518
|
+
This method will attempt to fetch the configuration if it hasn't been loaded yet.
|
519
|
+
|
520
|
+
"""
|
521
|
+
|
522
|
+
if not self.alarm_configuration:
|
523
|
+
await self.get_configuration()
|
524
|
+
|
525
|
+
if not self.alarm_configuration:
|
526
|
+
raise ConfigurationError("Failed to retrieve alarm configuration")
|
527
|
+
|
528
|
+
return self.alarm_configuration.alarm.name
|
529
|
+
|
492
530
|
async def get_devices_info(self) -> DeviceList:
|
493
531
|
"""Asynchronously retrieves information about various device types from the alarm configuration.
|
494
532
|
|
@@ -580,17 +618,17 @@ class DiagralAPI:
|
|
580
618
|
SystemStatus: An instance of SystemStatus containing the retrieved system status.
|
581
619
|
|
582
620
|
Raises:
|
583
|
-
|
621
|
+
ConfigurationError: If the API key, secret key, or PIN code is not provided.
|
584
622
|
|
585
623
|
"""
|
586
624
|
|
587
625
|
if not self.__apikey or not self.__secret_key:
|
588
|
-
raise
|
626
|
+
raise ConfigurationError(
|
589
627
|
"API key and secret key required to get system details"
|
590
628
|
)
|
591
629
|
|
592
630
|
if not self.__pincode:
|
593
|
-
raise
|
631
|
+
raise ConfigurationError("PIN code required to get system details")
|
594
632
|
|
595
633
|
_TIMESTAMP = str(int(time.time()))
|
596
634
|
_HMAC: str = generate_hmac_signature(
|
@@ -37,3 +37,11 @@ class ServerError(DiagralAPIError):
|
|
37
37
|
|
38
38
|
class ClientError(DiagralAPIError):
|
39
39
|
"""Raised when client returns error."""
|
40
|
+
|
41
|
+
|
42
|
+
class APIKeyCreationError(DiagralAPIError):
|
43
|
+
"""Raised when API key creation fails."""
|
44
|
+
|
45
|
+
|
46
|
+
class APIValidationError(DiagralAPIError):
|
47
|
+
"""Raised when API validation fails."""
|
@@ -8,7 +8,12 @@ from unittest.mock import AsyncMock, patch
|
|
8
8
|
|
9
9
|
import pytest
|
10
10
|
|
11
|
-
from pydiagral.exceptions import
|
11
|
+
from pydiagral.exceptions import (
|
12
|
+
APIKeyCreationError,
|
13
|
+
APIValidationError,
|
14
|
+
ConfigurationError,
|
15
|
+
DiagralAPIError,
|
16
|
+
)
|
12
17
|
|
13
18
|
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../src")))
|
14
19
|
import json
|
@@ -186,7 +191,7 @@ async def test_set_apikey(mock_request):
|
|
186
191
|
pincode=PIN_CODE,
|
187
192
|
) as diagral:
|
188
193
|
await diagral.login()
|
189
|
-
api_keys = await diagral.set_apikey()
|
194
|
+
api_keys: ApiKeyWithSecret = await diagral.set_apikey()
|
190
195
|
assert isinstance(api_keys, ApiKeyWithSecret)
|
191
196
|
assert api_keys.api_key == API_KEY
|
192
197
|
assert api_keys.secret_key == SECRET_KEY
|
@@ -198,22 +203,22 @@ async def test_set_apikey_with_invalid_user_rights(mock_request):
|
|
198
203
|
"""Test the `set_apikey` method of the `DiagralAPI` class when the user has invalid permissions.
|
199
204
|
|
200
205
|
This test simulates the scenario where a user with invalid permissions tries to set an API key.
|
201
|
-
It mocks the `mock_request` to raise an `
|
206
|
+
It mocks the `mock_request` to raise an `APIKeyCreationError` indicating that the user does not have the right permissions.
|
202
207
|
|
203
208
|
Args:
|
204
209
|
mock_request (Mock): A mock object for simulating API requests.
|
205
210
|
|
206
211
|
Raises:
|
207
|
-
|
212
|
+
APIKeyCreationError: If the user does not have the right permissions.
|
208
213
|
|
209
214
|
"""
|
210
215
|
|
211
|
-
mock_request.side_effect =
|
216
|
+
mock_request.side_effect = APIKeyCreationError(
|
212
217
|
"The user does not have the right permissions"
|
213
218
|
)
|
214
219
|
mock_request.side_effect = [
|
215
220
|
({"access_token": FAKE_TOKEN}, 200), # Response for login
|
216
|
-
|
221
|
+
APIKeyCreationError(
|
217
222
|
"The user does not have the right permissions"
|
218
223
|
), # Response for set_apikey
|
219
224
|
]
|
@@ -226,7 +231,7 @@ async def test_set_apikey_with_invalid_user_rights(mock_request):
|
|
226
231
|
pincode=PIN_CODE,
|
227
232
|
) as diagral:
|
228
233
|
await diagral.login()
|
229
|
-
with pytest.raises(
|
234
|
+
with pytest.raises(APIKeyCreationError):
|
230
235
|
await diagral.set_apikey()
|
231
236
|
|
232
237
|
|
@@ -310,14 +315,14 @@ async def test_validate_apikey_not_existing(mock_request):
|
|
310
315
|
|
311
316
|
This test mocks the responses for the login and validate_apikey requests. It first simulates a successful login
|
312
317
|
response and then simulates a response for the validate_apikey request with a list of API keys that do not match
|
313
|
-
the provided API key. The test expects an `
|
318
|
+
the provided API key. The test expects an `APIValidationError` to be raised when the `validate_apikey` method
|
314
319
|
is called with a non-existing API key.
|
315
320
|
|
316
321
|
Args:
|
317
322
|
mock_request (MagicMock): A mock object to simulate HTTP requests and responses.
|
318
323
|
|
319
324
|
Raises:
|
320
|
-
|
325
|
+
APIValidationError: If the API key validation fails.
|
321
326
|
|
322
327
|
"""
|
323
328
|
mock_request.side_effect = [
|
@@ -336,7 +341,7 @@ async def test_validate_apikey_not_existing(mock_request):
|
|
336
341
|
pincode=PIN_CODE,
|
337
342
|
) as diagral:
|
338
343
|
await diagral.login()
|
339
|
-
with pytest.raises(
|
344
|
+
with pytest.raises(APIValidationError):
|
340
345
|
await diagral.validate_apikey()
|
341
346
|
|
342
347
|
|
@@ -799,10 +804,10 @@ async def test_get_system_status_without_apikey(mock_request):
|
|
799
804
|
1. Set up the mock responses for the login and get_system_status API calls.
|
800
805
|
2. Create an instance of `DiagralAPI` with the provided credentials.
|
801
806
|
3. Perform the login operation.
|
802
|
-
4. Attempt to get the system status and expect an `
|
807
|
+
4. Attempt to get the system status and expect an `ConfigurationError` to be raised.
|
803
808
|
|
804
809
|
Raises:
|
805
|
-
|
810
|
+
ConfigurationError: If the API key is not provided or invalid.
|
806
811
|
|
807
812
|
"""
|
808
813
|
mock_request.side_effect = [
|
@@ -815,7 +820,7 @@ async def test_get_system_status_without_apikey(mock_request):
|
|
815
820
|
pincode=PIN_CODE,
|
816
821
|
) as diagral:
|
817
822
|
await diagral.login()
|
818
|
-
with pytest.raises(
|
823
|
+
with pytest.raises(ConfigurationError):
|
819
824
|
await diagral.get_system_status()
|
820
825
|
|
821
826
|
|
@@ -840,10 +845,10 @@ async def test_get_system_status_without_pincode(mock_request):
|
|
840
845
|
1. Create an instance of `DiagralAPI` with the provided credentials.
|
841
846
|
2. Call the `login` method to authenticate and obtain an access token.
|
842
847
|
3. Attempt to call the `get_system_status` method without providing a pincode.
|
843
|
-
4. Verify that an `
|
848
|
+
4. Verify that an `ConfigurationError` is raised, indicating that a pincode is required.
|
844
849
|
|
845
850
|
Expected Result:
|
846
|
-
- An `
|
851
|
+
- An `ConfigurationError` is raised when attempting to get the system status without a pincode.
|
847
852
|
|
848
853
|
"""
|
849
854
|
mock_request.side_effect = [
|
@@ -857,7 +862,7 @@ async def test_get_system_status_without_pincode(mock_request):
|
|
857
862
|
secret_key=SECRET_KEY,
|
858
863
|
) as diagral:
|
859
864
|
await diagral.login()
|
860
|
-
with pytest.raises(
|
865
|
+
with pytest.raises(ConfigurationError):
|
861
866
|
await diagral.get_system_status()
|
862
867
|
|
863
868
|
|
pydiagral-1.5.0b2/CHANGELOG.md
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
# [1.5.0-beta.2](https://github.com/mguyard/pydiagral/compare/v1.5.0-beta.1...v1.5.0-beta.2) (2025-02-28)
|
2
|
-
|
3
|
-
|
4
|
-
### Features
|
5
|
-
|
6
|
-
* **api:** 🚀 Add connection testing functionality with result handling ([a07bbfc](https://github.com/mguyard/pydiagral/commit/a07bbfc22a1f41418dad0347394cadcab31685e8))
|
7
|
-
|
8
|
-
# [1.5.0-beta.1](https://github.com/mguyard/pydiagral/compare/v1.4.0...v1.5.0-beta.1) (2025-02-28)
|
9
|
-
|
10
|
-
|
11
|
-
### Features
|
12
|
-
|
13
|
-
* **api:** 🚀 Add testing connection feature ([53981f6](https://github.com/mguyard/pydiagral/commit/53981f6bdb8b797b7f4408fbaf2264b66a58ab38))
|
14
|
-
|
15
|
-
# 1.4.0 (2025-02-23)
|
16
|
-
|
17
|
-
### Features
|
18
|
-
|
19
|
-
- Initial Public release
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|