> ## Documentation Index
> Fetch the complete documentation index at: https://docs.olostep.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Olostep Python SDK

> SDK Python officiel pour rechercher, extraire et structurer des données du Web

<Note>
  **Package PyPI**: [olostep](https://pypi.org/project/olostep/) | **Exigences**: Python 3.11+
</Note>

## Installation

<CodeGroup>
  ```bash pip theme={null}
  pip install olostep
  ```

  ```bash pip3 theme={null}
  pip3 install olostep
  ```

  ```bash poetry theme={null}
  poetry add olostep
  ```

  ```bash uv theme={null}
  uv pip install olostep
  ```
</CodeGroup>

## Authentification

Obtenez votre clé API depuis le [Tableau de bord Olostep](https://www.olostep.com/dashboard/).

## Démarrage rapide

Le SDK propose deux options de client selon votre cas d'utilisation :

<CardGroup cols={2}>
  <Card title="Client Sync (`Olostep`)" href="/sdks/python#sync-client-olostep" icon="sync">
    Idéal pour : Scripts et cas d'utilisation simples où vous préférez des opérations bloquantes.<br /><br />
    Le client sync offre une interface plus simple et bloquante, plus facile à utiliser si vous êtes nouveau dans l'async/await.
  </Card>

  <Card title="Client Async (`AsyncOlostep`)" href="/sdks/python#async-client-asyncolostep" icon="zap">
    Idéal pour : Applications en production et gestion de nombreuses requêtes simultanées.<br /><br />
    Le client async offre des opérations non bloquantes et est le choix recommandé pour les applications en production nécessitant un débit élevé.
  </Card>
</CardGroup>

# Client Sync (Olostep)

Le client sync (`Olostep`) offre une interface bloquante parfaite pour les scripts et les cas d'utilisation simples.

```python theme={null}
from olostep import Olostep

# Fournissez la clé API soit en passant le paramètre 'api_key'
# soit en définissant la variable d'environnement OLOSTEP_API_KEY

# Le client sync gère automatiquement la gestion des ressources
# Pas besoin de fermeture explicite - les ressources sont nettoyées après chaque opération
client = Olostep(api_key="YOUR_REAL_KEY")
scrape_result = client.scrapes.create(url_to_scrape="https://example.com")
```

### Scraping Web de base

```python theme={null}
from olostep import Olostep

client = Olostep(api_key="your-api-key")

# Scraping simple
result = client.scrapes.create(url_to_scrape="https://example.com")
print(f"Scraped {len(result.html_content)} characters")

# Formats multiples
result = client.scrapes.create(
    url_to_scrape="https://example.com",
    formats=["html", "markdown"]
)
print(f"HTML: {len(result.html_content)} chars")
print(f"Markdown: {len(result.markdown_content)} chars")
```

### Traitement par lot

```python theme={null}
from olostep import Olostep

client = Olostep(api_key="your-api-key")

# Traitez plusieurs URL efficacement
batch = client.batches.create(
    urls=[
        "https://www.google.com/search?q=python",
        "https://www.google.com/search?q=javascript",
        "https://www.google.com/search?q=typescript"
    ]
)

# Attendez la fin et traitez les résultats
for item in batch.items():
    content = item.retrieve(["html"])
    print(f"Processed {item.url}: {len(content.html_content)} bytes")
```

### Crawling Web intelligent

```python theme={null}
from olostep import Olostep

client = Olostep(api_key="your-api-key")

# Crawl avec filtrage intelligent
crawl = client.crawls.create(
    start_url="https://www.bbc.com",
    max_pages=100,
    include_urls=["/articles/**", "/blog/**"],
    exclude_urls=["/admin/**"]
)

for page in crawl.pages():
    content = page.retrieve(["html"])
    print(f"Crawled: {page.url}")
```

### Cartographie du site

```python theme={null}
from olostep import Olostep

client = Olostep(api_key="your-api-key")

# Extraire tous les liens d'un site web
maps = client.maps.create(url="https://example.com")

# Obtenez toutes les URL découvertes
urls = []
for url in maps.urls():
    urls.append(url)
    if len(urls) >= 10:  # Limite pour la démo
        break

print(f"Found {len(urls)} URLs")
```

### Réponses alimentées par l'IA

```python theme={null}
from olostep import Olostep

client = Olostep(api_key="your-api-key")

# Obtenez des réponses à partir de pages web en utilisant l'IA
answer = client.answers.create(
    task="What is the main topic of https://example.com?"
)
print(f"Answer: {answer.answer}")
```

# Client Async (AsyncOlostep)

Le client async (`AsyncOlostep`) est le client recommandé pour les applications à haute performance, les services backend, et lorsque vous devez gérer de nombreuses requêtes simultanées.

```python theme={null}
from olostep import AsyncOlostep

# Fournissez la clé API soit en passant le paramètre 'api_key'
# soit en définissant la variable d'environnement OLOSTEP_API_KEY

# GESTION DES RESSOURCES
# ======================
# Le SDK prend en charge deux modèles d'utilisation pour la gestion des ressources :

# 1. Gestionnaire de contexte (Recommandé pour un usage unique) :
#    Gère automatiquement le nettoyage des ressources
async with AsyncOlostep(api_key="YOUR_REAL_KEY") as client:
    scrape_result = await client.scrapes.create(url_to_scrape="https://example.com")
# Le transport est automatiquement fermé ici

# 2. Fermeture explicite (Pour les services de longue durée) :
#    Nécessite un nettoyage manuel des ressources
client = AsyncOlostep(api_key="YOUR_REAL_KEY")
try:
    scrape_result = await client.scrapes.create(url_to_scrape="https://example.com")
finally:
    await client.close()  # Fermez manuellement le transport
```

### Scraping Web de base

```python theme={null}
import asyncio
from olostep import AsyncOlostep

async def main():
    async with AsyncOlostep(api_key="your-api-key") as client:
        # Scraping simple
        result = await client.scrapes.create(url_to_scrape="https://example.com")
        print(f"Scraped {len(result.html_content)} characters")

        # Formats multiples
        result = await client.scrapes.create(
            url_to_scrape="https://example.com",
            formats=["html", "markdown"]
        )
        print(f"HTML: {len(result.html_content)} chars")
        print(f"Markdown: {len(result.markdown_content)} chars")

asyncio.run(main())
```

### Traitement par lot

```python theme={null}
import asyncio
from olostep import AsyncOlostep

async def main():
    async with AsyncOlostep(api_key="your-api-key") as client:
        # Traitez plusieurs URL efficacement
        batch = await client.batches.create(
            urls=[
                "https://www.google.com/search?q=python",
                "https://www.google.com/search?q=javascript",
                "https://www.google.com/search?q=typescript"
            ]
        )

        # Attendez la fin et traitez les résultats
        async for item in batch.items():
            content = await item.retrieve(["html"])
            print(f"Processed {item.url}: {len(content.html_content)} bytes")

asyncio.run(main())
```

### Crawling Web intelligent

```python theme={null}
import asyncio
from olostep import AsyncOlostep

async def main():
    async with AsyncOlostep(api_key="your-api-key") as client:
        # Crawl avec filtrage intelligent
        crawl = await client.crawls.create(
            start_url="https://www.bbc.com",
            max_pages=100,
            include_urls=["/articles/**", "/blog/**"],
            exclude_urls=["/admin/**"]
        )

        async for page in crawl.pages():
            content = await page.retrieve(["html"])
            print(f"Crawled: {page.url}")

asyncio.run(main())
```

### Cartographie du site

```python theme={null}
import asyncio
from olostep import AsyncOlostep

async def main():
    async with AsyncOlostep(api_key="your-api-key") as client:
        # Extraire tous les liens d'un site web
        maps = await client.maps.create(url="https://example.com")

        # Obtenez toutes les URL découvertes
        urls = []
        async for url in maps.urls():
            urls.append(url)
            if len(urls) >= 10:  # Limite pour la démo
                break

        print(f"Found {len(urls)} URLs")

asyncio.run(main())
```

### Réponses alimentées par l'IA

```python theme={null}
import asyncio
from olostep import AsyncOlostep

async def main():
    async with AsyncOlostep(api_key="your-api-key") as client:
        # Obtenez des réponses à partir de pages web en utilisant l'IA
        answer = await client.answers.create(
            task="What is the main topic of https://example.com?"
        )
        print(f"Answer: {answer.answer}")

asyncio.run(main())
```

## Référence SDK

### Structure des méthodes

Les deux clients SDK offrent la même interface claire et pythonique organisée en espaces de noms logiques :

| Espace de noms | Objectif                      | Méthodes clés                   |
| -------------- | ----------------------------- | ------------------------------- |
| `scrapes`      | Extraction d'URL unique       | `create()`, `get()`             |
| `batches`      | Traitement multi-URL          | `create()`, `info()`, `items()` |
| `crawls`       | Parcours de site web          | `create()`, `info()`, `pages()` |
| `maps`         | Extraction de liens           | `create()`, `urls()`            |
| `answers`      | Extraction alimentée par l'IA | `create()`, `get()`             |
| `retrieve`     | Récupération de contenu       | `get()`                         |

Chaque opération retourne des objets avec état et des méthodes ergonomiques pour les opérations de suivi.

## Gestion des erreurs

Capturez toutes les erreurs SDK en utilisant la classe d'exception de base :

```python theme={null}
from olostep import Olostep, Olostep_BaseError

client = Olostep(api_key="your-api-key")

try:
    result = client.scrapes.create(url_to_scrape="https://example.com")
except Olostep_BaseError as e:
    print(f"Error has occurred: {type(e).__name__}")
    print(f"Error message: {e}")
```

Pour des informations détaillées sur la gestion des erreurs, y compris la hiérarchie complète des exceptions et les options de gestion des erreurs granulaires, voir [Gestion des erreurs détaillée](/sdks/python#detailed-error-handling).

## Reprises automatiques

Le SDK réessaie automatiquement en cas d'erreurs transitoires (problèmes de réseau, problèmes temporaires du serveur) en fonction de la configuration `RetryStrategy`. Vous pouvez personnaliser le comportement de reprise en passant une instance `RetryStrategy` lors de la création du client :

```python theme={null}
from olostep import Olostep, RetryStrategy

retry_strategy = RetryStrategy(
    max_retries=3,
    initial_delay=1.0,
    jitter_min=0.2,
    jitter_max=0.8
)

client = Olostep(api_key="your-api-key", retry_strategy=retry_strategy)
result = client.scrapes.create("https://example.com")
```

Pour des options de configuration détaillées de la reprise et des meilleures pratiques, voir [Stratégie de reprise](/sdks/python#retry-strategy-configuration).

## Fonctionnalités avancées

### Coercition intelligente des entrées

Le SDK gère intelligemment divers formats d'entrée pour un maximum de commodité :

```python theme={null}
from olostep import Olostep, Country

client = Olostep(api_key="your-api-key")

# Formats : chaîne, liste ou enum
client.scrapes.create(url_to_scrape="https://example.com", formats="html")
client.scrapes.create(url_to_scrape="https://example.com", formats=["html", "markdown"])

# Pays : chaînes insensibles à la casse ou enums
client.scrapes.create(url_to_scrape="https://example.com", country="us")
client.scrapes.create(url_to_scrape="https://example.com", country=Country.US)

# Listes : valeurs uniques ou listes
client.batches.create(urls="https://example.com")    # URL unique
client.batches.create(urls=["https://a.com", "https://b.com"])  # Plusieurs URL
```

### Options de scraping avancées

```python theme={null}
from olostep import Olostep, Format, Country, WaitAction, FillInputAction

client = Olostep(api_key="your-api-key")

# Contrôle total sur le comportement de scraping
result = client.scrapes.create(
    url_to_scrape="https://news.google.com/",
    wait_before_scraping=3000,
    formats=[Format.HTML, Format.MARKDOWN],
    remove_css_selectors=["script", ".popup"],
    actions=[
        WaitAction(milliseconds=1500),
        FillInputAction(selector="searchbox", value="olostep")
    ],
    parser="@olostep/google-news",
    country=Country.US,
    remove_images=True
)
```

### Mise en cache

Par défaut, chaque requête de scraping récupère la page fraîche (`max_age=0`). Passez `max_age` pour réutiliser un résultat récent avec les mêmes paramètres et améliorer le temps de réponse. La valeur est en **secondes** ; le maximum est de 7 jours (`604800`). Voir [Mise en cache](/features/scrapes#caching) pour les détails.

```python theme={null}
# Optez pour la mise en cache : acceptez des résultats jusqu'à 1 jour (86400 secondes) anciens
result = client.scrapes.create(
    url_to_scrape="https://example.com",
    formats=["markdown"],
    max_age=86400
)
```

### Traitement par lot avec IDs personnalisés

```python theme={null}
from olostep import Olostep, Country

client = Olostep(api_key="your-api-key")

batch = client.batches.create([
    {"url": "https://www.google.com/search?q=python", "custom_id": "search_1"},
    {"url": "https://www.google.com/search?q=javascript", "custom_id": "search_2"},
    {"url": "https://www.google.com/search?q=typescript", "custom_id": "search_3"}
],
country=Country.US,
parser="@olostep/google-search"
)

# Traitez les résultats par ID personnalisé
# Lors de l'utilisation d'un parser, récupérez le contenu JSON au lieu de HTML
for item in batch.items():
    if item.custom_id == "search_2":
        content = item.retrieve(["json"])
        print(f"Search result: {content.json_content}")
```

### Crawling intelligent

```python theme={null}
from olostep import Olostep

client = Olostep(api_key="your-api-key")

# Crawl avec filtrage intelligent
crawl = client.crawls.create(
    start_url="https://www.bbc.com",
    max_pages=1000,
    max_depth=3,
    include_urls=["/articles/**", "/news/**"],
    exclude_urls=["/ads/**", "/tracking/**"],
    include_external=False,
    include_subdomain=True,
)

for page in crawl.pages():
    content = page.retrieve(["html"])
    print(f"Crawled: {page.url}")
```

### Cartographie du site avec filtres

```python theme={null}
from olostep import Olostep

client = Olostep(api_key="your-api-key")

# Extraire tous les liens avec filtrage avancé
maps = client.maps.create(
    url="https://www.bbc.com",
    include_subdomain=True,
    include_urls=["/articles/**", "/news/**"],
    exclude_urls=["/ads/**", "/tracking/**"]
)

# Obtenez les URL filtrées
urls = []
for url in maps.urls():
    urls.append(url)

print(f"Found {len(urls)} relevant URLs")
```

### Récupération des réponses

```python theme={null}
from olostep import Olostep

client = Olostep(api_key="your-api-key")

# Créez d'abord une réponse
created_answer = client.answers.create(
    task="What is the main topic of https://example.com?"
)

# Puis récupérez-la en utilisant l'ID
answer = client.answers.get(answer_id=created_answer.id)
print(f"Answer: {answer.answer}")
```

### Récupération de contenu

```python theme={null}
from olostep import Olostep

client = Olostep(api_key="your-api-key")

# Obtenez le contenu par ID de récupération
result = client.retrieve.get(retrieve_id="ret_123")

# Obtenez plusieurs formats
result = client.retrieve.get(retrieve_id="ret_123", formats=["html", "markdown", "text", "json"])
```

## Journalisation

Activez la journalisation pour déboguer les problèmes :

```python theme={null}
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("olostep")
logger.setLevel(logging.INFO)  # Utilisez DEBUG pour une sortie détaillée
```

**Niveaux de journalisation** : `INFO` (recommandé), `DEBUG` (détaillé), `WARNING`, `ERROR`

## Configuration de la stratégie de reprise

La classe `RetryStrategy` contrôle comment le SDK Olostep gère les erreurs API transitoires via des reprises automatiques avec backoff exponentiel et jitter. Cela aide à assurer une opération fiable dans les environnements de production où des problèmes de réseau temporaires, des limites de taux et une surcharge du serveur peuvent causer des échecs intermittents.

### Comportement par défaut

Par défaut, le SDK utilise la configuration de reprise suivante :

* **Reprises max** : 5 tentatives
* **Délai initial** : 2 secondes
* **Backoff** : Exponentiel (2^tentative)
* **Jitter** : 10-90% du délai (aléatoire)

Cela signifie :

* Tentative 1 : Immédiate
* Tentative 2 : \~2-3.6s de délai
* Tentative 3 : \~4-7.2s de délai
* Tentative 4 : \~8-14.4s de délai
* Tentative 5 : \~16-28.8s de délai

Durée maximale : \~57 secondes pour toutes les reprises (cas le pire)

### Configuration personnalisée

```python theme={null}
from olostep import AsyncOlostep, RetryStrategy

# Créez une stratégie de reprise personnalisée
retry_strategy = RetryStrategy(
    max_retries=3,
    initial_delay=1.0,
    jitter_min=0.2,  # Jitter minimum de 20%
    jitter_max=0.8,  # Jitter maximum de 80%
)

# Utilisez avec le client
async with AsyncOlostep(
    api_key="your-api-key",
    retry_strategy=retry_strategy
) as client:
    result = await client.scrapes.create("https://example.com")
```

### Quand les reprises se produisent

Le SDK réessaie automatiquement en cas de :

* **Problèmes temporaires du serveur** (`OlostepServerError_TemporaryIssue`)
* **Réponses de timeout** (`OlostepServerError_NoResultInResponse`)

Les autres erreurs (authentification, validation, ressource non trouvée, etc.) échouent immédiatement sans reprise.

### Reprises de transport vs de l'appelant

Le SDK a deux couches de reprise :

1. **Couche de transport** : Gère les échecs de connexion au niveau réseau (DNS, timeouts, etc.)
2. **Couche de l'appelant** : Gère les erreurs transitoires au niveau de l'API (contrôlées par `RetryStrategy`)

Les deux couches sont indépendantes et ont une configuration séparée. La durée maximale totale est la somme des deux couches.

### Calcul de la durée maximale

```python theme={null}
retry_strategy = RetryStrategy(max_retries=5, initial_delay=2.0)
max_duration = retry_strategy.max_duration()
print(f"Max call duration: {max_duration:.2f}s")
```

### Exemples de configuration

Voici quelques exemples de configuration de la stratégie de reprise pour différents cas d'utilisation.

#### Stratégie conservatrice

```python theme={null}
# Moins de reprises, délais plus courts
retry_strategy = RetryStrategy(
    max_retries=3,
    initial_delay=1.0,
    jitter_min=0.2,
    jitter_max=0.8
)
# Durée max : ~12.6s
```

#### Stratégie agressive

```python theme={null}
# Plus de reprises pour les opérations critiques
retry_strategy = RetryStrategy(
    max_retries=10,
    initial_delay=0.5
)
# Durée max : ~969.75s
```

#### Pas de reprises (échec rapide)

```python theme={null}
# Désactivez les reprises pour un retour d'échec immédiat
retry_strategy = RetryStrategy(max_retries=0)

client = AsyncOlostep(api_key="your-api-key", retry_strategy=retry_strategy)
```

#### Stratégie à haut débit

```python theme={null}
# Optimisé pour les opérations à haut volume
retry_strategy = RetryStrategy(
    max_retries=2,
    initial_delay=0.5,
    jitter_min=0.1,
    jitter_max=0.3  # Jitter plus faible pour un timing plus prévisible
)
# Durée max : ~1.95s
```

### Comprendre le jitter

Le jitter ajoute une randomisation pour éviter les problèmes de "troupeau tonitruant" lorsque de nombreux clients réessaient simultanément. Le jitter est calculé comme suit :

```python theme={null}
base_delay = initial_delay * (2 ** attempt)
jitter_range = base_delay * (jitter_max - jitter_min)
jitter = random.uniform(base_delay * jitter_min, base_delay * jitter_min + jitter_range)
final_delay = base_delay + jitter
```

Par exemple, avec `initial_delay=2.0`, `jitter_min=0.1`, `jitter_max=0.9` :

* Tentative 0 : base=2.0s, jitter=0.2-1.8s, final=2.2-3.8s
* Tentative 1 : base=4.0s, jitter=0.4-3.6s, final=4.4-7.6s
* Tentative 2 : base=8.0s, jitter=0.8-7.2s, final=8.8-15.2s

### Meilleures pratiques

#### Pour les applications en production

```python theme={null}
# Approche équilibrée pour la production
retry_strategy = RetryStrategy(
    max_retries=5,
    initial_delay=2.0,
    jitter_min=0.1,
    jitter_max=0.9
)
```

#### Pour le développement/test

```python theme={null}
# Retour rapide pour le développement
retry_strategy = RetryStrategy(
    max_retries=2,
    initial_delay=0.5,
    jitter_min=0.1,
    jitter_max=0.3
)
```

#### Pour les opérations par lot

```python theme={null}
# Conservateur pour les gros travaux par lot
retry_strategy = RetryStrategy(
    max_retries=3,
    initial_delay=1.0,
    jitter_min=0.2,
    jitter_max=0.8
)
```

### Surveillance et débogage

Le SDK journalise les informations de reprise au niveau DEBUG :

```
DEBUG: Temporary issue, retrying in 2.34s
DEBUG: No result in response, retrying in 4.67s
```

Activez la journalisation de débogage pour surveiller le comportement de reprise :

```python theme={null}
import logging
logging.getLogger("olostep").setLevel(logging.DEBUG)
```

### Gestion des erreurs

Lorsque toutes les reprises sont épuisées, l'erreur d'origine est levée :

```python theme={null}
try:
    result = await client.scrapes.create("https://example.com")
except OlostepServerError_TemporaryIssue as e:
    print(f"Failed after all retries: {e}")
    # Gérez l'échec permanent
```

### Considérations sur les performances

* **Mémoire** : Chaque tentative de reprise utilise de la mémoire supplémentaire pour les objets de requête/réponse
* **Temps** : Le temps total de l'opération peut être significativement plus long avec les reprises activées
* **Limites API** : Les reprises comptent contre vos limites d'utilisation de l'API
* **Réseau** : Plus de trafic réseau en raison des tentatives de reprise

Choisissez votre stratégie de reprise en fonction des exigences de votre application en matière de fiabilité par rapport aux performances.

## Gestion des erreurs détaillée

### Hiérarchie des exceptions

Le SDK Olostep fournit une hiérarchie d'exceptions complète pour différents scénarios d'échec. Toutes les exceptions héritent de `Olostep_BaseError`.

Il y a trois principaux types d'erreurs qui héritent directement de `Olostep_BaseError` :

1. **`Olostep_APIConnectionError`** - Échecs de connexion au niveau réseau
2. **`OlostepServerError_BaseError`** - Erreurs levées (en quelque sorte) par le serveur API
3. **`OlostepClientError_BaseError`** - Erreurs levées par le SDK client

### Pourquoi les erreurs de connexion sont séparées

`Olostep_APIConnectionError` est séparé des erreurs de serveur car il représente des échecs au niveau réseau qui se produisent avant que l'API puisse traiter la requête. Ce sont des problèmes de couche de transport (échecs DNS ou HTTP, timeouts, connexion refusée, etc.) plutôt que des erreurs au niveau de l'API. Les codes d'état HTTP (4xx, 5xx) sont considérés comme des réponses de l'API et sont catégorisés comme des erreurs de serveur, même s'ils indiquent des problèmes.

```
Olostep_BaseError
├── Olostep_APIConnectionError
├── OlostepServerError_BaseError
│   ├── OlostepServerError_TemporaryIssue
│   │   ├── OlostepServerError_NetworkBusy
│   │   └── OlostepServerError_InternalNetworkIssue
│   ├── OlostepServerError_RequestUnprocessable
│   │   ├── OlostepServerError_ParserNotFound
│   │   └── OlostepServerError_OutOfResources
│   ├── OlostepServerError_BlacklistedDomain
│   ├── OlostepServerError_FeatureApprovalRequired
│   ├── OlostepServerError_AuthFailed
│   ├── OlostepServerError_CreditsExhausted
│   ├── OlostepServerError_InvalidEndpointCalled
│   ├── OlostepServerError_ResourceNotFound
│   ├── OlostepServerError_NoResultInResponse
│   └── OlostepServerError_UnknownIssue
└── OlostepClientError_BaseError
    ├── OlostepClientError_RequestValidationFailed
    ├── OlostepClientError_ResponseValidationFailed
    ├── OlostepClientError_NoAPIKey
    ├── OlostepClientError_AsyncContext
    ├── OlostepClientError_BetaFeatureAccessRequired
    └── OlostepClientError_Timeout
```

### Gestion des erreurs recommandée

Pour la plupart des cas d'utilisation, capturez l'erreur de base et imprimez le nom de l'erreur :

```python theme={null}
from olostep import AsyncOlostep, Olostep_BaseError

try:
    result = await client.scrapes.create(url_to_scrape="https://example.com")
except Olostep_BaseError as e:
    print(f"Error has occurred: {type(e).__name__}")
    print(f"Error message: {e}")
```

Cette approche capture toutes les erreurs SDK et fournit des informations claires sur ce qui s'est mal passé. Le nom de l'erreur (par exemple, `OlostepServerError_AuthFailed`) est suffisamment descriptif pour comprendre le problème.

### Gestion des erreurs granulaires

Si vous avez besoin d'une gestion des erreurs plus spécifique, capturez directement les types d'erreurs spécifiques. **Évitez d'utiliser `OlostepServerError_BaseError` ou `OlostepClientError_BaseError`** - ces classes de base n'indiquent que qui a levé l'erreur (serveur vs client), pas qui est responsable de la corriger. C'est un détail d'implémentation qui n'aide pas avec la logique de gestion des erreurs.

Au lieu de cela, capturez les types d'erreurs spécifiques qui indiquent le problème réel :

```python theme={null}
from olostep import (
    AsyncOlostep,
    Olostep_BaseError,
    Olostep_APIConnectionError,
    OlostepServerError_AuthFailed,
    OlostepServerError_CreditsExhausted,
    OlostepClientError_NoAPIKey,
)

try:
    result = await client.scrapes.create(url_to_scrape="https://example.com")
except Olostep_APIConnectionError as e:
    print(f"Network error: {type(e).__name__}")
except OlostepServerError_AuthFailed:
    print("Invalid API key")
except OlostepServerError_CreditsExhausted:
    print("Credits exhausted")
except OlostepClientError_NoAPIKey:
    print("API key not provided")
except Olostep_BaseError as e:
    print(f"Error has occurred: {type(e).__name__}")
```

## Configuration

### Variables d'environnement

| Variable               | Description                      | Défaut                       |
| ---------------------- | -------------------------------- | ---------------------------- |
| `OLOSTEP_API_KEY`      | Votre clé API                    | Requis                       |
| `OLOSTEP_BASE_API_URL` | URL de base de l'API             | `https://api.olostep.com/v1` |
| `OLOSTEP_API_TIMEOUT`  | Timeout de la requête (secondes) | `150`                        |

## Obtenir de l'aide

* [Documentation complète](https://docs.olostep.com)
* [Slack Communautaire](https://join.slack.com/t/olostep-users/shared_invite/zt-2pn2ce0uu-~591qIdhAfJy~LXCWQS5UQ)
* [Email de support](mailto:info@olostep.com)

## Ressources

<CardGroup cols={2}>
  <Card title="Package PyPI" icon="python" href="https://pypi.org/project/olostep/">
    Voir sur PyPI
  </Card>

  <Card title="Obtenir une clé API" icon="key" href="https://www.olostep.com/auth">
    Inscrivez-vous gratuitement
  </Card>
</CardGroup>
