Skip to content

Commit 898e4a5

Browse files
committed
docs: update remaining poetry references to uv in CLI and python-sdk docs
1 parent 6f89ea3 commit 898e4a5

File tree

2 files changed

+6
-119
lines changed

2 files changed

+6
-119
lines changed

docs/docs/cli.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ We use [typer](https://typer.tiangolo.com) to construct the CLI, which in turn u
66

77
We follow a `git` like `command`, `sub-command` pattern, so it should feel quite familiar.
88

9-
poetry will install the alias `gal` for you to interact with the CLI. You can ask for help with:
9+
uv will install the alias `gal` for you to interact with the CLI. You can ask for help with:
1010

1111
::: mkdocs-typer
12-
:module: gallagher.cli
13-
:command: app
12+
:module: gallagher.cli
13+
:command: app
1414

1515
## Resources
1616

docs/docs/python-sdk.md

Lines changed: 3 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ Install via `pip` as follows:
1818
pip install gallagher
1919
```
2020

21-
or if you are using `poetry`:
21+
or if you are using `uv`:
2222

2323
```bash
24-
poetry add gallagher
24+
uv add gallagher
2525
```
2626

2727
For production application please make sure you target a particular version of the API client to avoid breaking changes.
@@ -315,117 +315,4 @@ if __name__ == "__main__":
315315
asyncio.run(main())
316316
```
317317

318-
Endpoints that provide either an `update` or a `change` method will provide:
319-
320-
- `endpoint_follow` which will be the HATEOS discovered endpoint
321-
- `dto_follow` which is a DTO class (typically a Summary) to be used to parse the updates
322-
323-
Following is an extract from the `Alarm` class to demonstrate how it's configured:
324-
325-
```python
326-
@classmethod
327-
async def get_config(cls) -> EndpointConfig:
328-
"""Return the configuration for Alarms
329-
330-
Arguments:
331-
cls: class reference
332-
"""
333-
return EndpointConfig(
334-
endpoint=Capabilities.CURRENT.features.alarms.alarms,
335-
endpoint_follow=Capabilities.CURRENT.features.alarms.updates,
336-
dto_follow=AlarmUpdateResponse,
337-
dto_list=AlarmSummaryResponse,
338-
dto_retrieve=AlarmDetail,
339-
)
340-
```
341-
342-
!!! warning
343-
344-
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):
375-
376-
```json
377-
{
378-
"@Cardholder UID": "2",
379-
"@City": "Hamilton",
380-
"@Company Name": "Gallagher Group",
381-
"@Country": "New Zealand",
382-
"@Email": "[email protected]",
383-
"@Personal URL": "C:\\DemoFiles\\CardholderURLs\\Emma Bennet.htm",
384-
"@Phone": "+64 7 838 9800",
385-
"@Photo": {
386-
"href": "https://commandcentre-api-au.security.gallagher.cloud/api/cardholders/340/personal_data/6550"
387-
},
388-
"firstName": "Emma",
389-
"href": "https://commandcentre-api-au.security.gallagher.cloud/api/cardholders/340",
390-
"id": "340",
391-
"lastName": "Bennett",
392-
"lastSuccessfulAccessTime": "2014-10-16T02:56:43Z"
393-
}
394-
```
395-
396-
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.
318+
Endpoints that provide either an `

0 commit comments

Comments
 (0)