You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/docs/design.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -36,7 +36,7 @@ Majority of the development was conducted on macOS, but the toolchain should be
36
36
In addition to the usual suspects (e.g pytest) we use:
37
37
38
38
-`task` - as the task runner of choice, it's widely available on platforms and supports Github actions. All endpoints are documented within the command line tool.
39
-
-`poetry` as our package manager of choice for the python project
39
+
-`uv` as our package manager of choice for the python project
40
40
-`mkdocs` for documentation, maintained using markdown
Copy file name to clipboardExpand all lines: docs/docs/installation.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -13,13 +13,13 @@ In the most trivial cases we recommend installation via `PyPI`. The package is d
13
13
The SDK can be installed by adding it as a dependency to your project:
14
14
15
15
```bash
16
-
poetry add gallagher
16
+
uv add gallagher
17
17
```
18
18
19
19
If you are feeling adventurous you can install everything by:
20
20
21
21
```bash
22
-
poetry add gallagher[all]
22
+
uv add gallagher[all]
23
23
```
24
24
25
25
### SDK
@@ -130,7 +130,7 @@ To contribute to the library, please fork this repository and lodge a pull reque
130
130
131
131
[Task](https://taskfile.dev) is a task runner / build tool that aims to be simpler and easier to use than, for example, GNU Make. Gallagher Python Toolkit uses Task to run common tasks such as testing, linting, and building the documentation. First follow the [installation steps](https://taskfile.dev/installation/) to install Task on your system.
132
132
133
-
All the `tasks` are quite logically grouped and most of them will need you to have a `virtualenv` initialised via `poetry`.
133
+
All the `tasks` are quite logically grouped and most of them will need you to have a `virtualenv` initialised via `uv`.
As a breaking change in `8.90` the operator must have the 'Create Events and Alarms' privilege in the division of the source item, if your request specifies a source item. Current versions only require that the operator has that privilege on at least one division.
345
-
346
-
## Error Handling
347
-
348
-
### Exceptions
349
-
350
-
These wrappers raise the following `Exceptions` when they encounter the corresponding HTTP codes:
351
-
352
-
-`gallagher.exception.UnlicensedFeatureException` on `HTTPStatus.FORBIDDEN` when an unlicensed endpoint is accessed (see the discovery section for details)
353
-
-`gallagher.exception.AuthenticationError` on `HTTPStatus.UNAUTHORIZED` if there are issues with authentication
354
-
- gallagher.exception.NotFoundException`on`HTTPStatus.NOT_FOUND`(GET only) - raised if a HTTP endpoint wasn't found e.g A`Detail` object wasn't found
355
-
356
-
### Warnings
357
-
358
-
## Additional Features
359
-
360
-
In addition to a nicely validated wrapper around the data sent by the Command Centre API, we provide provide the following helper interface to keep your interaction `pythonic` wherever possible.
361
-
362
-
## Personal Data Definitions
363
-
364
-
Personal Data Definitions are fields associated to a cardholder and are defined at a Command Centre level. These are dynamically discovered by calling the `/api/personal_data_fields`. When you fetch a cardholder detail, the API returns the `personal_data_fields` as part of the response in the following manner:
365
-
366
-
- children of the `personalDataFields` key in the cardholder detail
367
-
- accessible via key name prefixed with the `@` symbol i.e the personal data field `Email` is accessible via the key `@Email`
368
-
369
-
370
-
!!! tip
371
-
372
-
Note that the `personDataFields` has a `list` of objects, and each object has a single key which is the nae of the personal data field and the value is the related data.
373
-
374
-
To make things more `pythonic` i.e consider the following payload (partially represented):
and we had used the API client to fetch the cardholder detail (partial example):
397
-
398
-
```python title="Personal Data Fields"
399
-
cardholder =await Cardholder.retrieve(340)
400
-
```
401
-
402
-
`cardholder` would have two fields:
403
-
-`personal_data_definitions` which is a list of `CardholderPersonalDataDefinition` objects
404
-
-`pdf` which is a parsed object of the personal data fields
405
-
406
-
`cardholder.personal_data_definitions` is iterable, each instance exposing a `name` and `contents` fields. Use the `value` attribute of `contents` to access the PDF value:
407
-
408
-
```python
409
-
for pdf in cardholder.personal_data_definitions:
410
-
if pdf.name =='@Email':
411
-
print(pdf.name, pdf.contents.value)
412
-
```
413
-
414
-
!!! tip
415
-
416
-
See pyndatic's [Model validator](https://docs.pydantic.dev/latest/concepts/validators/#model-validators) feature in v2, in particular the `@model_validator(mode='after')` constructor.
417
-
418
-
The `cardholder` object will also expose a special attribute called `pdf`. Each instance available in the `personal_data_definitions` field will be mapped to a Pythonic `snake_cased` key, that lets you access the same `CardholderPersonalDataDefinition` object via the `@` prefixed key name. So the above example of accessing the `@Email` field can be done as follows:
419
-
420
-
```python
421
-
cardholder.pdf.email.value
422
-
```
423
-
424
-
The `pdf` attribute is dynamically populated object with dynamically generated keys. Here are some examples of how `PDF` field names are mapped to `snake_case` keys:
425
-
426
-
-`@Cardholder UID` would become `pdf.cardholder_uid`
427
-
-`@City` would become `pdf.city`
428
-
-`@Company Name` would become `pdf.company_name`
429
-
-`@PINNumber` would become `pdf.pin_number`
430
-
431
-
Both approaches have their merits and you should use the one that suits your use case.
0 commit comments