Reference

CaptchaAI en production : guide de gestion de la configuration

Une configuration solide pour CaptchaAI tient à une règle : ce qui change d'un environnement à l'autre ne doit jamais vivre dans le code. Clé API, concurrence, timeouts, proxy et polling se pilotent par variables d'environnement et fichiers de configuration : passer de la staging à la production ne demande aucun redéploiement.

Toutes les variables de configuration en un tableau

Voici les paramètres reconnus, avec leur variable d'environnement et leur valeur par défaut ; seule la clé API est obligatoire.

Paramètre Variable d'environnement Par défaut
Clé API (obligatoire) CAPTCHAAI_API_KEY
URL de soumission CAPTCHAAI_SUBMIT_URL https://ocr.captchaai.com/in.php
URL de polling CAPTCHAAI_POLL_URL https://ocr.captchaai.com/res.php
Intervalle de polling (s) CAPTCHAAI_POLL_INTERVAL 5
Tentatives de polling max CAPTCHAAI_MAX_POLLS 60
Concurrence CAPTCHAAI_CONCURRENCY 10
Timeout global (s) CAPTCHAAI_TIMEOUT 300
Proxy CAPTCHAAI_PROXY
URL de callback CAPTCHAAI_CALLBACK_URL
Tentatives (retry) CAPTCHAAI_RETRIES 3
Niveau de journalisation CAPTCHAAI_LOG_LEVEL info

Trois niveaux de priorité, du plus proche de l'opérateur au plus général

La valeur retenue vient de la couche la plus proche de l'exploitant : la variable d'environnement l'emporte sur le fichier de configuration, lui-même prioritaire sur les valeurs par défaut du code.

Priority (highest → lowest):

1. Environment variables     ← deployment-specific overrides
2. Config file (YAML/JSON)   ← version-controlled defaults
3. Application defaults      ← fallback values in code

Charger la configuration dans votre code

Python

import os
import yaml
from dataclasses import dataclass, field
from pathlib import Path


@dataclass
class CaptchaAIConfig:
    api_key: str = ""
    submit_url: str = "https://ocr.captchaai.com/in.php"
    poll_url: str = "https://ocr.captchaai.com/res.php"
    poll_interval: int = 5
    max_polls: int = 60
    concurrency: int = 10
    timeout: int = 300
    proxy: str = ""
    callback_url: str = ""
    retries: int = 3
    log_level: str = "info"

    @classmethod
    def load(cls, config_path=None):
        """Load config: env vars override file, which overrides defaults."""
        config = cls()

        # Layer 2: Config file
        if config_path and Path(config_path).exists():
            with open(config_path) as f:
                file_config = yaml.safe_load(f) or {}
            for key, value in file_config.items():
                if hasattr(config, key):
                    setattr(config, key, value)

        # Layer 1: Environment variables (highest priority)
        env_map = {
            "CAPTCHAAI_API_KEY": "api_key",
            "CAPTCHAAI_SUBMIT_URL": "submit_url",
            "CAPTCHAAI_POLL_URL": "poll_url",
            "CAPTCHAAI_POLL_INTERVAL": "poll_interval",
            "CAPTCHAAI_MAX_POLLS": "max_polls",
            "CAPTCHAAI_CONCURRENCY": "concurrency",
            "CAPTCHAAI_TIMEOUT": "timeout",
            "CAPTCHAAI_PROXY": "proxy",
            "CAPTCHAAI_CALLBACK_URL": "callback_url",
            "CAPTCHAAI_RETRIES": "retries",
            "CAPTCHAAI_LOG_LEVEL": "log_level",
        }

        for env_key, attr_name in env_map.items():
            value = os.environ.get(env_key)
            if value is not None:
                # Cast to correct type
                current = getattr(config, attr_name)
                if isinstance(current, int):
                    value = int(value)
                setattr(config, attr_name, value)

        config.validate()
        return config

    def validate(self):
        if not self.api_key:
            raise ValueError("CAPTCHAAI_API_KEY is required")
        if self.poll_interval < 1:
            raise ValueError("poll_interval must be >= 1")
        if self.concurrency < 1:
            raise ValueError("concurrency must be >= 1")


# Usage
config = CaptchaAIConfig.load("config/captchaai.yaml")
print(f"Concurrency: {config.concurrency}, Timeout: {config.timeout}s")

JavaScript

const fs = require("fs");
const yaml = require("js-yaml");
const path = require("path");

class CaptchaAIConfig {
  static defaults = {
    apiKey: "",
    submitUrl: "https://ocr.captchaai.com/in.php",
    pollUrl: "https://ocr.captchaai.com/res.php",
    pollInterval: 5,
    maxPolls: 60,
    concurrency: 10,
    timeout: 300,
    proxy: "",
    callbackUrl: "",
    retries: 3,
    logLevel: "info",
  };

  static envMap = {
    CAPTCHAAI_API_KEY: "apiKey",
    CAPTCHAAI_SUBMIT_URL: "submitUrl",
    CAPTCHAAI_POLL_URL: "pollUrl",
    CAPTCHAAI_POLL_INTERVAL: { key: "pollInterval", type: "int" },
    CAPTCHAAI_MAX_POLLS: { key: "maxPolls", type: "int" },
    CAPTCHAAI_CONCURRENCY: { key: "concurrency", type: "int" },
    CAPTCHAAI_TIMEOUT: { key: "timeout", type: "int" },
    CAPTCHAAI_PROXY: "proxy",
    CAPTCHAAI_CALLBACK_URL: "callbackUrl",
    CAPTCHAAI_RETRIES: { key: "retries", type: "int" },
    CAPTCHAAI_LOG_LEVEL: "logLevel",
  };

  static load(configPath = null) {
    let config = { ...CaptchaAIConfig.defaults };

    // Layer 2: Config file
    if (configPath && fs.existsSync(configPath)) {
      const ext = path.extname(configPath);
      const raw = fs.readFileSync(configPath, "utf8");
      const fileConfig = ext === ".json" ? JSON.parse(raw) : yaml.load(raw);
      config = { ...config, ...fileConfig };
    }

    // Layer 1: Environment variables
    for (const [envKey, mapping] of Object.entries(CaptchaAIConfig.envMap)) {
      const value = process.env[envKey];
      if (value !== undefined) {
        const attrKey = typeof mapping === "string" ? mapping : mapping.key;
        const type = typeof mapping === "string" ? "string" : mapping.type;
        config[attrKey] = type === "int" ? parseInt(value, 10) : value;
      }
    }

    CaptchaAIConfig.validate(config);
    return config;
  }

  static validate(config) {
    if (!config.apiKey) throw new Error("CAPTCHAAI_API_KEY is required");
    if (config.pollInterval < 1) throw new Error("pollInterval must be >= 1");
    if (config.concurrency < 1) throw new Error("concurrency must be >= 1");
  }
}

// Usage
const config = CaptchaAIConfig.load("config/captchaai.yaml");
console.log(`Concurrency: ${config.concurrency}, Timeout: ${config.timeout}s`);

Une configuration distincte par environnement

# config/captchaai.yaml — base
api_key: ""  # Always set via env var
concurrency: 5
poll_interval: 5
retries: 3
log_level: info
# config/captchaai.production.yaml
concurrency: 20
poll_interval: 3
timeout: 180
log_level: warning
# config/captchaai.staging.yaml
concurrency: 3
poll_interval: 5
timeout: 300
log_level: debug

Protéger les clés et les secrets

Ne stockez jamais votre clé API dans un fichier de configuration ni dans le dépôt ; masquez aussi les champs sensibles dans les logs.

Méthode Idéal pour Exemple
Variables d'environnement Conteneurs, CI/CD export CAPTCHAAI_API_KEY=abc123
AWS Secrets Manager Infrastructure AWS Rotation automatique
HashiCorp Vault Multi-cloud, sur site Secrets dynamiques avec TTL
Secrets Docker Docker Swarm / Compose Montés dans /run/secrets/
Fichier .env (dev uniquement) Développement local Bibliothèque dotenv

Injecter les secrets avec Docker Compose

services:
  captcha-worker:
    image: captcha-worker:latest
    environment:

      - CAPTCHAAI_API_KEY=${CAPTCHAAI_API_KEY}
      - CAPTCHAAI_CONCURRENCY=15
      - CAPTCHAAI_LOG_LEVEL=warning
    env_file:

      - .env.production

Activer ou désactiver des fonctions sans redéployer

class FeatureFlags:
    def __init__(self):
        self.flags = {
            "use_callback": os.environ.get("FF_USE_CALLBACK", "false") == "true",
            "enable_proxy": os.environ.get("FF_ENABLE_PROXY", "true") == "true",
            "max_concurrent": int(os.environ.get("FF_MAX_CONCURRENT", "10")),
        }

    def is_enabled(self, flag):
        return self.flags.get(flag, False)

    def get(self, flag, default=None):
        return self.flags.get(flag, default)

Checklist avant la mise en production

  • La clé API arrive par variable d'environnement, jamais depuis un fichier versionné.
  • La concurrence suit les threads de votre plan.
  • Les logs sont en warning et masquent les champs sensibles.
  • Le fichier .env reste hors du versionnement.

Hébergement des workers et conformité RGPD

Chez un hébergeur européen — OVHcloud, Scaleway ou une région AWS comme eu-west-3 (Paris) —, la configuration ne change pas : la clé API arrive toujours par variable d'environnement. Côté données, minimisez ce que vos logs conservent — un dump complet au démarrage finit par écrire la clé en clair — et vérifiez vos obligations RGPD dès que le pipeline traite des données personnelles.

FAQ

YAML ou JSON pour le fichier de configuration ?

Prenez YAML pour les fichiers édités à la main : il accepte les commentaires. Réservez JSON aux configurations générées par une machine ou à l'analyse stricte.

Peut-on modifier la concurrence sans redémarrer le worker ?

Oui, à condition de relire les paramètres à chaque lot de tâches, pas seulement au démarrage. Ajustez CAPTCHAAI_CONCURRENCY, puis envoyez un signal de rechargement.

Comment éviter que la clé API se retrouve dans les logs ?

Ne journalisez jamais l'objet de configuration complet. Masquez les champs sensibles avant affichage et gardez les logs en warning en production.

Faut-il un fichier de configuration par environnement, ou un seul ?

Un fichier de base versionné, plus un fichier par environnement qui ne surcharge que les différences. Chaque écart reste lisible en revue de code.

La configuration change-t-elle selon le type de CAPTCHA ?

Non : les mêmes variables couvrent tous les types, car CaptchaAI facture au thread simultané, pas à la résolution. Du forfait BASIC ($15/mois, 5 threads) aux paliers VIP, seule votre concurrence doit suivre les threads du plan.

Dépannage

Problème Cause Correctif
La clé API ne se charge pas Variable absente ou mal nommée Vérifiez echo $CAPTCHAAI_API_KEY
Le fichier de configuration est ignoré Mauvais chemin ou bibliothèque YAML manquante Installez pyyaml / js-yaml et vérifiez le chemin
La production utilise les réglages de dev Surcharge par environnement non appliquée Vérifiez NODE_ENV / APP_ENV et la priorité des variables
La clé apparaît dans les journaux Le dump de configuration inclut la clé API Masquez les champs sensibles dans les logs

Articles connexes

Prochaines étapes

Partez des modèles ci-dessus, puis créez une clé API CaptchaAI. Pour aller plus loin : la sécurité des clés API et le filtrage d'IP, la résolution avec Docker et l'architecture multi-régions.

Les commentaires sont désactivés pour cet article.