Provider Smoke Tests

GitHub

Validate free-tier provider keys directly from Python with LiteLLM's SDK — isolate provider issues before any gateway YAML.

25m10m reading15m lab

Project Files

free-models-samples
Explorer
README.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
# Free Model Samples

This folder contains direct LiteLLM Python smoke tests for free or free-tier model providers.

Use these samples before creating a full LiteLLM gateway use case. The idea is simple:

1. Prove the provider key and model work directly from Python.
2. Move the working model id into a LiteLLM `litellm_config.yaml`.
3. Expose it through the proxy with a clean local alias like `free-chat`.
4. Add fallback, budgets, cache, UI, or observability only after the basic provider route works.

## What These Samples Prove

These scripts do not start the LiteLLM proxy. They call providers through the LiteLLM Python SDK.

That is useful because it isolates provider issues first:

- API key is missing or invalid.
- Free quota is exhausted.
- Model id changed or is unavailable.
- Provider has rate limits.
- Your network or account cannot reach the provider.

After a sample works here, the same model can be added to a use-case folder with Docker Compose and `litellm_config.yaml`.

## Install

From this folder:

```bash
python3 -m venv .venv
source .venv/bin/activate
pip install litellm requests
```

## Environment Variables

Set only the keys for the provider you want to test.

```bash
export GEMINI_API_KEY="..."
export GROQ_API_KEY="..."
export OPENROUTER_API_KEY="..."
export HUGGINGFACE_API_KEY="..."
export CLOUDFLARE_API_TOKEN="..."
export CLOUDFLARE_ACCOUNT_ID="..."
```

Notes:

- Gemini uses `GEMINI_API_KEY`.
- Groq uses `GROQ_API_KEY`.
- OpenRouter uses `OPENROUTER_API_KEY`.
- Hugging Face uses `HUGGINGFACE_API_KEY`.
- Cloudflare Workers AI needs both token and account id for LiteLLM provider routing.

## Test Each Sample

Run one provider at a time.

### Gemini

```bash
python3 gemini.py
```

Current model:

```text
gemini/gemini-2.5-flash
```

Use this first if you want the easiest free-tier smoke test.

### Groq

```bash
python3 groq.py
```

Current model:

```text
groq/llama-3.3-70b-versatile
```

Use this when you want a fast hosted open-model test.

### OpenRouter

List available free models:

```bash
python3 open_router_models.py
```

Try free models with fallback inside the script:

```bash
python3 open_route.py
```

Current tested models:

```text
openrouter/openai/gpt-oss-20b:free
openrouter/qwen/qwen3-coder:free
openrouter/meta-llama/llama-3.2-3b-instruct:free
openrouter/google/gemma-4-26b-a4b-it:free
```

OpenRouter free models change often. Always run `open_router_models.py` before locking a model into a LiteLLM config.

### Hugging Face

```bash
python3 huggingface.py
```

Current tested models:

```text
huggingface/Qwen/Qwen2.5-7B-Instruct
huggingface/microsoft/Phi-3-mini-4k-instruct
huggingface/google/gemma-2-2b-it
```

Hugging Face free inference can be slower and less predictable than Gemini, Groq, or OpenRouter. Treat this as a fallback exploration provider, not the first recommended path.

### Cloudflare Workers AI

```bash
python3 cloudflare.py
```

Current model:

```text
cloudflare/@cf/meta/llama-3.3-70b-instruct-fp8-fast
```

Use this if you already have Cloudflare Workers AI enabled and want to test their hosted model route.

## How To Turn A Working Sample Into A LiteLLM Use Case

Create a dedicated use-case folder when a provider sample works and you want repeatable gateway testing.

Recommended folder pattern:

```text
free-models-gateway/
  docker-compose.yml
  env.example
  litellm_config.yaml
  README.md
```

The use-case folder should own:

- Docker Compose runtime
- `.env` shape
- LiteLLM model aliases
- fallback routing
- UI/database/cache only if that use case needs them

Keep `free-models-samples/` as direct provider smoke tests. Do not make every sample script its own production setup.

## LiteLLM Config Examples Per Provider

Use stable aliases in your app. Keep provider-specific model ids inside `litellm_config.yaml`.

### Gemini Config

```yaml
model_list:
  - model_name: free-gemini-chat
    litellm_params:
      model: gemini/gemini-2.5-flash
      api_key: os.environ/GEMINI_API_KEY
```

### Groq Config

```yaml
model_list:
  - model_name: free-groq-chat
    litellm_params:
      model: groq/llama-3.3-70b-versatile
      api_key: os.environ/GROQ_API_KEY
```

### OpenRouter Config

```yaml
model_list:
  - model_name: free-openrouter-chat
    litellm_params:
      model: openrouter/openai/gpt-oss-20b:free
      api_key: os.environ/OPENROUTER_API_KEY
```

### Hugging Face Config

```yaml
model_list:
  - model_name: free-huggingface-chat
    litellm_params:
      model: huggingface/Qwen/Qwen2.5-7B-Instruct
      api_key: os.environ/HUGGINGFACE_API_KEY
```

### Cloudflare Config

```yaml
model_list:
  - model_name: free-cloudflare-chat
    litellm_params:
      model: cloudflare/@cf/meta/llama-3.3-70b-instruct-fp8-fast
      api_key: os.environ/CLOUDFLARE_API_TOKEN
      account_id: os.environ/CLOUDFLARE_ACCOUNT_ID
```

## One Gateway With Provider Fallback

After each direct sample works, combine the stable providers into one gateway config:

```yaml
model_list:
  - model_name: free-chat
    litellm_params:
      model: gemini/gemini-2.5-flash
      api_key: os.environ/GEMINI_API_KEY

  - model_name: free-chat-groq
    litellm_params:
      model: groq/llama-3.3-70b-versatile
      api_key: os.environ/GROQ_API_KEY

  - model_name: free-chat-openrouter
    litellm_params:
      model: openrouter/openai/gpt-oss-20b:free
      api_key: os.environ/OPENROUTER_API_KEY

router_settings:
  num_retries: 1
  fallbacks:
    - free-chat: [free-chat-groq, free-chat-openrouter]
```

Application code should call only:

```text
free-chat
```

The gateway decides whether the request goes to Gemini, Groq, or OpenRouter.

## Suggested Testing Order

1. Run `gemini.py`.
2. Run `groq.py`.
3. Run `open_router_models.py`, then `open_route.py`.
4. Run `cloudflare.py` if you have Workers AI enabled.
5. Run `huggingface.py` last because free inference can be slower and less reliable.
6. Move the working model ids into a LiteLLM use-case folder.
7. Test `/v1/models` through the proxy.
8. Test `/v1/chat/completions` through the proxy.
9. Add fallback only after each individual provider route works.

## When To Create A New Use Case Folder

Create a new use case when you want to prove a gateway behavior, not just a provider call.

Good use-case candidates:

- `free-models-gateway/`: one LiteLLM proxy that routes across Gemini, Groq, OpenRouter, Hugging Face, and Cloudflare.
- `cost-governance/`: virtual keys, budgets, and per-key limits.
- `semantic-cache/`: Redis-backed cache to reduce repeated model calls.
- `guardrails/`: PII redaction and prompt filtering before provider calls.
- `observability/`: per-key usage, latency, and model routing visibility.

## Troubleshooting

- `/v1/models` only proves LiteLLM loaded config. It does not prove the provider key or free quota works.
- A direct Python sample failing usually means provider setup is wrong, not Docker or proxy config.
- OpenRouter free models can disappear or become rate-limited. Refresh the list before debugging.
- Hugging Face hosted inference may be cold, slow, or unavailable for some models.
- Cloudflare requires the right account id and Workers AI access in addition to the API token.
TEXTUTF-8
Ln 2897 files

Why a smoke-test step before the gateway

You will save hours by isolating two questions:
  1. 1 Is the provider key correct and the model reachable?
  2. 2 Is my gateway configuration correct?
If you wire a provider into litellm_config.yaml and the request fails, you can't tell which side is broken. A direct Python sample answers question 1 in isolation. Only after the sample works do you copy the model id into a use-case folder.

These scripts use the LiteLLM Python SDK — they do not start the proxy. That is the point.

What these samples prove:
  • API key is valid and not exhausted
  • Model id still exists (OpenRouter free models churn often)
  • Provider is reachable from your network
  • Free-tier rate limits aren't blocking you

Install

In the folder where you downloaded the samples:

python3 -m venv .venv
source .venv/bin/activate
pip install litellm requests

Set only the keys you want to test

Export only the providers you actually have keys for. Skip the rest.

export GEMINI_API_KEY="..."
export GROQ_API_KEY="..."
export OPENROUTER_API_KEY="..."
export HUGGINGFACE_API_KEY="..."
export CLOUDFLARE_API_TOKEN="..."
export CLOUDFLARE_ACCOUNT_ID="..."   # Cloudflare needs BOTH token + account id
💡

Tip: Cloudflare Workers AI is the one provider that needs two secrets — most others only need an API key. Worth a flag in any team .env template.


Lab: Run one provider at a time

Gemini — easiest first smoke test

python3 gemini.py

Backing model:
gemini/gemini-2.5-flash

Groq — fast hosted open-model

python3 groq.py

Backing model:
groq/llama-3.3-70b-versatile

OpenRouter — list, then call

OpenRouter's free model list changes often. Always list before locking a model id into a config:

python3 open_router_models.py
python3 open_route.py

Currently tested:

openrouter/openai/gpt-oss-20b:free
openrouter/qwen/qwen3-coder:free
openrouter/meta-llama/llama-3.2-3b-instruct:free

Hugging Face — slowest, run last

python3 huggingface.py

Currently tested:
huggingface/Qwen/Qwen2.5-7B-Instruct
huggingface/microsoft/Phi-3-mini-4k-instruct
huggingface/google/gemma-2-2b-it
⚠️

Warning: Hugging Face free inference can be slow, cold, or unavailable for specific models. Treat HF as a fallback exploration provider, not the first recommended path.

Cloudflare Workers AI

python3 cloudflare.py

Backing model:
cloudflare/@cf/meta/llama-3.3-70b-instruct-fp8-fast

Suggested testing order

The recommended sequence is built so the most reliable provider proves your setup first:
  1. 1 Gemini — easiest free-tier smoke test
  2. 2 Groq — fast, hosted open model
  3. 3 OpenRouter — list models first, then run
  4. 4 Cloudflare — only if you have Workers AI enabled
  5. 5 Hugging Face — last, free inference is the least predictable
  6. 6 Move the working model ids into a LiteLLM use-case folder (Phase 4)
  7. 7 Test /v1/models through the proxy
  8. 8 Test /v1/chat/completions through the proxy
  9. 9 Add fallback only after each individual provider route works

Per-provider LiteLLM config snippets

Once a sample passes, this is the YAML shape you copy into the gateway. Use stable app aliases — keep provider-specific model ids inside the config.

model_list:
  - model_name: free-gemini-chat
    litellm_params:
      model: gemini/gemini-2.5-flash
      api_key: os.environ/GEMINI_API_KEY

  - model_name: free-groq-chat
    litellm_params:
      model: groq/llama-3.3-70b-versatile
      api_key: os.environ/GROQ_API_KEY

  - model_name: free-openrouter-chat
    litellm_params:
      model: openrouter/openai/gpt-oss-20b:free
      api_key: os.environ/OPENROUTER_API_KEY

  - model_name: free-huggingface-chat
    litellm_params:
      model: huggingface/Qwen/Qwen2.5-7B-Instruct
      api_key: os.environ/HUGGINGFACE_API_KEY

  - model_name: free-cloudflare-chat
    litellm_params:
      model: cloudflare/@cf/meta/llama-3.3-70b-instruct-fp8-fast
      api_key: os.environ/CLOUDFLARE_API_TOKEN
      account_id: os.environ/CLOUDFLARE_ACCOUNT_ID

Common Issues

401 Unauthorized from a provider

The API key is wrong, expired, or scoped to a different project. The smoke-test step is exactly where you want to catch this.

model_not_found from OpenRouter

Free-tier models on OpenRouter come and go. Re-run open_router_models.py and pick a current free model id.

Hugging Face request hangs or 503s

Cold-start on free inference. Retry once. If still failing, pick a different HF model from the tested list above.

Cloudflare bad request even with valid token

You forgot CLOUDFLARE_ACCOUNT_ID. The token alone is not enough — LiteLLM needs both to construct the Workers AI URL.

Next Steps