Learn how to route Python PyMongo traffic through a QuotaGuard Static IP using a native SOCKS proxy.
pip install pymongo PySocks
QUOTAGUARDSTATIC_URL: Your QuotaGuard Static proxy URL:
socks5://user:password@eu-west-static-01.quotaguard.com:1080Found in your QuotaGuard Dashboard.
MONGO_URIA standard mongodb:// connection string with explicit hosts (see below).
Note: mongodb+srv:// URIs are not supported — DNS SRV lookups happen before the proxy is involved. See below for how to convert.
mongodb:// URI from your mongodb+srv:// URIRun this once from any machine that can reach MongoDB directly:
from pymongo import MongoClient
client = MongoClient("mongodb+srv://user:password@your-cluster.mongodb.net/",
serverSelectionTimeoutMS=10000)
info = client.admin.command("isMaster")
print("Replica Set:", info.get("setName"))
print("Hosts:", info.get("hosts"))
Then build your URI:
mongodb://user:password@host1:27017,host2:27017,host3:27017/?ssl=true&replicaSet=<setName>&authSource=adminConnect to MongoDB through a QuotaGuard Static SOCKS5 proxy using pure Python, no QGTunnel wrapper required.
Suitable for environments where you can't run a wrapper process, such as PythonAnywhere.
1. Copy quotaguard.py into your project.
2. At the very top of your entry point — before importing pymongo or any other network library — add:
from quotaguard import configure_socks_proxy
configure_socks_proxy()
3. Then import and use pymongo as normal:
from pymongo import MongoClient
client = MongoClient(os.environ["MONGO_URI"])That's it. Every TCP connection your process makes will be routed through the proxy.
# Directly
QUOTAGUARDSTATIC_URL=socks5://... MONGO_URI=mongodb://... python app.py
# Docker
docker build -t qg-static-python-mongo-example .
docker run \
-e QUOTAGUARDSTATIC_URL=socks5://... \
-e MONGO_URI=mongodb://... \
qg-static-python-mongo-example
"""
MongoDB (PyMongo) via QuotaGuard Static — no QGTunnel.
Copy quotaguard.py into your project, then follow the same three-step pattern
shown here: call configure_socks_proxy(), import MongoClient, write your app.
Environment variables:
QUOTAGUARDSTATIC_URL socks5://user:password@...quotaguard.com:1080
MONGO_URI mongodb://user:password@host1:27017,.../?ssl=true&...
Note: mongodb+srv:// URIs are not supported — see the README for how to convert.
"""
import os
# ── Step 1: patch the socket layer BEFORE importing pymongo ─────────────────────
from quotaguard import configure_socks_proxy
configure_socks_proxy()
# ── Step 2: now it's safe to import pymongo ─────────────────────────────────────
from pymongo import MongoClient
# ── Step 3: write your application as normal ────────────────────────────────────
def main():
mongo_uri = os.environ.get("MONGO_URI")
if not mongo_uri:
raise RuntimeError("Set MONGO_URI to a standard mongodb:// connection string.")
if mongo_uri.startswith("mongodb+srv://"):
raise RuntimeError(
"mongodb+srv:// URIs are not supported — DNS SRV lookups bypass the proxy.\n"
"Please convert to a standard mongodb:// URI first (see the README)."
)
print("Connecting to MongoDB via QuotaGuard Static...")
client = MongoClient(mongo_uri, serverSelectionTimeoutMS=10000)
result = client.admin.command("ping")
print(f"MongoDB ping: {result}")
print("✓ Successfully connected to MongoDB through QuotaGuard Static")
if __name__ == "__main__":
main()
"""
quotaguard.py — drop this file into your project unchanged.
Call configure_socks_proxy() once at the very top of your entry point,
before importing pymongo or any other network library.
"""
import os
import socket as _socket
import socks
from urllib.parse import urlparse
def configure_socks_proxy():
"""
Configure PySocks as the default SOCKS5 proxy and monkey-patch socket.socket
so that all outgoing TCP connections are routed through QuotaGuard Static.
Must be called before importing pymongo (or any other network library).
"""
proxy_url = os.getenv("QUOTAGUARDSTATIC_URL") or os.getenv("QUOTAGUARD_URL")
if not proxy_url:
raise RuntimeError(
"No proxy URL found. Set the QUOTAGUARDSTATIC_URL environment variable "
"to your QuotaGuard Static proxy URL."
)
proxy = urlparse(proxy_url)
if proxy.scheme not in ("socks5", "socks5h"):
raise RuntimeError(
f"Expected a socks5:// proxy URL, got scheme: {proxy.scheme!r}. "
f"Check your QUOTAGUARDSTATIC_URL value."
)
if not proxy.hostname or not proxy.port:
raise RuntimeError("Proxy URL is missing a host or port.")
# Configure PySocks to use this proxy for all new sockets
socks.set_default_proxy(
socks.SOCKS5,
proxy.hostname,
int(proxy.port),
rdns=True, # Resolve hostnames on the proxy side
username=proxy.username,
password=proxy.password,
)
# Replace socket.socket with socks.socksocket so all connections use the proxy
_socket.socket = socks.socksocket
# PyMongo creates sockets with SOCK_CLOEXEC OR'd into the type flag:
# socket.socket(af, socktype | getattr(socket, "SOCK_CLOEXEC", 0), proto)
# This produces a type value of 524289 (SOCK_STREAM | SOCK_CLOEXEC), which
# ssl.SSLSocket then rejects with "Socket type must be stream or datagram".
# Removing SOCK_CLOEXEC from the socket module causes PyMongo to fall back to
# creating plain SOCK_STREAM sockets, which ssl is happy with.
if hasattr(_socket, "SOCK_CLOEXEC"):
del _socket.SOCK_CLOEXEC
# Use an official Python runtime as a parent image
FROM python:latest
# Set the working directory in the container
WORKDIR /app
# Copy the current directory contents into the container at /app
COPY . /app
# Install the required Python packages
RUN pip install --no-cache-dir pymongo PySocks
# Command to run when the container starts, assuming the environment variable is passed at runtime
CMD ["python", "app.py"]