> For the complete documentation index, see [llms.txt](https://unsloth.ai/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://unsloth.ai/docs/fr/integrations/connecter-le-sdk-python-a-unsloth.md).

# Connecter le SDK Python à Unsloth

Unsloth propose trois dialectes compatibles avec OpenAI au même URL de base. Chat Completions, Responses et Anthropic Messages, donc tous les SDK Python courants fonctionnent avec lui. \
\
Vous ne modifiez que le `base_url` et `api_key`  sur le client ; tout le reste (streaming, appel d'outils, vision, sortie structurée) se comporte comme le documente le SDK. Cette page couvre les deux SDK vers lesquels la plupart des développeurs se tournent d'abord : le SDK Python officiel **SDK Python OpenAI** et le SDK Python officiel **SDK Python Anthropic**.

{% hint style="info" %}
Si vous ne savez pas quelle URL / clé / nom de modèle utiliser, lisez d'abord la présentation de l'API. Elle vous guide pour démarrer, charger un modèle et créer une `sk-unsloth-…` clé.
{% endhint %}

### 🔑 Prérequis

Avant d'exécuter l'un des extraits ci-dessous, vous aurez besoin de :

* **Unsloth exécuté localement** avec un modèle chargé (notez le port : généralement `8000` ou `8888`).
* **Un `sk-unsloth-…` clé API** créée depuis **Paramètres → API**.
* **Un nom de modèle.** Le nom du modèle GGUF dans Unsloth (par exemple `qwen-local`, `unsloth/Qwen3.6-27B-GGUF`). Si vous l'oubliez, exécutez :

  ```bash
  curl http://localhost:8888/v1/models -H "Authorization: Bearer sk-unsloth-…"
  ```

  et copiez le `champ id` .

Définissez la clé comme variable d'environnement afin de ne jamais la coller dans le code :

```bash
export UNSLOTH_STUDIO_AUTH_TOKEN=sk-unsloth-xxxxxxxxxxxx
```

#### 🤖 SDK OpenAI

Le `/v1/chat/completions` point de terminaison est un remplacement direct pour le SDK Python OpenAI. Le client traite Unsloth comme n'importe quel autre fournisseur compatible avec OpenAI.

**1. Installez le SDK :**

```bash
pip install openai
```

**2. Créez un client** pointé vers Unsloth :

```python
import os
from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:8888/v1",              # votre port Unsloth + /v1
    api_key=os.environ["UNSLOTH_STUDIO_AUTH_TOKEN"],     # votre clé sk-unsloth-…
)
```

#### Complétion de chat basique

```python
response = client.chat.completions.create(
    model="default",                               # le nom que vous avez donné au modèle dans Unsloth ou default
    messages=[
        {"role": "user", "content": "Donnez-moi deux faits sur Paris"}
    ],
)
print(response.choices[0].message.content)
```

<figure><img src="/files/88328c2424c9d470d85be8c7b3f33b0359890f33" alt=""><figcaption></figcaption></figure>

#### Streaming

Définissez `stream=True` et itérez sur le générateur renvoyé :

```python
stream = client.chat.completions.create(
    model="qwen-local",
    messages=[{"role": "user", "content": "Écris un haïku sur les LLM exécutés localement."}],
    stream=True,
)
for chunk in stream:
    if chunk.choices:
        delta = chunk.choices[0].delta.content
        if delta:
            print(delta, end="", flush=True)
```

<figure><img src="/files/c835bf351445b4a50866654a9d758044699014fe" alt=""><figcaption></figcaption></figure>

#### Images (vision)

Attachez une image sous forme de `image_url` partie de contenu. Unsloth accepte soit une URL HTTP(S), soit une URI `data:` base64 :

```python
import base64
from pathlib import Path

img_b64 = base64.b64encode(Path("test.jpg").read_bytes()).decode()

response = client.chat.completions.create(
    model="default",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image_url",
                    "image_url": {"url": f"data:image/jpeg;base64,{img_b64}"},
                },
                {"type": "text", "text": "Qu'y a-t-il dans cette image ?"},
            ],
        }
    ],
)
print(response.choices[0].message.content)
```

{% hint style="info" %}
Le modèle chargé doit être multimodal. Si vous chargez un modèle texte seul, la requête de vision réussira structurellement, mais le modèle ne pourra pas « voir » l'image.
{% endhint %}

<figure><img src="/files/8a3d50822b21b9b5a577ed30544103f54ff52eb0" alt=""><figcaption></figcaption></figure>

#### Appel de fonction (outils OpenAI)

Passez des `outils` de style OpenAI et, éventuellement, `tool_choice` et Unsloth les transmet au backend. Votre client est chargé d'exécuter chaque appel d'outil et de renvoyer le résultat au tour suivant :

```python
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Obtenir la météo actuelle d'une ville",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {"type": "string", "description": "Nom de ville, par exemple 'Paris'"},
                },
                "required": ["city"],
            },
        },
    }
]

response = client.chat.completions.create(
    model="default",
    messages=[{"role": "user", "content": "Quel temps fait-il à Perth en ce moment ?"}],
    tools=tools,
    tool_choice="auto",
)

tool_call = response.choices[0].message.tool_calls[0]
print(tool_call.function.name, tool_call.function.arguments)
```

<figure><img src="/files/800caab698b435a3583ffecf7b078b57838d8194" alt=""><figcaption></figcaption></figure>

#### Outils côté serveur Unsloth (raccourci)

En plus des outils côté client de style OpenAI, Unsloth peut exécuter **Python**, **bash**, et **recherche web** côté serveur et renvoyer automatiquement les résultats en streaming. Activez cette option via le paramètre `extra_body` afin que les champs soient transmis tels quels à Unsloth :

```python
stream = client.chat.completions.create(
    model="default",
    messages=[{"role": "user", "content": "Quel est 123 * 456 ? Utilise Python pour le calculer."}],
    stream=True,
    extra_body={
        "enable_tools": True,
        "enabled_tools": ["python", "web_search"],
        "session_id": "my-session",
    },
)
for chunk in stream:
    if chunk.choices:
        delta = chunk.choices[0].delta.content
        if delta:
            print(delta, end="", flush=True)
```

<figure><img src="/files/a42c75b7a0f31576cc2aae70fd0c0a3b5e97c586" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/f5ff47043429c901b8bf23d171adea8bdd7d510e" alt=""><figcaption></figcaption></figure>

Le `session_id` est facultatif. Utilisez-le pour conserver l'état des outils (p. ex. un noyau Python) d'un appel à l'autre.

{% hint style="info" %}
`enabled_tools` prend actuellement en charge `"python"`, `"bash"`, et `"web_search"`. Les résultats des outils sont renvoyés en streaming sous forme de `tool_result` événements afin que le modèle puisse les voir au tour suivant.
{% endhint %}

**Liste des modèles**

```python
models = client.models.list()
for m in models.data:
    print(m.id)
```

<figure><img src="/files/ce2bdad1d0f353ab49168aa685327e63321b31a7" alt=""><figcaption></figcaption></figure>

#### 🧠 SDK Anthropic

Le `/v1/messages` point de terminaison est un remplacement direct pour le SDK Python Anthropic.

**1. Installez le SDK :**

```bash
pip install anthropic
```

**2. Créez un client** pointé vers Unsloth :

```python
import os
from anthropic import Anthropic

client = Anthropic(
    base_url="http://localhost:8888",                 # votre port Unsloth (pas de /v1 ici - le SDK l'ajoute)
    api_key="dummy",                                  # une valeur aléatoire non vide
    default_headers={"Authorization": "Bearer {os.environ['UNSLOTH_STUDIO_AUTH_TOKEN']}"} # votre clé sk-unsloth-…
)
```

#### Message basique

```python
message = client.messages.create(
    model="default",
    max_tokens=1024,
    messages=[
        {"role": "user", "content": "Dis bonjour dans trois langues."}
    ],
)
print(message.content[0].text)
```

<figure><img src="/files/65d7c15acbbc9b57632c5dc5c5179fda8874813b" alt=""><figcaption></figcaption></figure>

#### Streaming

Le SDK expose un gestionnaire de contexte qui renvoie des différences de texte :

```python
with client.messages.stream(
    model="default",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Explique LoRA en deux phrases."}],
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)
```

#### Images (vision)

Le contenu image de style Anthropic utilise un `bloc source` avec des données base64 :

```python
import base64
from pathlib import Path

img_b64 = base64.standard_b64encode(Path("photo.jpg").read_bytes()).decode()

message = client.messages.create(
    model="default",
    max_tokens=1024,
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image",
                    "source": {
                        "type": "base64",
                        "media_type": "image/jpeg",
                        "data": img_b64,
                    },
                },
                {"type": "text", "text": "Qu'y a-t-il dans cette image ?"},
            ],
        }
    ],
)
print(message.content[0].text)
```

<figure><img src="/files/8ba1d590e4ac84964e81a9418b001ab7e683c1b8" alt=""><figcaption></figcaption></figure>

#### Appel d'outil (outils Anthropic)

Passez des outils de style Anthropic `outils` avec un `input_schema` et Unsloth les transmet nativement :

```python
tools = [
    {
        "name": "get_weather",
        "description": "Obtenir la météo actuelle d'une ville",
        "input_schema": {
            "type": "object",
            "properties": {
                "city": {"type": "string", "description": "Nom de ville, par exemple 'Tokyo'"},
            },
            "required": ["city"],
        },
    }
]

message = client.messages.create(
    model="default",
    max_tokens=1024,
    tools=tools,
    tool_choice={"type": "auto"},
    messages=[{"role": "user", "content": "Quel temps fait-il à Tokyo ?"}],
)

for block in message.content:
    if block.type == "tool_use":
        print(block.name, block.input)
```

<figure><img src="/files/5b6168a91fa66da26809660f2666c6459a6a4575" alt=""><figcaption></figcaption></figure>

#### Outils côté serveur Unsloth (raccourci)

La même `enable_tools` / `enabled_tools` / `session_id` raccourci fonctionne avec `/v1/messages` transmettez-le `extra_body`:

```python
with client.messages.stream(
    model="default",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Cherche les fonctionnalités de Python 3.13 et résume-les."}],
    extra_body={
        "enable_tools": True,
        "enabled_tools": ["web_search", "python"],
        "session_id": "my-session",
    },
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)
```

<figure><img src="/files/0c6493522466e551fdecc298e302d03b846e4200" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/3f763f0b220f05d9ec24696e004f85b04868b36a" alt=""><figcaption></figcaption></figure>

Unsloth émet des `tool_result` événements SSE personnalisés pour la vue du modèle sur la sortie de chaque appel d'outil. Le SDK Anthropic les transmet tels quels via son flux d'événements.

#### Décodage JSON (`response_format`)

Unsloth prend en charge les sorties structurées de style OpenAI via `response_format`. Passez un schéma JSON et le modèle est contraint de produire un JSON conforme.

````python
import json
import os
import re
from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:8888/v1",
    api_key=os.environ["UNSLOTH_STUDIO_AUTH_TOKEN"],
)

response = client.chat.completions.create(
    model="default",
    stream=False,
    temperature=0.0,
    max_tokens=1024,
    messages=[
        {
            "role": "user",
            "content": "Choisissez un pays : Japon, Égypte ou Pérou. Expliquez pourquoi en une phrase.",
        },
    ],
    response_format={
        "type": "json_schema",
        "json_schema": {
            "name": "country_pick",
            "schema": {
                "type": "object",
                "properties": {
                    "country": {"type": "string", "enum": ["Japan", "Egypt", "Peru"]},
                    "reason":  {"type": "string"},
                },
                "required": ["country", "reason"],
                "additionalProperties": False,
            },
            "strict": True,
        },
    },
)

raw = response.choices[0].message.content
# Retirez le cadre Markdown que Gemma 4 entoure autour du JSON, puis analysez-le.
cleaned = re.sub(r"^```(?:json)?\s*", "", raw)
cleaned = re.sub(r"\s*```$", "", cleaned)
parsed = json.loads(cleaned)

print(json.dumps(parsed, indent=2))
print()
print("pays :", parsed["country"])
print("raison :", parsed["reason"])
````

Le `strict: True` ce drapeau indique à Unsloth d'appliquer le schéma pendant le décodage plutôt que de compter sur le modèle pour s'y conformer de lui-même. `additionalProperties: False` et `required` fonctionnent comme dans le JSON Schema standard.

La sortie du terminal devrait ressembler à peu près à ceci :

<figure><img src="/files/c4c076fb1cba4528620f7a0d0cfb85f6301f38fc" alt=""><figcaption></figcaption></figure>

## Retirez le cadre Markdown que Gemma 4 entoure autour du JSON, puis analysez-le.

cleaned = re.sub(r"^`(?:json)?\s*", "", raw) cleaned = re.sub(r"\s*`$", "", cleaned) parsed = json.loads(cleaned)

print(json.dumps(parsed, indent=2)) print() print("pays :", parsed\["country"]) print("raison :", parsed\["reason"])

### 🧪 Choisir un SDK

Les deux SDK fonctionnent avec Unsloth. Le bon choix dépend du reste de votre pile :

* Utilisez le **SDK OpenAI** si votre code dépend déjà du package Python OpenAI, que vous voulez un `outils` / `tool_choice`style OpenAI, ou que vous prévoyez d'appeler l'API Responses.
* Utilisez le **SDK Anthropic** si votre code dépend déjà du package Anthropic, que vous préférez le `input_schema` format d'outils Anthropic, ou que vous voulez les types d'événements de streaming natifs d'Anthropic.

Vous pouvez utiliser les deux dans le même projet. Unsloth les sert sur le même port, donc une seule `sk-unsloth-…` clé authentifie les deux.

### ❔ Dépannage

**`401 Non autorisé`**  Le `UNSLOTH_STUDIO_API_KEY` la variable d'environnement n'est pas définie, ou la clé est incorrecte. Réexportez-la et vérifiez avec `echo $UNSLOTH_STUDIO_API_KEY`.

**`404 Introuvable` du SDK OpenAI** Vérifiez que `base_url` se termine par `/v1`. Le SDK OpenAI ajoute les chemins de point de terminaison à l'URL de base tels quels.

**`404 Introuvable` du SDK Anthropic** Vérifiez que `base_url` fait **ne** se termine pas par `/v1`. Le SDK Anthropic ajoute `/v1/messages` lui-même.

**`extra_body` les champs n'arrivent pas jusqu'à Unsloth** Assurez-vous d'utiliser une version récente de `openai` / `anthropic` SDK. Les anciennes versions ignorent silencieusement les champs inconnus. Mettez à niveau avec `pip install -U openai anthropic`.

**Le streaming « se bloque » puis tout s'affiche d'un coup** Quoi que ce soit qui enveloppe votre sortie met en mémoire tampon. Dans un script, `print(..., flush=True)`; dans un notebook, c'est généralement correct ; derrière un proxy, désactivez la mise en mémoire tampon des réponses sur le proxy.

Pour les problèmes au niveau des points de terminaison (mauvais port, modèle non chargé, connexion perdue, etc.), consultez la page de présentation de l'API.

### Facultatif : définir les valeurs par défaut du serveur

Vous pouvez configurer le comportement par défaut du serveur avant de vous connecter avec le SDK Python, lorsque vous utilisez la `unsloth run` commande.

```bash
# Démarrez le serveur avec des valeurs par défaut personnalisées
unsloth run \
  --model unsloth/Qwen3-1.7B-GGUF \
  --reasoning off \
  --temp 0.6 \
  -p 8888
```

Utilisez `--reasoning off` pour désactiver la réflexion, ou `--reasoning on` pour l'activer pour les modèles qui prennent en charge le raisonnement.

```bash
# Exposez l'API sur votre réseau local
unsloth run \
  --model unsloth/Qwen3-1.7B-GGUF \
  -H 0.0.0.0 \
  -p 8888
```

Cela démarre le serveur sur `0.0.0.0:8888`, ce qui permet à d'autres appareils de votre réseau local de se connecter.

Ces paramètres deviennent les valeurs par défaut du serveur lorsque les requêtes ne spécifient pas leurs propres paramètres de génération.

Les valeurs au niveau de la requête comme `temperature`, `top_p`, `max_tokens`, et `stream` peuvent toujours remplacer les valeurs par défaut pour cette requête.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://unsloth.ai/docs/fr/integrations/connecter-le-sdk-python-a-unsloth.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
