confamnode 0.3.0__tar.gz → 0.3.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {confamnode-0.3.0 → confamnode-0.3.3}/PKG-INFO +335 -91
- {confamnode-0.3.0 → confamnode-0.3.3}/README.md +333 -89
- {confamnode-0.3.0 → confamnode-0.3.3}/confamnode/registry.py +24 -30
- {confamnode-0.3.0 → confamnode-0.3.3}/pyproject.toml +1 -1
- {confamnode-0.3.0 → confamnode-0.3.3}/tests/test_client.py +2 -2
- {confamnode-0.3.0 → confamnode-0.3.3}/tests/test_embed.py +34 -33
- {confamnode-0.3.0 → confamnode-0.3.3}/tests/test_gist.py +48 -35
- {confamnode-0.3.0 → confamnode-0.3.3}/tests/test_stream.py +32 -28
- {confamnode-0.3.0 → confamnode-0.3.3}/uv.lock +1 -1
- {confamnode-0.3.0 → confamnode-0.3.3}/.gitignore +0 -0
- {confamnode-0.3.0 → confamnode-0.3.3}/.python-version +0 -0
- {confamnode-0.3.0 → confamnode-0.3.3}/LICENSE +0 -0
- {confamnode-0.3.0 → confamnode-0.3.3}/confamnode/__init__.py +0 -0
- {confamnode-0.3.0 → confamnode-0.3.3}/confamnode/ansa.py +0 -0
- {confamnode-0.3.0 → confamnode-0.3.3}/confamnode/builders.py +0 -0
- {confamnode-0.3.0 → confamnode-0.3.3}/confamnode/client.py +0 -0
- {confamnode-0.3.0 → confamnode-0.3.3}/confamnode/config.py +0 -0
- {confamnode-0.3.0 → confamnode-0.3.3}/confamnode/exceptions.py +0 -0
- {confamnode-0.3.0 → confamnode-0.3.3}/confamnode/models.py +0 -0
- {confamnode-0.3.0 → confamnode-0.3.3}/confamnode/utils.py +0 -0
- {confamnode-0.3.0 → confamnode-0.3.3}/tests/__init__.py +0 -0
- {confamnode-0.3.0 → confamnode-0.3.3}/tests/test_ansa.py +0 -0
- {confamnode-0.3.0 → confamnode-0.3.3}/tests/test_cache_flag.py +0 -0
- {confamnode-0.3.0 → confamnode-0.3.3}/tests/test_client_errors.py +0 -0
- {confamnode-0.3.0 → confamnode-0.3.3}/tests/test_exceptions.py +0 -0
- {confamnode-0.3.0 → confamnode-0.3.3}/tests/test_init.py +0 -0
- {confamnode-0.3.0 → confamnode-0.3.3}/tests/test_models.py +0 -0
- {confamnode-0.3.0 → confamnode-0.3.3}/tests/test_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: confamnode
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Summary: The Nigerian AI inference gateway
|
|
5
5
|
Project-URL: Repository, https://github.com/confamnodeai/confamnode
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/confamnodeai/confamnode/issues
|
|
@@ -88,7 +88,7 @@ from confamnode import ConfamNode
|
|
|
88
88
|
client = ConfamNode(api_key="confam-xxx")
|
|
89
89
|
|
|
90
90
|
ansa = client.gist(
|
|
91
|
-
model="
|
|
91
|
+
model="gemini/gemini-3.5-flash-lite",
|
|
92
92
|
messages="How you dey?"
|
|
93
93
|
)
|
|
94
94
|
|
|
@@ -108,7 +108,7 @@ from confamnode import ConfamNode
|
|
|
108
108
|
client = ConfamNode(api_key="confam-xxx")
|
|
109
109
|
|
|
110
110
|
stream = client.gist(
|
|
111
|
-
model="
|
|
111
|
+
model="gemini/gemini-3.5-flash-lite",
|
|
112
112
|
messages="Wetin be the capital of 9ja?",
|
|
113
113
|
stream=True
|
|
114
114
|
)
|
|
@@ -134,7 +134,7 @@ print(f"ID: {ansa.id}")
|
|
|
134
134
|
Every `gist()` call returns an `Ansa` object:
|
|
135
135
|
|
|
136
136
|
```python
|
|
137
|
-
ansa = client.gist(model="
|
|
137
|
+
ansa = client.gist(model="gemini/gemini-3.5-flash-lite", messages="How you dey?")
|
|
138
138
|
|
|
139
139
|
# Response
|
|
140
140
|
ansa.text # response text
|
|
@@ -181,7 +181,7 @@ client = ConfamNode(api_key="confam-xxx")
|
|
|
181
181
|
|
|
182
182
|
# Single string in → one flat vector out
|
|
183
183
|
result = client.embed(
|
|
184
|
-
model="
|
|
184
|
+
model="liquid/lfm-2.5-embedding-350m:free",
|
|
185
185
|
input="How you dey?"
|
|
186
186
|
)
|
|
187
187
|
|
|
@@ -191,22 +191,20 @@ print(f"Tokens: {result.usage.total_tokens}")
|
|
|
191
191
|
|
|
192
192
|
# List in → list of vectors out, always — even with one item
|
|
193
193
|
result = client.embed(
|
|
194
|
-
model="
|
|
194
|
+
model="liquid/lfm-2.5-embedding-350m:free",
|
|
195
195
|
input=["How you dey?", "Wetin dey happen?"]
|
|
196
196
|
)
|
|
197
197
|
|
|
198
198
|
print(len(result.embeddings)) # 2
|
|
199
199
|
```
|
|
200
200
|
|
|
201
|
-
`confam-embed-local` is currently the only available embedding model. More coming soon.
|
|
202
|
-
|
|
203
201
|
### Task types
|
|
204
202
|
|
|
205
203
|
Some embedding models expect a task-type hint (e.g. `"query"` vs. `"document"`) to produce better embeddings for retrieval use cases. This defaults sensibly server-side if omitted — only pass it if you need a specific one:
|
|
206
204
|
|
|
207
205
|
```python
|
|
208
206
|
result = client.embed(
|
|
209
|
-
model="
|
|
207
|
+
model="liquid/lfm-2.5-embedding-350m:free",
|
|
210
208
|
input="find me a good jollof rice recipe",
|
|
211
209
|
task_type="query"
|
|
212
210
|
)
|
|
@@ -219,7 +217,7 @@ print(result.task_type_applied) # confirms what actually happened for this call
|
|
|
219
217
|
### The EmbeddingResult Object
|
|
220
218
|
|
|
221
219
|
```python
|
|
222
|
-
result = client.embed(model="
|
|
220
|
+
result = client.embed(model="liquid/lfm-2.5-embedding-350m:free", input="How you dey?")
|
|
223
221
|
|
|
224
222
|
result.embeddings # vector(s) — shape matches your input shape
|
|
225
223
|
result.model # model that served the request
|
|
@@ -234,46 +232,41 @@ result.id # unique request ID
|
|
|
234
232
|
result.raw # full raw response
|
|
235
233
|
```
|
|
236
234
|
|
|
237
|
-
### Batch limits (`confam-embed-local`)
|
|
238
|
-
|
|
239
|
-
Self-hosted embedding requests to `confam-embed-local` are served in batches of up to 4 concurrent requests at a time. If you're embedding a large number of documents, being aware of this batching ceiling will give you a more predictable sense of total time than assuming unlimited concurrency.
|
|
240
|
-
|
|
241
235
|
---
|
|
242
236
|
|
|
243
237
|
## Models
|
|
244
238
|
|
|
245
|
-
|
|
239
|
+
#### Free Tier
|
|
246
240
|
|
|
247
|
-
| Model |
|
|
248
|
-
|
|
249
|
-
| `
|
|
250
|
-
| `
|
|
241
|
+
| Model | Modality | Input ₦/1M | Output ₦/1M | Input ₦/1K | Output ₦/1K |
|
|
242
|
+
|---|---|---|---|---|---|
|
|
243
|
+
| `gemini/gemini-3.1-flash-lite` | Text/Image/Video/File/Audio -> Text | ₦0 | ₦0| ₦0 | ₦0 |
|
|
244
|
+
| `gemini/gemini-3.5-flash-lite` | Text/Image/Video/File/Audio -> Text | ₦0 | ₦0| ₦0 | ₦0 |
|
|
245
|
+
| `nvidia/nemotron-3-super-120b-a12b:free` | Text -> Text | ₦0 | ₦0| ₦0 | ₦0 |
|
|
246
|
+
| `nvidia/nemotron-3-ultra-550b-a55b:free` | Text -> Text | ₦0 | ₦0| ₦0 | ₦0 |
|
|
251
247
|
|
|
252
|
-
|
|
248
|
+
#### Paid Tier
|
|
253
249
|
|
|
254
|
-
| Model |
|
|
255
|
-
|
|
256
|
-
| `
|
|
257
|
-
| `confam-deep-reasoning` | Complex thinking, multi-step analysis | Image-Text-to-Text | ₦234 | ₦468 | ₦0.234 | ₦0.468 |
|
|
258
|
-
| `confam-code` | Coding assistance, 1M context | Image-Text-to-Text | ₦234 | ₦468 | ₦0.234 | ₦0.468 |
|
|
250
|
+
| Model | Modality | Input ₦/1M | Output ₦/1M | Input ₦/1K | Output ₦/1K |
|
|
251
|
+
|---|---|---|---|---|---|
|
|
252
|
+
| `deepseek/deepseek-v4.1-flash` | Text/Image -> Text | ₦704 | ₦2,813 | ₦0.704 | ₦2.813 |
|
|
259
253
|
|
|
260
|
-
###
|
|
254
|
+
### Embeddings
|
|
261
255
|
|
|
262
|
-
|
|
263
|
-
|---|---|---|---|---|---|---|
|
|
264
|
-
| `confam-health` | Local model, health information use cases — data stays in Nigeria | Image-Text-to-Text | ₦500 | ₦1,500 | ₦0.500 | ₦1.500 |
|
|
265
|
-
| `confam-local` | Local model, general-purpose — data stays in Nigeria | Text-to-Text | ₦500 | ₦1,500 | ₦0.500 | ₦1.500 |
|
|
256
|
+
#### Free Tier
|
|
266
257
|
|
|
267
|
-
|
|
258
|
+
| Model | Modality | Input ₦/1M | Output ₦/1M | Input ₦/1K | Output ₦/1K |
|
|
259
|
+
|---|---|---|---|---|---|
|
|
260
|
+
| `liquid/lfm-2.5-embedding-350m:free` | Text -> Embeddings | ₦0 | ₦0 | ₦0 | ₦0 |
|
|
268
261
|
|
|
269
|
-
|
|
270
|
-
|---|---|---|
|
|
271
|
-
| `confam-embed-local` | Self-hosted text embeddings — data stays in Nigeria | Local |
|
|
262
|
+
#### Paid Tier
|
|
272
263
|
|
|
273
|
-
|
|
264
|
+
| Model | Modality | Input ₦/1M | Output ₦/1M | Input ₦/1K | Output ₦/1K |
|
|
265
|
+
|---|---|---|---|---|---|
|
|
266
|
+
| `google/gemini-embedding-001` | Text -> Embeddings | ₦352 | ₦0 | ₦0.352 | ₦0 |
|
|
267
|
+
| `google/gemini-embedding-2` | Text/Image/File/Audio/Video -> Text | ₦469 | ₦0 | ₦0.469 | ₦0 |
|
|
274
268
|
|
|
275
|
-
|
|
276
|
-
Ideal for banks, fintechs, hospitals, law firms, and government agencies.
|
|
269
|
+
More embedding models coming soon.
|
|
277
270
|
|
|
278
271
|
More models coming soon. Contact [hello@confamnode.com](mailto:hello@confamnode.com) for early access.
|
|
279
272
|
|
|
@@ -299,7 +292,6 @@ Rate limits vary by plan. Contact [hello@confamnode.com](mailto:hello@confamnode
|
|
|
299
292
|
|
|
300
293
|
- **Free tier** — shared capacity with lower limits
|
|
301
294
|
- **Paid tier** — dedicated higher limits
|
|
302
|
-
- **Local models** (`confam-health`, `confam-local`) — deployed on dedicated Nigerian hardware (Jetson AGX Orin), with a shared concurrency cap across both models. Under heavy simultaneous load, requests queue briefly rather than failing outright.
|
|
303
295
|
|
|
304
296
|
---
|
|
305
297
|
|
|
@@ -310,21 +302,21 @@ ConfamNode adds a default system message to every request giving the model a Nig
|
|
|
310
302
|
```python
|
|
311
303
|
# Use ConfamNode default identity (default)
|
|
312
304
|
ansa = client.gist(
|
|
313
|
-
model="
|
|
305
|
+
model="gemini/gemini-3.5-flash-lite",
|
|
314
306
|
messages="Who are you?"
|
|
315
307
|
)
|
|
316
308
|
# "I am ConfamNode, Nigeria's AI inference gateway..."
|
|
317
309
|
|
|
318
310
|
# Override with your own system message
|
|
319
311
|
ansa = client.gist(
|
|
320
|
-
model="
|
|
312
|
+
model="gemini/gemini-3.5-flash-lite",
|
|
321
313
|
messages="Who are you?",
|
|
322
314
|
system="You are a helpful customer service agent for Konga."
|
|
323
315
|
)
|
|
324
316
|
|
|
325
317
|
# Disable system message entirely
|
|
326
318
|
ansa = client.gist(
|
|
327
|
-
model="
|
|
319
|
+
model="gemini/gemini-3.5-flash-lite",
|
|
328
320
|
messages="Who you be?",
|
|
329
321
|
system=None
|
|
330
322
|
)
|
|
@@ -341,14 +333,14 @@ Pass `cache=True` to let the gateway serve and store a cached response — usefu
|
|
|
341
333
|
```python
|
|
342
334
|
# Default — caching off, fresh response every call
|
|
343
335
|
ansa = client.gist(
|
|
344
|
-
model="
|
|
336
|
+
model="deepseek/deepseek-v4.1-flash",
|
|
345
337
|
messages="How you dey?"
|
|
346
338
|
)
|
|
347
339
|
|
|
348
340
|
# Enable caching — the gateway may return a stored response for a
|
|
349
341
|
# matching request, and store this one for next time
|
|
350
342
|
ansa = client.gist(
|
|
351
|
-
model="
|
|
343
|
+
model="deepseek/deepseek-v4.1-flash",
|
|
352
344
|
messages="How you dey?",
|
|
353
345
|
cache=True
|
|
354
346
|
)
|
|
@@ -362,25 +354,31 @@ Caching must be enabled for your account for `cache=True` to take effect. A cach
|
|
|
362
354
|
|
|
363
355
|
## Reasoning Models
|
|
364
356
|
|
|
357
|
+
- nvidia/nemotron-3-super-120b-a12b:free
|
|
358
|
+
- nvidia/nemotron-3-ultra-550b-a55b:free
|
|
359
|
+
- gemini/gemini-3.1-flash-lite
|
|
360
|
+
- gemini/gemini-3.5-flash-lite
|
|
361
|
+
- deepseek/deepseek-v4.1-flash
|
|
362
|
+
|
|
365
363
|
Enable extended thinking for complex problems:
|
|
366
364
|
|
|
367
365
|
```python
|
|
368
366
|
ansa = client.gist(
|
|
369
|
-
model="
|
|
367
|
+
model="nvidia/nemotron-3-ultra-550b-a55b:free",
|
|
370
368
|
messages="One trader buy goods for ₦50,000 sell am for ₦75,000. After e pay ₦5,000 for transport and ₦3,000 for market, wetin be the real profit? Show how you calculate am.",
|
|
371
369
|
reasoning_effort="low"
|
|
372
|
-
# one of: "
|
|
370
|
+
# one of: "high", "medium", "low", "minimal", "none"
|
|
373
371
|
)
|
|
374
372
|
|
|
375
373
|
print(ansa.reasoning) # thinking trace
|
|
376
374
|
print(ansa.text) # final answer
|
|
377
375
|
```
|
|
378
376
|
|
|
379
|
-
Also available on
|
|
377
|
+
Also available on reasoning models for more complex multi-step problems:
|
|
380
378
|
|
|
381
379
|
```python
|
|
382
380
|
ansa = client.gist(
|
|
383
|
-
model="
|
|
381
|
+
model="nvidia/nemotron-3-ultra-550b-a55b:free",
|
|
384
382
|
messages="Analyse the financial risk of a Nigerian fintech expanding to Ghana...",
|
|
385
383
|
reasoning_effort="high"
|
|
386
384
|
)
|
|
@@ -389,58 +387,50 @@ print(ansa.reasoning) # full thinking trace
|
|
|
389
387
|
print(ansa.text) # final analysis
|
|
390
388
|
```
|
|
391
389
|
|
|
392
|
-
### Controlling reasoning mode (`confam-local`)
|
|
393
|
-
|
|
394
|
-
`confam-local` reasons in `<think>` blocks by default. To disable this per-request, pass `enable_thinking` nested under `chat_template_kwargs` via `extra_body` — this must be nested this way rather than passed as a top-level kwarg, or it will be silently ignored:
|
|
395
|
-
|
|
396
|
-
```python
|
|
397
|
-
result = client.gist(
|
|
398
|
-
model="confam-local",
|
|
399
|
-
messages="How you dey?",
|
|
400
|
-
extra_body={"chat_template_kwargs": {"enable_thinking": False}}
|
|
401
|
-
)
|
|
402
|
-
```
|
|
403
|
-
|
|
404
390
|
---
|
|
405
391
|
|
|
406
|
-
##
|
|
407
|
-
|
|
408
|
-
### Best models for RAG
|
|
409
|
-
|
|
410
|
-
| Model | Why | Context |
|
|
411
|
-
|---|---|---|
|
|
412
|
-
| `confam-intelligence` | General RAG, reliable, long context | 1M tokens |
|
|
413
|
-
| `confam-code` | Code search, documentation RAG | 1M tokens |
|
|
414
|
-
| `confam-deep-reasoning` | Complex RAG, multi-hop reasoning | 1M tokens |
|
|
415
|
-
|
|
416
|
-
`confam-embed-local` pairs well with any of the above for retrieval — see [Embeddings](#embeddings).
|
|
417
|
-
|
|
418
|
-
---
|
|
419
|
-
|
|
420
|
-
## Data Residency
|
|
421
|
-
|
|
422
|
-
Nigerian businesses handling sensitive data can use local models that run entirely on Nigerian hardware — data is never transmitted abroad:
|
|
392
|
+
## Working with Images
|
|
423
393
|
|
|
424
394
|
```python
|
|
395
|
+
def encode_image_b64(image_path: Path) -> tuple[str, str]:
|
|
396
|
+
"""Returns (base64_data, mime_type)."""
|
|
397
|
+
mime = "image/jpeg"
|
|
398
|
+
suffix = image_path.suffix.lower()
|
|
399
|
+
if suffix == ".png":
|
|
400
|
+
mime = "image/png"
|
|
401
|
+
elif suffix == ".webp":
|
|
402
|
+
mime = "image/webp"
|
|
403
|
+
elif suffix in (".jpg", ".jpeg"):
|
|
404
|
+
mime = "image/jpeg"
|
|
405
|
+
data = base64.b64encode(image_path.read_bytes()).decode("utf-8")
|
|
406
|
+
return data, mime
|
|
407
|
+
|
|
408
|
+
image_path = Path("<image_path>")
|
|
409
|
+
img_b64, mime = encode_image_b64(image_path)
|
|
410
|
+
|
|
411
|
+
messages = [
|
|
412
|
+
{
|
|
413
|
+
"role": "user",
|
|
414
|
+
"content": [
|
|
415
|
+
{"type": "text", "text": "Describe this image"},
|
|
416
|
+
{
|
|
417
|
+
"type": "image_url",
|
|
418
|
+
"image_url": {"url": f"data:{mime};base64,{img_b64}"}
|
|
419
|
+
}
|
|
420
|
+
],
|
|
421
|
+
},
|
|
422
|
+
]
|
|
423
|
+
|
|
425
424
|
ansa = client.gist(
|
|
426
|
-
model="
|
|
427
|
-
messages=
|
|
425
|
+
model="gemini/gemini-3.5-flash-lite",
|
|
426
|
+
messages=messages
|
|
428
427
|
)
|
|
429
428
|
|
|
430
|
-
|
|
431
|
-
print(ansa.
|
|
429
|
+
if ansa.reasoning:
|
|
430
|
+
print(f"***Reasoning Start***\n{ansa.reasoning}\n***Reasoning End***")
|
|
432
431
|
print(ansa.text)
|
|
433
432
|
```
|
|
434
433
|
|
|
435
|
-
For health information use cases, `confam-health` offers the same data-residency guarantee on a model tuned for that domain.
|
|
436
|
-
|
|
437
|
-
**Ideal for:**
|
|
438
|
-
- Nigerian banks and fintechs
|
|
439
|
-
- Healthcare companies
|
|
440
|
-
- Law firms
|
|
441
|
-
- Government agencies
|
|
442
|
-
- Any business with strict data residency requirements
|
|
443
|
-
|
|
444
434
|
---
|
|
445
435
|
|
|
446
436
|
## Environment Variable
|
|
@@ -484,7 +474,7 @@ from confamnode import (
|
|
|
484
474
|
|
|
485
475
|
try:
|
|
486
476
|
ansa = client.gist(
|
|
487
|
-
model="
|
|
477
|
+
model="gemini/gemini-3.5-flash-lite",
|
|
488
478
|
messages="How you dey?"
|
|
489
479
|
)
|
|
490
480
|
except ConfamAuthError:
|
|
@@ -507,6 +497,260 @@ All specific exceptions above are subclasses of `ConfamNodeError` — catching t
|
|
|
507
497
|
|
|
508
498
|
---
|
|
509
499
|
|
|
500
|
+
## REST API
|
|
501
|
+
|
|
502
|
+
ConfamNode provides an OpenAI-compatible REST API that you can call from any programming language or HTTP client without installing the ConfamNode SDK.
|
|
503
|
+
|
|
504
|
+
**Base URL:** `https://api.confamnode.com/v1`
|
|
505
|
+
|
|
506
|
+
### Authentication
|
|
507
|
+
|
|
508
|
+
Set your API key as an environment variable:
|
|
509
|
+
|
|
510
|
+
```bash
|
|
511
|
+
export CONFAMNODE_API_KEY="confam-xxx"
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
All requests require Bearer-token authentication and a JSON content type.
|
|
515
|
+
|
|
516
|
+
---
|
|
517
|
+
|
|
518
|
+
### 1. Chat Completions
|
|
519
|
+
|
|
520
|
+
**Endpoint:** `POST https://api.confamnode.com/v1/chat/completions`
|
|
521
|
+
|
|
522
|
+
#### cURL
|
|
523
|
+
|
|
524
|
+
```bash
|
|
525
|
+
curl -X POST https://api.confamnode.com/v1/chat/completions \
|
|
526
|
+
-H "Authorization: Bearer $CONFAMNODE_API_KEY" \
|
|
527
|
+
-H "Content-Type: application/json" \
|
|
528
|
+
-d '{
|
|
529
|
+
"model": "gemini/gemini-3.5-flash-lite",
|
|
530
|
+
"messages": [
|
|
531
|
+
{
|
|
532
|
+
"role": "user",
|
|
533
|
+
"content": "How you dey?"
|
|
534
|
+
}
|
|
535
|
+
]
|
|
536
|
+
}'
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
#### Python — HTTPX (Synchronous)
|
|
540
|
+
|
|
541
|
+
Install HTTPX:
|
|
542
|
+
|
|
543
|
+
```bash
|
|
544
|
+
pip install httpx
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
```python
|
|
548
|
+
import os
|
|
549
|
+
import httpx
|
|
550
|
+
|
|
551
|
+
response = httpx.post(
|
|
552
|
+
"https://api.confamnode.com/v1/chat/completions",
|
|
553
|
+
headers={
|
|
554
|
+
"Authorization": f"Bearer {os.environ['CONFAMNODE_API_KEY']}",
|
|
555
|
+
"Content-Type": "application/json",
|
|
556
|
+
},
|
|
557
|
+
json={
|
|
558
|
+
"model": "gemini/gemini-3.5-flash-lite",
|
|
559
|
+
"messages": [
|
|
560
|
+
{"role": "user", "content": "How you dey?"}
|
|
561
|
+
],
|
|
562
|
+
},
|
|
563
|
+
timeout=60.0,
|
|
564
|
+
)
|
|
565
|
+
|
|
566
|
+
response.raise_for_status()
|
|
567
|
+
ansa = response.json()
|
|
568
|
+
|
|
569
|
+
print(ansa["choices"][0]["message"]["content"])
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
#### Python — HTTPX (Asynchronous)
|
|
573
|
+
|
|
574
|
+
Use `httpx.AsyncClient` when working with async applications, such as FastAPI services or asynchronous workers.
|
|
575
|
+
|
|
576
|
+
```python
|
|
577
|
+
import os
|
|
578
|
+
import asyncio
|
|
579
|
+
import httpx
|
|
580
|
+
|
|
581
|
+
async def main():
|
|
582
|
+
async with httpx.AsyncClient(timeout=60.0) as client:
|
|
583
|
+
response = await client.post(
|
|
584
|
+
"https://api.confamnode.com/v1/chat/completions",
|
|
585
|
+
headers={
|
|
586
|
+
"Authorization": f"Bearer {os.environ['CONFAMNODE_API_KEY']}",
|
|
587
|
+
"Content-Type": "application/json",
|
|
588
|
+
},
|
|
589
|
+
json={
|
|
590
|
+
"model": "gemini/gemini-3.5-flash-lite",
|
|
591
|
+
"messages": [
|
|
592
|
+
{"role": "user", "content": "How you dey?"}
|
|
593
|
+
],
|
|
594
|
+
},
|
|
595
|
+
)
|
|
596
|
+
|
|
597
|
+
response.raise_for_status()
|
|
598
|
+
ansa = response.json()
|
|
599
|
+
|
|
600
|
+
print(ansa["choices"][0]["message"]["content"])
|
|
601
|
+
|
|
602
|
+
asyncio.run(main())
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
**Note:** In an existing async application, use `await main()` or await the request from your existing async function instead of calling `asyncio.run()`.
|
|
606
|
+
|
|
607
|
+
#### JavaScript — Fetch API
|
|
608
|
+
|
|
609
|
+
Works in modern browsers and Node.js environments that support `fetch`. This example uses Node.js environment variables.
|
|
610
|
+
|
|
611
|
+
```javascript
|
|
612
|
+
const response = await fetch(
|
|
613
|
+
"https://api.confamnode.com/v1/chat/completions",
|
|
614
|
+
{
|
|
615
|
+
method: "POST",
|
|
616
|
+
headers: {
|
|
617
|
+
Authorization: `Bearer ${process.env.CONFAMNODE_API_KEY}`,
|
|
618
|
+
"Content-Type": "application/json",
|
|
619
|
+
},
|
|
620
|
+
body: JSON.stringify({
|
|
621
|
+
model: "gemini/gemini-3.5-flash-lite",
|
|
622
|
+
messages: [
|
|
623
|
+
{ role: "user", content: "How you dey?" },
|
|
624
|
+
],
|
|
625
|
+
}),
|
|
626
|
+
}
|
|
627
|
+
);
|
|
628
|
+
|
|
629
|
+
if (!response.ok) {
|
|
630
|
+
throw new Error(
|
|
631
|
+
`HTTP ${response.status}: ${await response.text()}`
|
|
632
|
+
);
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
const ansa = await response.json();
|
|
636
|
+
console.log(ansa.choices[0].message.content);
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
---
|
|
640
|
+
|
|
641
|
+
### 2. Embeddings
|
|
642
|
+
|
|
643
|
+
Generate vector embeddings for semantic search, retrieval-augmented generation (RAG), and other machine-learning applications.
|
|
644
|
+
|
|
645
|
+
**Endpoint:** `POST https://api.confamnode.com/v1/embeddings`
|
|
646
|
+
|
|
647
|
+
#### cURL
|
|
648
|
+
|
|
649
|
+
```bash
|
|
650
|
+
curl -X POST https://api.confamnode.com/v1/embeddings \
|
|
651
|
+
-H "Authorization: Bearer $CONFAMNODE_API_KEY" \
|
|
652
|
+
-H "Content-Type: application/json" \
|
|
653
|
+
-d '{
|
|
654
|
+
"model": "liquid/lfm-2.5-embedding-350m:free",
|
|
655
|
+
"input": "How you dey?"
|
|
656
|
+
}'
|
|
657
|
+
```
|
|
658
|
+
|
|
659
|
+
#### Python — HTTPX (Synchronous)
|
|
660
|
+
|
|
661
|
+
```python
|
|
662
|
+
import os
|
|
663
|
+
import httpx
|
|
664
|
+
|
|
665
|
+
response = httpx.post(
|
|
666
|
+
"https://api.confamnode.com/v1/embeddings",
|
|
667
|
+
headers={
|
|
668
|
+
"Authorization": f"Bearer {os.environ['CONFAMNODE_API_KEY']}",
|
|
669
|
+
"Content-Type": "application/json",
|
|
670
|
+
},
|
|
671
|
+
json={
|
|
672
|
+
"model": "liquid/lfm-2.5-embedding-350m:free",
|
|
673
|
+
"input": "How you dey?",
|
|
674
|
+
},
|
|
675
|
+
timeout=60.0,
|
|
676
|
+
)
|
|
677
|
+
|
|
678
|
+
response.raise_for_status()
|
|
679
|
+
result = response.json()
|
|
680
|
+
|
|
681
|
+
print(result)
|
|
682
|
+
```
|
|
683
|
+
|
|
684
|
+
#### Python — HTTPX (Asynchronous)
|
|
685
|
+
|
|
686
|
+
```python
|
|
687
|
+
import os
|
|
688
|
+
import asyncio
|
|
689
|
+
import httpx
|
|
690
|
+
|
|
691
|
+
async def main():
|
|
692
|
+
async with httpx.AsyncClient(timeout=60.0) as client:
|
|
693
|
+
response = await client.post(
|
|
694
|
+
"https://api.confamnode.com/v1/embeddings",
|
|
695
|
+
headers={
|
|
696
|
+
"Authorization": f"Bearer {os.environ['CONFAMNODE_API_KEY']}",
|
|
697
|
+
"Content-Type": "application/json",
|
|
698
|
+
},
|
|
699
|
+
json={
|
|
700
|
+
"model": "liquid/lfm-2.5-embedding-350m:free",
|
|
701
|
+
"input": "How you dey?",
|
|
702
|
+
},
|
|
703
|
+
)
|
|
704
|
+
|
|
705
|
+
response.raise_for_status()
|
|
706
|
+
result = response.json()
|
|
707
|
+
|
|
708
|
+
print(result)
|
|
709
|
+
|
|
710
|
+
asyncio.run(main())
|
|
711
|
+
```
|
|
712
|
+
|
|
713
|
+
#### JavaScript — Fetch API
|
|
714
|
+
|
|
715
|
+
```javascript
|
|
716
|
+
const response = await fetch(
|
|
717
|
+
"https://api.confamnode.com/v1/embeddings",
|
|
718
|
+
{
|
|
719
|
+
method: "POST",
|
|
720
|
+
headers: {
|
|
721
|
+
Authorization: `Bearer ${process.env.CONFAMNODE_API_KEY}`,
|
|
722
|
+
"Content-Type": "application/json",
|
|
723
|
+
},
|
|
724
|
+
body: JSON.stringify({
|
|
725
|
+
model: "liquid/lfm-2.5-embedding-350m:free",
|
|
726
|
+
input: "How you dey?",
|
|
727
|
+
}),
|
|
728
|
+
}
|
|
729
|
+
);
|
|
730
|
+
|
|
731
|
+
if (!response.ok) {
|
|
732
|
+
throw new Error(
|
|
733
|
+
`HTTP ${response.status}: ${await response.text()}`
|
|
734
|
+
);
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
const result = await response.json();
|
|
738
|
+
console.log(result);
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
---
|
|
742
|
+
|
|
743
|
+
### Notes
|
|
744
|
+
|
|
745
|
+
- **Authentication:** Include your API key in the `Authorization: Bearer` header for every request.
|
|
746
|
+
- **Content type:** Send JSON requests using `Content-Type: application/json`.
|
|
747
|
+
- **Synchronous vs. asynchronous:** Use `httpx.post()` for synchronous code and `httpx.AsyncClient` with `await` for asynchronous code.
|
|
748
|
+
- **API key security:** Never expose your API key in public repositories or browser-side code. For frontend applications, make authenticated requests through your backend.
|
|
749
|
+
- **No SDK required:** These examples call the REST API directly.
|
|
750
|
+
- **Pricing:** Applicable API charges are calculated in Nigerian Naira (₦).
|
|
751
|
+
|
|
752
|
+
---
|
|
753
|
+
|
|
510
754
|
## Private AI Deployment
|
|
511
755
|
|
|
512
756
|
Need data-residential private AI on your own infrastructure?
|