1665 words
8 minutes
Python Requests Module - Complete Guide
🌐 Python Requests Module - Complete Guide

📚 Table of Contents
- Introduction
- Installation
- Making GET Requests
- Making POST Requests
- Other HTTP Methods
- Request Headers
- Query Parameters
- Response Object
- Working with JSON
- Sending Data
- File Upload
- File Download
- Sessions
- Cookies
- Authentication
- Timeouts and Retries
- SSL Verification
- Proxies
- Error Handling
- Practical Projects
1. Introduction

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
pip install requestsImport
import requestsCheck Version
import requestsprint(requests.__version__)3. Making GET Requests
Basic GET Request
import requests
# Make a GET requestresponse = requests.get("https://httpbin.org/get")
# Print responseprint(response.text)Check Status
response = requests.get("https://httpbin.org/get")
print(response.status_code) # 200print(response.ok) # True (if status < 400)print(response.reason) # OKCommon Status Codes
| Code | Meaning |
|---|---|
| 200 | OK - Success |
| 201 | Created |
| 301 | Moved Permanently |
| 302 | Found (Redirect) |
| 400 | Bad Request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not Found |
| 500 | Internal Server Error |
4. Making POST Requests
Basic POST
import requests
# POST with form datadata = { "username": "admin", "password": "secret123"}
response = requests.post("https://httpbin.org/post", data=data)print(response.text)POST with JSON
import requests
# POST with JSON bodyjson_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 resourceresponse = requests.put("https://httpbin.org/put", data={"key": "value"})
# PATCH - Partial updateresponse = requests.patch("https://httpbin.org/patch", data={"key": "value"})
# DELETE - Delete resourceresponse = requests.delete("https://httpbin.org/delete")
# HEAD - Get headers onlyresponse = requests.head("https://httpbin.org/get")print(response.headers)
# OPTIONS - Get allowed methodsresponse = requests.options("https://httpbin.org/get")6. Request 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
| Header | Purpose |
|---|---|
User-Agent | Identify the client |
Accept | Expected response type |
Content-Type | Type of data being sent |
Authorization | Authentication token |
Cookie | Session cookies |
Referer | Previous page URL |
View Response Headers
response = requests.get("https://httpbin.org/get")
# All headersprint(response.headers)
# Specific headerprint(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=CasablancaMultiple 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=security8. Response Object
All Response Properties
import requests
response = requests.get("https://httpbin.org/get")
# Statusprint(response.status_code) # 200print(response.ok) # Trueprint(response.reason) # OK
# Contentprint(response.text) # Response as stringprint(response.content) # Response as bytesprint(response.json()) # Response as dict (if JSON)
# Headersprint(response.headers) # Response headersprint(response.request.headers) # Request headers
# URLprint(response.url) # Final URL (after redirects)
# Encodingprint(response.encoding) # utf-8
# Cookiesprint(response.cookies) # Response cookies
# History (redirects)print(response.history) # List of redirects
# Timeprint(response.elapsed) # Time takenprint(response.elapsed.total_seconds())9. Working with JSON
Automatic JSON Parsing
import requests
response = requests.get("https://api.github.com/users/torvalds")
# Parse JSON responsedata = response.json()
print(data["name"]) # Linus Torvaldsprint(data["public_repos"]) # Number of reposprint(data["followers"]) # Followers countSend JSON Data
import requests
data = { "title": "Hello", "body": "World", "userId": 1}
# Method 1: Using json parameterresponse = requests.post( "https://jsonplaceholder.typicode.com/posts", json=data)
# Method 2: Manual (sets Content-Type automatically with json=)import jsonresponse = requests.post( "https://jsonplaceholder.typicode.com/posts", data=json.dumps(data), headers={"Content-Type": "application/json"})
print(response.json())Pretty Print JSON
import requestsimport json
response = requests.get("https://api.github.com/users/torvalds")data = response.json()
# Pretty printprint(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 textresponse = requests.post( "https://httpbin.org/post", data="raw text data", headers={"Content-Type": "text/plain"})
# Send raw bytesresponse = requests.post( "https://httpbin.org/post", data=b"binary data")11. File Upload
Upload Single File
import requests
# Open file in binary modefiles = { "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 requestsfrom 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 sessionsession = requests.Session()
# Loginlogin_data = {"username": "admin", "password": "secret"}session.post("https://example.com/login", data=login_data)
# Subsequent requests use same cookiesresponse = session.get("https://example.com/dashboard")response = session.get("https://example.com/profile")
# Close sessionsession.close()Session with Default Headers
import requests
session = requests.Session()
# Set default headers for all requestssession.headers.update({ "User-Agent": "MyApp/1.0", "Authorization": "Bearer my_token"})
# All requests will use these headersresponse = 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 block14. Cookies
View Cookies
import requests
response = requests.get("https://httpbin.org/cookies/set?name=Ahmed")print(response.cookies)
# Get specific cookiefor cookie in response.cookies: print(f"{cookie.name}: {cookie.value}")Send Cookies
import requests
# Method 1: Dictionarycookies = { "session_id": "abc123", "user": "Ahmed"}response = requests.get("https://httpbin.org/cookies", cookies=cookies)print(response.json())
# Method 2: CookieJarjar = 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 cookiessession.cookies.set("token", "secret123")
response = session.get("https://httpbin.org/cookies")print(response.json())15. Authentication
Basic Authentication
import requestsfrom requests.auth import HTTPBasicAuth
# Method 1response = 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) # 200Digest Authentication
import requestsfrom 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 headersheaders = {"X-API-Key": "your_api_key"}response = requests.get("https://api.example.com/data", headers=headers)
# In query paramsparams = {"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 requestsfrom requests.adapters import HTTPAdapterfrom urllib3.util.retry import Retry
# Configure retry strategyretry_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 retrysession = requests.Session()adapter = HTTPAdapter(max_retries=retry_strategy)session.mount("http://", adapter)session.mount("https://", adapter)
# Use sessionresponse = session.get("https://example.com/api")17. SSL Verification
Disable SSL Verification (Not Recommended!)
import requestsimport urllib3
# Disable warningsurllib3.disable_warnings()
# Skip SSL verificationresponse = requests.get("https://self-signed.badssl.com/", verify=False)Custom Certificate
import requests
# Use custom CA bundleresponse = requests.get("https://example.com", verify="/path/to/ca-bundle.crt")
# Use client certificateresponse = 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 requestsfrom 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()
# Usagegithub = GitHubAPI()user = github.get_user("torvalds")print(f"Name: {user['name']}")print(f"Followers: {user['followers']}")Project 3: Website Checker
import requestsimport 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 websiteswebsites = [ "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 requestsfrom 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
| Method | Description |
|---|---|
requests.get() | GET request |
requests.post() | POST request |
requests.put() | PUT request |
requests.delete() | DELETE request |
response.text | Response as string |
response.json() | Parse JSON |
response.status_code | HTTP status code |
response.headers | Response headers |
response.cookies | Response 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 🥷🏻