# Fichier: python_cheats/cheatsheets/httpie.txt
# Cheatsheet HTTPie - Guide Ultra-Détaillé pour Grands Débutants


[OK] CONCEPTS FONDAMENTAUX (EXPLICATIONS TRÈS DÉTAILLÉES)

# === QU'EST-CE QUE HTTPIE ? ===

# Imagine que tu veux tester une API (Application Programming Interface)
# Par exemple: l'API de Twitter, GitHub, ou ton propre serveur Flask
# Tu dois envoyer des requêtes HTTP (GET, POST, PUT, DELETE...)

# Solution classique (compliquée):
# 1. Utiliser curl (très compliqué avec plein d'options bizarres)
# 2. Écrire du code Python avec requests (long pour juste tester)
# 3. Utiliser Postman (lourd, interface graphique, pas pratique en CLI)

# HTTPIE = Outil en ligne de commande SIMPLE et LISIBLE!
# Tu tapes juste:
# http GET https://api.github.com/users/octocat
# Et BAM! Tu vois une belle réponse colorée et formatée!

# HTTPie rend les requêtes HTTP aussi simples que possible
# = Syntaxe intuitive, sortie colorée, debuggage facile


# === POURQUOI HTTPIE AU LIEU DE CURL ? ===

# CURL (l'ancien outil):
curl -X POST https://api.example.com/users \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer token123" \
  -d '{"name":"John","email":"john@example.com"}'
# = COMPLIQUÉ! Beaucoup d'options (-X, -H, -d)
# = Difficile à lire et à mémoriser

# HTTPIE (le nouveau):
http POST https://api.example.com/users \
  Authorization:"Bearer token123" \
  name=John email=john@example.com
# = SIMPLE! Naturel et intuitif
# = Facile à lire et comprendre

# Autres avantages HTTPie:
# - Sortie colorée (JSON bien formaté)
# - Détection automatique du Content-Type
# - Support des sessions (cookies persistants)
# - Téléchargement de fichiers facile
# - Syntaxe raccourcie pour localhost


# === VOCABULAIRE HTTP (TRÈS IMPORTANT!) ===

# HTTP = HyperText Transfer Protocol
# = Protocole de communication entre client (toi) et serveur (API)

# REQUÊTE (Request)
# = Message que TU envoies au serveur
# Contient:
#   - Méthode (GET, POST, PUT, DELETE...)
#   - URL (https://api.example.com/users)
#   - Headers (Authorization, Content-Type...)
#   - Body/Données (pour POST/PUT)

# RÉPONSE (Response)
# = Message que le SERVEUR te renvoie
# Contient:
#   - Status Code (200 OK, 404 Not Found, 500 Error...)
#   - Headers (Content-Type, Date...)
#   - Body/Données (JSON, HTML, texte...)

# MÉTHODES HTTP (Les actions possibles)

# GET = Récupérer des données
# Exemple: Lire la liste des utilisateurs
# http GET https://api.example.com/users

# POST = Créer de nouvelles données
# Exemple: Créer un nouvel utilisateur
# http POST https://api.example.com/users name=John

# PUT = Modifier des données existantes (remplacement complet)
# Exemple: Mettre à jour un utilisateur
# http PUT https://api.example.com/users/1 name=Jane

# PATCH = Modifier partiellement des données existantes
# Exemple: Modifier juste l'email d'un utilisateur
# http PATCH https://api.example.com/users/1 email=new@example.com

# DELETE = Supprimer des données
# Exemple: Supprimer un utilisateur
# http DELETE https://api.example.com/users/1

# HEAD = Comme GET mais sans le body (juste les headers)
# OPTIONS = Voir quelles méthodes sont supportées


# HEADERS (En-têtes)
# = Métadonnées de la requête/réponse
# Exemples courants:
#   - Content-Type: application/json (type de données)
#   - Authorization: Bearer token123 (authentification)
#   - User-Agent: HTTPie/3.2.1 (qui envoie la requête)
#   - Accept: application/json (type de réponse accepté)

# BODY (Corps)
# = Les données réelles envoyées/reçues
# Formats courants:
#   - JSON: {"name": "John", "age": 30}
#   - Form data: name=John&age=30
#   - Plain text: Juste du texte
#   - Files: Fichiers uploadés

# STATUS CODES (Codes de statut)
# = Nombre indiquant le résultat de la requête

# 2xx = Succès
#   - 200 OK: Tout va bien
#   - 201 Created: Ressource créée avec succès
#   - 204 No Content: Succès mais pas de contenu à renvoyer

# 3xx = Redirection
#   - 301 Moved Permanently: Ressource déplacée définitivement
#   - 302 Found: Redirection temporaire

# 4xx = Erreur client (ta faute!)
#   - 400 Bad Request: Requête mal formée
#   - 401 Unauthorized: Pas authentifié
#   - 403 Forbidden: Pas les permissions
#   - 404 Not Found: Ressource introuvable
#   - 429 Too Many Requests: Trop de requêtes (rate limit)

# 5xx = Erreur serveur (pas ta faute!)
#   - 500 Internal Server Error: Bug côté serveur
#   - 502 Bad Gateway: Problème de proxy
#   - 503 Service Unavailable: Serveur indisponible


# === COMMENT ÇA MARCHE? (FLUX COMPLET) ===

# 1. Tu tapes une commande HTTPie dans ton terminal:
http GET https://api.github.com/users/octocat

# 2. HTTPie construit une requête HTTP:
#    GET /users/octocat HTTP/1.1
#    Host: api.github.com
#    User-Agent: HTTPie/3.2.1
#    Accept: application/json

# 3. HTTPie envoie la requête au serveur GitHub

# 4. Le serveur GitHub traite la requête:
#    - Cherche l'utilisateur "octocat"
#    - Prépare les données JSON

# 5. Le serveur répond:
#    HTTP/1.1 200 OK
#    Content-Type: application/json
#    {
#      "login": "octocat",
#      "name": "The Octocat",
#      "bio": "GitHub mascot"
#    }

# 6. HTTPie reçoit la réponse et l'affiche:
#    - Colore le JSON
#    - Formate joliment
#    - Affiche les headers si demandé

# 7. Tu vois la réponse dans ton terminal!


[OK] INSTALLATION SUPER DÉTAILLÉE

# === ÉTAPE 1: VÉRIFIER SI PYTHON EST INSTALLÉ ===

# HTTPie nécessite Python 3.7+

# Vérifier la version Python:
python --version
# ou
python3 --version

# Doit afficher: Python 3.7.0 ou plus récent
# Exemple: Python 3.11.0

# Si Python n'est pas installé:
# - macOS: brew install python
# - Windows: https://www.python.org/downloads/
# - Linux: sudo apt install python3 python3-pip


# === ÉTAPE 2: INSTALLER HTTPIE ===

# HTTPie s'installe avec pip (le gestionnaire de packages Python)

# === MÉTHODE 1: Installation avec pip (RECOMMANDÉE) ===

# macOS/Linux:
pip3 install httpie

# Windows:
pip install httpie

# Alternative avec pip pour utilisateur uniquement (pas admin):
pip3 install --user httpie

# Cela télécharge et installe HTTPie
# Affiche:
# Collecting httpie
# Downloading httpie-3.2.1-py3-none-any.whl
# Successfully installed httpie-3.2.1

# Vérifier l'installation:
http --version
# Affiche: 3.2.1 (ou version plus récente)


# === MÉTHODE 2: Installation avec Homebrew (macOS/Linux) ===

# Si tu as Homebrew installé:
brew install httpie

# Vérifier:
http --version


# === MÉTHODE 3: Installation avec apt (Ubuntu/Debian) ===

# Mettre à jour les packages:
sudo apt update

# Installer HTTPie:
sudo apt install httpie

# Vérifier:
http --version


# === MÉTHODE 4: Installation avec dnf (Fedora) ===

sudo dnf install httpie


# === MÉTHODE 5: Installation depuis les sources ===

# Cloner le dépôt GitHub:
git clone https://github.com/httpie/httpie.git
cd httpie

# Installer:
pip install -e .

# Vérifier:
http --version


# === ÉTAPE 3: TESTER L'INSTALLATION ===

# Faire une requête de test simple:
http httpie.io/hello

# Doit afficher quelque chose comme:
# HTTP/1.1 200 OK
# Content-Type: application/json
# {
#     "hello": "world"
# }

# Si ça marche: HTTPie est bien installé!
# Si erreur: Vérifie que python et pip sont à jour


# === PROBLÈMES COURANTS D'INSTALLATION ===

# Problème 1: "command not found: http"
# Cause: HTTPie pas dans le PATH
# Solution:
# - Ajoute ~/.local/bin au PATH
# - Ou utilise: python -m httpie au lieu de http

# Problème 2: "Permission denied"
# Cause: Pas les droits d'installation
# Solution:
pip3 install --user httpie

# Problème 3: "No module named 'pip'"
# Cause: pip pas installé
# Solution:
# macOS/Linux: python3 -m ensurepip
# Windows: python -m ensurepip


[OK] SYNTAXE DE BASE (EXPLICATIONS TRÈS DÉTAILLÉES)

# === FORMAT GÉNÉRAL D'UNE COMMANDE HTTPIE ===

# Structure:
http [OPTIONS] [MÉTHODE] URL [ITEMS]

# Explications:

# [OPTIONS] = Flags pour modifier le comportement
# Exemples: --verbose, --download, --session=user1
# OPTIONNEL (peut être omis)

# [MÉTHODE] = Type de requête HTTP
# Exemples: GET, POST, PUT, DELETE, PATCH
# OPTIONNEL pour GET (méthode par défaut)

# URL = L'adresse de l'API
# Exemples: https://api.example.com/users, http://localhost:5000/
# OBLIGATOIRE

# [ITEMS] = Headers, paramètres, données JSON
# Exemples: name=John, Authorization:Bearer token
# OPTIONNEL


# === EXEMPLES DE BASE ===

# Exemple 1: Requête GET simple
http https://httpbin.org/get

# Explication:
# - Pas de OPTIONS
# - Pas de MÉTHODE (GET par défaut)
# - URL: https://httpbin.org/get
# - Pas d'ITEMS

# Exemple 2: Requête POST avec données
http POST https://httpbin.org/post name=John age=30

# Explication:
# - POST = méthode
# - URL: https://httpbin.org/post
# - name=John age=30 = données JSON envoyées


# === RACCOURCIS URL ===

# HTTPie a des raccourcis pour les URLs courantes

# Localhost avec port:
http :5000/api/users
# = http://localhost:5000/api/users

# Localhost sans port (port 80 par défaut):
http :/api/users
# = http://localhost/api/users

# HTTPS par défaut si domaine:
http example.com
# = https://example.com

# HTTP explicite:
http http://example.com


# === TYPES D'ITEMS (TRÈS IMPORTANT!) ===

# HTTPie utilise des symboles pour distinguer les types

# 1. HEADERS (En-têtes) avec ":"
# Syntaxe: Header-Name:value
# Exemple:
http https://httpbin.org/headers Authorization:"Bearer token123"

# Envoie:
# GET /headers HTTP/1.1
# Authorization: Bearer token123

# 2. QUERY PARAMETERS (Paramètres URL) avec "==" (double égal)
# Syntaxe: param==value
# Exemple:
http https://httpbin.org/get search==python limit==10

# Envoie:
# GET /get?search=python&limit=10 HTTP/1.1

# 3. JSON DATA (Données JSON) avec "="
# Syntaxe: field=value
# Exemple:
http POST https://httpbin.org/post name=John email=john@example.com

# Envoie:
# POST /post HTTP/1.1
# Content-Type: application/json
# {
#   "name": "John",
#   "email": "john@example.com"
# }

# 4. FORM DATA (Données formulaire) avec "="
# Syntaxe: --form field=value
# Exemple:
http --form POST https://httpbin.org/post name=John

# Envoie:
# POST /post HTTP/1.1
# Content-Type: application/x-www-form-urlencoded
# name=John

# 5. FILES (Fichiers) avec "@"
# Syntaxe: field@/path/to/file
# Exemple:
http --form POST https://httpbin.org/post photo@~/image.jpg

# 6. JSON NON-STRING avec ":="
# Syntaxe: field:=value
# Exemple (envoyer un nombre, booléen, array):
http POST https://httpbin.org/post age:=30 active:=true tags:='["python","api"]'

# Envoie:
# {
#   "age": 30,          # nombre, pas "30"
#   "active": true,      # booléen, pas "true"
#   "tags": ["python", "api"]  # array
# }

# 7. RAW JSON (JSON brut) avec ":="
# Syntaxe: field:=@file.json
# Exemple:
http POST https://httpbin.org/post data:=@payload.json


# === RÉSUMÉ DES SYMBOLES ===

# :   = Header          (Authorization:token)
# ==  = Query param     (search==python)
# =   = JSON string     (name=John)
# :=  = JSON non-string (age:=30)
# @   = File            (photo@image.jpg)
# =@  = Data from file  (data=@file.txt)
# :=@ = JSON from file  (json:=@data.json)


[OK] REQUÊTES GET (RÉCUPÉRER DES DONNÉES)

# === GET SIMPLE ===

# Récupérer des données d'une API

# Exemple 1: API publique GitHub
http GET https://api.github.com/users/octocat

# Raccourci (GET est la méthode par défaut):
http https://api.github.com/users/octocat

# Affiche:
# HTTP/1.1 200 OK
# Content-Type: application/json
# {
#     "login": "octocat",
#     "id": 583231,
#     "name": "The Octocat",
#     "bio": "GitHub mascot"
# }


# === GET AVEC QUERY PARAMETERS ===

# Les query parameters = paramètres dans l'URL
# Format: ?param1=value1&param2=value2

# Exemple: Rechercher des repos GitHub
http https://api.github.com/search/repositories q==python sort==stars

# Équivalent à:
# https://api.github.com/search/repositories?q=python&sort=stars

# Explications:
# q==python = paramètre "q" avec valeur "python"
# sort==stars = paramètre "sort" avec valeur "stars"
# Le "==" dit: "C'est un query parameter, pas du JSON"


# === GET AVEC HEADERS ===

# Les headers = métadonnées de la requête

# Exemple: Authentification avec token
http https://api.github.com/user \
  Authorization:"token ghp_xxxxxxxxxxxxx"

# Envoie:
# GET /user HTTP/1.1
# Authorization: token ghp_xxxxxxxxxxxxx

# Exemple: Accepter seulement du JSON
http https://api.example.com/data \
  Accept:"application/json"


# === GET AVEC PLUSIEURS QUERY PARAMS ===

# Combiner plusieurs paramètres

http https://api.example.com/products \
  category==electronics \
  min_price==100 \
  max_price==500 \
  sort==price \
  order==asc

# Équivalent à:
# https://api.example.com/products?category=electronics&min_price=100&max_price=500&sort=price&order=asc


# === GET LOCALHOST ===

# Tester ton propre serveur local

# Ton serveur Flask/Django sur port 5000:
http :5000/api/users

# Avec query params:
http :5000/api/users page==1 limit==10

# Avec headers:
http :5000/api/users Authorization:"Bearer mytoken"


[OK] REQUÊTES POST (CRÉER DES DONNÉES)

# === POST AVEC JSON (LE PLUS COURANT) ===

# Envoyer des données JSON au serveur

# Exemple: Créer un utilisateur
http POST https://httpbin.org/post \
  name=John \
  email=john@example.com \
  age:=30

# Explication:
# POST = méthode HTTP
# name=John = JSON string {"name": "John"}
# email=john@example.com = JSON string
# age:=30 = JSON number {"age": 30} (pas "30"!)

# Envoie automatiquement:
# POST /post HTTP/1.1
# Content-Type: application/


# Exemple complet: Créer un utilisateur avec tous les détails

http POST https://httpbin.org/post \
  name=John \
  email=john@example.com \
  age:=30 \
  is_active:=true \
  tags:='["python","api","testing"]' \
  preferences:='{"theme":"dark","notifications":true}'

# Explication détaillée:
# name=John = JSON string {"name": "John"}
# email=john@example.com = JSON string {"email": "john@example.com"}
# age:=30 = JSON number {"age": 30} (le := veut dire "valeur brute")
# is_active:=true = JSON boolean {"is_active": true}
# tags:='[...]' = JSON array (array = liste)
# preferences:='{}' = JSON object (objet = dictionnaire)

# HTTPie envoie automatiquement:
# POST /post HTTP/1.1
# Content-Type: application/json
#
# {
#   "name": "John",
#   "email": "john@example.com",
#   "age": 30,
#   "is_active": true,
#   "tags": ["python", "api", "testing"],
#   "preferences": {
#     "theme": "dark",
#     "notifications": true
#   }
# }


# === POST AVEC FORMULAIRE (form-data) ===

# Quand utiliser form-data au lieu de JSON?
# - Upload de fichiers
# - Formulaires HTML traditionnels
# - APIs qui demandent spécifiquement du form-data

# Syntaxe:
http --form POST https://httpbin.org/post \
  name=John \
  email=john@example.com

# Le flag --form dit: "Envoie en format formulaire, pas JSON!"

# HTTPie envoie:
# POST /post HTTP/1.1
# Content-Type: application/x-www-form-urlencoded
#
# name=John&email=john@example.com

# Différence avec JSON:
# - JSON: {"name": "John", "email": "john@example.com"}
# - Form: name=John&email=john@example.com (URL-encoded)


# === POST AVEC FICHIER ===

# Scénario: Tu veux uploader un fichier (image, PDF, etc)

# Exemple: Upload une photo de profil

http --form POST https://httpbin.org/post \
  photo@~/Desktop/image.jpg \
  name=John

# Explication:
# --form = utiliser form-data (obligatoire pour files)
# photo@~/Desktop/image.jpg = champ "photo" avec le fichier image.jpg
# name=John = champ "name" avec la valeur "John"

# Symbole @: dit à HTTPie "c'est un chemin vers un fichier"
# ~ = le dossier home de l'utilisateur (raccourci)

# HTTPie envoie:
# POST /post HTTP/1.1
# Content-Type: multipart/form-data; boundary=...
#
# --boundary--
# Content-Disposition: form-data; name="photo"; filename="image.jpg"
# [données binaires de l'image]
# --boundary--
# Content-Disposition: form-data; name="name"
#
# John
# --boundary--

# Autres exemples:
# Plusieurs fichiers:
http --form POST api.example.com/upload \
  document@~/file1.pdf \
  attachment@~/file2.txt

# Depuis le dossier actuel:
http --form POST api.example.com/upload photo@./image.jpg


# === POST AVEC DONNÉES DEPUIS UN FICHIER ===

# Scénario: Ton payload JSON est très gros et dans un fichier

# D'abord, créer un fichier JSON:
# payload.json:
# {
#   "title": "Mon premier article",
#   "content": "Ceci est un article très long...",
#   "tags": ["blog", "python", "api"]
# }

# Puis envoyer:
http POST https://api.example.com/articles < payload.json

# Ou:
http --json POST https://api.example.com/articles @payload.json

# Explication:
# < payload.json = redirect le fichier vers l'input de HTTPie
# @payload.json = dit à HTTPie "lis les données depuis ce fichier"

# HTTPie envoie le contenu EXACT du fichier comme body!


# === POST AVEC VARIABLES D'ENVIRONNEMENT ===

# Scénario: Tu as une clé API secrète dans une variable

# D'abord, définir la variable:
export API_TOKEN="sk_test_12345abcde"

# Puis l'utiliser dans HTTPie:
http POST https://api.example.com/users \
  Authorization:"Bearer $API_TOKEN" \
  name=John

# HTTPie substitue $API_TOKEN par sa valeur réelle!

# Affiche:
# Authorization: Bearer sk_test_12345abcde

# ATTENTION: Jamais mettre les tokens directement dans les scripts!
# Toujours les stocker dans des variables d'environnement


# === RÉPONSE POST (COMPRENDRE LA RÉPONSE) ===

# Quand tu fais une requête POST, le serveur répond:

http POST https://httpbin.org/post name=John age:=30

# HTTPie affiche:
# HTTP/1.1 200 OK              <- Status line (code 200 = succès)
# Content-Type: application/json  <- Response headers
# Date: Mon, 15 Jan 2024 19:10:00 GMT
# Server: gunicorn/20.1.0
#
# {                           <- Response body (JSON)
#   "args": {},
#   "data": "",
#   "files": {},
#   "form": {},
#   "json": {
#     "name": "John",
#     "age": 30
#   },
#   "url": "https://httpbin.org/post"
# }

# Explication:
# - Status 200 = tout va bien (ressource créée)
# - Status 201 = ressource créée avec succès (mieux!)
# - Status 400 = requête mal formée
# - Status 500 = erreur serveur


[OK] REQUÊTES PUT ET PATCH (MODIFIER DES DONNÉES)

# === DIFFÉRENCE PUT vs PATCH ===

# PUT = Remplacer COMPLÈTEMENT la ressource
# Exemple: Remplacer tout un utilisateur
# Si tu envoies seulement {"name": "Jane"}
# Tous les autres champs (email, age, etc) sont perdus!

# PATCH = Mettre à jour PARTIELLEMENT la ressource
# Exemple: Modifier juste le nom
# Les autres champs restent inchangés


# === PUT COMPLET ===

# Scénario: Remplacer complètement un utilisateur

http PUT https://api.example.com/users/123 \
  name=Jane \
  email=jane@example.com \
  age:=28

# HTTPie envoie:
# PUT /users/123 HTTP/1.1
# Content-Type: application/json
# {
#   "name": "Jane",
#   "email": "jane@example.com",
#   "age": 28
# }

# Important: Envoie TOUS les champs!
# Si tu oublies un champ, il sera supprimé/mis à null


# === PATCH PARTIEL (RECOMMANDÉ!) ===

# Scénario: Modifier juste le nom, garder le reste

http PATCH https://api.example.com/users/123 \
  name=Jane

# HTTPie envoie:
# PATCH /users/123 HTTP/1.1
# Content-Type: application/json
# {
#   "name": "Jane"
# }

# Avantage: Les autres champs restent inchangés!
# Serveur: "OK, change juste le nom, le rest stay like before"

# Exemple complet avec plusieurs modifications:
http PATCH https://api.example.com/users/123 \
  name=Jane \
  email=jane_new@example.com \
  is_verified:=true


# === EXEMPLE CONCRET: API RESTful ===

# Workflow complet CRUD (Create, Read, Update, Delete)

# 1. CRÉER (POST):
http POST https://api.example.com/posts \
  title="Mon premier article" \
  content="Contenu de l'article"

# Réponse:
# HTTP/1.1 201 Created
# { "id": 1, "title": "...", "content": "..." }

# 2. LIRE (GET):
http GET https://api.example.com/posts/1

# Réponse:
# HTTP/1.1 200 OK
# { "id": 1, "title": "...", "content": "..." }

# 3. METTRE À JOUR (PATCH):
http PATCH https://api.example.com/posts/1 \
  title="Mon article modifié"

# Réponse:
# HTTP/1.1 200 OK
# { "id": 1, "title": "Mon article modifié", "content": "..." }

# 4. SUPPRIMER (DELETE):
http DELETE https://api.example.com/posts/1

# Réponse:
# HTTP/1.1 204 No Content


[OK] REQUÊTES DELETE (SUPPRIMER DES DONNÉES)

# === DELETE SIMPLE ===

# Supprimer une ressource

http DELETE https://api.example.com/users/123

# HTTPie envoie:
# DELETE /users/123 HTTP/1.1

# Réponses possibles:
# - 204 No Content = suppression réussie, pas de contenu à retourner
# - 200 OK = suppression réussie, retour un message
# - 404 Not Found = utilisateur n'existe pas


# === DELETE AVEC AUTHENTIFICATION ===

# Scénario: Supprimer un utilisateur (besoin d'autorisation)

http DELETE https://api.example.com/users/123 \
  Authorization:"Bearer token_secret_123"

# Envoie le token pour prouver que tu as le droit de supprimer


# === DELETE AVEC QUERY PARAMETERS ===

# Scénario: Supprimer avec conditions

http DELETE https://api.example.com/posts \
  user_id==123 \
  older_than==30

# HTTPie envoie:
# DELETE /posts?user_id=123&older_than=30 HTTP/1.1

# Signifie: "Supprime les posts de l'utilisateur 123 plus vieux que 30 jours"


# === SUPPRIMER AVEC CONFIRMATION ===

# Certaines APIs demandent une confirmation

http DELETE https://api.example.com/account \
  password=my_password \
  confirm:=true

# Envoie le mot de passe et une confirmation pour plus de sécurité


[OK] OPTIONS & HEADERS AVANCÉS

# === VOIR LES HEADERS DE LA RÉPONSE ===

# Scénario: Tu veux voir les en-têtes (pas seulement le body)

http --headers https://api.example.com/users

# Ou le raccourci:
http -h https://api.example.com/users

# Affiche:
# HTTP/1.1 200 OK
# Content-Type: application/json
# Content-Length: 1234
# Date: Mon, 15 Jan 2024 19:10:00 GMT
# Server: nginx
# X-Custom-Header: value
# Set-Cookie: session=abc123; Path=/

# Explication des headers courants:
# Content-Type = type de contenu (application/json, text/html, etc)
# Content-Length = taille du body en bytes
# Date = quand la réponse a été envoyée
# Server = quel serveur a répondu
# Set-Cookie = cookies à sauvegarder
# X-Custom-Header = headers personnalisés (commencent par X-)


# === VER UNIQUEMENT LES HEADERS (PAS LE BODY) ===

http --headers https://api.example.com/users

# Affiche seulement les headers HTTP
# Utile pour vérifier les cookies, content-type, etc


# === VOIR LA REQUÊTE COMPLÈTE (VIA VERBOSE) ===

# Scénario: Tu veux voir EXACTEMENT ce que HTTPie envoie

http --verbose https://api.example.com/users name=John age:=30

# Ou le raccourci:
http -v https://api.example.com/users name=John age:=30

# Affiche:
# > GET /users HTTP/1.1    <- Ligne de requête
# > Host: api.example.com   <- Headers de requête
# > User-Agent: HTTPie/3.2.1
# > Authorization: Bearer token
# >
# > {"name": "John", "age": 30}  <- Body de requête
#
# < HTTP/1.1 200 OK         <- Status line réponse
# < Content-Type: application/json  <- Headers réponse
# <
# < {"id": 123, ...}        <- Body réponse

# Symboles:
# > = Requête (ce que tu envoies)
# < = Réponse (ce que tu reçois)


# === VER REQUÊTE ET RÉPONSE AVEC PLUS DE DÉTAILS ===

http --verbose --verbose https://api.example.com/users

# Ou:
http -vv https://api.example.com/users

# Affiche encore plus de détails:
# - Timing (combien de temps prend la requête)
# - Infos SSL/TLS
# - Détails de connexion


# === AJOUTER DES HEADERS PERSONNALISÉS ===

# Scénario: Ajouter un header custom pour une API

http https://api.example.com/users \
  X-Custom-Header:"custom-value" \
  X-Request-ID:"req-12345" \
  User-Agent:"Mon-App/1.0"

# Syntaxe: Header-Name:value

# HTTPie envoie:
# GET /users HTTP/1.1
# X-Custom-Header: custom-value
# X-Request-ID: req-12345
# User-Agent: Mon-App/1.0

# Headers courants à ajouter:
# User-Agent: Identifier ton app
# X-API-Key: Clé API
# Accept-Language: Langue préférée
# Referer: Page d'origine


# === AUTHENTIFICATION BASIQUE ===

# Scénario: L'API demande username et password

# Syntaxe: --auth username:password
http --auth john:password123 https://api.example.com/profile

# HTTPie encode automatiquement en Base64 et ajoute:
# Authorization: Basic am9objpwYXNzd29yZDEyMw==

# Équivalent à:
http https://api.example.com/profile \
  Authorization:"Basic am9objpwYXNzd29yZDEyMw=="

# ATTENTION: Le mot de passe est visible dans l'historique bash!
# Mieux: Utiliser une variable d'environnement
http --auth $USERNAME:$PASSWORD https://api.example.com/profile


# === AUTHENTIFICATION BEARER TOKEN (PLUS COURANT) ===

# Scénario: L'API utilise des tokens Bearer (OAuth, JWT, etc)

http https://api.example.com/profile \
  Authorization:"Bearer eyJhbGciOiJIUzI1NiIs..."

# Ou plus court (HTTPie a un raccourci):
http --auth-type bearer --auth "token-value" https://api.example.com/profile


# === GÉRER LES COOKIES ===

# Scénario: Une API utilise des sessions/cookies

# HTTPie gère automatiquement les cookies!
# Pas besoin de faire quoi que ce soit

# Exemple:
http POST https://api.example.com/login email=john@example.com password=pass123
# Réponse: Set-Cookie: session=abc123

# Ensuite, HTTPie envoie automatiquement le cookie:
http https://api.example.com/profile
# HTTPie ajoute: Cookie: session=abc123


# === IGNORER LES ERREURS SSL ===

# ATTENTION: À utiliser SEULEMENT en développement!
# En production, JAMAIS ignorer SSL!

http --verify=no https://api-mauvais-certificat.example.com/users

# Ou:
http --insecure https://api-mauvais-certificat.example.com/users

# Permet de tester même si le certificat SSL est invalide


# === DÉFINIR UN TIMEOUT ===

# Scénario: L'API est lente, tu veux pas attendre 30 secondes

http --timeout=10 https://api-lente.example.com/users
# Attendre max 10 secondes, sinon erreur

http --timeout=5.5 https://api.example.com/users
# Timeout de 5.5 secondes


[OK] PARAMÈTRES D'URL & QUERY STRINGS (TRÈS DÉTAILLÉ)

# === DIFFÉRENCE URL PARAMETERS vs QUERY STRINGS ===

# URL PARAMETERS (dans le chemin):
http https://api.example.com/users/123/posts/456

# - users = ressource
# - 123 = identifiant de l'utilisateur
# - posts = sous-ressource
# - 456 = identifiant du post

# QUERY STRINGS (après le ?):
http https://api.example.com/users?page=1&limit=10

# - page=1 = paramètre
# - limit=10 = paramètre

# Avec HTTPie:
http https://api.example.com/users page==1 limit==10

# Les == signifient: "C'est un query parameter, pas du JSON"


# === QUERY PARAMETERS COMPLEXES ===

# Paramètres multiples:
http https://api.example.com/search \
  q==python \
  category==tutorials \
  sort==popularity \
  order==desc \
  limit==20

# Équivalent à:
# https://api.example.com/search?q=python&category=tutorials&sort=popularity&order=desc&limit=20

# HTTPie encode automatiquement les caractères spéciaux:
http https://api.example.com/search \
  q=="hello world"  # l'espace devient %20

# Équivalent à:
# https://api.example.com/search?q=hello%20world


# === QUERY PARAMETERS AVEC ARRAYS ===

# Certaines APIs acceptent des arrays en query params:

http https://api.example.com/users \
  ids==1 \
  ids==2 \
  ids==3

# Envoie:
# https://api.example.com/users?ids=1&ids=2&ids=3

# Ou HTTPie le fait automatiquement:
http https://api.example.com/users ids==1,2,3

# Dépend de l'API


# === PARAMÈTRES DANS L'URL ===

# Scénario: Récupérer un utilisateur spécifique

http https://api.example.com/users/123

# Scénario: Récupérer les posts d'un utilisateur

http https://api.example.com/users/123/posts

# Scénario: Récupérer un post spécifique d'un utilisateur

http https://api.example.com/users/123/posts/456


# === COMBINAISON URL PARAMETERS + QUERY STRINGS ===

# Très courant dans les APIs réelles!

http https://api.example.com/users/123/posts \
  sort==date \
  order==desc \
  limit==10

# Envoie:
# GET /users/123/posts?sort=date&order=desc&limit=10 HTTP/1.1

# Signifie: "Récupère les posts de l'utilisateur 123, triés par date descendante, max 10"


[OK] GESTION DES FICHIERS & TÉLÉCHARGEMENTS

# === TÉLÉCHARGER UN FICHIER ===

# Scénario: L'API retourne un fichier (PDF, image, etc)

# Télécharger et afficher:
http https://api.example.com/files/document.pdf

# Affiche le contenu binaire (pas très lisible!)

# Mieux: Télécharger dans un fichier

http --download https://api.example.com/files/document.pdf

# Ou le raccourci:
http -d https://api.example.com/files/document.pdf

# HTTPie:
# 1. Télécharge le fichier
# 2. Le sauvegarde avec le bon nom (document.pdf)
# 3. Affiche une barre de progression
# 4. Affiche: "Downloaded to /path/to/document.pdf"

# Spécifier le nom du fichier:
http --download https://api.example.com/files/document \
  --output=my_document.pdf

# Ou:
http -d https://api.example.com/files/document -o my_document.pdf


# === TÉLÉCHARGER PLUSIEURS FICHIERS ===

# D'une requête GET (si l'API retourne une archive):
http --download https://api.example.com/export --output=data.zip

# De requêtes multiples:
http -d https://api.example.com/file1.pdf -o file1.pdf
http -d https://api.example.com/file2.pdf -o file2.pdf
http -d https://api.example.com/file3.pdf -o file3.pdf


# === PROGRESSION DE TÉLÉCHARGEMENT ===

# HTTPie affiche automatiquement une barre de progression:
# Downloaded to document.pdf
# |████████████████████████████████| 100% 1.5 MB / 1.5 MB


# === UPLOADER PLUSIEURS FICHIERS ===

# Scénario: L'API accepte plusieurs fichiers dans une requête

http --form POST https://api.example.com/upload \
  file@./document1.pdf \
  file@./document2.pdf \
  file@./image.jpg \
  description="Mes fichiers"

# HTTPie envoie tout dans une seule requête multipart/form-data


# === UPLOADER AVEC CONTENT-TYPE CUSTOM ===

# Certaines APIs demandent un content-type spécifique pour les files

http --form POST https://api.example.com/upload \
  document@./file.pdf;type=application/pdf \
  name=John

# Le ";type=..." spécifie le MIME type du fichier


[OK] SESSIONS & COOKIES PERSISTANTS

# === CRÉER UNE SESSION ===

# Scénario: Tu dois faire plusieurs requêtes authentifiées
# Stocker manuellement les cookies est pénible!

# HTTPie peut sauvegarder les sessions automatiquement

# Première requête (avec login):
http --session=my_session POST https://api.example.com/login \
  email=john@example.com \
  password=password123

# Affiche:
# HTTP/1.1 200 OK
# Set-Cookie: session=abc123xyz
# { "token": "...", "user": "John" }

# HTTPie sauvegarde:
# - Le cookie session=abc123xyz
# - Le token
# - Tous les headers et cookies

# Fichier sauvegardé: ~/.config/httpie/sessions/api.example.com/my_session.json


# === UTILISER UNE SESSION SAUVEGARDÉE ===

# Toutes les requêtes suivantes utilisent la session:

http --session=my_session https://api.example.com/profile

# HTTPie:
# 1. Lit la session sauvegardée
# 2. Utilise le cookie session=abc123xyz
# 3. Le serveur te reconnaît automatiquement!

# Sans avoir à passer l'authentification à chaque fois!


# === EXEMPLE COMPLET: WORKFLOW AVEC SESSION ===

# 1. LOGIN et création de session:
http --session=work POST https://api.example.com/login \
  email=user@example.com \
  password=secure_password

# Réponse: Cookie + Token sauvegardés

# 2. Utiliser la session (les requêtes suivantes):
http --session=work https://api.example.com/profile
# Tu vois ton profil!

http --session=work POST https://api.example.com/posts \
  title="Mon article"
# Crée un post!

http --session=work https://api.example.com/profile
# Voir la liste de tes posts!

# 3. LOGOUT (supprimer la session):
http --session=work POST https://api.example.com/logout
# Puis:
rm ~/.config/httpie/sessions/api.example.com/work.json


# === PARAMÈTRES DE SESSION ===

# Sessions spécifiques à un type d'authentification:

# Session pour tests (pas de sécurité):
http --session=dev_session https://api.example.com/

# Session pour production (SSL strict):
http --session=prod_session --verify=yes https://api.example.com/

# Voir toutes les sessions sauvegardées:
ls ~/.config/httpie/sessions/


[OK] OPTIONS & FLAGS UTILES

# === FLAG: --pretty (formatage) ===

# Par défaut, HTTPie formate joliment le JSON
http https://api.example.com/users

# Affiche coloré et indenté:
# {
#   "users": [
#     { "id": 1, "name": "John" }
#   ]
# }

# Désactiver le formatage (JSON brut):
http --pretty=none https://api.example.com/users
# Affiche: {"users":[{"id":1,"name":"John"}]}

# Forcer le formatage sur réponse pas JSON:
http --pretty=all https://api.example.com/data


# === FLAG: --raw (ignorer le traitement) ===

# HTTPie traite normalement le contenu
http --raw https://api.example.com/text

# --raw dit: "Affiche tel quel, pas de coloration"


# === FLAG: --stream (streaming) ===

# Scénario: L'API envoie beaucoup de données

http --stream https://api.example.com/large-file

# HTTPie affiche les données AU FUR ET À MESURE
# Sans attendre la fin de la requête


# === FLAG: --continue (ignorer les erreurs) ===

# Scénario: Tu fais plusieurs requêtes et une échoue

# Normalement, HTTPie s'arrête à la première erreur
http GET https://api.example.com/valid
http GET https://api.example.com/invalid  # Erreur!
http GET https://api.example.com/valid2   # Pas exécuté

# Avec --continue:
http --continue GET https://api.example.com/valid
http --continue GET https://api.example.com/invalid  # Erreur, mais continue
http --continue GET https://api.example.com/valid2   # Exécuté!


# === FLAG: --check-status ===

# Par défaut, HTTPie affiche les erreurs mais exit avec code 0

http https://api.example.com/404  # Erreur 404 mais exit code 0

# Avec --check-status:
http --check-status https://api.example.com/404  # Exit code 1 si erreur!

# Utile pour les scripts bash:
http --check-status https://api.example.com/users || echo "Erreur!"


# === FLAG: --follow (redirection) ===

# Par défaut, HTTPie suit les redirections (301, 302)

# Désactiver:
http --follow=no https://old-api.example.com/users

# Limiter le nombre de redirections:
http --max-redirects=5 https://api.example.com/users


# === FLAG: --timeout ===

# Déjà vu avant:
http --timeout=10 https://slow-api.example.com/users


# === FLAG: --proxy ===

# Utiliser un proxy:
http --proxy=http://proxy.example.com:8080 https://api.example.com/users

# Proxy socks5:
http --proxy=socks5://proxy.example.com:1080 https://api.example.com/users


# === FLAG: --cert & --cert-key ===

# Utiliser un certificat client:
http --cert=./cert.pem --cert-key=./key.pem https://api.example.com/

# Certaines APIs demandent un certificat au lieu d'un username/password


# === VOIR LA VERSION ===

http --version
# Affiche: 3.2.1


# === VOIR L'AIDE ===

http --help
# Affiche toutes les options disponibles

http --help | less
# Afficher avec pagination


[OK] ASTUCES & BONNES PRATIQUES

# === ASTUCES DE SYNTAXE ===

# 1. Pas d'espace après les symboles:
http :5000/api/users name=John  # Correct
http :5000 /api/users name=John  # ERREUR

# 2. Guillemets si la valeur a des espaces:
http https://api.example.com search="hello world"
# Au lieu de: http https://api.example.com search=hello world (2 paramètres!)

# 3. Échapper les caractères spéciaux:
http https://api.example.com email="test@example.com"
http https://api.example.com query="a&b=c"  # & échappé par les guillemets


# === LIRE À PARTIR DE STDIN ===

# Piping avec d'autres commandes:

echo '{"name":"John"}' | http POST https://api.example.com/users

# Les données viennent de echo au lieu de la ligne de commande


# === ENREGISTRER LA RÉPONSE DANS UN FICHIER ===

# Redirection standard bash:
http https://api.example.com/users > response.json

# HTTPie enregistre TOUT (headers + body)

# Juste le body (avec jq):
http https://api.example.com/users | jq . > response.json


# === VÉRIFIER SI L'API EST EN LIGNE ===

# Scénario: Tu veux tester juste la connexion
http --head https://api.example.com/health

# HEAD = comme GET mais sans le body
# Réponse: HTTP/1.1 200 OK (rapide!)


# === FAIRE DES REQUÊTES RÉPÉTÉES ===

# Scénario: Tester la performance

# Une seule fois:
http https://api.example.com/users

# Plusieurs fois (script bash):
for i in {1..10}; do
  http https://




[OK] JSON COMPLEXE & DONNÉES IMBRIQUÉES (TRÈS DÉTAILLÉ)

# === STRUCTURES JSON SIMPLES ===

# Rappel: = pour strings, := pour non-strings

http POST https://api.example.com/users \
  name=John \
  email=john@example.com \
  age:=30

# Envoie:
# {"name": "John", "email": "john@example.com", "age": 30}


# === OBJETS JSON IMBRIQUÉS ===

# Scénario: Créer un utilisateur avec adresse (objet imbriqué)

http POST https://api.example.com/users \
  name=John \
  address:='{"street":"123 Main St","city":"New York","zip":"10001"}'

# Explication:
# address:= dit "c'est du JSON brut"
# '{"street":"..."}' = l'objet JSON (entre guillemets simples pour bash)

# HTTPie envoie:
# {
#   "name": "John",
#   "address": {
#     "street": "123 Main St",
#     "city": "New York",
#     "zip": "10001"
#   }
# }


# === ARRAYS (LISTES) DANS JSON ===

# Scénario: Créer un utilisateur avec une liste de tags

http POST https://api.example.com/users \
  name=John \
  tags:='["python","api","testing"]'

# HTTPie envoie:
# {
#   "name": "John",
#   "tags": ["python", "api", "testing"]
# }

# Accéder à un élément du array (si JSON accepte):
# Certaines APIs acceptent des chemins comme: tags[0]=python


# === ARRAYS D'OBJETS (TRÈS COURANT!) ===

# Scénario: Créer une commande avec plusieurs produits

http POST https://api.example.com/orders \
  order_id=ORD-123 \
  customer=John \
  items:='[{"product":"Laptop","qty":1,"price":999.99},{"product":"Mouse","qty":2,"price":29.99}]'

# HTTPie envoie:
# {
#   "order_id": "ORD-123",
#   "customer": "John",
#   "items": [
#     {"product": "Laptop", "qty": 1, "price": 999.99},
#     {"product": "Mouse", "qty": 2, "price": 29.99}
#   ]
# }


# === VALEURS NULL ET VIDES ===

# Envoyer null (valeur vide):
http POST https://api.example.com/users \
  name=John \
  bio:=null

# HTTPie envoie:
# {"name": "John", "bio": null}

# Envoyer une string vide:
http POST https://api.example.com/users \
  name=John \
  bio=""

# HTTPie envoie:
# {"name": "John", "bio": ""}


# === BOOLÉENS (true/false) ===

# Important: Utiliser := pour les booléens!

http POST https://api.example.com/users \
  name=John \
  is_active:=true \
  is_admin:=false

# HTTPie envoie:
# {"name": "John", "is_active": true, "is_admin": false}

# ERREUR COURANTE:
http POST https://api.example.com/users \
  name=John \
  is_active=true  # MAUVAIS! Envoie "true" comme string

# HTTPie envoie (INCORRECT):
# {"name": "John", "is_active": "true"}  # String au lieu de booléen!


# === NOMBRES (INT, FLOAT) ===

# Entiers:
http POST https://api.example.com/products \
  name="Laptop" \
  stock:=50 \
  price:=999.99

# HTTPie envoie:
# {"name": "Laptop", "stock": 50, "price": 999.99}

# Nombres négatifs:
http POST https://api.example.com/transactions \
  amount:=-100.50

# HTTPie envoie:
# {"amount": -100.50}


# === CRÉER UN JSON DEPUIS UN FICHIER ===

# Créer d'abord un fichier: user_data.json
# {
#   "name": "John",
#   "email": "john@example.com",
#   "address": {
#     "street": "123 Main St",
#     "city": "New York"
#   },
#   "tags": ["python", "api"]
# }

# Puis envoyer:
http POST https://api.example.com/users < user_data.json

# HTTPie lit le fichier complet et l'envoie comme body


# === UTILISER JQ POUR CONSTRUIRE JSON COMPLEXE ===

# Scénario: Les données sont complexes, tu utilises jq

# Créer le JSON avec jq:
jq -n '{name:"John",age:30,tags:["python","api"]}' | \
http POST https://api.example.com/users

# jq crée le JSON, HTTPie l'envoie


[OK] ERREURS HTTP COURANTES & SOLUTIONS

# === ERREUR 400: BAD REQUEST ===

# Cause: Ta requête est mal formée
http POST https://api.example.com/users \
  name=John \
  email="pas-un-email"  # Format email invalide?

# Réponse:
# HTTP/1.1 400 Bad Request
# {
#   "error": "Invalid email format"
# }

# Solutions:
# 1. Vérifier le format des données
# 2. Lire le message d'erreur du serveur
# 3. Consulter la documentation de l'API


# === ERREUR 401: UNAUTHORIZED ===

# Cause: Tu n'es pas authentifié
http https://api.example.com/profile

# Réponse:
# HTTP/1.1 401 Unauthorized
# {
#   "error": "Missing authentication token"
# }

# Solution:
http https://api.example.com/profile \
  Authorization:"Bearer token_valid_123"


# === ERREUR 403: FORBIDDEN ===

# Cause: Tu n'as pas les permissions
http DELETE https://api.example.com/users/456 \
  Authorization:"Bearer token_user_normal"

# Réponse:
# HTTP/1.1 403 Forbidden
# {
#   "error": "Only admins can delete users"
# }

# Solution: Utiliser un compte avec plus de permissions


# === ERREUR 404: NOT FOUND ===

# Cause: La ressource n'existe pas
http https://api.example.com/users/99999

# Réponse:
# HTTP/1.1 404 Not Found
# {
#   "error": "User not found"
# }

# Solutions:
# 1. Vérifier l'ID/URL
# 2. S'assurer que la ressource existe vraiment


# === ERREUR 409: CONFLICT ===

# Cause: Données en conflit (ex: email déjà utilisé)
http POST https://api.example.com/users \
  name=John \
  email=existing@example.com  # Cet email existe déjà

# Réponse:
# HTTP/1.1 409 Conflict
# {
#   "error": "Email already registered"
# }

# Solution: Utiliser un email différent


# === ERREUR 429: TOO MANY REQUESTS (RATE LIMITING) ===

# Cause: Tu fais trop de requêtes trop vite
for i in {1..1000}; do
  http https://api.example.com/users
done

# Réponse:
# HTTP/1.1 429 Too Many Requests
# {
#   "error": "Rate limit exceeded",
#   "retry_after": 60
# }

# Solution:
# 1. Attendre avant de relancer
# 2. Réduire la fréquence des requêtes
# 3. Respecter les limites de l'API
# 4. Implémenter un système de queue (attente)


# === ERREUR 500: INTERNAL SERVER ERROR ===

# Cause: Bug côté serveur (pas ta faute!)
http https://api.example.com/users

# Réponse:
# HTTP/1.1 500 Internal Server Error
# {
#   "error": "Something went wrong on our end"
# }

# Solutions:
# 1. Attendre que le serveur soit réparé
# 2. Contacter le support de l'API
# 3. Vérifier le statut du service (status page)


# === DÉBOGUER LES ERREURS ===

# Mode verbose pour voir la requête exacte:
http --verbose POST https://api.example.com/users \
  name=John \
  email=john@example.com

# Affiche:
# > POST /users HTTP/1.1
# > Host: api.example.com
# > Content-Type: application/json
# >
# > {"name":"John","email":"john@example.com"}
#
# < HTTP/1.1 400 Bad Request
# < {"error": "..."}

# Mode verbose très détaillé:
http -vv POST https://api.example.com/users \
  name=John \
  email=john@example.com

# Affiche aussi les headers SSL, timing, etc


[OK] AUTHENTIFICATION AVANCÉE

# === BEARER TOKEN (JWT, OAuth) ===

# Format standard pour les API modernes

http https://api.example.com/profile \
  Authorization:"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

# Explication:
# - Authorization = nom du header
# - Bearer = type d'authentification
# - eyJ... = le token (JWT, OAuth token, etc)

# Token court (pour l'exemple):
http https://api.example.com/profile \
  Authorization:"Bearer sk_live_12345abcde"


# === API KEY ===

# Certaines APIs utilisent des clés au lieu de tokens

# Format 1: Header personnalisé
http https://api.example.com/users \
  X-API-Key:"sk_test_12345abcde"

# Format 2: Query parameter
http https://api.example.com/users \
  api_key==sk_test_12345abcde

# Format 3: Header Authorization
http https://api.example.com/users \
  Authorization:"ApiKey sk_test_12345abcde"

# Dépend de l'API, consulter la documentation


# === AUTHENTIFICATION DIGEST ===

# Plus rare, mais utilisée par certaines APIs

http --auth-type digest --auth john:password123 \
  https://api.example.com/profile

# HTTPie gère automatiquement le handshake Digest


# === STOCKER LES TOKENS DE MANIÈRE SÉCURISÉE ===

# MAUVAIS: Mettre le token directement dans le script
http https://api.example.com/profile \
  Authorization:"Bearer sk_live_abc123"  # VISIBLE dans l'historique bash!

# BON 1: Variable d'environnement
export API_TOKEN="sk_live_abc123"
http https://api.example.com/profile \
  Authorization:"Bearer $API_TOKEN"

# BON 2: Fichier .env (non-git)
# Créer .env:
# API_TOKEN=sk_live_abc123

# Puis charger:
source .env
http https://api.example.com/profile \
  Authorization:"Bearer $API_TOKEN"

# BON 3: Session HTTPie
http --session=myapi POST https://api.example.com/login \
  api_key=sk_live_abc123

# Ensuite utiliser la session sans passer la clé:
http --session=myapi https://api.example.com/profile


[OK] WORKING WITH FORMS & FILE UPLOADS

# === FORM-DATA vs JSON (RAPPEL) ===

# JSON (par défaut):
http POST https://api.example.com/users \
  name=John \
  email=john@example.com

# Content-Type: application/json
# Body: {"name":"John","email":"john@example.com"}

# Form-data:
http --form POST https://api.example.com/users \
  name=John \
  email=john@example.com

# Content-Type: application/x-www-form-urlencoded
# Body: name=John&email=john@example.com


# === UPLOADER UN FICHIER (CAS COURANT) ===

# Scénario: Formulaire avec photo de profil

http --form POST https://api.example.com/profile/upload \
  photo@~/Downloads/profile.jpg \
  name=John

# Explication:
# --form = utiliser form-data
# photo@ = nom du champ formulaire
# ~/Downloads/profile.jpg = chemin du fichier

# HTTPie envoie:
# POST /profile/upload HTTP/1.1
# Content-Type: multipart/form-data; boundary=...
#
# --boundary--
# Content-Disposition: form-data; name="photo"; filename="profile.jpg"
# [données binaires de l'image]
# --boundary--
# Content-Disposition: form-data; name="name"
#
# John
# --boundary--


# === UPLOADER PLUSIEURS FICHIERS ===

# Scénario: Uploader plusieurs photos

http --form POST https://api.example.com/gallery/upload \
  files@~/photo1.jpg \
  files@~/photo2.jpg \
  files@~/photo3.jpg \
  title="Mon album"

# Certaines APIs acceptent plusieurs fichiers avec le même nom


# === UPLOADER AVEC TEXTE ENRICHI ===

# Scénario: Formulaire avec texte long (description)

http --form POST https://api.example.com/posts/create \
  title="Mon article" \
  content@~/article.txt \
  tags="python,api"

# content@= lit le fichier et l'envoie comme champ de formulaire


# === GÉRER LES UPLOADS VOLUMINEUX ===

# Scénario: Uploader une vidéo de 500MB

# Avec --stream (affiche la progression):
http --form POST https://api.example.com/upload \
  video@~/videos/big_video.mp4 \
  --stream

# Affiche:
# Upload: 0% [............................] 250MB/500MB

# Avec timeout adapté:
http --timeout=300 --form POST https://api.example.com/upload \
  video@~/videos/big_video.mp4

# 300 secondes = 5 minutes de timeout


# === RÉSOUDRE LES ERREURS D'UPLOAD ===

# Erreur: "File not found"
http --form POST https://api.example.com/upload \
  photo@~/nonexistent.jpg
# Vérifier le chemin!

# Erreur: "File too large"
# - Vérifier les limites d'upload de l'API
# - Compresser le fichier (image, vidéo)
# - Demander une limite supérieure

# Erreur: "Invalid file type"
http --form POST https://api.example.com/upload \
  photo@~/file.txt  # Pas une image!
# Utiliser:
create_user "John" "john@example.com"
list_users


# === BON: Tester avant de deployer ===

# Sur ta machine locale d'abord:
http :5000/api/test data=example

# Sur le serveur de test:
http https://staging.api.example.com/test data=example

# Seulement après, sur la production:
http https://api.example.com/test data=example


# === BON: Utiliser des variables pour les URLs ===

# Au lieu de:
http POST https://api.example.com/users name=John
http GET https://api.example.com/users
http DELETE https://api.example.com/users/1

# Mieux:
API="https://api.example.com"
http POST $API/users name=John
http GET $API/users
http DELETE $API/users/1

# Ou pour plusieurs environnements:
export ENV="staging"
export API="https://$ENV.api.example.com"


# === BON: Vérifier les status codes ===

# Dans un script:
if http --check-status POST https://api.example.com/users \
    name=John > /dev/null 2>&1; then
  echo "[OK] Utilisateur créé"
else
  echo "[X] Erreur lors de la création"
fi


# === MAUVAIS: Mettre des tokens dans les scripts ===

# [X] JAMAIS FAIRE:
http https://api.example.com/profile \
  Authorization:"Bearer sk_live_secret_123"

# [OK] FAIRE AU LIEU:
export API_TOKEN="sk_live_secret_123"
http https://api.example.com/profile \
  Authorization:"Bearer $API_TOKEN"


# === MAUVAIS: Ignorer les erreurs ===

# [X] MAUVAIS:
http POST https://api.example.com/users name=John 2>/dev/null
# Erreur silencieuse!

# [OK] BON:
if ! http --check-status POST https://api.example.com/users name=John; then
  echo "Erreur: impossible de créer l'utilisateur"
  exit 1
fi


# === BON: Documenter l'API avec des commentaires ===

# Récupérer l'utilisateur courant
# GET /profile
# Headers: Authorization: Bearer token
http https://api.example.com/profile \
  Authorization:"Bearer $API_TOKEN"

# Créer un nouvel utilisateur
# POST /users
# Body: name (string), email (string), age (number optional)
http POST https://api.example.com/users \
  name=John \
  email=john@example.com \
  age:=30


[OK] RESSOURCES & AIDE

# === AIDE RAPIDE ===

http --help
# Affiche TOUTES les options

http --help | less
# Affiche avec pagination


# === EXEMPLES FOURNIS PAR HTTPIE ===

http --debug https://api.example.com/users
# Affiche les infos de debug


# === DOCUMENTATION OFFICIELLE ===

# Site: https://httpie.io
# GitHub: https://github.com/httpie/httpie
# Doc: https://httpie.io/docs


# === TESTS AVEC HTTPBIN (BONNE PRATIQUE!) ===

# httpbin.org = serveur de test pour API
# Parfait pour apprendre HTTPie sans avoir une API réelle

# Test GET:
http https://httpbin.org/get

# Test POST:
http POST https://httpbin.org/post name=John email=john@example.com

# Test avec headers:
http https://httpbin.org/headers X-Custom:"test"

# Test avec query params:
http https://httpbin.org/get page==1 limit==10

# Test avec fichier:
http --form POST https://httpbin.org/post file@~/test.txt

# Test DELETE:
http DELETE https://httpbin.org/delete id==123

# Test les status codes:
http https://httpbin.org/status/404  # Simule 404
http https://httpbin.org/status/500  # Simule 500

# Test rate limiting:
http https://httpbin.org/delay/5     # Répond après 5 secondes


# === PRATIQUE AVEC DES APIS PUBLIQUES ===

# GitHub API (sans authentification):
http https://api.github.com/users/torvalds

# OpenWeather API (gratuit avec clé):
http https://api.openweathermap.org/data/2.5/weather \
  q==Paris \
  appid==YOUR_API_KEY

# JSONPlaceholder (API gratuite de test):
http https://jsonplaceholder.typicode.com/users
http https://jsonplaceholder.typicode.com/posts/1

# Résum

[OK] RÉSUMÉ FINAL - AIDE-MÉMOIRE

# === LES 10 COMMANDES PLUS UTILES ===

# 1. Simple GET:
http https://api.example.com/users

# 2. POST avec données:
http POST https://api.example.com/users name=John email=john@example.com

# 3. Avec authentification:
http https://api.example.com/profile Authorization:"Bearer token123"

# 4. Mode verbose (debug):
http --verbose POST https://api.example.com/users name=John

# 5. Télécharger un fichier:
http --download https://api.example.com/file.pdf

# 6. Uploader un fichier:
http --form POST https://api.example.com/upload file@~/image.jpg

# 7. Avec session:
http --session=myapi POST https://api.example.com/login email=user@example.com

# 8. Query parameters:
http https://api.example.com/users page==1 limit==10

# 9. JSON complexe:
http POST https://api.example.com/users address:='{"city":"NY","zip":"10001"}'

# 10. Vérifier les erreurs:
http --check-status https://api.example.com/critical


# === LES 5 SYMBOLES CLÉS À MÉMORISER ===

# :   = Header (Authorization:token)
# ==  = Query param (search==python)
# =   = JSON string (name=John)
# :=  = JSON non-string (age:=30)
# @   = Fichier (photo@image.jpg)


# === CHECKLIST AVANT UNE REQUÊTE ===

# [OK] L'URL est correcte?
# [OK] La méthode est correcte (GET, POST, PUT, DELETE)?
# [OK] Les headers sont corrects (Authorization)?
# [OK] Les données sont au bon format (JSON vs form)?
# [OK] Les symboles sont corrects (:, ==, =, :=)?
# [OK] Les fichiers existent (pour upload)?
# [OK] L'API est accessible (pas de firewall)?


# === ERREURS FRÉQUENTES ET SOLUTIONS ===

# "command not found: http"
# -> pip3 install httpie

# "SSL: CERTIFICATE_VERIFY_FAILED"
# -> http --verify=no https://api.example.com

# "Connection timeout"
# -> http --timeout=30 https://api.example.com

# "401 Unauthorized"
# -> Ajouter Authorization header

# "429 Too Many Requests"
# -> Ralentir les requêtes (sleep, respecter rate limit)

# "400 Bad Request"
# -> Vérifier le format des données


# === PASSER À L'ÉTAPE SUPÉRIEURE ===

# Maintenant que tu sais utiliser HTTPie, tu peux:

# 1. Tester les APIs sans coder
# 2. Déboguer les problèmes de requête
# 3. Automatiser avec des scripts bash
# 4. Intégrer avec des workflows CI/CD
# 5. Monitorer des services en production
# 6. Développer des intégrations API

# HTTPie t'accompagne à chaque étape! le bon type de fichier


[OK] RÉPONSES COMPLEXES & PARSING

# === RECEVOIR UNE GROSSE RÉPONSE JSON ===

# Scénario: L'API retourne 1000 utilisateurs

http https://api.example.com/users

# Affiche tout le JSON (peut être très long!)

# Mieux: Filtrer avec jq
http https://api.example.com/users | jq '.[0:5]'
# Affiche seulement les 5 premiers

http https://api.example.com/users | jq '.[] | select(.age > 30)'
# Affiche seulement les utilisateurs de plus de 30 ans


# === EXTRAIRE UN CHAMP SPÉCIFIQUE ===

# Scénario: Tu veux juste les noms

http https://api.example.com/users | jq -r '.[].name'

# Affiche:
# John
# Jane
# Bob

# Le -r = "raw output" (sans guillemets)


# === RÉPONSE AVEC HEADERS PERSONNALISÉS ===

# Certaines APIs retournent des données dans les headers

http --headers https://api.example.com/data

# Affiche:
# HTTP/1.1 200 OK
# X-Total-Count: 1000
# X-Current-Page: 1
# Content-Type: application/json
#
# {...}

# Extraire un header avec jq:
http https://api.example.com/data --headers | grep "X-Total-Count"


# === RÉPONSE AVEC PAGINATION ===

# Scénario: L'API retourne 10 résultats par page

# Page 1:
http https://api.example.com/users page==1 limit==10

# Page 2:
http https://api.example.com/users page==2 limit==10

# Page 3:
http https://api.example.com/users page==3 limit==10

# Ou avec offset:
http https://api.example.com/users offset==0 limit==10
http https://api.example.com/users offset==10 limit==10
http https://api.example.com/users offset==20 limit==10


# === SAUVEGARDER LA RÉPONSE ENTIÈRE ===

# Redirection bash:
http https://api.example.com/users > response.json

# Affiche la réponse ET la sauvegarde

# Sauvegarder SANS afficher:
http https://api.example.com/users > response.json 2>&1

# Ajouter à un fichier (append):
http https://api.example.com/users >> response.json


# === TRAITER LA RÉPONSE EN TEMPS RÉEL ===

# Scénario: Streamer une grosse réponse

http --stream https://api.example.com/stream | jq '.'

# Affiche les données AU FUR ET À MESURE


[OK] SCRIPTS & AUTOMATISATION

# === BOUCLE SIMPLE ===

# Créer 10 utilisateurs:

for i in {1..10}; do
  http POST https://api.example.com/users \
    name="User$i" \
    email="user$i@example.com"
done

# HTTPie exécute 10 fois


# === LIRE DEPUIS UN FICHIER ===

# Fichier: users.txt
# John john@example.com
# Jane jane@example.com
# Bob bob@example.com

# Script:
while read name email; do
  http POST https://api.example.com/users \
    name="$name" \
    email="$email"
done < users.txt

# Crée 3 utilisateurs en lisant du fichier


# === UTILISER AVEC JQ POUR BOUCLER ===

# Créer des posts pour chaque utilisateur

http https://api.example.com/users | jq -r '.[] | .id' | while read user_id; do
  http POST https://api.example.com/posts \
    user_id="$user_id" \
    title="Post de l'utilisateur $user_id"
done


# === ATTENDRE ENTRE LES REQUÊTES ===

# Scénario: L'API a une limite de requêtes, attendre entre chaque

for i in {1..100}; do
  http POST https://api.example.com/data \
    item_number="$i"
  
  sleep 1  # Attendre 1 seconde
done

# Ou attendre 0.5 secondes:
sleep 0.5


# === VÉRIFIER LES ERREURS DANS LE SCRIPT ===

# Si une requête échoue, arrêter le script:

http --check-status https://api.example.com/critical || exit 1

# Continue seulement si le code est 2xx
# Sinon, exit avec erreur

# Script complet:
#!/bin/bash
set -e  # Arrêter à la première erreur

http --check-status https://api.example.com/setup
http --check-status https://api.example.com/initialize
http --check-status https://api.example.com/run

echo "Tout s'est bien passé!"


# === EXPORTER LES RÉSULTATS ===

# Récolter les réponses dans un fichier

> results.json  # Vider le fichier

for i in {1..10}; do
  http https://api.example.com/data/$i | jq '.' >> results.json
done

# results.json contient toutes les réponses


# === SCRIPTS EN PYTHON AVEC HTTPIE ===

# Scénario: Utiliser HTTPie dans un script Python

import subprocess
import json

# Faire une requête HTTPie
result = subprocess.run(
  ["http", "GET", "https://api.example.com/users"],
  capture_output=True,
  text=True
)

# Récupérer la réponse
response = json.loads(result.stdout)
print(response)


[OK] CAS D'USAGE RÉELS & EXEMPLES

# === CAS 1: TESTER UNE API REST COMPLÈTE ===

# Workflow CRUD complet:

# 1. CRÉER (CREATE)
http --verbose POST https://api.example.com/posts \
  title="Premier article" \
  content="Contenu de l'article" \
  tags:='["python","api"]'

# Réponse: { "id": 1, "title": "Premier article", ... }

# 2. LIRE (READ)
http GET https://api.example.com/posts/1

# Réponse: { "id": 1, "title": "Premier article", ... }

# 3. METTRE À JOUR (UPDATE)
http PATCH https://api.example.com/posts/1 \
  title="Premier article (modifié)"

# Réponse: { "id": 1, "title": "Premier article (modifié)", ... }

# 4. SUPPRIMER (DELETE)
http DELETE https://api.example.com/posts/1

# Réponse: HTTP/1.1 204 No Content


# === CAS 2: INTÉGRATION AVEC GITHUB API ===

# 1. Récupérer les infos d'un utilisateur:
http https://api.github.com/users/octocat

# 2. Lister les repos:
http https://api.github.com/users/octocat/repos page==1 per_page==10

# 3. Créer une issue (avec authentification):
http POST https://api.github.com/repos/owner/repo/issues \
  Authorization:"token ghp_xxxxx" \
  title="Bug: La page crash" \
  body="Quand je clique sur le bouton, ça crash"

# 4. Créer un webhook:
http POST https://api.github.com/repos/owner/repo/hooks \
  Authorization:"token ghp_xxxxx" \
  name=web \
  config:='{"url":"https://example.com/webhook","content_type":"json"}'


# === CAS 3: INTÉGRATION AVEC STRIPE API ===

# Créer un client:
http POST https://api.stripe.com/v1/customers \
  --auth=sk_test_12345abcde: \
  email=customer@example.com \
  name="John Doe"

# Créer un paiement:
http POST https://api.stripe.com/v1/payment_intents \
  --auth=sk_test_12345abcde: \
  amount:=5000 \
  currency=usd \
  customer=cus_123456


# === CAS 4: TESTER UNE API LOCALE (Flask) ===

# Ton serveur Flask tourne sur localhost:5000

# 1. Tester GET:
http :5000/api/users

# 2. Tester POST:
http POST :5000/api/users \
  name=John \
  email=john@example.com

# 3. Tester avec authentification:
http :5000/api/profile \
  Authorization:"Bearer dev_token_123"

# 4. Tester avec erreurs:
http --verbose :5000/api/invalid

# 5. Tester avec session:
http --session=dev POST :5000/login email=dev@example.com password=pass123
http --session=dev :5000/profile


# === CAS 5: MONITORING SIMPLE ===

# Vérifier si l'API est en ligne toutes les 5 minutes:

#!/bin/bash

while true; do
  if http --check-status :5000/health > /dev/null 2>&1; then
    echo "[OK] API OK - $(date)"
  else
    echo "[X] API DOWN - $(date)"
  fi
  
  sleep 300  # Attendre 5 minutes
done


[OK] DÉPANNAGE & PROBLÈMES COURANTS

# === PROBLÈME: SSL CERTIFICATE VERIFY FAILED ===

# Cause: Certificat invalide/auto-signé

http https://api-staging.example.com/users
# Erreur: SSL: CERTIFICATE_VERIFY_FAILED

# Solutions:

# 1. Ignorer (SEULEMENT en dev!):
http --verify=no https://api-staging.example.com/users

# 2. Ajouter le certificat:
http --cert=/path/to/cert.pem https://api.example.com/users

# 3. Utiliser HTTP (si API le permet):
http http://api-staging.example.com/users


# === PROBLÈME: CONNECTION TIMEOUT ===

# Cause: L'API est lente ou indisponible

http https://api-lente.example.com/users
# Erreur: Connection timeout

# Solutions:

# 1. Augmenter le timeout:
http --timeout=30 https://api-lente.example.com/users

# 2. Vérifier si l'API est en ligne:
http :5000/health

# 3. Vérifier la connexion internet:
ping api-lente.example.com


# === PROBLÈME: MEMORY ERROR (Réponse trop grosse) ===

# Cause: La réponse est énorme et épuise la RAM

http https://api.example.com/all_data
# MemoryError: Can't allocate...

# Solutions:

# 1. Utiliser --stream:
http --stream https://api.example.com/all_data

# 2. Paginer les résultats:
http https://api.example.com/data page==1 limit==100

# 3. Filtrer avec jq:
http https://api.example.com/all_data | jq '.items[0:10]'


# === PROBLÈME: AUTHENTIFICATION REJETÉE ===

# Cause: Token invalide/expiré

http https://api.example.com/profile \
  Authorization:"Bearer invalid_token"
# Erreur: 401 Unauthorized

# Solutions:

# 1. Vérifier le token:
echo $API_TOKEN
# S'il est vide, tu ne l'as pas défini!

# 2. Régénérer le token:
http POST https://api.example.com/auth/login \
  email=user@example.com \
  password=mypassword
# Utiliser le nouveau token

# 3. Vérifier les permissions:
# Peut-être que ton compte n'a pas le droit d'accéder à /profile


# === PROBLÈME: RÉPONSE VIDE ===

# Cause: L'API ne retourne rien (204 No Content)

http GET https://api.example.com/empty
# HTTP/1.1 204 No Content
# (rien!)

# C'est normal! 204 = "Succès mais rien à retourner"

# Mais si c'est pas attendu:
http --verbose GET https://api.example.com/empty
# Voir si vraiment vide


# === PROBLÈME: REQUEST BODY IGNORÉ ===

# Cause: Utiliser GET avec données

http GET https://api.example.com/search \
  query=python  # GET IGNORE LES DONNÉES!

# Solution: Utiliser POST ou PUT:
http POST https://api.example.com/search \
  query=python

# Ou query parameters:
http GET https://api.example.com/search \
  query==python  # == au lieu de =


[OK] INTÉGRATION AVEC D'AUTRES OUTILS

# === COMBINER AVEC CURL ===

# HTTPie et curl peuvent se compléter

# HTTPie pour les APIs (facile):
http POST https://api.example.com/users name=John

# curl pour les cas complexes (si HTTPie ne suffit pas):
curl -X POST https://api.example.com/users \
  -H "Content-Type: application/json" \
  -d '{"name":"John"}'


# === COMBINER AVEC JQ ===

# HTTPie envoie, jq traite:

http https://api.example.com/users | jq '.[] | {name, email}'

# Affiche seulement les noms et emails


# === COMBINER AVEC GREP ===

# Chercher dans les résultats:

http https://api.example.com/users | grep "john"

# Affiche seulement les lignes contenant "john"


# === COMBINER AVEC AWK ===

# Extraire des colonnes:

http https://api.example.com/users --headers | awk '{print $1}'

# Affiche les en-têtes


# === UTILISER DANS GITHUB ACTIONS ===

# Script CI/CD qui teste une API:

# .github/workflows/api-test.yml
name: API Test

on: [push]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Install HTTPie
        run: pip install httpie
      - name: Test API
        run: http --check-status GET https://api.example.com/health
      - name: Create test data
        run: http POST https://api.example.com/test data=example


# === UTILISER DANS DOCKER ===

# Dockerfile:
FROM python:3.11
RUN pip install httpie

ENTRYPOINT ["http"]

# Puis dans le container:
docker build -t my-httpie .
docker run my-httpie GET https://api.example.com/users


[OK] CONSEILS & BONNES PRATIQUES

# === BON: Documenter tes requêtes ===

# Créer un fichier requests.sh avec les requêtes courantes:

#!/bin/bash

# Créer un utilisateur
create_user() {
  http POST https://api.example.com/users \
    name="$1" \
    email="$2"
}

# Lister les utilisateurs
list_users() {
  http GET https://api.example.com/users
}

...