Python requests

Learn how to use Python requests for HTTPS GET and POST requests. Install requests with pip, check response.status_code, handle 200 responses, use raise_for_status(), set timeouts, and compare requests with urllib and pycurl.

Published

Updated

Read time 8 min read

Reviewed byDeepak Prasad

Python requests

The requests library is a third-party Python package for sending HTTP and HTTPS requests. You will see it in API clients, automation scripts, status checks, downloads, and web service tests.

Tested on: Python 3.13.3; requests 2.32.3; kernel 6.14.0-37-generic.


Quick answer: send an HTTPS GET request with requests

requests is not part of the Python standard library. Install it with python -m pip install requests, then call requests.get() and read response.status_code.

python
import requests

response = requests.get("https://example.com", timeout=10)
print(response.status_code)
print(response.text[:80])

A successful response from https://example.com returns status code 200 and HTML in response.text.


Python requests quick reference

Task Use
Install requests python -m pip install requests
Import requests import requests
HTTPS GET request requests.get("https://example.com")
POST form data requests.post(url, data=data)
POST JSON data requests.post(url, json=data)
Check status code response.status_code
Check 200 OK response.status_code == 200
Raise for HTTP error response.raise_for_status()
Read response text response.text
Read response bytes response.content
Parse JSON response.json()
Send query params requests.get(url, params=params)
Send headers requests.get(url, headers=headers)
Set timeout requests.get(url, timeout=10)
Verify HTTPS certificate verify=True by default
Standard-library alternative urllib.request

What is Python requests?

requests is a third-party HTTP client library. It supports GET, POST, PUT, DELETE, PATCH, HEAD, and OPTIONS, and each call returns a Response object.

For many API tasks, the interface is simpler than lower-level standard-library tools: you pass a URL, optional parameters, and read attributes on the response.

The Requests documentation shows that methods such as get() and post() return a Response object with status_code, text, content, and json().


Is requests part of the Python standard library?

No. requests is not built into Python. Install it with pip before you import it.

If someone asks whether requests is a standard Python library, the direct answer is no. The standard-library option for URL work is urllib. Python’s own urllib.request documentation notes that the Requests package is recommended when you want a higher-level HTTP client interface.


Install requests

Use python -m pip install requests inside a virtual environment for project work.

text
python -m pip install requests

Verify the install:

python
import requests

print(requests.__version__)

This prints the installed version, such as 2.32.3. Use pip3 only when python -m pip is not available on your system. See install a Python package from GitHub for pip workflow details.


Make an HTTPS GET request with requests

Pass an https:// URL to requests.get(). TLS certificate verification is enabled by default.

python
import requests

response = requests.get("https://example.com", timeout=10)
print(response.status_code)
print("Example Domain" in response.text)

For a JSON API:

python
import requests

response = requests.get(
    "https://jsonplaceholder.typicode.com/todos/1",
    timeout=10,
)
print(response.status_code)
print(response.json()["title"])

The Requests API documents the verify parameter. It defaults to True, so HTTPS certificates are checked unless you change that setting for controlled debugging only.


Check response status code

response.status_code is the HTTP status as an integer. 200 means OK. 404 means not found. 500 means a server error.

python
import requests

response = requests.get(
    "https://jsonplaceholder.typicode.com/todos/1",
    timeout=10,
)

if response.status_code == 200:
    print("OK")
else:
    print("Unexpected status:", response.status_code)

print("response.ok:", response.ok)

response.ok is True for status codes below 400. It is not the same as checking for exactly 200 OK. Use response.status_code == 200 when your code requires that specific code.

The Requests documentation defines status_code as the integer HTTP status and notes that ok is true for codes below 400.


Common requests status codes

Status code Meaning Common handling
200 OK Parse or use the response
201 Created Resource created
204 No Content Success, no response body
301/302 Redirect Usually followed automatically
400 Bad Request Check request payload or params
401 Unauthorized Check authentication
403 Forbidden Check permissions or token
404 Not Found Check URL or resource
429 Too Many Requests Back off or retry later
500 Internal Server Error Server-side issue
503 Service Unavailable Retry later

You can also compare against named codes:

python
import requests

response = requests.get("https://example.com", timeout=10)
print(response.status_code == requests.codes.ok)

requests.codes.ok corresponds to 200.


Handle HTTP errors with raise_for_status()

Call response.raise_for_status() when you want unsuccessful HTTP status codes to raise an exception.

python
import requests

response = requests.get("https://httpbin.org/status/404", timeout=15)

try:
    response.raise_for_status()
except requests.HTTPError as exc:
    print(type(exc).__name__, exc.response.status_code)

This raises HTTPError for HTTP error responses. Connection failures and timeouts raise other exceptions such as ConnectionError and Timeout. The Requests quickstart lists RequestException and related types.


Read response content

Use the attribute that matches the body type you need.

python
import requests

response = requests.get(
    "https://jsonplaceholder.typicode.com/todos/1",
    timeout=10,
)

print(type(response.text).__name__)
print(response.json()["id"])
print(len(response.content))
  • response.text returns decoded string content.
  • response.content returns bytes.
  • response.json() parses JSON and raises JSONDecodeError when the body is not valid JSON.

To save a response body to disk, write response.content or response.text with write to file in Python after you confirm the parent folder exists.


Send query parameters

Pass a dictionary to params= instead of building the query string by hand.

python
import requests

response = requests.get(
    "https://httpbin.org/get",
    params={"q": "python", "limit": 10},
    timeout=15,
)

print(response.json()["args"])

The server receives q=python and limit=10 in the query string.


Send POST requests

Use data= for HTML form fields. Use json= when the API expects a JSON body.

Form data:

python
import requests

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

The form field contains the posted fields. json is None because no JSON body was sent.

JSON body:

python
import requests

payload = {"username": "john", "role": "admin"}

response = requests.post(
    "https://httpbin.org/post",
    json=payload,
    timeout=15,
)
body = response.json()
print(body["form"])
print(body["json"])

With json=payload, the server receives JSON in the request body. The json field in the echo response contains your payload, and form is empty.


Send request headers

Use headers= for Authorization, Accept, User-Agent, and other request headers.

python
import requests

headers = {
    "Accept": "application/json",
    "Authorization": "Bearer YOUR_TOKEN_HERE",
    "User-Agent": "my-script/1.0",
}

response = requests.get(
    "https://httpbin.org/headers",
    headers=headers,
    timeout=15,
)

print(response.json()["headers"]["Authorization"])

Use placeholder tokens in examples. Do not publish real API keys or passwords.


Set timeout for requests

Always set a timeout in real scripts. Without one, a request can wait indefinitely. Log failures and retries with Python logging instead of bare print when the client runs unattended.

python
import requests

try:
    response = requests.get("https://example.com", timeout=10)
    print(response.status_code)
except requests.Timeout:
    print("Request timed out")

You can pass a tuple for connect and read timeouts, for example timeout=(3.05, 27).

The Requests quickstart states that requests do not time out unless you set timeout explicitly.


requests HTTPS and SSL verification

HTTPS URLs work directly with requests. Certificate verification is on by default.

python
import requests

response = requests.get("https://example.com", timeout=10)
print(response.url.startswith("https://"))

When a server uses a private certificate authority, pass a CA bundle path to verify, for example requests.get(url, verify="/path/to/company-ca.pem", timeout=10). Replace the path with your real bundle file. Avoid verify=False in production. Disable verification only for controlled local debugging.


requests vs urllib

Feature requests urllib
Included with Python No Yes
Install needed Yes No
API style Higher-level and simpler Lower-level standard library
JSON convenience Easier More manual
Sessions and cookies Easier with Session More manual
Best for Most scripts and API calls Standard-library-only environments

urllib is the standard-library package for opening and reading URLs, including urllib.request.


urllib vs requests: which should you use?

Use requests when you want readable code for common HTTP and API tasks. Use urllib when external dependencies are not allowed or you want zero third-party packages. When downloading to a local path, check if a file exists before overwriting an existing export.

Neither choice is a beginner mistake. They solve the same problem at different levels of abstraction.

Same HTTPS GET with requests:

python
import requests

response = requests.get("https://example.com", timeout=10)
print(response.status_code)
print(len(response.text))

Same HTTPS GET with urllib (standard library):

python
import urllib.request

with urllib.request.urlopen("https://example.com", timeout=10) as response:
    body = response.read().decode()
    print(response.status)
    print(len(body))

Both examples fetch https://example.com and print an HTTP status plus the response body length. With requests, use response.status_code and response.text. With urllib, open the URL in a context manager, read bytes, and decode when you need a string.

For stdlib-only error handling patterns, see Python try except.


pycurl vs requests

requests is the better default for everyday HTTP and REST API work in Python.

pycurl wraps libcurl and can be useful when you need lower-level curl-style control, custom TLS options, or libcurl features that requests does not expose directly. Install it with python -m pip install pycurl.

Simple GET with requests:

python
import requests

response = requests.get("https://example.com", timeout=10)
print(response.status_code)
print(response.headers.get("Content-Type"))

Similar GET with pycurl:

python
import pycurl
from io import BytesIO

buffer = BytesIO()
curl = pycurl.Curl()
curl.setopt(curl.URL, "https://example.com/")
curl.setopt(curl.WRITEDATA, buffer)
curl.setopt(curl.TIMEOUT, 10)
curl.perform()
status = curl.getinfo(curl.RESPONSE_CODE)
content_type = curl.getinfo(curl.CONTENT_TYPE)
curl.close()

print(status)
print(content_type)
print(len(buffer.getvalue()))

The requests version is shorter for typical API calls. The pycurl version maps closely to libcurl options, which some teams prefer when they already rely on curl behavior. Most beginners should start with requests unless a project specifically requires pycurl features.


Summary

requests is a third-party HTTP library, not built into Python. Install it with pip, send HTTPS GET requests with requests.get(), and inspect response.status_code to see whether the server returned 200 or another code. Use raise_for_status() to turn HTTP errors into exceptions, set timeout in real scripts, and choose urllib when you need a standard-library-only solution.


References


Frequently Asked Questions

1. Is requests part of the Python standard library?

No. requests is a third-party library. Install it with python -m pip install requests. Use urllib when you need only the standard library.

2. How do you check if a requests response returned 200?

Read response.status_code and compare it to 200. Do not rely on response.ok when you need exactly 200 OK.

3. What is the difference between data= and json= in requests.post()?

Use data= for HTML form fields. Use json= to send a JSON request body. Many APIs expect json=, not data=.

4. What does response.raise_for_status() do?

It raises requests.HTTPError when the HTTP status code indicates an error. It does not catch connection or timeout failures.

5. When should you use requests instead of urllib?

Use requests for most scripts and API calls when an external dependency is fine. Use urllib when you must stay in the standard library.

6. Can the requests library make asynchronous HTTP calls?

No. requests is synchronous. For async HTTP, use httpx or aiohttp instead.
Bashir Alam

Data Analyst and Machine Learning Engineer

Computer Science graduate from the University of Central Asia, currently employed as a full-time Machine Learning Engineer at uExel. His expertise lies in OCR, text extraction, data preprocessing, and …