<!--
SPDX-FileCopyrightText: 2025 Intevation GmbH

SPDX-License-Identifier: Apache-2.0
-->

# ISDuBA Python Client
A client library for accessing ISDuBA API, based on code generated by https://github.com/openapi-generators/openapi-python-client and adapted to ISDuBA-specific needs.

## Usage
First, create a client instance:

```python
from isduba import Client

client = Client(base_url="https://isduba.example.com")
```

Then, login with your credentials:
```python
client.login(username='ada', password='bob')
```

Now call your endpoint and use your models:

```python
from isduba.api.default import get_about

about = get_about.sync(client=client)
# access the response's value as attributes:
about.version
# or if you need more info (e.g. status_code)
response = get_about.sync_detailed(client=client)
```

Or do the same thing with an async version:

```python
from isduba.api.default import get_about

about = await get_about.asyncio(client=client)
response = await get_about.asyncio_detailed(client=client)
```

### Get documents
```python
from isduba.api.default import get_documents

data = get_documents.sync(client=client, advisories=True, count=1, orders='-critical', limit=10, offset=0)
# search for a string
get_documents.sync(client=client, query='"csaf" search _clientSearch as')
# search for a product. Query syntax: https://github.com/ISDuBA/ISDuBA/blob/main/docs/filter_expr.md
data = get_documents.sync(client=client, query='"putty" ilikepname', limit=2)
```

### Usage Logic

Things to know:
1. Every path/method combo becomes a Python module with four functions:
    1. `sync`: Blocking request that returns parsed data (if successful) or `None`
    1. `sync_detailed`: Blocking request that always returns a `Request`, optionally with `parsed` set if the request was successful.
    1. `asyncio`: Like `sync` but async instead of blocking
    1. `asyncio_detailed`: Like `sync_detailed` but async instead of blocking

1. All path/query params, and bodies become method arguments.
1. If your endpoint had any tags on it, the first tag will be used as a module name for the function (my_tag above)
1. Any endpoint which did not have a tag will be in `isduba.api.default`

## Typing

All responses are objects, you can add typing information with the models:

```python
from isduba.models import WebAboutInfo
from isduba.api.default import get_about
from isduba.types import Response

about: WebAboutInfo = get_about.sync(client=client)
# access the response's value as attributes:
about.version
# or if you need more info (e.g. status_code)
response: Response[WebAboutInfo] = get_about.sync_detailed(client=client)
```

## Advanced customizations

There are more settings on the generated `Client` class which let you control more runtime behavior, check out the docstring on that class for more info. You can also customize the underlying `httpx.Client` or `httpx.AsyncClient` (depending on your use-case):

```python
from isduba import Client

def log_request(request):
    print(f"Request event hook: {request.method} {request.url} - Waiting for response")

def log_response(response):
    request = response.request
    print(f"Response event hook: {request.method} {request.url} - Status {response.status_code}")

client = Client(
    base_url="https://isduba.example.com",
    httpx_args={"event_hooks": {"request": [log_request], "response": [log_response]}},
)
```
