llmf
Free, keyless LLM access in one call — with automatic multi-provider fallback.
llmf (llmfree) is a stdlib-only Python library and CLI for public, no-API-key OpenAI-compatible endpoints. It picks a live target, falls back on errors, and runs on desktop and Termux.
import llmf
r = llmf.chat("Explain the CAP theorem in two sentences.")
print(r) # Reply is a str subclass
print(r.source) # "provider/model"
print(r.provider, r.model, round(r.latency, 3), r.usage)
Package metadata (pip show llmf)
Name: llmf
Version: 0.4.0
Summary: llmf (llmfree): free, keyless LLM chat with automatic multi-provider fallback — stdlib only.
Home-page: https://github.com/MoonLite-Br/llmfree
Author: Html
Author-email: moonlite-br@users.noreply.github.com
License: MIT
Requires-Python: >=3.8
Requires:
| Field | Value |
|---|---|
| Name | llmf |
| Version | 0.4.0 |
| Dependencies | none |
| License | MIT |
| Repository | https://github.com/MoonLite-Br/llmfree |
| PyPI | https://pypi.org/project/llmf/ |
pip install -U llmf
pip show llmf
Install
pip install -U llmf
python -c "import llmf; print(llmf.__version__)"
llmf version
Python API
Short form → Reply
import llmf
r = llmf.chat("Hello!")
assert isinstance(r, str)
r.text # same as str(r)
r.source # "provider/model"
r.provider, r.model
r.latency # seconds
r.usage # dict or None
r.finish_reason
r.reasoning # optional
r.attempts # list of Attempt(provider, model, ok, latency, error)
model= aliases: fast | best | code | vision | reasoning
Also fuzzy names, full provider/id, or a list tried in order.
llmf.chat("hi", model="code", max_tokens=256, temperature=0.3)
llmf.chat("hi", model=["best", "fast"])
llmf.chat("Describe this", images=["photo.jpg"], model="vision") # uses vision_timeout (default 90s)
llmf.chat("...", json=True)
for piece in llmf.stream("Count 1 to 5"):
print(piece, end="", flush=True)
OpenAI-shaped form
from llmf import LLMF
llm = LLMF()
c = llm.chat.completions.create(
model="best",
messages=[{"role": "user", "content": "Hello"}],
)
print(c.choices[0].message.content)
print(c.model, c.provider, c.usage, c.latency, c.attempts)
for chunk in llm.chat.completions.create(
model="fast",
messages=[{"role": "user", "content": "Count to 3"}],
stream=True,
):
delta = chunk.choices[0].delta.content
if delta:
print(delta, end="")
Catalog, doctor, config
llmf.models.list() # chat/free catalog by default
llmf.models.list(live=True) # merge live /models (still chat/free by default)
llmf.models.list(live=True, include_non_chat=True) # also TTS/embed/image/guard ids
llmf.models.resolve("fast")
llmf.models.check() # real call per model; ~24h cache
llmf.models.check(include_live=True, include_non_chat=False)
llmf.providers.list()
llmf.health.check()
llmf.configure(timeout=30, vision_timeout=90, routing="adaptive", race=2)
llmf.register("lab", "http://localhost:11434/v1", ["llama3"], front=True)
llmf.discover()
Env: LLMF_TIMEOUT, LLMF_PROXY, LLMF_MODEL, LLMF_ROUTING.
Proxy: http://, https://, socks5://, socks5h://, socks4:// (stdlib).
CLI
usage: llmf [options] "question" ask once (also reads stdin)
llmf chat interactive chat (/reset, /exit)
llmf models [list|check|resolve NAME]
llmf doctor [--all] [--include-non-chat] [--include-limited]
llmf providers | health
llmf serve [--port N]
llmf version
Commands
| Command | Description |
|---|---|
llmf "…" / llmf ask "…" |
One-shot ask |
llmf chat |
Interactive REPL |
llmf models / models list |
Catalog table |
llmf models list --live |
+ live /models (chat/free only by default) |
llmf models list --live --include-non-chat |
Include non-chat ids |
llmf models resolve fast |
Expand alias |
llmf models check / llmf doctor |
Probe every chat model once |
llmf doctor --all |
Also test live-discovered model ids |
llmf doctor --include-limited |
Include strict daily-quota providers |
llmf doctor --include-non-chat |
Include non-chat model ids |
llmf doctor --no-save |
Do not write health cache |
llmf providers |
Provider table |
llmf health |
Quick OK/FAIL ping |
llmf serve |
Local OpenAI-compatible server |
llmf version |
Print version |
Flags
| Flag | Meaning |
|---|---|
-m / --model |
Alias, fuzzy name, or provider/model |
-p / --provider |
Force provider |
-s / --system |
System prompt |
-i / --interactive |
REPL |
--image PATH |
Image path/URL (repeatable) |
--max-tokens -t / --temperature |
Sampling |
--stream --json -v |
Stream / JSON / show source |
--routing ranked|adaptive |
Fallback strategy |
--race N |
Parallel hedged requests |
--timeout --proxy URL |
Timeout / HTTP(S)/SOCKS proxy |
--live |
Live model list |
--all |
Doctor: include live ids |
--include-limited |
Doctor: quota-limited providers |
--include-non-chat |
List/doctor: non-chat models |
--no-save |
Doctor: skip cache write |
--host --port --api-key --cors |
serve bind / auth / CORS |
--strict-models --no-fallback |
serve strictness |
Examples
$ llmf "Say hi in one short sentence."
Hello! How can I help you today?
$ llmf -v "2+2=?"
ovh/…
4
$ llmf --json "Say hi in one short sentence."
{"text": "…", "provider": "…", "model": "…", "latency": 0.4, ...}
$ llmf models
MODEL TAGS STATUS
…
$ llmf models resolve fast
…
$ llmf doctor
Testing every model once (providers in parallel)...
OK …/… 0.90s Hello…
FAIL …/… 5.00s HTTP 429
$ llmf serve --port 8000
# http://127.0.0.1:8000 — /v1/chat/completions, /v1/models, …
Behaviour (0.4)
- 429 handling: plain rate-limit → provider cooldown ~60s; capacity /
ResourceExhausted→ that model sleeps ~10 min; “use a paid model” → model sleeps hours. models.list(live=…)/doctor --all: default chat + free only (skip whisper/tts/embedding/image/video/OCR/guard and priced ids). Override withinclude_non_chat=True/--include-non-chat.fasttag: dynamic from measured latency (≤1s joins; failures sink).vision_timeout: default 90s for image requests and vision checks in doctor.- Fallback + optional
routing="adaptive"andrace=N; doctor results cached ~24h. - Total failure →
llmf.AllProvidersFailedwith.errors.
Safety
- Endpoints are unofficial and free; they may change or vanish.
- Do not send secrets or personal data.
discover()is opt-in external catalog access.llmf servedefaults to localhost, no CORS, unless you enable--cors/--api-key.
Development
git clone https://github.com/MoonLite-Br/llmfree.git
cd llmfree
python -m unittest discover -s tests -v
python live_test.py # optional live internet report (JSON)
python -m build && twine check dist/*
History: CHANGELOG.md.
License
MIT © 2026 Html / MoonLite-Br
Metadata
Release files for llmf 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| llmf-0.4.0.tar.gz | 57.3 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| llmf-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 109.1 kB
Release files / llmf-0.4.0.tar.gz
| Download URL | llmf-0.4.0.tar.gz |
|---|---|
| Size | 57.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
61e28d9097cb17bdbb1fcb4a9198246de06c0e6f10d969a9e18a0b92fe316413
|
|
BLAKE2b-256 checksum How to use checksums |
53601013dea519746118b774545a4d8ef0a94aaa2da9b534cb4c4033238f6bc0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Release files / llmf-0.4.0-py3-none-any.whl
| Download URL | llmf-0.4.0-py3-none-any.whl |
|---|---|
| Size | 51.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
04e0d4fad76b18525444f2fdc9238664d89d8fdb3f7c43c34f4af170ef1fba23
|
|
BLAKE2b-256 checksum How to use checksums |
92634a3c11d7a3dbc038454e86286f43c3b68719f3b90ab0a1199cc049c54a60
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Security for llmf 0.4.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.