Menu

HTTP request di Python: memakai library requests (GET, POST, JSON)

Cara membuat HTTP request di Python dengan library requests: GET, POST, query parameter, header, body JSON, dan menangani error.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

Mengambil data dari internet dalam beberapa baris

Kebanyakan program Python sungguhan pada akhirnya perlu berkomunikasi dengan sesuatu lewat jaringan: REST API, layanan cuaca, endpoint GitHub, atau sebuah unduhan. Standard library bisa melakukannya (lewat urllib), tapi alat yang jadi standar di dunia Python adalah library pihak ketiga bernama requests. API-nya jauh lebih ramah sehingga layak dengan satu kali pip install.

pip install requests

Kalau kamu belum bekerja di dalam virtual environment, siapkan dulu satu, agar instalasi ini hanya berlaku untuk proyekmu.

GET request pertama

Tiga baris: panggil get, cek status code, lihat body-nya. response.text adalah body response dalam bentuk string. Di sini dipotong karena JSON lengkapnya panjang.

Status code yang perlu kamu kenali, setidaknya selevel cheat sheet:

  • 200: OK, semuanya berhasil.
  • 201: Created (response yang umum untuk POST).
  • 301 / 302: redirect; secara default requests mengikutinya otomatis.
  • 400: bad request; ada yang salah dari apa yang kamu kirim.
  • 401 / 403: belum terautentikasi / tidak diizinkan.
  • 404: resource-nya tidak ada.
  • 429: kena rate limit; pelan-pelan.
  • 500: error di server.

Mengurai response JSON

Saat endpoint mengembalikan JSON, panggil .json() pada response: ia mengurai body-nya dan memberimu dict (atau list):

Di balik layar, .json() sama dengan json.loads(response.text), hanya jalan pintas untuk kasus yang umum.

Mengirim query parameter

Jangan menempelkan ?key=value&... ke URL secara manual. Berikan dict ke params=:

requests menangani URL encoding untukmu: spasi, karakter khusus, dan Unicode semuanya aman.

URL yang benar-benar dikirim tersedia di response.url, berguna untuk debugging.

POST request dengan body JSON

Untuk mengirim data, seperti membuat resource, mengirim formulir, atau memanggil endpoint yang mengubah data, pakai requests.post:

import requests

payload = {
    "title": "Docs update",
    "body": "Added HTTP requests page.",
    "labels": ["docs"],
}

response = requests.post(
    "https://api.example.com/issues",
    json=payload,
    headers={"Authorization": "Bearer YOUR_TOKEN"},
)

print(response.status_code)
print(response.json())

Argumen json= melakukan dua hal: mengubah payload menjadi JSON dan mengatur Content-Type: application/json. Kamu bisa melakukan keduanya sendiri dengan data=json.dumps(payload) dan header yang eksplisit, tapi json= adalah jalan pintas yang idiomatis.

Untuk data form-encoded (jenis yang dikirim formulir HTML klasik), pakai data=:

requests.post("https://example.com/login", data={"user": "rosa", "password": "..."})

Berikan header khusus apa pun sebagai dict:

import requests

response = requests.get(
    "https://api.example.com/profile",
    headers={
        "Authorization": "Bearer abc123",
        "User-Agent": "my-tool/1.0",
    },
)

Kebanyakan API meminta header Authorization untuk autentikasi. Skema persisnya (Bearer, Basic, Token) ada di dokumentasi mereka.

Timeout itu wajib

Secara default, requests akan menunggu response selamanya. Di program sungguhan, itu membuat server yang tidak stabil berubah menjadi skrip yang macet. Selalu berikan timeout:

import requests

try:
    response = requests.get("https://api.example.com/slow", timeout=5)
except requests.Timeout:
    print("Server took too long.")

Angkanya dalam detik. timeout=5 berarti "menyerah kalau belum ada response dalam 5 detik." Kamu bisa memberikan tuple (connect_timeout, read_timeout) untuk kontrol yang lebih detail.

Penanganan error

Ada dua jenis masalah yang bisa terjadi:

  1. Error di level HTTP (4xx, 5xx): server merespons, tapi response-nya berupa error. response.status_code memberitahumu.
  2. Masalah di level jaringan: timeout, kegagalan DNS, host yang tidak bisa dijangkau. Masalah ini memunculkan exception.

Pola idiomatis yang menggabungkan keduanya:

raise_for_status() tidak melakukan apa-apa untuk response 2xx dan memunculkan exception untuk yang lainnya. RequestException adalah base class untuk setiap error yang dimunculkan requests: satu tangkapan untuk "apa pun yang salah saat berkomunikasi dengan endpoint ini."

Mengunduh file

Untuk unduhan biner yang besar, alirkan (stream) response-nya agar tidak tertahan di memori:

import requests

url = "https://example.com/large.zip"

with requests.get(url, stream=True, timeout=30) as r:
    r.raise_for_status()
    with open("large.zip", "wb") as f:
        for chunk in r.iter_content(chunk_size=8192):
            f.write(chunk)

stream=True memberi tahu requests agar tidak memuat body di awal. iter_content(chunk_size=...) menghasilkan body sepotong demi sepotong, yang langsung kamu tulis ke disk.

Session: memakai ulang koneksi dan nilai default

Kalau kamu akan membuat beberapa request ke layanan yang sama, pakai Session. Session memakai ulang koneksi TCP di baliknya (lebih cepat) dan memungkinkan kamu mengatur nilai default sekali saja:

import requests

session = requests.Session()
session.headers.update({"Authorization": "Bearer abc123"})

# Every request through this session carries the header.
a = session.get("https://api.example.com/users/1")
b = session.get("https://api.example.com/users/2")
c = session.post("https://api.example.com/users", json={"name": "Rosa"})

Untuk skrip yang memanggil API yang sama puluhan kali, session memberi percepatan yang terasa.

Contoh realistis: client GitHub kecil

Mengambil rilis terbaru dari sebuah repo:

import requests

def latest_release(owner, repo):
    url = f"https://api.github.com/repos/{owner}/{repo}/releases/latest"
    response = requests.get(url, timeout=10)
    response.raise_for_status()
    data = response.json()
    return {
        "tag": data["tag_name"],
        "name": data["name"],
        "published": data["published_at"],
        "url": data["html_url"],
    }

release = latest_release("python", "cpython")
print(release)

Kurang dari lima belas baris: susun URL, kirim request, cek error, ambil field yang kamu butuhkan. Begitulah bentuk kebanyakan API client yang akan kamu tulis.

Bagaimana dengan urllib?

urllib.request dari standard library bisa melakukan semua yang bisa dilakukan requests, dengan lebih banyak baris dan kenyamanan yang lebih buruk. Kalau kamu benar-benar tidak bisa menambah dependensi, ia tersedia:

import json
import urllib.request

with urllib.request.urlopen("https://api.github.com/repos/python/cpython") as r:
    data = json.loads(r.read().decode("utf-8"))

print(data["name"])

Untuk apa pun yang lebih dari skrip singkat, requests (atau httpx kalau kamu butuh async) layak diinstal.

Beberapa kebiasaan baik

  • Selalu atur timeout. Tanpa kecuali.
  • Pakai raise_for_status() di skrip yang mengharapkan keberhasilan: ia mengubah response yang buruk menjadi exception yang jelas.
  • Berikan dict ke params= dan json=, bukan string yang disusun sendiri.
  • Bungkus pemanggilan yang saling terkait dalam Session saat kamu memanggil API yang sama berkali-kali.
  • Catat response.status_code dan response.text saat debugging: body-nya biasanya memberi tahu persis apa yang tidak disukai server.

Berikutnya: tanggal dan waktu

Dengan requests di perlengkapanmu, kamu bisa berkomunikasi dengan API web modern mana pun, mengunduh file, dan membuat integrasi kecil antar layanan. Digabung dengan halaman JSON dan CSV sebelumnya, sekarang kamu punya siklus lengkap "ambil data, baca, olah, lalu tulis kembali", bentuk dari sangat banyak skrip Python sungguhan. Tapi sebagian besar data itu punya timestamp, dan halaman berikutnya membahas cara Python merepresentasikan tanggal, waktu, dan jebakan zona waktu yang perlu dihindari.

Pertanyaan yang sering diajukan

Bagaimana cara membuat HTTP request di Python?

Instal library requests dengan pip install requests, lalu panggil requests.get(url) untuk GET atau requests.post(url, json=...) untuk POST. Objek response punya .status_code, .text, .json(), dan .headers. Contoh: r = requests.get('https://api.example.com/users/1').

Sebaiknya pakai requests atau urllib?

Pakai requests untuk apa pun yang kamu tulis sendiri, karena API-nya jauh lebih ramah. urllib sudah bawaan dan cukup kalau menambah dependensi tidak mungkin, tapi butuh lebih banyak kode untuk hal seperti body JSON dan session. Untuk produksi, banyak tim juga memakai httpx (library yang kompatibel dengan requests dan mendukung async).

Bagaimana cara mengirim JSON dalam POST request di Python?

Berikan json={'key': 'value'} ke requests.post(...). requests mengubah dict itu menjadi JSON dan mengatur Content-Type: application/json untukmu. Jangan memberikan data= dan json= sekaligus; pilih salah satu.

Bagaimana cara menangani error dengan library requests?

Cek response.status_code (200 berarti berhasil), atau panggil response.raise_for_status() untuk memunculkan exception pada 4xx/5xx. Masalah di level jaringan (timeout, kegagalan DNS) memunculkan subclass dari requests.RequestException; tangkap itu untuk mencakup keduanya.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai