Wishful thinking for Python
Project description
wishful ๐ช
"Code so good, you'd think it was wishful thinking"
Stop writing boilerplate. Start wishing for it instead.
wishful turns your wildest import dreams into reality. Just write the import you wish existed, and an LLM conjures up the code on the spot. The first run? Pure magic. Every run after? Blazing fast, because it's cached like real Python.
Think of it as wishful thinking, but for imports. The kind that actually works.
โจ Quick Wish
1. Install the dream
pip install wishful
2. Set your credentials (litellm reads the usual suspects)
Export them or toss them in a .env file:
export OPENAI_API_KEY=...
export DEFAULT_MODEL=azure/gpt-4.1
``
or
```bash
export AZURE_API_KEY=...
export AZURE_API_BASE=https://<your-endpoint>.openai.azure.com/
export AZURE_API_VERSION=2025-04-01-preview
export DEFAULT_MODEL=azure/gpt-4.1
or any provider else supported by litellm
3. Import your wildest fantasies
from wishful.text import extract_emails
from wishful.dates import to_yyyy_mm_dd
raw = "Contact us at team@example.com or sales@demo.dev"
print(extract_emails(raw)) # ['team@example.com', 'sales@demo.dev']
print(to_yyyy_mm_dd("31.12.2025")) # '2025-12-31'
What just happened?
- First import: wishful waves its wand ๐ช, asks the LLM to write
extract_emailsandto_yyyy_mm_dd, validates the code for safety, and caches it to.wishful/text.pyand.wishful/dates.py. - Every subsequent run: instant. Just regular Python imports. No latency, no drama, no API calls.
It's like having a junior dev who never sleeps and always delivers exactly what you asked for (well, almost always).
๐ฏ Wishful Guidance: Help the AI Read Your Mind
Want better results? Drop hints. Literal comments. wishful reads the code around your import and forwards that context to the LLM.
# desired: parse standard nginx combined logs into list of dicts
from wishful.logs import parse_nginx_logs
records = parse_nginx_logs(Path("/var/log/nginx/access.log").read_text())
The AI sees your comment and knows exactly what you're after. It's like pair programming, but your partner is a disembodied intelligence with questionable opinions about semicolons.
๐๏ธ Cache Ops: Because Sometimes Wishes Need Revising
Python API
import wishful
# See what you've wished for
wishful.inspect_cache() # ['.wishful/text.py', '.wishful/dates.py']
# Regret a wish? Regenerate it
wishful.regenerate("wishful.text") # Next import re-generates from scratch
# Nuclear option: forget everything
wishful.clear_cache() # Deletes the entire .wishful/ directory
CLI Commands
wishful comes with a command-line interface for managing your cache:
# View all cached modules
wishful inspect
# Clear the entire cache
wishful clear
# Regenerate a specific module
wishful regen wishful.text
The cache is just regular Python files in .wishful/. Want to tweak the generated code? Edit it directly. It's your wish, after all.
โ๏ธ Configuration: Fine-Tune Your Wishes
import wishful
wishful.configure(
model="gpt-4o-mini", # Switch models like changing channels
cache_dir="/tmp/.wishful", # Hide your wishes somewhere else
spinner=False, # Silence the "generating..." spinner
review=True, # Paranoid? Review code before it runs
allow_unsafe=False, # Keep the safety rails ON (recommended)
)
Environment Variables (for the env-obsessed)
Set these in your shell or .env file:
WISHFUL_MODEL/DEFAULT_MODELโ which AI overlord to summonWISHFUL_CACHE_DIRโ where to stash generated wishes (default:.wishful)WISHFUL_REVIEWโ set to1to manually approve every wish (trust issues?)WISHFUL_DEBUGโ verbose logging for when things go sidewaysWISHFUL_UNSAFEโ set to1to disable safety checks (โ ๏ธ danger zone)WISHFUL_SPINNERโ set to0to disable the fancy spinnerWISHFUL_MAX_TOKENSโ cap the LLM's verbosity (default: 800)WISHFUL_TEMPERATUREโ creativity dial (default: 0 = boring but safe)
๐ก๏ธ Safety Rails: Wishful Isn't That Reckless
Generated code gets AST-scanned to block obviously dangerous patterns:
- โ Imports like
os,subprocess,sys - โ Calls to
eval()orexec() - โ
open()in write/append mode - โ Shenanigans like
os.system()orsubprocess.call()
Override at your own peril: WISHFUL_UNSAFE=1 or allow_unsafe=True turns off the guardrails.
๐งช Testing: Wishes Without Consequences
Need deterministic, offline behavior? Set WISHFUL_FAKE_LLM=1 and wishful will generate placeholder stub functions instead of hitting the network.
Perfect for CI, unit tests, or when your Wi-Fi is acting up.
export WISHFUL_FAKE_LLM=1
python my_tests.py # No API calls, just predictable stubs
๐ฎ How the Magic Actually Works
Here's the 30-second version:
- Import hook: wishful installs a
MagicFinderonsys.meta_paththat interceptswishful.*imports. - Cache check: If
.wishful/<module>.pyexists, it loads instantly. No AI needed. - LLM generation: If not cached, wishful calls the LLM (via
litellm) to generate the code based on your import and surrounding context. - Validation: The generated code is AST-parsed and safety-checked (unless you disabled that like a madman).
- Execution: Code is written to
.wishful/, compiled, and executed as the import result. - Transparency: The cache is just plain Python files. Edit them. Commit them. They're yours.
It's import hooks meets LLMs meets "why didn't this exist already?"
๐ญ Fun with Wishful Thinking
# Need some cosmic horror? Just wish for it.
from wishful.story import cosmic_horror_intro
intro = cosmic_horror_intro(
setting="a deserted amusement park",
word_count_at_least=100
)
print(intro) # ๐ข๐ป
# Math that writes itself
from wishful.numbers import primes_from_to, sum_list
total = sum_list(list=primes_from_to(1, 100))
print(total) # 1060 (probably)
# Because who has time to write date parsers?
from wishful.dates import parse_fuzzy_date
print(parse_fuzzy_date("next Tuesday")) # Your guess is as good as mine
๐ป Development: Working with This Repo
This project uses uv for blazing-fast Python package management.
Setup
# Install uv if needed
curl -LsSf https://astral.sh/uv/install.sh | sh
# Clone the repo
git clone https://github.com/pyros-projects/wishful.git
cd wishful
# Install dependencies (uv handles everything)
uv sync
Running Tests
# Run the full test suite
uv run pytest tests/ -v
# Run a specific test file
uv run pytest tests/test_import_hook.py -v
# Run with coverage
uv run pytest --cov=wishful tests/
Running Examples
All examples support WISHFUL_FAKE_LLM=1 for deterministic testing:
# Run with fake LLM (no API calls)
WISHFUL_FAKE_LLM=1 uv run python examples/00_quick_start.py
# Run with real LLM (requires API keys)
uv run python examples/00_quick_start.py
Adding Dependencies
# Add a runtime dependency
uv add package-name
# Add a dev dependency
uv add --dev package-name
# Update all dependencies
uv lock --upgrade
Project Structure
wishful/
โโโ src/wishful/ # Main package
โ โโโ __init__.py # Public API
โ โโโ __main__.py # CLI interface
โ โโโ config.py # Configuration
โ โโโ cache/ # Cache management
โ โโโ core/ # Import hooks
โ โโโ llm/ # LLM integration
โ โโโ safety/ # Safety validation
โโโ tests/ # Test suite
โโโ examples/ # Usage examples
โโโ pyproject.toml # Project config
๐ค FAQ (Frequently Asked Wishes)
Q: Is this production-ready?
A: Define "production." ๐
Q: What if the LLM generates bad code?
A: That's what the cache is for. Check .wishful/, tweak it, commit it, and it's locked in.
Q: Can I use this with OpenAI/Claude/local models?
A: Yes! Built on litellm, so anything it supports works here.
Q: What if I import something that doesn't make sense?
A: The LLM will do its best. Results may vary. Hilarity may ensue.
Q: Is this just lazy programming?
A: It's not lazy. It's efficient wishful thinking. ๐
๐ License
MIT. Wish responsibly.
Go forth and wish. โจ
Your imports will never be the same.
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 wishful-0.1.3.tar.gz.
File metadata
- Download URL: wishful-0.1.3.tar.gz
- Upload date:
- Size: 12.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7a80be4c50e78c9370ec62832af6e9768179c0c468d0c2ad4db20c97f06b778d
|
|
| MD5 |
fd88a8535f90804d04a7d540d93918d7
|
|
| BLAKE2b-256 |
c0336f1f6cb71d5caa9b4bc25646e2ff535c1eb9f7001b7429fb3e5f1f50af05
|
File details
Details for the file wishful-0.1.3-py3-none-any.whl.
File metadata
- Download URL: wishful-0.1.3-py3-none-any.whl
- Upload date:
- Size: 17.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1f5248b3a8f747f60c1deaba1f370fad7e43f0c30e67b1a285b268bf8cc30e46
|
|
| MD5 |
3e0c7ce774263e44c4f60aa72ca743c9
|
|
| BLAKE2b-256 |
7adfb1179caf2276e3e5a02c00073d7d713a7c243d77aa7dbedd1c0e09ef3d73
|