Swiss army knife for AI developers
Project description
shapezero
Swiss army knife for AI developers.
pip install shapezero
Why?
Because every AI project needs the same boring utilities:
- Cache LLM responses (stop burning money on duplicate calls)
- Parse messy outputs (extract JSON from markdown fences)
- Count tokens (will this fit in context?)
- Manage conversations (track message history)
- Build context (turn folders into prompts)
One import. Zero dependencies. Just works.
Quick Start
import shapezero as sz
# Cache responses
sz.cache.set("my prompt", "my response")
cached = sz.cache.get("my prompt") # Returns "my response"
# Parse LLM outputs
data = sz.parse.json('Sure! Here\'s the JSON:\n```json\n{"key": "value"}\n```')
# Returns: {"key": "value"}
code = sz.parse.code('```python\nprint("hello")\n```', lang="python")
# Returns: 'print("hello")'
answer = sz.parse.boolean("Yes, I think that's correct")
# Returns: True
# Count tokens
count = sz.tokens.count("Hello world")
# Returns: 2
# Manage conversations
chat = sz.convo.new(system="You are helpful.")
chat.user("Hello").assistant("Hi there!")
messages = chat.messages()
# Returns: [{"role": "system", "content": "You are helpful."}, ...]
# Build context from files
ctx = sz.context.from_folder("./src", max_tokens=4000)
prompt = f"Review this code:\n{ctx}"
Modules
sz.cache — Response Caching
# Basic get/set
sz.cache.set("prompt", "response", model="gpt-4")
sz.cache.get("prompt", model="gpt-4")
# With TTL (time-to-live)
sz.cache.get("prompt", ttl="1h") # Expire after 1 hour
sz.cache.get("prompt", ttl="7d") # Expire after 7 days
# As decorator
@sz.cache.prompt(ttl="1d", model="claude-3")
def ask_llm(prompt):
return client.complete(prompt)
# Cleanup
sz.cache.clear() # Clear all
sz.cache.clear(older_than="7d") # Clear old entries
sz.cache.stats() # Get cache stats
sz.parse — Extract Structured Data
# JSON (handles markdown fences, trailing commas, etc.)
sz.parse.json('```json\n{"key": "value"}\n```')
# Code blocks
sz.parse.code(response, lang="python")
sz.parse.code_blocks(response) # Get all blocks
# Boolean from natural language
sz.parse.boolean("Yes, definitely") # True
sz.parse.boolean("No, I don't think so") # False
# Lists
sz.parse.list_items("1. First\n2. Second\n3. Third")
# Extract from text
sz.parse.emails("Contact me at test@example.com")
sz.parse.urls("Check out https://example.com")
sz.parse.numbers("The price is $19.99")
# XML-style tags
sz.parse.xml_tag("<answer>42</answer>", "answer") # "42"
# Clean LLM fluff
sz.parse.clean("Sure! Here's what you asked for...")
sz.tokens — Token Management
# Count tokens
sz.tokens.count("Hello world")
sz.tokens.count_messages([{"role": "user", "content": "Hi"}])
# Check limits
sz.tokens.fits("long text...", limit=4096)
# Truncate to fit
sz.tokens.truncate("very long text...", max_tokens=100)
# Split into chunks
sz.tokens.split(long_document, chunk_size=1000, overlap=100)
# Estimate cost
sz.tokens.estimate_cost(prompt, response, model="claude-3.5-sonnet")
# Returns: {"input_tokens": 50, "output_tokens": 100, "total_cost": 0.00045}
sz.convo — Conversation Management
# Create conversation
chat = sz.convo.new(system="You are a helpful assistant.")
# Add messages (chainable)
chat.user("Hello").assistant("Hi!").user("How are you?")
# Get messages for API
messages = chat.messages()
# Get last message
last = chat.last()
last_user = chat.last(role="user")
# Fork conversation (for branching)
branch = chat.fork()
# Save/load
chat.save("conversation.json")
chat = sz.convo.load("conversation.json")
# Context window management
chat = sz.convo.new(system="...", max_tokens=4000)
# Automatically drops old messages when limit exceeded
sz.context — Build Prompts from Files
# From single file
ctx = sz.context.from_file("main.py")
# From folder
ctx = sz.context.from_folder("./src")
# With filters
ctx = sz.context.from_folder(
"./src",
ignore=["tests", "*.test.js"],
include=["*.py", "*.js"],
max_tokens=8000
)
# Use in prompt
prompt = f"Review this code:\n\n{ctx}"
# Get info
print(ctx.summary()) # "12 files, ~3,450 tokens"
print(len(ctx)) # 12
Installation
Zero dependencies (pure Python):
pip install shapezero
With accurate token counting (requires tiktoken):
pip install shapezero[tiktoken]
Without tiktoken, token counts are estimated as len(text) // 4.
Single File
Don't want to pip install? Just copy shapezero/__init__.py into your project:
curl -o shapezero.py https://raw.githubusercontent.com/shapezero/shapezero/main/shapezero/__init__.py
import shapezero as sz
# Done.
License
MIT — do whatever you want.
Links
- Website: shapezeroai.com
- GitHub: github.com/shapezero/shapezero
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 shapezero-0.1.0.tar.gz.
File metadata
- Download URL: shapezero-0.1.0.tar.gz
- Upload date:
- Size: 10.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8318d1e2349eb567164e97fb1a35ab1f04818fd28f87965bd3fafa1ccfdd6f7b
|
|
| MD5 |
ccbad13832615a74e0565fb4a559260e
|
|
| BLAKE2b-256 |
55d26ec29d5b8a8882a7a054a1b32247e0e4cfd7d1cf030f2e8ea135d828eeef
|
File details
Details for the file shapezero-0.1.0-py3-none-any.whl.
File metadata
- Download URL: shapezero-0.1.0-py3-none-any.whl
- Upload date:
- Size: 10.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
91183979cf04be393af0c16e9e8f77a2f78d21f0351290113edec9c2d1ea2c55
|
|
| MD5 |
40113d7a4ad8529c5e54f219a47c06d0
|
|
| BLAKE2b-256 |
b991d7f8193a0c4a08a7f020f2c888ba72fb966cc83b139ba85fcf8fa953dba7
|