Skip to content

Commit 2dee52b

Browse files
authored
Merge pull request #242 from hand-e-fr/multiple_model_support
cicd: invstigate
2 parents 469794d + 614723d commit 2dee52b

18 files changed

Lines changed: 637 additions & 244 deletions

.github/workflows/quality_check.yml

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,21 @@ jobs:
9292

9393
- name: Install dependencies
9494
run: pip install .[tests]
95+
96+
- name: Debug Environment
97+
run: |
98+
echo "Le nom du modèle est : $OPENHOSTA_DEFAULT_MODEL_NAME"
99+
if [ -z "$OPENHOSTA_DEFAULT_MODEL_API_KEY" ]; then
100+
echo "ERREUR : La clé API est vide !"
101+
else
102+
echo "La clé API est bien présente (valeur masquée)."
103+
fi
95104
96-
- name: Run functionnal tests
97-
env:
98-
OPENHOSTA_DEFAULT_MODEL_NAME: gpt-4.1
99-
OPENHOSTA_DEFAULT_MODEL_API_KEY: ${{ secrets.OPENHOSTA_DEFAULT_MODEL_API_KEY }}
100-
run: python -m pytest tests/functionnal -v --cov=OpenHosta
105+
# - name: Run functionnal tests
106+
# env:
107+
# OPENHOSTA_DEFAULT_MODEL_NAME: gpt-4.1
108+
# OPENHOSTA_DEFAULT_MODEL_API_KEY: ${{ secrets.OPENHOSTA_DEFAULT_MODEL_API_KEY }}
109+
# run: python -m pytest tests/functionnal -v --cov=OpenHosta
101110

102111
notify:
103112
needs: [code-quality, static-analysis, functionnal-tests]

Makefile

Lines changed: 0 additions & 94 deletions
This file was deleted.

README.md

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
# OpenHosta
22

3-
v3.0 - Integrates Inria Comments
4-
53
<br/>You can read the doc or directly have a look at [tests files](https://github.com/hand-e-fr/OpenHosta/tree/main/tests/) for multiples exemples.
64

75
OpenHosta is a powerful Python extension designed to seamlessly integrate semantic capabilities seen in Large Language Models (LLMs) into tradictional development environments, enabling AI-powered function emulation that maintains native Python syntax and paradigms. Its strength lies in its simplicity and flexibility, allowing developers to easily create AI-enhanced applications while maintaining clean, Pythonic code structure.
@@ -65,12 +63,26 @@ result
6563
# <DocumentType.OLD_BOOK: 'old_book'>
6664
```
6765

66+
For workloads requiring high concurrency (such as web servers or batch processing), you can use `emulate_async` to perform non-blocking LLM calls:
67+
68+
```python
69+
import asyncio
70+
from OpenHosta import emulate_async
71+
72+
async def translate_batch(texts: list[str], target_language: str) -> list[str]:
73+
"""Translates a list of texts into the specified language."""
74+
# Process multiple LLM calls in parallel!
75+
return await emulate_async()
76+
```
77+
6878
## Table of Content
6979

7080
- [OpenHosta](#openhosta)
7181
- [Table of Content](#table-of-content)
7282
- [How to install OpenHosta ?](#how-to-install-openhosta-)
73-
- [Example](#example)
83+
- [Quick Start Examples](#quick-start-examples)
84+
- [Option A: Local Execution (Ollama)](#option-a-local-execution-ollama)
85+
- [Option B: Remote API (OpenAI)](#option-b-remote-api-openai)
7486
- [Further information](#further-information)
7587
- [Contributing](#contributing)
7688
- [License](#license)
@@ -139,13 +151,15 @@ print(translate("Hello World!", "French"))
139151
When you want the highest capability models with zero setup. Set your API credentials via `.env`:
140152

141153
```env
142-
OPENHOSTA_DEFAULT_MODEL_NAME="gpt-4o"
154+
OPENHOSTA_DEFAULT_MODEL_NAME="gpt-4.1"
143155
OPENHOSTA_DEFAULT_MODEL_API_KEY="put-your-api-key-here"
156+
# OPENHOSTA_DEFAULT_MODEL_BASE_URL="https://api.openai.com/v1"
144157
```
145158

146159
```python
147160
from OpenHosta import emulate
148161

162+
149163
def translate(text: str, language: str) -> str:
150164
"""Translates the text into the specified language."""
151165
return emulate()

docs/V4_CHANGELOG.md

Lines changed: 0 additions & 26 deletions
This file was deleted.

docs/core_functions.md

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,36 @@ def translate(text: str, language: str) -> str:
1515
print(translate("Hello", "French"))
1616
```
1717

18-
## `emulate` (Asynchronous Mode)
19-
Useful for web applications or multiple parallel calls.
18+
## `emulate_async`
19+
Useful for web applications, heavy IO, or executing multiple LLM calls in parallel without blocking the main event loop.
2020

2121
```python
2222
import asyncio
23-
from OpenHosta.asynchrone import emulate
23+
from OpenHosta import emulate_async
2424

2525
async def capitalize_cities(sentence: str) -> str:
2626
"""Capitalize the first letter of all city names in a sentence."""
27-
return await emulate()
27+
return await emulate_async()
2828

2929
print(asyncio.run(capitalize_cities("je suis allé à paris")))
3030
```
3131

32+
## `emulate_iterator`
33+
Returns a lazily evaluated generator/iterator. It yields elements one-by-one directly from the underlying LLM streams, vastly reducing latency for list generations.
34+
35+
> Note: tested mainly with qwen3:8b-instruct served by ollama
36+
37+
```python
38+
from OpenHosta import emulate_iterator
39+
40+
def generate_ideas(topic: str) -> list[str]:
41+
"""Yield multiple creative ideas based on the topic."""
42+
return emulate_iterator()
43+
44+
for idea in generate_ideas("Open Source Marketing"):
45+
print(idea) # Starts printing before the entire list is fully generated
46+
```
47+
3248
## `closure`
3349
Replicates lambda functions.
3450

docs/doc.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ Documentation for version: **4.0** (Preparing)
44

55
Welcome to the **OpenHosta** documentation hub. Here you'll find everything you need to leverage Large Language Models (LLMs) natively within your Python projects. OpenHosta transforms human language and semantic structures into pure, executable Python functions.
66

7-
> **What's New in V4?** Check out the [V4 Changelog](V4_CHANGELOG.md) to discover our brand-new Guarded Types, complete Ollama integration, and Generative Data Extraction Engines.
87

98
---
109

@@ -36,6 +35,7 @@ Take off your conceptual hat and observe OpenHosta in action through functional
3635
- 📚 [**Text Classification:**](examples/text_classification.md) Sorting streams of text directly into rigidly typed `Enum` states.
3736
- 🗃️ [**Data Extraction:**](examples/data_extraction.md) Populating massive `Dataclasses` and `Pydantic` modules straight from unstructured text blobs.
3837
- 👁️ [**Local OCR with Ollama:**](examples/ocr_local_ollama.md) Passing images using `PIL.Image` directly into `emulate`, performing OCR securely and locally using `glm-ocr`.
38+
-[**Parallel Processing:**](examples/parallel_processing.md) Running asynchronous workloads, parsing dataclasses like invoices, and batching prompts.
3939

4040
---
4141

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Example: Parallel Processing and Batch Context
2+
3+
When dealing with a vast amount of documents, or extracting information continuously in a backend server context, using `emulate_async` prevents UI blocking and increases thoroughput.
4+
5+
## 1. Extracting Invoices Using Async Tasks
6+
7+
This example demonstrates how to use `emulate_async` alongside `dataclasses` and `asyncio.gather` for highly concurrent validation. We define a data structure for invoice sender coordinates, and extract it instantly from multiple unstructured snippets.
8+
9+
```python
10+
import asyncio
11+
from dataclasses import dataclass
12+
from OpenHosta import emulate_async
13+
14+
@dataclass
15+
class InvoiceSender:
16+
company_name: str
17+
address: str
18+
city: str
19+
postal_code: str
20+
siret_number: str
21+
22+
async def extract_sender_coordinates(invoice_text: str) -> InvoiceSender:
23+
"""
24+
Parses the invoice text to find the exact coordinates of the invoice sender.
25+
Does not extract the recipient!
26+
"""
27+
return await emulate_async()
28+
29+
async def main():
30+
invoice_1 = "From: ACME Corp Ltd. 12 rue de la Paix, Paris, 75000. SIRET: 123456789. Billed to: John Doe."
31+
invoice_2 = "Facture envoyée le 12 Mars. Expéditeur: BricoPro. 5 impasse des artisans, 69002 Lyon. N° SIRET : 987654321."
32+
33+
# Using asyncio.create_task or asyncio.gather allows both requests to be sent
34+
# to the API / Local model concurrently!
35+
tasks = [
36+
asyncio.create_task(extract_sender_coordinates(invoice_1)),
37+
asyncio.create_task(extract_sender_coordinates(invoice_2))
38+
]
39+
40+
results = await asyncio.gather(*tasks)
41+
42+
for res in results:
43+
print(f"Company: {res.company_name} | City: {res.city} | SIRET: {res.siret_number}")
44+
45+
# Run the event loop
46+
if __name__ == "__main__":
47+
asyncio.run(main())
48+
```
49+
50+
## 2. The BatchDataContext Manager (Coming soon)
51+
52+
OpenHosta provides an elegant context manager under development `BatchDataContext` designed exclusively to simplify multi-processing workloads without manually tampering with event loops or explicit tasks.
53+
54+
```python
55+
from OpenHosta import emulate_async
56+
from OpenHosta import BatchDataContext
57+
58+
async def name_list(topic: str) -> list[str]:
59+
"""Generates three names related to the topic."""
60+
return await emulate_async()
61+
62+
async def first_name(person: str) -> str:
63+
"""Returns the first name of the famous person."""
64+
return await emulate_async()
65+
66+
async def alt_name(person: str) -> str:
67+
"""Returns an alternative alias of the person."""
68+
return await emulate_async()
69+
70+
# Batch size allows processing N queries in a sliding window
71+
with BatchDataContext(batch_size=10) as my_data:
72+
# Case A: Function inherently returning a list
73+
my_data["A"] = name_list("Macron")
74+
75+
# Case B: Python Array encapsulating multiple separate Async Coroutines
76+
my_data["B"] = [first_name("Trump"), alt_name("Trump")]
77+
78+
# Case C: Inserting strict generic static data
79+
my_data["C"] = "Static Data"
80+
81+
# Block closes, wait occurs, then dictionary items are completely resolved!
82+
print("Résultat final :", my_data)
83+
```

litellm_config.yaml.example

Lines changed: 0 additions & 21 deletions
This file was deleted.

0 commit comments

Comments
 (0)