Skip to content

Commit 72aac3c

Browse files
authored
Merge pull request #86 from anomaly/update-docs-poetry-to-uv
Update docs poetry to uv
2 parents dbb8813 + 898e4a5 commit 72aac3c

File tree

4 files changed

+10
-123
lines changed

4 files changed

+10
-123
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/design.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ Majority of the development was conducted on macOS, but the toolchain should be
3636
In addition to the usual suspects (e.g pytest) we use:
3737

3838
- `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
4040
- `mkdocs` for documentation, maintained using markdown
4141

4242
## SDK

docs/docs/installation.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ In the most trivial cases we recommend installation via `PyPI`. The package is d
1313
The SDK can be installed by adding it as a dependency to your project:
1414

1515
```bash
16-
poetry add gallagher
16+
uv add gallagher
1717
```
1818

1919
If you are feeling adventurous you can install everything by:
2020

2121
```bash
22-
poetry add gallagher[all]
22+
uv add gallagher[all]
2323
```
2424

2525
### SDK
@@ -130,7 +130,7 @@ To contribute to the library, please fork this repository and lodge a pull reque
130130

131131
[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.
132132

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`.
134134

135135
!!! info
136136

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)