Unified Python library for AI model API calls
Project description
Hopper
A unified Python library for AI model API calls.
Named after Grace Hopper — the original abstraction layer between human intent and machine execution.
Supported providers
Anthropic, OpenAI, Google Gemini, Together AI, Perplexity, xAI Grok, Kimi (Moonshot AI), Z.AI (GLM), Fugu (Sakana AI).
Installation
pip install medicalsphere-hopper
Install only the provider SDKs you need:
pip install "medicalsphere-hopper[anthropic]" # Anthropic
pip install "medicalsphere-hopper[openai]" # OpenAI, Perplexity, Grok, Kimi, Z.AI
pip install "medicalsphere-hopper[google]" # Google Gemini
pip install "medicalsphere-hopper[together]" # Together AI
pip install "medicalsphere-hopper[anthropic,openai,google,together]" # all
For local development:
git clone <repo>
cd hopper
uv sync --all-extras
Usage
import asyncio
import hopper
from hopper import CanonicalRequest, CanonicalMessage, Credentials
request = CanonicalRequest(
model="claude-sonnet", # model ID or alias
messages=[CanonicalMessage(role="user", content="Hello!")],
system="You are a helpful assistant.",
)
credentials = Credentials(api_key="sk-ant-...")
# single response
envelope = asyncio.run(hopper.complete(request, credentials))
print(envelope.response.content)
# streaming
async def stream():
async for chunk in hopper.stream(request, credentials):
print(chunk.delta, end="", flush=True)
asyncio.run(stream())
Image input
from hopper import ImagePart, TextPart
request = CanonicalRequest(
model="claude-sonnet",
messages=[
CanonicalMessage(
role="user",
content=[
ImagePart(data="<base64>", media_type="image/jpeg"),
TextPart(text="What is in this image?"),
],
)
],
)
Multi-turn conversations
messages = [
CanonicalMessage(role="user", content="My name is Alice."),
CanonicalMessage(role="assistant", content="Got it, Alice!"),
CanonicalMessage(role="user", content="What's my name?"),
]
request = CanonicalRequest(model="claude-sonnet", messages=messages)
Model aliases
Every model has short aliases so you don't need to remember full IDs:
"claude-sonnet" → claude-sonnet-4-6
"claude-haiku" → claude-haiku-4-5-20251001
"gemini-3-flash" → gemini-3-flash-preview
"gpt-5.4-mini" → gpt-5.4-mini-2026-03-17
"grok" → grok-4.20
"sonar" → perplexity/sonar
"kimi" → kimi-k2.6
"glm" → glm-5.2
"zai" → glm-5.2
"fugu" → fugu (model ID, no alias needed)
"fugu-ultra" → fugu-ultra
Calling models not in the registry
Hopper ships with a curated model registry, but providers release new models
frequently. You can call any model from a supported provider without waiting
for the registry to be updated — just pass provider=:
request = CanonicalRequest(
model="claude-sonnet-5-new", # not in the registry yet
provider="anthropic", # tells Hopper which adapter to use
messages=[CanonicalMessage(role="user", content="Hello!")],
)
Use extra_params to pass any parameters alongside it:
request = CanonicalRequest(
model="claude-sonnet-5-new",
provider="anthropic",
messages=[...],
extra_params={"temperature": 0.7, "top_p": 0.9},
)
extra_params works for registered models too — anything in there is forwarded
to the provider API without filtering.
Smoke tests
Hopper never reads API keys from the environment — credentials are always passed explicitly by the caller. This keeps secret management entirely outside the library.
The smoke test is the one exception: it's a developer tool for verifying real API connectivity, so it reads keys from a local .env file that is never committed.
Setup:
cp .env.example .env
# fill in keys for the providers you want to test:
# ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, TOGETHER_API_KEY,
# PERPLEXITY_API_KEY, XAI_API_KEY, KIMI_API_KEY, ZAI_API_KEY, FUGU_API_KEY
Providers without a key are skipped automatically.
Run:
uv run python tests/smoke_test.py # all sections (basic + image + multi-turn)
uv run python tests/smoke_test.py --stream # streaming mode
uv run python tests/smoke_test.py --no-image # skip image tests
uv run python tests/smoke_test.py --no-multi # skip multi-turn tests
The image test uses tests/assets/image_example.jpeg and verifies that models can count the five asterisk markers in the image.
Unit tests
uv run pytest
Adding a provider
- Add
hopper/models/<provider>.yaml - Add
hopper/adapters/<provider>.pyexposing anADAPTERinstance
The router picks them up automatically — no other files need to change.
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 medicalsphere_hopper-0.5.3.tar.gz.
File metadata
- Download URL: medicalsphere_hopper-0.5.3.tar.gz
- Upload date:
- Size: 252.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.21 {"installer":{"name":"uv","version":"0.9.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2b9582f425d0b6d0f4308f753092b20a0c6e0af03ef0126dcfd2f7ea269ec0a8
|
|
| MD5 |
667f995d2c2bf7259075731d22ee53ad
|
|
| BLAKE2b-256 |
61790d0f319c060822405b349f3d83d2b3acc4c11c573614ebe2eed7b9230e53
|
File details
Details for the file medicalsphere_hopper-0.5.3-py3-none-any.whl.
File metadata
- Download URL: medicalsphere_hopper-0.5.3-py3-none-any.whl
- Upload date:
- Size: 34.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.21 {"installer":{"name":"uv","version":"0.9.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eb30abb4747fbbe2cc495e6e96684b9027cdf59b1813288c83c8f27df633efce
|
|
| MD5 |
661fddbadc451b7ceba448eda3230e87
|
|
| BLAKE2b-256 |
0f709be73f09d48b001cbf82c92ba996b0c41f15bd3341edfeabe2f00f441093
|