Advocate HTTP Client

raw JSON →
1.0.0 verified Thu Apr 16 auth: no python

Advocate is a Python library providing a safe wrapper around the popular `requests` library for making HTTP requests on behalf of a third party. It helps prevent common security pitfalls like SSRF by allowing developers to define strict URL validation patterns, limit redirects, set timeouts, and control request options. The current version is 1.0.0, and it maintains a stable release cadence focused on security and reliability.

pip install advocate
error advocate.exceptions.InvalidURLError: URL 'http://evil.com' does not match configured regex pattern.
cause The URL provided to an Advocate request method (e.g., `get`, `post`) does not match the regular expression pattern defined in the `url_regex_pattern` parameter during `Advocate` initialization.
fix
Review your Advocate instance's url_regex_pattern to ensure it correctly allows the URLs you intend to access. If the URL is genuinely invalid, do not attempt to access it. If it should be allowed, adjust the regex pattern carefully.
error advocate.exceptions.RedirectError: Request resulted in a redirect to 'https://new-location.com' but raise_on_redirect is True.
cause The requested URL returned an HTTP redirect, but the `Advocate` instance was configured with `raise_on_redirect=True`, which explicitly forbids following redirects.
fix
If you intend to follow redirects, set raise_on_redirect=False during Advocate initialization. If redirects are a security concern (as often recommended for third-party requests), investigate why the target URL is redirecting.
error AttributeError: 'Advocate' object has no attribute 'json'
cause You are attempting to call a response method like `.json()`, `.text`, or `.status_code` directly on the `Advocate` instance itself, instead of on the `response` object returned by its request methods.
fix
Store the result of advocate.get() (or post, etc.) in a variable, then call response methods on that variable. Example: response = advocate.get(url); data = response.json().
gotcha The `url_regex_pattern` is critical for security. If it's too broad or incorrectly specified, it can negate Advocate's safety features, potentially exposing your application to Server-Side Request Forgery (SSRF) vulnerabilities.
fix Thoroughly test your `url_regex_pattern` to ensure it only permits intended URLs. Use online regex testers and consider edge cases. It's often safer to define a whitelist of allowed domains/paths rather than trying to blacklist.
gotcha Misconfiguring `max_redirects` and `raise_on_redirect` can lead to unexpected behavior or security issues. For third-party requests, unsolicited redirects might point to malicious or unintended destinations.
fix For sensitive third-party requests, it's generally recommended to set `max_redirects=0` and `raise_on_redirect=True` to explicitly control and prevent redirects. Only allow redirects if you fully trust the redirect chain.
gotcha Advocate adds overhead due to URL validation and other safety checks. Using it for requests where there is no third-party involvement or trust concern can introduce unnecessary performance penalties.
fix Only use `Advocate` when making HTTP requests on behalf of an untrusted third party or when strict URL validation and request control are required for security. For internal or trusted requests, use `requests` directly.

This quickstart demonstrates how to initialize `Advocate` with a strict URL regex pattern, disable redirects, set a timeout, and make a safe GET request. It also shows how the library prevents requests to URLs that don't match the configured pattern, raising `InvalidURLError`.

from advocate import Advocate

# Configure Advocate for safe third-party requests
# This example allows requests only to google.com/search
advocate = Advocate(
    url_regex_pattern="^https://www\.google\.com/search",
    max_redirects=0, # Disallow redirects for this sensitive operation
    raise_on_redirect=True,
    timeout=5, # Set a timeout to prevent hanging requests
    requests_options={
        "headers": {"User-Agent": "MySafeClient/1.0"},
        "verify": True # Ensure SSL verification is on
    }
)

try:
    # Make a safe GET request
    response = advocate.get("https://www.google.com/search?q=python+advocate")
    response.raise_for_status() # Raise an exception for HTTP errors (4xx or 5xx)
    print(f"Request successful! Status: {response.status_code}")
    print("First 200 characters of response:")
    print(response.text[:200])
except advocate.exceptions.InvalidURLError as e:
    print(f"Invalid URL error: {e}")
except advocate.exceptions.RedirectError as e:
    print(f"Redirect error: {e}")
except Exception as e:
    print(f"An unexpected error occurred: {e}")

# Example of a disallowed URL (will raise InvalidURLError)
try:
    advocate.get("http://internal-api.example.com/sensitive-data")
except advocate.exceptions.InvalidURLError as e:
    print(f"Successfully blocked disallowed URL: {e}")
except Exception as e:
    print(f"Unexpected error for disallowed URL: {e}")