Tinfoil Python Library
A Python client for secure AI model inference through Tinfoil.
Installation
# With uv
uv add tinfoil
# With pip
pip install tinfoil
Usage
The Tinfoil SDK automatically selects a router enclave and verifies it against the official GitHub repository. You just need to provide your API key:
import os
from tinfoil import TinfoilAI
client = TinfoilAI(
api_key=os.getenv("TINFOIL_API_KEY")
)
chat_completion = client.chat.completions.create(
model="llama3-3-70b",
messages=[
{
"role": "user",
"content": "Hi",
}
],
)
print(chat_completion.choices[0].message.content)
Audio Transcription with Whisper
You can transcribe audio files using OpenAI's Whisper model:
import os
from tinfoil import TinfoilAI
client = TinfoilAI(
api_key=os.getenv("TINFOIL_API_KEY")
)
with open("audio.mp3", "rb") as audio_file:
transcription = client.audio.transcriptions.create(
file=audio_file,
model="whisper-large-v3-turbo",
)
print(transcription.text)
Async Usage
Simply import AsyncTinfoilAI instead of TinfoilAI and use await with each API call:
import os
import asyncio
from tinfoil import AsyncTinfoilAI
client = AsyncTinfoilAI(
api_key=os.getenv("TINFOIL_API_KEY")
)
async def main() -> None:
stream = await client.chat.completions.create(
model="llama3-3-70b",
messages=[{"role": "user", "content": "Say this is a test"}],
stream=True,
)
async for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content is not None:
print(chunk.choices[0].delta.content, end="", flush=True)
print()
asyncio.run(main())
Functionality between the synchronous and asynchronous clients is otherwise identical.
Low-level HTTP Endpoints
You can also perform arbitrary GET/POST requests that are verified:
import os
from tinfoil import NewSecureClient
api_key = os.getenv("TINFOIL_API_KEY")
tfclient = NewSecureClient()
# GET example
resp = tfclient.get(
"https://example.com/health",
headers={"Authorization": f"Bearer {api_key}"},
params={"query": "value"},
timeout=30,
)
print(resp.status_code, resp.text)
# POST example
payload = {"key": "value"}
resp = tfclient.post(
"https://example.com/analyze",
headers={
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
},
json=payload,
timeout=30,
)
print(resp.status_code, resp.text)
Prompt Cache Scoping
The inference router partitions its prompt cache per API identity, so your cached prompts are never observable by other tenants. Within your tenant, the SDK scopes caching further with a user_cache_secret: requests carrying the same secret share cached prompt prefixes, requests carrying different secrets cannot observe each other's cache timing. The secret never reaches the model — the router consumes it to derive the cache namespace and strips it from the request.
By default the SDK generates a random secret and persists it at ~/.tinfoil/user_cache_secret (mode 0600, shared with the other Tinfoil SDKs on the same machine), so caching just works with per-machine scoping. You can control it explicitly:
from tinfoil import TinfoilAI
# Pin the secret for this client (e.g. one stable value per end user)
client = TinfoilAI(api_key=api_key, user_cache_secret=secret)
# Or provision it via the environment
# TINFOIL_USER_CACHE_SECRET=<secret> use this value
# TINFOIL_USER_CACHE_SECRET= (set but empty) disable: tenant-wide caching
# Servers that hold many end users' conversations should scope per request;
# a field set here always wins over the client-level secret:
chat_completion = client.chat.completions.create(
model="llama3-3-70b",
messages=[{"role": "user", "content": "Hi"}],
extra_body={"user_cache_secret": per_user_secret},
)
# Opt out entirely (tenant-wide caching, no file written)
client = TinfoilAI(api_key=api_key, user_cache_secret="")
AsyncTinfoilAI and NewSecureClient accept the same user_cache_secret parameter. If the secret cannot be persisted (no home directory, read-only filesystem), the SDK falls back to an in-memory secret and warns once: cache continuity then resets on every process restart. Containerized deployments should set TINFOIL_USER_CACHE_SECRET explicitly — one value per end user if requests are per-user, or empty to keep tenant-wide caching across replicas.
Security
Please report security vulnerabilities by emailing security@tinfoil.sh.
We aim to respond to (legitimate) security reports within 24 hours.
Development
Install uv before following these instructions.
# Set up the development environment and install the package
uv sync
# Run all tests (requires the TINFOIL_API_KEY environment variable)
export TINFOIL_API_KEY="..."
uv run pytest
# Run unit tests
uv run pytest -m "not integration"
# Run integration tests (requires the TINFOIL_API_KEY environment variable)
export TINFOIL_API_KEY="..."
uv run pytest -m integration
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 tinfoil-0.13.4.tar.gz.
File metadata
- Download URL: tinfoil-0.13.4.tar.gz
- Upload date:
- Size: 679.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
35c52f77e163d9b5aaba91de6faac6f9a7dd09d4f2e64903e414088d952574fc
|
|
| MD5 |
16408cd9d4e1e73170ee6a5503f7253a
|
|
| BLAKE2b-256 |
cd58b1b441341dc93f96aeed43d122f9b4baa1ce32f864bab5536218e255d3c5
|
Provenance
The following attestation bundles were made for tinfoil-0.13.4.tar.gz:
Publisher:
release.yml on tinfoilsh/tinfoil-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tinfoil-0.13.4.tar.gz -
Subject digest:
35c52f77e163d9b5aaba91de6faac6f9a7dd09d4f2e64903e414088d952574fc - Sigstore transparency entry: 2166743634
- Sigstore integration time:
-
Permalink:
tinfoilsh/tinfoil-python@f1de01aee74e7bb9456d998cf56d7ef55f118b30 -
Branch / Tag:
refs/tags/v0.13.4 - Owner: https://github.com/tinfoilsh
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@f1de01aee74e7bb9456d998cf56d7ef55f118b30 -
Trigger Event:
push
-
Statement type:
File details
Details for the file tinfoil-0.13.4-py3-none-any.whl.
File metadata
- Download URL: tinfoil-0.13.4-py3-none-any.whl
- Upload date:
- Size: 100.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4bc68ad0685cb12c74d38a4c080e72fc7b285353492064e6f3aef1f77a07c2f8
|
|
| MD5 |
e6c025917a59d51d35158deaa9195a83
|
|
| BLAKE2b-256 |
9d34ed9f76b5a6e8dc830d89b9046c9ddd579ddee39f4cefe9615ba35f9b0560
|
Provenance
The following attestation bundles were made for tinfoil-0.13.4-py3-none-any.whl:
Publisher:
release.yml on tinfoilsh/tinfoil-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tinfoil-0.13.4-py3-none-any.whl -
Subject digest:
4bc68ad0685cb12c74d38a4c080e72fc7b285353492064e6f3aef1f77a07c2f8 - Sigstore transparency entry: 2166743646
- Sigstore integration time:
-
Permalink:
tinfoilsh/tinfoil-python@f1de01aee74e7bb9456d998cf56d7ef55f118b30 -
Branch / Tag:
refs/tags/v0.13.4 - Owner: https://github.com/tinfoilsh
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@f1de01aee74e7bb9456d998cf56d7ef55f118b30 -
Trigger Event:
push
-
Statement type: