Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Requests is a third-party Python library for making HTTP requests. It lets your program contact websites and APIs, send data, authenticate, manage cookies, download files, and inspect the server’s response without manually implementing HTTP. You install it with python -m pip install requests, call a method such as requests.get() or requests.post(), and work with the returned Response object.

This guide explains what Requests does, the request-and-response model, common code patterns, important options, failure handling, and when another approach may be more suitable.

What Requests does

Requests is a synchronous HTTP/1.1 client library. Python code uses it to communicate with web servers and HTTP APIs. Typical jobs include:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Fetching an HTML page or API resource.
  • Calling REST-style endpoints with query parameters.
  • Submitting form fields or JSON.
  • Uploading files with multipart form data.
  • Downloading large responses as a stream.
  • Sending cookies, authentication, custom headers, proxies, and client certificates.
  • Following redirects, applying timeouts, and reusing connections.

A request does not guarantee a successful application result. The server returns a Response containing a status code, headers, cookies, and body; your code must inspect those values and handle errors deliberately.

Install Requests and verify your environment

Installation

Install the package into the Python environment that will run your program:

python -m pip install requests

The current Requests documentation states official support for Python 3.10 and newer and notes that it runs on PyPy. Support and version details can change, so check the project documentation when pinning an environment.

A minimal request

import requests

response = requests.get("https://api.example.com/items", timeout=30)
print(response.status_code)
print(response.text)

get() returns a Response. text decodes the body as text; content gives you bytes, which is appropriate for images, archives, and other binary files.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The request-and-response pattern

Check status before using data

HTTP status codes describe the server’s result. A 2xx code generally indicates success, 3xx indicates redirection, 4xx points to a client-side problem such as bad credentials or parameters, and 5xx indicates a server-side failure. Use raise_for_status() when non-2xx responses should become exceptions:

import requests

response = requests.get("https://api.example.com/items", timeout=30)
response.raise_for_status()
items = response.json()
print(items)

For an API that may return a useful error body, catch requests.HTTPError and log the status and response text without exposing secrets.

Read JSON, headers, and cookies

data = response.json()          # decodes valid JSON
content_type = response.headers.get("Content-Type")
server_cookie = response.cookies.get("session")

.json() raises an exception if the body is not valid JSON, even when the HTTP status is 200. Check the content type or catch the decoding error when an endpoint can return HTML or an empty body.

GET requests: pages, APIs, and query parameters

Use GET to retrieve a resource. Put query-string values in params; Requests URL-encodes them correctly:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import requests

params = {"q": "python", "page": 2, "include_archived": False}
r = requests.get("https://api.example.com/search", params=params, timeout=20)
r.raise_for_status()
print(r.url)       # useful for debugging the final URL
print(r.json())

Do not concatenate untrusted values into a URL by hand. params also handles repeated keys when given a list of tuples.

POST, PUT, PATCH, and DELETE

Form-encoded data

payload = {"username": "ada", "newsletter": "yes"}
r = requests.post("https://api.example.com/signup", data=payload, timeout=30)
r.raise_for_status()

data= sends form-style fields. The server must support the corresponding content type.

JSON request bodies

payload = {"name": "Ada", "role": "developer"}
r = requests.post(
    "https://api.example.com/users",
    json=payload,
    timeout=30,
)
r.raise_for_status()
created = r.json()

json= serializes the Python object and sets the JSON content type. Use it instead of manually calling json.dumps() for ordinary JSON APIs.

Other methods

The API includes options(), head(), put(), patch(), and delete() in addition to get() and post():

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
requests.head(url, timeout=20)
requests.put(url, json=payload, timeout=20)
requests.patch(url, json=changes, timeout=20)
requests.delete(url, timeout=20)

Whether a method is allowed, and what its body means, is defined by the target service’s API.

Headers, authentication, and cookies

Headers and bearer tokens

headers = {
    "Accept": "application/json",
    "Authorization": "Bearer YOUR_TOKEN",
    "User-Agent": "my-app/1.0",
}
r = requests.get("https://api.example.com/me", headers=headers, timeout=30)
r.raise_for_status()

Keep API keys outside source control, preferably in environment variables or a secret manager. Never print authorization headers in debug logs.

Basic authentication and cookies

r = requests.get(
    "https://api.example.com/private",
    auth=("username", "password"),
    cookies={"consent": "yes"},
    timeout=30,
)

For several related calls, use a Session. It persists cookies and default headers and uses connection pooling:

with requests.Session() as session:
    session.headers.update({"Accept": "application/json"})
    login = session.post(
        "https://api.example.com/login",
        json={"user": "ada", "password": "secret"},
        timeout=30,
    )
    login.raise_for_status()
    profile = session.get("https://api.example.com/profile", timeout=30)
    profile.raise_for_status()

Timeouts, redirects, TLS, proxies, and streaming

Always set a timeout

Without a timeout, a stalled connection can wait indefinitely. A tuple separates connection and read limits:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
r = requests.get(url, timeout=(5, 30))

Catch requests.exceptions.Timeout and decide whether a bounded retry is safe for the operation.

TLS verification and certificates

Requests verifies TLS certificates by default. Keep verification enabled in production. The verify argument can point to a custom CA bundle when your organization uses a private certificate authority. Disabling verification is not a routine fix: it removes protection against certificate and man-in-the-middle errors.

r = requests.get(url, verify="/path/to/company-ca-bundle.pem", timeout=30)

Redirects and proxies

Requests follows redirects for common requests by default. Set allow_redirects=False when you need to inspect the first response. A proxy can be supplied with the proxies mapping, subject to your network and service’s policy.

Stream large downloads

with requests.get(file_url, stream=True, timeout=(5, 120)) as r:
    r.raise_for_status()
    with open("archive.zip", "wb") as output:
        for chunk in r.iter_content(chunk_size=1024 * 1024):
            if chunk:
                output.write(chunk)

Streaming avoids loading the whole file into memory. Check the response status before writing bytes to disk.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Uploading files

Use files= for multipart uploads:

with open("photo.jpg", "rb") as fh:
    r = requests.post(
        "https://api.example.com/upload",
        files={"photo": ("photo.jpg", fh, "image/jpeg")},
        data={"caption": "Profile photo"},
        timeout=60,
    )
r.raise_for_status()

Requests builds the multipart boundaries and content headers. Follow the API’s field names and size limits.

Reliability and performance practices

  • Set connect and read timeouts on every network call.
  • Call raise_for_status() or explicitly branch on status codes.
  • Retry only idempotent operations, or use an idempotency key when the API supports one. Retrying a payment or create request blindly can duplicate work.
  • Reuse a Session for many calls to the same service; urllib3-backed connection pooling reduces repeated connection setup.
  • Use streaming for large responses and close responses with a context manager.
  • Respect rate limits, Retry-After, authentication expiry, and the service’s terms.
  • Record request IDs, status codes, elapsed time, and endpoint names while redacting tokens, passwords, and personal data.

Common failures and fixes

ModuleNotFoundError: No module named 'requests'

Install into the active interpreter with python -m pip install requests. In an IDE or virtual environment, ensure its selected interpreter is the same one used for installation.

Timeout or connection error

Check the URL, DNS, firewall, proxy, and server availability. Use a bounded timeout, then retry only when the operation is safe and the service permits it.

401 or 403 response

Verify the token, authentication scheme, required scopes, clock settings, and permission for the specific resource. Do not “fix” authorization by disabling TLS verification.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

404 response

Confirm the path, API version, URL encoding, and HTTP method. Print response.url when diagnosing query parameters.

429 or 5xx response

Honor rate-limit headers and Retry-After where provided. Apply bounded exponential backoff for transient failures, and avoid retry storms.

JSON decoding error

The endpoint may have returned HTML, an empty body, or malformed JSON. Inspect status, content type, and a safely truncated portion of response.text before calling .json().

Requests versus other approaches

Requests is a straightforward synchronous client. It is a good fit for scripts, web back ends that make occasional outbound calls, integrations, and command-line tools. If an application must maintain many concurrent connections without blocking, an asynchronous HTTP client may be more appropriate; that is a different programming model and is not a claim that Requests is unsuitable for every concurrent design. The official Requests materials establish its own API and features, not a universal ranking against other libraries.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If your Python task is obtaining a clean image or PDF of a web page rather than processing HTTP yourself, ScreenshotNeo provides a single HTTP endpoint. It accepts a URL and can return PNG, JPEG, WebP, or PDF. Before capture it accepts cookie/consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients.

Python

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)

See the full options and response details in the ScreenshotNeo documentation.

cURL

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Node.js

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

ScreenshotNeo includes full-page and lazy-image loading, CSS-selector element capture, dark mode, device and viewport controls, retina scale, PDF paper settings, custom CSS and JavaScript, clicks, waits, blocking rules, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, cache TTLs, signed links, asynchronous webhooks, bulk capture of up to 100 URLs per call, usage API, OpenAPI specification, and familiar parameter names for easier migration. Every feature is on every plan: 1,000 shots per month are free with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

FAQ

Is Requests part of Python’s standard library?

No. It is an installable third-party package.

Can Requests call HTTPS APIs?

Yes. HTTPS is supported, with certificate verification enabled by default.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Does a successful network call mean the API operation succeeded?

No. Inspect the HTTP status and validate the response body for the service you called.

Can Requests run JavaScript in a web page?

No. It is an HTTP client, not a browser automation engine; it receives server responses and does not render a page like a browser.

Frequently Asked Questions

Is Requests free to use?

Requests is distributed as a Python package; the supplied official materials describe installation and documentation rather than a separate paid license or service plan.

How do I prevent secrets from leaking in logs?

Store credentials in environment variables or a secret manager, redact authorization headers and cookies, and avoid logging complete request URLs when they contain sensitive query values.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Should every request be retried automatically?

No. Retry only transient failures and operations that are safe to repeat, or use an API-provided idempotency mechanism.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.