Metadata-Version: 2.4
Name: ohttpy
Version: 0.1a12
Classifier: Programming Language :: Rust
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Programming Language :: Python :: 3
Requires-Dist: httpx>=0.27,<0.99
Requires-Dist: requests>=2.22,<2.99
Summary: A package that allows for client-side OHTTP-wrapping over HTTP communication
Author-email: Lorica Cybersecurity <support@loricacyber.com>
Requires-Python: >=3.7
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM

# `ohttpy` Package

## Introduction
This package allows for client-side OHTTP-wrapping over HTTP communication. It acheives this by providing drop-in replacement classes for `requests.Session` and `httpx.BaseTransport` classes that abstract the OHTTP layer.

> **_NOTE:_** This package utilizes a [modified Rust library that implements OHTTP](https://github.com/microsoft/ohttp) and relies on the [chunked OHTTP protocol](https://datatracker.ietf.org/doc/draft-ietf-ohai-chunked-ohttp) which has not been ratified into a standard at the time of writing.

> **_NOTE:_** At the time of writing, this package is currently under active development and therefore, only compatible with chunked-OHTTP gateways that advertise public keys in a specific fashion.

## Requests Session Example
To use OHTTP in a `requests.Session` setting, simply replace the object construction with `ohttpy.Session`:
```python
import ohttpy

# Create ohttpy session that inherits from requests.Session.
session = ohttpy.Session()

# Use session like a request.Session including streaming response support.
resp = session.post("http://ohttp-server/path/to/post", data="test data", stream=True)
resp.raise_for_error()
for chunk in resp.iter_content():
    if chunk:
        print(chunk.decode(), end="", flush=True)
```

## HTTPX Transport Example
To use OHTTP in a `httpx.Transport` setting, simply replace the object construction with `ohttpy.Transport`:
```python
import httpx
import ohttpy

# Initialize httpx client with the ohttpy Transport that inherits from httpx.Transport
httpx_client = httpx.Client(transport=ohttpy.Transport())

# Use client as normal including streaming response support.
method = "GET"
url = "http://ohttp-server/path/to/get/"
with httpx_client.stream(method, url) as resp:
    resp.raise_for_error()
    for chunk in resp.stream:
        print(chunk.decode(), end="", flush=True)
```

This is also applicable to clients that utilize `httpx` for their HTTP communication, for example `openai` client:
```python
import httpx
import openai
import ohttpy

# Initialize httpx client with the ohttpy Transport that inherits from httpx.Transport
httpx_client = httpx.Client(transport=ohttpy.Transport())
url = "http://ohttp-server"
api_key = "API_KEY"

# Configure OpenAI client with httpx client
client = openai.OpenAI(
    api_key=api_key,
    http_client=httpx_client,
    base_url=url + "/v1")

# Use OpenAI SDK as normal for example llama chat (including stream capability)
completion = client.chat.completions.create(
    model="meta-llama/Llama-3.2-3B-Instruct",
    messages=[
        {"role": "system", "content": "You are a helpful AI assistant."},
        {"role": "user", "content": "where does the sun rise from?"},
    ],
    temperature=0.2,
    top_p=0.7,
    max_tokens=1024,
    stream=True,
)
for chunk in completion:
    print(chunk.choices[0].delta.content or "", end="", flush=True)
```
