Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions docs/installation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Install and Setup

The Keystone platform includes an official Python client that simplifies integration with the application's REST API.
It handles authentication, request execution, and response parsing, allowing developers to concentrate on application
logic rather than API mechanics.

The client is published on PyPI and can be installed in the standard fashion.

```bash
pip install keystone-api-client
```

!!! note "Version Compatibility"

The API client version should match the major and minor version of the upstream API server.
For example, if the API version is `2.3.x`, the compatible client version is `2.3.y`.
Using a mismatched client version may still function, but compatibility is not guaranteed and may
result in inconsistent behavior.
58 changes: 58 additions & 0 deletions docs/logging.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Application Logging

The Keystone Python client exposes a dedicated logger (`kclient`) that records structured request metadata using the
standard Python logging framework. The logger is registered automatically when the package is imported and can be
configured like any other Python logger.

## Logger Configuration

Custom handlers, formatters, and filters may be attached directly to the kclient logger.
Because the logger behaves like any standard Python logger, you can control output destinations, define
message structures, adjust verbosity, and apply filtering based on logged metadata.

```python
import logging
import keystone_client

handler = logging.StreamHandler()
handler.setFormatter(
logging.Formatter('%(asctime)s %(levelname)s %(name)s: %(message)s')
)

logging.getLogger('kclient').addHandler(handler)
```

In addition to the standard Python logging attributes, the `kclient` logger includes the following package-specific fields:

| Field Name | Description |
|------------|----------------------------------------------------------------------------|
| `cid` | Per-session logging id used to correlate requests across a client session. |
| `baseurl` | Base API server URL, including http protocol. |
| `method` | HTTP method for outgoing requests, or an empty string if not applicable. |
| `endpoint` | API endpoint for outgoing requests, or an empty string if not applicable. |
| `url` | Full API URL for outgoing requests, or an empty string if not applicable. |

## Session IDs

Each client session is assigned a unique correlation ID (CID) that accompanies all emitted log records.
This identifier provides a reference value for correlating client and API logs across multiple endpoints and requests.
CID values are suitable for inclusion in log messages, passing to downstream services, or correlating requests
for debugging and performance monitoring.

=== "Synchronous"

```python
from keystone_client import KeystoneClient

with KeystoneClient(url="http://localhost:8000") as client:
print(client.cid)
```

=== "Asynchronous"

```python
from keystone_client import AsyncKeystoneClient

async with AsyncKeystoneClient(url="http://localhost:8000") as aclient:
print(aclient.cid)
```
159 changes: 6 additions & 153 deletions docs/index.md → docs/requests.md
Original file line number Diff line number Diff line change
@@ -1,126 +1,8 @@
---
hide:
- navigation
---
# Making API Requests

# Introduction

Keystone provides a Python client for streamlining interactions with the application's REST API.
The client automates user authentication and data parsing, freeing developers to focus on core application logic.

## Installation

The Python client is hosted on PyPI and can be installed in the standard fashion.

!!! note "Version Compatibility"

The API client version should match the major and minor version of the upstream API server.
For example, if the API version is `2.3.x`, the compatible client version is `2.3.y`.
Using a mismatched client version may still function, but compatibility is not guaranteed and may
result in inconsistent behavior.


```bash
pip install keystone-api-client
```

## Instantiating a Client

The client package provides support for synchronous and asynchronous API calls.
In both cases, requests are pooled across a shared session, reducing HTTP overhead.
The following example instantiates a new session for a locally running server on port `8000`.
Creating the session with a context manager ensures open connections are automatically closed when no longer in use.

=== "Synchronous"

```python
from keystone_client import KeystoneClient

with KeystoneClient(url="http://localhost:8000") as client:
... # Your synchronous code here
```

=== "Asynchronous"

```python
from keystone_client import AsyncKeystoneClient

async with AsyncKeystoneClient(url="http://localhost:8000") as aclient:
... # Your asynchronous code here
```

Sessions can also be opened and closed manually.
This approach is generally discouraged as it increases the likelihood of resource leaks and unclosed connections.

=== "Synchronous"

```python
from keystone_client import KeystoneClient

client = KeystoneClient(url="http://localhost:8000"):
# Your synchronous code here
client.close()
```

=== "Asynchronous"

```python
from keystone_client import AsyncKeystoneClient

aclient = AsyncKeystoneClient(url="http://localhost:8000"):
# Your asynchronous code here
await aclient.close()
```

Client sessions will automatically manage any relevant session tokens.
This includes assigning a unique correlation ID (CID) used to track requests across Keystone application logs.
CID values are suitable for inclusion in log messages, passing to downstream services, or correlating requests
for debugging and performance monitoring.

=== "Synchronous"

```python
from keystone_client import KeystoneClient

with KeystoneClient(url="http://localhost:8000") as client:
print(client.cid)
```

=== "Asynchronous"

```python
from keystone_client import AsyncKeystoneClient

async with AsyncKeystoneClient(url="http://localhost:8000") as aclient:
print(aclient.cid)
```

## Authenticating a Session

The `login` and `logout` methods are used to handle user authentication.
Once authenticated, the client will automatically manage the resulting session tokens.

=== "Synchronous"

```python
from keystone_client import KeystoneClient

with KeystoneClient(url="http://localhost:8000") as client:
client.login(username="username", password="password")
assert client.is_authenticated()
client.logout()
```

=== "Asynchronous"

```python
from keystone_client import AsyncKeystoneClient

async with AsyncKeystoneClient(url="http://localhost:8000") as aclient:
await aclient.login(username="username", password="password")
assert await aclient.is_authenticated()
await aclient.logout()
```
Client classes (`KeystoneClient` and `AsyncKeystoneClient`) provide a high-level interface for interacting the API.
This includes methods for generic HTTP requests in addition to resource-specific CRUD helpers for common workflows.
All requests automatically include any active authentication or session metadata.

## Generic HTTP Requests

Expand All @@ -137,7 +19,7 @@ Any relevant session/authentication tokens are included automatically when submi

Request/response logic is handled using the `httpx` library.
API responses are returned as `httpx.Response` objects which encapsulate the response data and status code.
Users are encouraged to familiarize themselves with the `httpx.Response` object and it's methods for parsing response
Users are encouraged to familiarize themselves with the `httpx` library and it's methods for parsing response
data and related metadata.
A simple example is provided below.

Expand Down Expand Up @@ -169,7 +51,7 @@ A simple example is provided below.

## CRUD Operations

Dedicated methods are provided for create, retrieve, update, and delete (CRUD) operations for each API resource.
Dedicated methods are provided for create, retrieve, update, and delete (CRUD) operations against each API resource.
These methods simplify data manipulation by automatically handling the request and response logic.

CRUD methods adhere to the following naming scheme:
Expand Down Expand Up @@ -291,32 +173,3 @@ The `raise_not_exists` argument can be used to raise an exception instead.
```python
await aclient.delete_cluster(pk=1, raise_not_exists=True)
```

## Application Logging

API clients automatically log all requests to the `kclient` log handler.
In addition to the standard default values, `kclient` logs include the application specific values listed below.

| Field Name | Description |
|------------|----------------------------------------------------------------------------|
| `cid` | Per-session logging id used to correlate requests across a client session. |
| `baseurl` | Base API server URL, including http protocol. |
| `method` | HTTP method for outgoing requests, or an empty string if not applicable. |
| `endpoint` | API endpoint for outgoing requestst, or an empty string if not applicable. |
| `url` | Full API URL for outgoing requests, or an empty string if not applicable. |

The `kclient` logger is automatically registered when importing the `keystone_client` package.
Formatting, filtering, and persisting log values is left to the user.
For example:

```python
import logging
import keystone_client

handler = logging.StreamHandler()
handler.setFormatter(
logging.Formatter('%(cid)s - %(baseurl)s - %(method)s - %(endpoint)s - %(message)s')
)

logging.getLogger('kclient').addHandler(handler)
```
79 changes: 79 additions & 0 deletions docs/session.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Starting a Session

Interacting with the Keystone API begins by creating a client session.
Session objects encapsulate the connection state, authentication details, and request configuration, allowing the
client to efficiently reuse connections and manage resources across multiple API calls.

## Instantiating a Client

The client package provides support for synchronous and asynchronous API calls.
The following example instantiates a new session for a locally running server on port `8000`.
Creating the session with a context manager ensures open connections are automatically closed when no longer in use.

=== "Synchronous"

```python
from keystone_client import KeystoneClient

with KeystoneClient(url="http://localhost:8000") as client:
... # Your synchronous code here
```

=== "Asynchronous"

```python
from keystone_client import AsyncKeystoneClient

async with AsyncKeystoneClient(url="http://localhost:8000") as aclient:
... # Your asynchronous code here
```

Sessions can also be opened and closed manually, although this approach is generally discouraged as it increases
the likelihood of resource leaks and unclosed connections.

=== "Synchronous"

```python
from keystone_client import KeystoneClient

client = KeystoneClient(url="http://localhost:8000"):
# Your synchronous code here
client.close()
```

=== "Asynchronous"

```python
from keystone_client import AsyncKeystoneClient

aclient = AsyncKeystoneClient(url="http://localhost:8000"):
# Your asynchronous code here
await aclient.close()
```

## Authenticating a Session

The `login` and `logout` methods are used to handle user authentication.
Once authenticated, the client will automatically manage the resulting session tokens.

=== "Synchronous"

```python
from keystone_client import KeystoneClient

with KeystoneClient(url="http://localhost:8000") as client:
client.login(username="username", password="password")
assert client.is_authenticated()
client.logout()
```

=== "Asynchronous"

```python
from keystone_client import AsyncKeystoneClient

async with AsyncKeystoneClient(url="http://localhost:8000") as aclient:
await aclient.login(username="username", password="password")
assert await aclient.is_authenticated()
await aclient.logout()
```
5 changes: 5 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
site_name: Keystone Python Client
nav:
- installation.md
- session.md
- requests.md
- logging.md
Loading