Metadata-Version: 2.5
Name: henergyqueai
Version: 0.1.0
Summary: Bibliothèque officielle de l’API HenergyqueAI : Velys, Oryne et Aelyr depuis Python.
Project-URL: Homepage, https://henergyqueai.fr
Project-URL: Documentation, https://henergyqueai.fr/plateforme/docs#bibliotheques
License-Expression: MIT
License-File: LICENSE
Keywords: aelyr,api,henergyqueai,ia,oryne,velys
Classifier: Natural Language :: French
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Typing :: Typed
Requires-Python: >=3.9
Requires-Dist: httpx<1,>=0.25
Description-Content-Type: text/markdown

# henergyqueai

La bibliothèque officielle de l’API [HenergyqueAI](https://henergyqueai.fr) pour Python : Velys, Oryne et Aelyr en quelques lignes.

- Python 3.9+, une seule dépendance (httpx).
- Un client classique et un client asynchrone.
- Streaming, outils, images, sorties JSON.
- Nouvelles tentatives automatiques sur les erreurs passagères.

```sh
pip install henergyqueai
```

Créez une clé sur [henergyqueai.fr/plateforme/cles](https://henergyqueai.fr/plateforme/cles), puis :

```sh
export HENERGYQUEAI_API_KEY="hak_…"
```

## Premier appel

```python
from henergyqueai import HenergyqueAI

client = HenergyqueAI()  # lit HENERGYQUEAI_API_KEY

print(client.ask("Donne-moi trois idées de prénom pour un chat."))
```

`ask` utilise Velys par défaut :

```python
client.ask("Relis cette fonction.", model="oryne", system="Réponds en une phrase.")
```

## Conversation complète

```python
reponse = client.chat.create(
    model="oryne",
    messages=[
        {"role": "system", "content": "Tu es un relecteur de code exigeant."},
        {"role": "user", "content": "Que penses-tu de `for i in range(len(liste))` ?"},
    ],
    temperature=0.3,
)

print(reponse.text)  # le texte, déjà extrait
print(reponse.usage.total_tokens)
```

Les réponses sont des dictionnaires dont les clés se lisent aussi comme des attributs : `reponse.choices[0].message.content` ou `reponse["choices"][0]["message"]["content"]`.

## Streaming

```python
with client.chat.stream(
    model="velys",
    messages=[{"role": "user", "content": "Raconte une histoire courte."}],
) as flux:
    for texte in flux.text_stream:
        print(texte, end="", flush=True)
    finale = flux.final_completion()
```

## Client asynchrone

```python
import asyncio
from henergyqueai import AsyncHenergyqueAI

async def main():
    async with AsyncHenergyqueAI() as client:
        print(await client.ask("Bonjour !"))
        flux = client.chat.stream(model="velys", messages=[{"role": "user", "content": "Un haïku."}])
        async for texte in flux.text_stream:
            print(texte, end="", flush=True)

asyncio.run(main())
```

## Outils

```python
import json

reponse = client.chat.create(
    model="oryne",
    messages=[{"role": "user", "content": "Quel temps fait-il à Nantes ?"}],
    tools=[{
        "type": "function",
        "function": {
            "name": "meteo",
            "description": "La météo actuelle d’une ville",
            "parameters": {"type": "object", "properties": {"ville": {"type": "string"}}, "required": ["ville"]},
        },
    }],
)

for appel in reponse.choices[0].message.get("tool_calls") or []:
    ville = json.loads(appel.function.arguments)["ville"]
    # … exécutez l’outil, puis renvoyez son résultat dans un message {"role": "tool", "tool_call_id": appel.id, "content": …}
```

## Format messages

```python
message = client.messages.create(
    model="aelyr",
    system="Tu es précis et concis.",
    messages=[{"role": "user", "content": "Explique la différence entre TCP et UDP."}],
)
print(message.text)

with client.messages.stream(model="aelyr", messages=[{"role": "user", "content": "Un haïku."}]) as flux:
    for texte in flux.text_stream:
        print(texte, end="")

client.messages.count_tokens(model="velys", messages=[{"role": "user", "content": "Bonjour"}]).input_tokens
```

`max_tokens` vaut 1024 par défaut dans la bibliothèque.

## Modèles et consommation

```python
[modele.id for modele in client.models.list()]  # ["velys", "oryne", "aelyr"]
client.models.retrieve("oryne")
client.usage().requests.remaining
```

## Erreurs

```python
from henergyqueai import RateLimitError, AuthenticationError

try:
    client.ask("Bonjour")
except RateLimitError as erreur:
    print(f"Réessayez dans {erreur.retry_after} s.")
except AuthenticationError:
    print("Clé invalide.")
```

Chaque erreur porte `status`, `type`, `code`, `param`, `request_id` et `retry_after`. Les autres classes sont `InvalidRequestError`, `PermissionDeniedError`, `NotFoundError`, `ServerError`, `ConnectionError` et `TimeoutError`, toutes filles de `HenergyqueAIError`.

Les erreurs passagères (429, 5xx, coupure réseau) sont retentées deux fois, en respectant `retry-after`. La limite quotidienne de votre offre n’est jamais retentée.

## Options

```python
client = HenergyqueAI(
    "hak_…",          # sinon HENERGYQUEAI_API_KEY
    timeout=60.0,     # secondes (10 minutes par défaut)
    max_retries=3,    # 2 par défaut
)
```

## Licence

MIT
