Quick answer
How do I use a US city proxy in Python?
Build the proxy URL from the gateway and a city username, then pass it to requests: http://USERNAME-country-us-state-il-city-chicago:[email protected]:7777. Add -zip- for a neighborhood or -session- to keep one IP. MetroProxies includes city, ZIP and ASN targeting on every plan from $0.50/GB (October 2026). No KYC; crypto.
import requests
user = "USERNAME-country-us-state-il-city-chicago"
proxy = f"http://{user}:[email protected]:7777"
r = requests.get("https://ipinfo.io/json", proxies={"http": proxy, "https": proxy}, timeout=30)
r.raise_for_status()
print(r.json().get("city"), r.json().get("org"))
How do I fall back from ZIP to city to state?
Small places can have no IP online at a given moment. Try the narrow request first, widen one level at a time, and return the level that answered so you can store it with the result. The function below does exactly that and gives up after the state level instead of retrying forever.
import requests
GATEWAY = "gw.metroproxies.com:7777"
USER, PASSWORD = "USERNAME", "PASSWORD"
def fetch_local(url: str, state: str, city: str | None = None, zip_code: str | None = None) -> tuple[str, requests.Response]:
levels = []
if city and zip_code:
levels.append(("zip", f"-state-{state}-city-{city}-zip-{zip_code}"))
if city:
levels.append(("city", f"-state-{state}-city-{city}"))
levels.append(("state", f"-state-{state}"))
last_error: Exception | None = None
for level, segment in levels:
proxy = f"http://{USER}-country-us{segment}:{PASSWORD}@{GATEWAY}"
try:
r = requests.get(url, proxies={"http": proxy, "https": proxy}, timeout=30)
r.raise_for_status()
return level, r
except requests.RequestException as e:
last_error = e
raise RuntimeError(f"no IP at zip, city or state level: {last_error}")
level, resp = fetch_local("https://ipinfo.io/json", "nm", city="albuquerque", zip_code="87102")
print(level, resp.json().get("city"))
import requests
user = "USERNAME-country-us-state-wa-city-tacoma-session-tac01-ttl-15"
proxy = f"http://{user}:[email protected]:7777"
with requests.Session() as s:
s.proxies = {"http": proxy, "https": proxy}
first = s.get("https://api.ipify.org", timeout=30).text
# step 1, step 2 ... on your own site, all from the same Tacoma IP
second = s.get("https://api.ipify.org", timeout=30).text
print(first, second, "same IP" if first == second else "IP changed: restart the flow")
Which Python details trip people up?
- New IP per request:
requests.Session()keeps the connection open, so rotating mode gives one IP for the whole session. Use plainrequests.get()calls or a newSessionper request to rotate. - SOCKS5: install
pip install "requests[socks]"and usesocks5h://so that the proxy resolves hostnames, not your machine. Port 7778. - Special characters in the password: URL-encode them with
urllib.parse.quote(password, safe=""). - Timeouts: always set one; residential exits can be slower than data-center ones.
- Be polite: keep the request rate to each site modest and follow robots.txt and its terms.
Where should I go next?
Start from the five-minute setup, compare with the Node.js and curl examples, and keep IPs with sticky sessions by city. All docs: documentation.
What else do people ask about Python?
Does httpx work too?
Yes. In httpx 0.28 and later, pass proxy="http://USERNAME-country-us-state-il-city-chicago:[email protected]:7777" to httpx.Client(). Older versions used a proxies argument.
Were these examples run against the gateway?
They are syntax-checked with python -I -m py_compile on Python 3.10+, with USERNAME and PASSWORD as placeholders. Run them with your own credentials.
How do I get the ASN of the exit IP?
The org field of ipinfo.io's reply starts with it ("AS7922 ..." for Comcast). For ASN targeting, add -asn-7922 to the username; see ASN targeting.