Python SDK for Pendra — UK-based, privacy-first LLM inference
Project description
pendra-python
Official Python SDK for Pendra — UK-based, privacy-first LLM inference.
Your data is processed in the UK, never stored, never shared with US cloud providers.
Installation
pip install pendra
Quick Start
import pendra
client = pendra.Pendra(
api_key="pdr_sk_...", # or set PENDRA_API_KEY env var
)
response = client.chat.completions.create(
model="qwen3.5:0.8b",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What is the capital of the UK?"},
],
)
print(response.choices[0].message.content)
# → London is the capital of the United Kingdom.
Your first request — full sequence
Pendra serves inference from workers you (or your org) run, so a brand-new account needs three things in place before that chat.completions.create() call returns a 200:
- A worker connected. Install Pendra on any host with a GPU or CPU and run
pendra setup. The wizard walks through pasting a worker key from console.pendra.ai/workers and connecting to the API. - A model on disk. The worker only serves models it has locally. From the worker host run, e.g.,
pendra models install qwen3.5:0.8b. Browse console.pendra.ai/models for the full catalogue. - An API key. Create one at console.pendra.ai/api-keys and pass it as
api_key=above.
If your call returns 404 Model 'X' is in the catalogue but no connected worker has it installed yet, skip back to step 2 — that's the API telling you the model is known but hasn't been pulled onto a worker yet.
Streaming
with client.chat.completions.create(
model="qwen3.5:0.8b",
messages=[{"role": "user", "content": "Write me a short poem about London."}],
stream=True,
) as stream:
for chunk in stream:
print(chunk.choices[0].delta.content or "", end="", flush=True)
Async
import asyncio
import pendra
async def main():
async with pendra.AsyncPendra(api_key="pdr_sk_...") as client:
# Non-streaming
response = await client.chat.completions.create(
model="qwen3.5:0.8b",
messages=[{"role": "user", "content": "Hello!"}],
)
print(response.choices[0].message.content)
# Streaming
stream = await client.chat.completions.create(
model="qwen3.5:0.8b",
messages=[{"role": "user", "content": "Count to 5"}],
stream=True,
)
async for chunk in stream:
print(chunk.choices[0].delta.content or "", end="", flush=True)
asyncio.run(main())
List Models
models = client.models.list()
for model in models:
print(model.id)
Image Generation
Generate images from a text prompt. Returns base64-encoded PNGs by default.
import base64
response = client.images.generations.create(
model="x/z-image-turbo",
prompt="A red London double-decker bus at sunset",
size="1024x1024",
)
with open("bus.png", "wb") as f:
f.write(base64.b64decode(response.data[0].b64_json))
Async usage mirrors the sync API:
async with pendra.AsyncPendra(api_key="pdr_sk_...") as client:
response = await client.images.generations.create(
model="x/z-image-turbo",
prompt="A red London double-decker bus at sunset",
)
Image generation is non-streaming — the response is returned as a single JSON payload once the worker finishes.
Environment Variables
| Variable | Description |
|---|---|
PENDRA_API_KEY |
Your Pendra API key (pdr_sk_...) |
OpenAI Compatibility
The Pendra SDK is fully compatible with the OpenAI Python SDK interface. To migrate:
# Before
from openai import OpenAI
client = OpenAI(api_key="sk-...")
# After
from pendra import Pendra
client = Pendra(api_key="pdr_sk_...")
The client.chat.completions.create() interface is identical.
Self-Hosted Workers
Run inference on your own GPUs with a single command. Your prompts and completions never leave your infrastructure.
curl -fsSL https://get.pendra.ai/worker | bash
See the Workers documentation for full setup instructions.
Licence
Apache-2.0
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pendra-0.6.0.tar.gz.
File metadata
- Download URL: pendra-0.6.0.tar.gz
- Upload date:
- Size: 43.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
db3db6cd2694aea113eb352e8172fdcefd4c2b880c45e1e2aa4ab54f107f13ad
|
|
| MD5 |
3ac44ee6a3fde22e5335d4dcda60bc63
|
|
| BLAKE2b-256 |
f9a16405e8c5f8c95d57ad96f06d786b4a7e2b6d74512ffdcd6acdeead828a3d
|
Provenance
The following attestation bundles were made for pendra-0.6.0.tar.gz:
Publisher:
publish-sdk-python.yml on Pendra-Cloud/pendra
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pendra-0.6.0.tar.gz -
Subject digest:
db3db6cd2694aea113eb352e8172fdcefd4c2b880c45e1e2aa4ab54f107f13ad - Sigstore transparency entry: 2116594683
- Sigstore integration time:
-
Permalink:
Pendra-Cloud/pendra@1c4eebe1321ea4391ee704b464536f1feffea897 -
Branch / Tag:
refs/tags/sdk-python-v0.6.0 - Owner: https://github.com/Pendra-Cloud
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-sdk-python.yml@1c4eebe1321ea4391ee704b464536f1feffea897 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pendra-0.6.0-py3-none-any.whl.
File metadata
- Download URL: pendra-0.6.0-py3-none-any.whl
- Upload date:
- Size: 38.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9bdf73f3cb747d3f754d658ab963d819f3171fa829e4c6cbf36594c7809e33e5
|
|
| MD5 |
711782db2eb0e240b7fe40734a7d46a2
|
|
| BLAKE2b-256 |
9a0739ada03f0a70607b415cb8d6389855387b98a0219b2c914c00d8d01e4d65
|
Provenance
The following attestation bundles were made for pendra-0.6.0-py3-none-any.whl:
Publisher:
publish-sdk-python.yml on Pendra-Cloud/pendra
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pendra-0.6.0-py3-none-any.whl -
Subject digest:
9bdf73f3cb747d3f754d658ab963d819f3171fa829e4c6cbf36594c7809e33e5 - Sigstore transparency entry: 2116594735
- Sigstore integration time:
-
Permalink:
Pendra-Cloud/pendra@1c4eebe1321ea4391ee704b464536f1feffea897 -
Branch / Tag:
refs/tags/sdk-python-v0.6.0 - Owner: https://github.com/Pendra-Cloud
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-sdk-python.yml@1c4eebe1321ea4391ee704b464536f1feffea897 -
Trigger Event:
push
-
Statement type: