1665 words
8 minutes
Python Requests Module - Complete Guide

🌐 Python Requests Module - Complete Guide#

Requests Library


📚 Table of Contents#

  1. Introduction
  2. Installation
  3. Making GET Requests
  4. Making POST Requests
  5. Other HTTP Methods
  6. Request Headers
  7. Query Parameters
  8. Response Object
  9. Working with JSON
  10. Sending Data
  11. File Upload
  12. File Download
  13. Sessions
  14. Cookies
  15. Authentication
  16. Timeouts and Retries
  17. SSL Verification
  18. Proxies
  19. Error Handling
  20. Practical Projects

1. Introduction#

HTTP Methods

Requests is the most popular HTTP library for Python. It makes sending HTTP requests simple and human-friendly.

Why Use Requests?#

  • ✅ Simple and clean API
  • ✅ Handles encoding automatically
  • ✅ Sessions with cookies
  • ✅ SSL verification
  • ✅ Automatic JSON decoding

2. Installation#

Terminal window
pip install requests

Import#

import requests

Check Version#

import requests
print(requests.__version__)

3. Making GET Requests#

Basic GET Request#

import requests
# Make a GET request
response = requests.get("https://httpbin.org/get")
# Print response
print(response.text)

Check Status#

response = requests.get("https://httpbin.org/get")
print(response.status_code) # 200
print(response.ok) # True (if status < 400)
print(response.reason) # OK

Common Status Codes#

CodeMeaning
200OK - Success
201Created
301Moved Permanently
302Found (Redirect)
400Bad Request
401Unauthorized
403Forbidden
404Not Found
500Internal Server Error

4. Making POST Requests#

Basic POST#

import requests
# POST with form data
data = {
"username": "admin",
"password": "secret123"
}
response = requests.post("https://httpbin.org/post", data=data)
print(response.text)

POST with JSON#

import requests
# POST with JSON body
json_data = {
"name": "Ahmed",
"age": 25,
"city": "Casablanca"
}
response = requests.post("https://httpbin.org/post", json=json_data)
print(response.json())

5. Other HTTP Methods#

import requests
# PUT - Update resource
response = requests.put("https://httpbin.org/put", data={"key": "value"})
# PATCH - Partial update
response = requests.patch("https://httpbin.org/patch", data={"key": "value"})
# DELETE - Delete resource
response = requests.delete("https://httpbin.org/delete")
# HEAD - Get headers only
response = requests.head("https://httpbin.org/get")
print(response.headers)
# OPTIONS - Get allowed methods
response = requests.options("https://httpbin.org/get")

6. Request Headers#

HTTP Headers

Custom Headers#

import requests
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"Accept": "application/json",
"Authorization": "Bearer your_token_here",
"X-Custom-Header": "custom_value"
}
response = requests.get("https://httpbin.org/headers", headers=headers)
print(response.json())

Common Headers#

HeaderPurpose
User-AgentIdentify the client
AcceptExpected response type
Content-TypeType of data being sent
AuthorizationAuthentication token
CookieSession cookies
RefererPrevious page URL

View Response Headers#

response = requests.get("https://httpbin.org/get")
# All headers
print(response.headers)
# Specific header
print(response.headers["Content-Type"])
print(response.headers.get("Server"))

7. Query Parameters#

Method 1: In URL#

response = requests.get("https://httpbin.org/get?name=Ahmed&age=25")

Method 2: Using params (Better!)#

import requests
params = {
"name": "Ahmed",
"age": 25,
"city": "Casablanca"
}
response = requests.get("https://httpbin.org/get", params=params)
print(response.url)
# Output: https://httpbin.org/get?name=Ahmed&age=25&city=Casablanca

Multiple Values for Same Key#

params = {
"tags": ["python", "hacking", "security"]
}
response = requests.get("https://httpbin.org/get", params=params)
print(response.url)
# Output: https://httpbin.org/get?tags=python&tags=hacking&tags=security

8. Response Object#

All Response Properties#

import requests
response = requests.get("https://httpbin.org/get")
# Status
print(response.status_code) # 200
print(response.ok) # True
print(response.reason) # OK
# Content
print(response.text) # Response as string
print(response.content) # Response as bytes
print(response.json()) # Response as dict (if JSON)
# Headers
print(response.headers) # Response headers
print(response.request.headers) # Request headers
# URL
print(response.url) # Final URL (after redirects)
# Encoding
print(response.encoding) # utf-8
# Cookies
print(response.cookies) # Response cookies
# History (redirects)
print(response.history) # List of redirects
# Time
print(response.elapsed) # Time taken
print(response.elapsed.total_seconds())

9. Working with JSON#

Automatic JSON Parsing#

import requests
response = requests.get("https://api.github.com/users/torvalds")
# Parse JSON response
data = response.json()
print(data["name"]) # Linus Torvalds
print(data["public_repos"]) # Number of repos
print(data["followers"]) # Followers count

Send JSON Data#

import requests
data = {
"title": "Hello",
"body": "World",
"userId": 1
}
# Method 1: Using json parameter
response = requests.post(
"https://jsonplaceholder.typicode.com/posts",
json=data
)
# Method 2: Manual (sets Content-Type automatically with json=)
import json
response = requests.post(
"https://jsonplaceholder.typicode.com/posts",
data=json.dumps(data),
headers={"Content-Type": "application/json"}
)
print(response.json())

Pretty Print JSON#

import requests
import json
response = requests.get("https://api.github.com/users/torvalds")
data = response.json()
# Pretty print
print(json.dumps(data, indent=2))

10. Sending Data#

Form Data (application/x-www-form-urlencoded)#

import requests
data = {
"username": "admin",
"password": "secret"
}
response = requests.post("https://httpbin.org/post", data=data)
print(response.json()["form"])

JSON Data (application/json)#

import requests
data = {
"name": "Ahmed",
"skills": ["python", "hacking"]
}
response = requests.post("https://httpbin.org/post", json=data)
print(response.json()["json"])

Raw Data#

import requests
# Send raw text
response = requests.post(
"https://httpbin.org/post",
data="raw text data",
headers={"Content-Type": "text/plain"}
)
# Send raw bytes
response = requests.post(
"https://httpbin.org/post",
data=b"binary data"
)

11. File Upload#

Upload Single File#

import requests
# Open file in binary mode
files = {
"file": open("document.pdf", "rb")
}
response = requests.post("https://httpbin.org/post", files=files)
print(response.json()["files"])

Upload with Custom Filename#

import requests
files = {
"file": ("custom_name.pdf", open("document.pdf", "rb"), "application/pdf")
}
response = requests.post("https://httpbin.org/post", files=files)

Upload Multiple Files#

import requests
files = [
("files", ("file1.txt", open("file1.txt", "rb"))),
("files", ("file2.txt", open("file2.txt", "rb"))),
]
response = requests.post("https://httpbin.org/post", files=files)

Upload File with Form Data#

import requests
files = {"file": open("image.jpg", "rb")}
data = {"description": "My photo", "tags": "vacation"}
response = requests.post(
"https://httpbin.org/post",
files=files,
data=data
)

12. File Download#

Download Small File#

import requests
url = "https://example.com/image.jpg"
response = requests.get(url)
with open("downloaded_image.jpg", "wb") as f:
f.write(response.content)
print("Downloaded!")

Download Large File (Streaming)#

import requests
url = "https://example.com/large_file.zip"
with requests.get(url, stream=True) as response:
response.raise_for_status()
total_size = int(response.headers.get("Content-Length", 0))
downloaded = 0
with open("large_file.zip", "wb") as f:
for chunk in response.iter_content(chunk_size=8192):
f.write(chunk)
downloaded += len(chunk)
# Progress
if total_size:
percent = (downloaded / total_size) * 100
print(f"\rDownloading: {percent:.1f}%", end="")
print("\nDownload complete!")

Download with Progress Bar#

import requests
from tqdm import tqdm
url = "https://example.com/file.zip"
response = requests.get(url, stream=True)
total_size = int(response.headers.get("Content-Length", 0))
with open("file.zip", "wb") as f:
with tqdm(total=total_size, unit="B", unit_scale=True) as pbar:
for chunk in response.iter_content(chunk_size=8192):
f.write(chunk)
pbar.update(len(chunk))

13. Sessions#

Sessions persist cookies and settings across requests.

Basic Session#

import requests
# Create session
session = requests.Session()
# Login
login_data = {"username": "admin", "password": "secret"}
session.post("https://example.com/login", data=login_data)
# Subsequent requests use same cookies
response = session.get("https://example.com/dashboard")
response = session.get("https://example.com/profile")
# Close session
session.close()

Session with Default Headers#

import requests
session = requests.Session()
# Set default headers for all requests
session.headers.update({
"User-Agent": "MyApp/1.0",
"Authorization": "Bearer my_token"
})
# All requests will use these headers
response = session.get("https://httpbin.org/headers")
print(response.json())

Session Context Manager#

import requests
with requests.Session() as session:
session.headers["Authorization"] = "Bearer token123"
response = session.get("https://api.example.com/data")
# Session automatically closed after this block

14. Cookies#

View Cookies#

import requests
response = requests.get("https://httpbin.org/cookies/set?name=Ahmed")
print(response.cookies)
# Get specific cookie
for cookie in response.cookies:
print(f"{cookie.name}: {cookie.value}")

Send Cookies#

import requests
# Method 1: Dictionary
cookies = {
"session_id": "abc123",
"user": "Ahmed"
}
response = requests.get("https://httpbin.org/cookies", cookies=cookies)
print(response.json())
# Method 2: CookieJar
jar = requests.cookies.RequestsCookieJar()
jar.set("session_id", "abc123", domain="httpbin.org")
response = requests.get("https://httpbin.org/cookies", cookies=jar)

Cookies with Session#

import requests
session = requests.Session()
# Set cookies
session.cookies.set("token", "secret123")
response = session.get("https://httpbin.org/cookies")
print(response.json())

15. Authentication#

Basic Authentication#

import requests
from requests.auth import HTTPBasicAuth
# Method 1
response = requests.get(
"https://httpbin.org/basic-auth/user/pass",
auth=HTTPBasicAuth("user", "pass")
)
# Method 2 (shortcut)
response = requests.get(
"https://httpbin.org/basic-auth/user/pass",
auth=("user", "pass")
)
print(response.status_code) # 200

Digest Authentication#

import requests
from requests.auth import HTTPDigestAuth
response = requests.get(
"https://httpbin.org/digest-auth/auth/user/pass",
auth=HTTPDigestAuth("user", "pass")
)

Bearer Token#

import requests
headers = {
"Authorization": "Bearer your_access_token"
}
response = requests.get("https://api.example.com/data", headers=headers)

API Key Authentication#

import requests
# In headers
headers = {"X-API-Key": "your_api_key"}
response = requests.get("https://api.example.com/data", headers=headers)
# In query params
params = {"api_key": "your_api_key"}
response = requests.get("https://api.example.com/data", params=params)

16. Timeouts and Retries#

Set Timeout#

import requests
try:
# Timeout in seconds
response = requests.get("https://httpbin.org/delay/5", timeout=3)
except requests.Timeout:
print("Request timed out!")

Connect vs Read Timeout#

import requests
# (connect_timeout, read_timeout)
response = requests.get(
"https://httpbin.org/get",
timeout=(3.05, 27) # 3.05s to connect, 27s to read
)

Automatic Retries#

import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
# Configure retry strategy
retry_strategy = Retry(
total=3, # Total retries
backoff_factor=1, # Wait 1, 2, 4 seconds between retries
status_forcelist=[500, 502, 503, 504] # Retry on these status codes
)
# Create session with retry
session = requests.Session()
adapter = HTTPAdapter(max_retries=retry_strategy)
session.mount("http://", adapter)
session.mount("https://", adapter)
# Use session
response = session.get("https://example.com/api")

17. SSL Verification#

import requests
import urllib3
# Disable warnings
urllib3.disable_warnings()
# Skip SSL verification
response = requests.get("https://self-signed.badssl.com/", verify=False)

Custom Certificate#

import requests
# Use custom CA bundle
response = requests.get("https://example.com", verify="/path/to/ca-bundle.crt")
# Use client certificate
response = requests.get(
"https://example.com",
cert=("/path/to/client.cert", "/path/to/client.key")
)

18. Proxies#

HTTP/HTTPS Proxy#

import requests
proxies = {
"http": "http://proxy.example.com:8080",
"https": "http://proxy.example.com:8080"
}
response = requests.get("https://httpbin.org/ip", proxies=proxies)
print(response.json())

SOCKS Proxy#

# pip install requests[socks]
import requests
proxies = {
"http": "socks5://127.0.0.1:9050",
"https": "socks5://127.0.0.1:9050"
}
response = requests.get("https://httpbin.org/ip", proxies=proxies)

Proxy with Authentication#

import requests
proxies = {
"http": "http://user:password@proxy.example.com:8080",
"https": "http://user:password@proxy.example.com:8080"
}
response = requests.get("https://httpbin.org/ip", proxies=proxies)

19. Error Handling#

Handle Exceptions#

import requests
try:
response = requests.get("https://example.com", timeout=5)
response.raise_for_status() # Raise error for 4xx/5xx
data = response.json()
except requests.ConnectionError:
print("Failed to connect!")
except requests.Timeout:
print("Request timed out!")
except requests.HTTPError as e:
print(f"HTTP Error: {e}")
except requests.RequestException as e:
print(f"Request failed: {e}")
except ValueError:
print("Invalid JSON response")

Check Before Processing#

import requests
response = requests.get("https://api.example.com/data")
if response.ok: # status_code < 400
data = response.json()
print(data)
else:
print(f"Error: {response.status_code}")
print(response.text)

20. Practical Projects#

Project 1: Web Scraper#

import requests
from bs4 import BeautifulSoup
def scrape_website(url):
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0"
}
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.text, "html.parser")
# Get all links
links = []
for a in soup.find_all("a", href=True):
links.append(a["href"])
return links
links = scrape_website("https://example.com")
for link in links[:10]:
print(link)

Project 2: API Client#

import requests
class GitHubAPI:
BASE_URL = "https://api.github.com"
def __init__(self, token=None):
self.session = requests.Session()
if token:
self.session.headers["Authorization"] = f"token {token}"
def get_user(self, username):
response = self.session.get(f"{self.BASE_URL}/users/{username}")
return response.json()
def get_repos(self, username):
response = self.session.get(f"{self.BASE_URL}/users/{username}/repos")
return response.json()
def search_repos(self, query):
params = {"q": query}
response = self.session.get(f"{self.BASE_URL}/search/repositories", params=params)
return response.json()
# Usage
github = GitHubAPI()
user = github.get_user("torvalds")
print(f"Name: {user['name']}")
print(f"Followers: {user['followers']}")

Project 3: Website Checker#

import requests
import time
def check_websites(urls):
results = []
for url in urls:
try:
start = time.time()
response = requests.get(url, timeout=10)
elapsed = time.time() - start
results.append({
"url": url,
"status": response.status_code,
"time": round(elapsed, 2),
"ok": response.ok
})
except requests.RequestException as e:
results.append({
"url": url,
"status": "ERROR",
"time": None,
"ok": False,
"error": str(e)
})
return results
# Check websites
websites = [
"https://google.com",
"https://github.com",
"https://python.org",
"https://nonexistent.invalid"
]
results = check_websites(websites)
for r in results:
status = "✓" if r["ok"] else "✗"
print(f"{status} {r['url']:30} - {r['status']} ({r['time']}s)")

Project 4: Login Automation#

import requests
def login_to_site(url, username, password):
session = requests.Session()
# Get login page (for CSRF token)
login_page = session.get(url)
# Parse CSRF token if needed (example)
# from bs4 import BeautifulSoup
# soup = BeautifulSoup(login_page.text, "html.parser")
# csrf = soup.find("input", {"name": "csrf_token"})["value"]
# Submit login form
login_data = {
"username": username,
"password": password,
# "csrf_token": csrf
}
response = session.post(url, data=login_data)
if "Welcome" in response.text or response.url != url:
print("[+] Login successful!")
return session
else:
print("[-] Login failed!")
return None
# Example usage
# session = login_to_site("https://example.com/login", "admin", "password")

Project 5: Directory Brute Force#

import requests
from concurrent.futures import ThreadPoolExecutor
def check_path(base_url, path):
url = f"{base_url}/{path}"
try:
response = requests.get(url, timeout=5)
if response.status_code == 200:
print(f"[+] Found: {url}")
return url
elif response.status_code == 403:
print(f"[!] Forbidden: {url}")
except:
pass
return None
def dir_brute(base_url, wordlist_path, threads=10):
with open(wordlist_path) as f:
paths = [line.strip() for line in f]
print(f"[*] Starting brute force on {base_url}")
print(f"[*] Wordlist: {len(paths)} paths")
found = []
with ThreadPoolExecutor(max_workers=threads) as executor:
results = executor.map(lambda p: check_path(base_url, p), paths)
found = [r for r in results if r]
print(f"\n[*] Found {len(found)} paths")
return found
# Example usage
# dir_brute("https://example.com", "wordlist.txt")

🎯 Quick Reference#

MethodDescription
requests.get()GET request
requests.post()POST request
requests.put()PUT request
requests.delete()DELETE request
response.textResponse as string
response.json()Parse JSON
response.status_codeHTTP status code
response.headersResponse headers
response.cookiesResponse cookies

🎉 Master HTTP with Requests!#

Now you can:

  • Make any HTTP request
  • Handle authentication
  • Work with APIs
  • Scrape websites
  • Upload/download files

Created by cat0x01 🥷🏻