Metadata-Version: 2.1
Name: peakprivacy
Version: 0.1.0
Summary: The official PeakPrivacy Python Client
Home-page: https://github.com/freihandlabor/peakprivacy-python
Author: freihandlabor GmbH
Author-email: freihandlabor GmbH <support@freihandlabor.com>
License: MIT License
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
Project-URL: Homepage, https://peakprivacy.ch/
Project-URL: Repository, https://github.com/freihandlabor/peakprivacy-python
Project-URL: Documentation, https://peakprivacy.ch/en/guide/api
Project-URL: Issues, https://github.com/freihandlabor/peakprivacy-python/issues
Project-URL: Changelog, https://github.com/freihandlabor/peakprivacy-python/blob/main/CHANGELOG.md
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.7.1
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.31.0
Requires-Dist: typing>=3.7.4
Requires-Dist: httpx>=0.23.0

# PeakPrivacy Python Client

The PeakPrivacy Python Client provides convenient access to the PeakPrivacy REST API from any Python 3.7+
application. The client includes type definitions for all request params and response fields.

## Documentation

The REST API documentation can be found [on peakprivacy.ch](https://peakprivacy.ch/en/guide/api).
The full API of this client can be found in [api.md](api.md).

## Installation

```sh
pip install peakprivacy
```

## Usage

The full API of this client can be found in [api.md](api.md).

```python
import os
from dotenv import load_dotenv

load_dotenv()
from peakprivacy import PeakPrivacy

client = PeakPrivacy(
    # This is the default and can be omitted
    api_token=os.environ.get("PEAKPRIVACY_API_TOKEN")
)

chat_completion = client.chat.completions.create(
    model='mistral-swiss',
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Hello!"}
    ]
)
```

While you can provide an `api_token` keyword argument,
we recommend using [python-dotenv](https://pypi.org/project/python-dotenv/)
to add `PEAKPRIVACY_API_TOKEN="My API Token"` to your `.env` file
so that your API Token is not stored in source control.

## Streaming Responses

We provide support for streaming responses using Server Side Events (SSE).

Simply add ```stream=True``` parameter into the ```client.chat.completions.create``` method.

Pay attention to the fact that handling streaming responses is different from handling regular responses.

Check out the example below.

```python
load_dotenv()
from peakprivacy import PeakPrivacy

client = PeakPrivacy(
    # This is the default and can be omitted
    api_token=os.environ.get("PEAKPRIVACY_API_TOKEN")
)

stream = client.chat.completions.create(
    model='mistral-swiss',
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Hello!"}
    ],
    stream=True
)

for chunk in stream:
    print(chunk.choices[0].delta.content or "", end="")
```

## Supported models

As long as you can utilize a model from the code example above, ```model='mistral-swiss'```, there is a range of options available for use.

You can find the full list of supported models [on peakprivacy.ch](https://peakprivacy.ch/en/guide/api) or by using the ```client.models.list()``` method. 

For a complete description of the method, refer to [api.md](api.md).

```python
load_dotenv()
from peakprivacy import PeakPrivacy

client = PeakPrivacy(
    # This is the default and can be omitted
    api_token=os.environ.get("PEAKPRIVACY_API_TOKEN")
)

models = client.models.list()
print(models)
```


## Handling errors

When the client is unable to connect to the API (for example, due to network connection problems or a timeout), a
subclass of `peakprivacy.ApiConnectionError` is raised.

When the API returns a non-success status code (that is, 4xx or 5xx response), a subclass
of `peakprivacy.ApiStatusError` is raised, containing `status_code` and `response` properties.

All errors inherit from `peakprivacy.ApiError`.

```python
import os
from dotenv import load_dotenv

load_dotenv()
from peakprivacy import PeakPrivacy, ApiTokenNotFoundError, AuthenticationError, PermissionDeniedError, ApiError,
    ApiConnectionError, ApiStatusError

try:
    client = PeakPrivacy(
        # This is the default and can be omitted
        api_token=os.environ.get("PEAKPRIVACY_API_TOKEN")
    )
except ApiTokenNotFoundError as err:
    # exception if token not found
    print(err)
except Exception as err:
    # exception if something went incredibly wrong
    print(err)

try:
    chat_completion = client.chat.completions.create(
        model='mistral-swiss',
        messages=[
            {"role": "system", "content": "You are a helpful assistant."},
            {"role": "user", "content": "Hello!"}
        ]
    )
except AuthenticationError as e:
    # 401 catch example ("You Shall Not Pass")
    print(f"AuthenticationError: {e.status_code}, {e.message}, {e.response}")
except PermissionDeniedError as e:
    # 403 catch example (Nope, Not Today, Not Ever)
    print(f"PermissionDeniedError: {e.status_code}, {e.message}, {e.response}")
except ApiStatusError as e:
    # 400, 401, 403, 404, 422, 429, >=500 catch example ("Gremlins in the API: Someone fed them after midnight!")
    print(f"ApiStatusError: {e.status_code}, {e.message}, {e.response}")
except ApiConnectionError as e:
    # request errors
    print(f"ApiConnectionError: {e.status_code}")
except ApiError as e:
    # parent for all errors
    print(f"ApiError: {e.status_code}")
except Exception as err:
    # exception if something went incredibly wrong ("Houston, We’ve Had a Problem")
    print(err)
```

Error codes are as followed:

| Status Code | Error Type                 |
|-------------|----------------------------|
| 400         | `BadRequestError`          |
| 401         | `AuthenticationError`      |
| 403         | `PermissionDeniedError`    |
| 404         | `NotFoundError`            |
| 422         | `UnprocessableEntityError` |
| 429         | `RateLimitError`           |
| >=500       | `InternalServerError`      |
| N/A         | `ApiConnectionError`       |

## Requirements

Python 3.7 or higher.

# Package structure

### Client API

```python
client = PeakPrivacy(
    # This is the default and can be omitted
    api_token=os.environ.get("PEAKPRIVACY_API_TOKEN")
)
```

### Chat api_token validation API

```python
client.chat.check_api_token()
```

### Chat supported models list API

```python
client.models.list()
```

### Chat Completions API

```python
client.chat.completions.create(
    model='mistral-swiss',
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Hello!"}
    ]
)
```
