🇪🇺 Fixed outbound IP for PythonAnywhere

🇪🇺 Static IP for PythonAnywhere

Your PythonAnywhere app calls partner APIs that enforce IP whitelisting, but its shared cloud infra rotates your outbound IP. Route requests and httpx calls through two fixed EU IPs with one HTTPS_PROXY env var.

flask_app.py

# PythonAnywhere WSGI env

HTTPS_PROXY=https://user:pass@eu-01.outboundgateway.com:8443

import requests

resp = requests.get(

  "https://api.partner.eu/data",

  headers={"Authorization": "Bearer .."}

)

The Problem

PythonAnywhere is a great Python host, but its shared cloud infrastructure means your app's outbound IP is dynamic. Partner APIs that enforce IP whitelisting block those rotating IPs.

Partner APIs enforce IP allowlisting

Payment providers, CRMs, and enterprise APIs require IP whitelisting. When your PythonAnywhere app gets a new outbound IP from the shared pool, the whitelist breaks and API calls fail silently.

Shared infra rotates IPs

PythonAnywhere runs your Django, Flask, or web2py app on shared infrastructure. The outbound IP depends on which server the load balancer assigns, and it changes without warning.

No native static IP feature

PythonAnywhere doesn't offer a static outbound IP. You can't pin one through their dashboard or settings. You need an external proxy to give your app a predictable egress.

Free and Hacker plans share IPs

On PythonAnywhere's free and lower-tier plans, multiple apps share the same outbound IP pool. Your API calls inherit the reputation of other tenants on the same address, which can trigger rate limits or blocks.

The Solution

Set one env var. All outbound calls route through your static EU IP.

The Python requests library (and httpx, urllib3) automatically reads HTTPS_PROXY from the environment. Set it once in your PythonAnywhere WSGI file and every outbound call your app makes leaves through your fixed EU IPs.

No code changes. Set HTTPS_PROXY and your existing requests.get() calls work as-is.
Two fixed EU IPs with automatic failover. If one goes down, the other takes over.
TLS passthrough. The proxy never sees your traffic. API keys and payloads stay encrypted.

Implementation

Set HTTPS_PROXY in your PythonAnywhere WSGI file. Your existing code works as-is.

Python (requests in a Django/Flask view)

Your existing view code works as-is. requests reads HTTPS_PROXY from the environment automatically.

# /var/www/yourusername_pythonanywhere_com_wsgi.py
import os
import requests

# Set the proxy at the top of your WSGI file
os.environ["HTTPS_PROXY"] = "https://user:pass@eu-01.outboundgateway.com:8443"
os.environ["PARTNER_API_TOKEN"] = "your_token"

# Then your existing app code works as-is
# requests honours HTTPS_PROXY automatically
resp = requests.get(
    "https://api.partner.eu/data",
    headers={"Authorization":
        f"Bearer {os.environ['PARTNER_API_TOKEN']}"},
)

Alternative: Use a .env file

If you prefer not to hardcode in the WSGI file, store it in a .env file in your home directory and load it.

# /home/yourusername/.env
HTTPS_PROXY=https://user:pass@eu-01.outboundgateway.com:8443

# In your WSGI file, load it:
from dotenv import load_dotenv
load_dotenv("/home/yourusername/.env")

Two IPs, automatic failover

Your account comes with two static IP addresses (for example 51.xx.xx.10 and 51.xx.xx.11). Whitelist both on your partner API. If one proxy node is briefly unavailable, traffic shifts to the other.

📖 Complete Documentation: For detailed examples, error handling, and other Python libraries, see the Python SSL Proxy Guide and all other language guides.

Why PythonAnywhere developers choose OutboundGateway

A pair of fixed IPs

Two addresses to whitelist, with automatic failover. No rotating shared pool to chase.

Zero code changes

Set HTTPS_PROXY in your WSGI file and your existing requests, httpx, and urllib3 calls work as-is.

EU-hosted

European data centres and a GDPR-conscious setup, giving your app a predictable EU address.

Works on any plan

Free, Hacker, Web Dev, or Custom. The proxy is just an env var, so it works regardless of your PythonAnywhere tier.

Encrypted end to end

TLS passthrough means the proxy can't read your traffic. API keys and payloads stay private.

Flexible plans

Starting from €19/month. Flexible plans for every scale. Cancel anytime.

Give your PythonAnywhere app a static EU IP

Stop letting dynamic IPs break your partner API integrations. Set one env var and your outbound calls route through two fixed EU IPs.

€19/month starter plan • 7-day refund policy • Direct founder support

Frequently asked questions

Does PythonAnywhere offer a static outbound IP?

No. PythonAnywhere runs your app on shared cloud infrastructure, so the outbound IP depends on which server the load balancer assigns. They don't offer a fixed outbound IP on any plan. OutboundGateway fills the gap: set HTTPS_PROXY in your WSGI file and your app gets two fixed EU IPs.

Where do I set HTTPS_PROXY on PythonAnywhere?

Add os.environ["HTTPS_PROXY"] = "https://user:pass@eu-01.outboundgateway.com:8443" at the top of your WSGI file (found at /var/www/yourusername_pythonanywhere_com_wsgi.py). Or store it in a .env file in your home directory and load it with python-dotenv. Either way, Python's requests library picks it up automatically.

Does this work with Django, Flask, and web2py on PythonAnywhere?

Yes. The proxy works at the Python library level, not the framework level. Whether you run Django, Flask, web2py, Bottle, or any other Python framework on PythonAnywhere, as long as your outbound HTTP calls use requests, httpx, or urllib3, they will route through the proxy automatically.

Still deciding?

Happy to talk through how a two-IP EU egress fits your PythonAnywhere project.

Contact Our Founders →