Activate HTTP Proxy in Your Django Project Without Using Extra Packages

source

icroservice architecture has been concurred our software architectures since couple years ago and because of that, you need to find a way to connect your containers together specially when you have a distributed system and your nodes are in different hosts around the world.
Another issue is that some countries has been banned their users from accessing the internet, both websites and APIs, and developer need to find a way to access free internet.
On the other hand, the services that published their APIs has been banned the connections from inside of some countries. (Hard to believe)
A big example for this situation is a trade bot developer who is trying to requests famous exchanges like Binance (or other exchanges around the world), when developer can’t request exchange APIs, therefore you need to request APIs in your project with proxy.
So, here you’ll learn how to pass all requests with requests python package through proxy server.

There’s two different scenarios:
1- Use proxy when run service on local server
2- Use proxy when you run your service with uWSGI/ASGI

At this point we assume that you already have created a bash service to open a port on your server, so we just pass requests through this address.
for example you’ll pass all requests to proxy route on localhost (127.0.0.1) address with port 1080 .
On the other hand you can open a port with ssh -D command, so a tunnel will be open.
For example ssh dev@google.com -D 1080 will open a tunnel and if you configure your application, all data will be passes through this tunnel.

Let’s get started…

Installing the requirements (I have not used third-party packages like django-proxy):

$ pip install requests
$ pip install pysocks

Python requests package supports proxies with pysocks package.

Pysocks package will read default keys (like http , https , ftp , etc.) through environment variables (There’s also another way to set the proxy in request, you can pass proxies dict variable to request)

First we use a variable to determinate if we should use proxy in our application or not, and after that we’ll define PROXY_HOST and PROXY_PORT variables to get this variables dynamically from environment. in your settings.py define ENABLE_PROXY PROXY_HOST and PROXY_PORT variables:

# settings.py
import os
# Set default values depend on your needs.
ENABLE_PROXY = os.environ.get("ENABLE_PROXY", False)
ENABLE_HOST = os.environ.get("ENABLE_HOST", '127.0.0.1')
ENABLE_PORT = os.environ.get("ENABLE_PORT", 1080)

Then we need to config our application to use or not to use proxy when it starts. Due to this, if you’re running your application on localhost with command python manage.py runserver you need to edit manage.py module. on the other hand (in production and deployment area) you need to set this config on uWSGI or ASGI module.

pysockes module will automatically inspect two main variables (http_proxy and https_proxy) in your environment and will set them to every request.

Let’s start with localhost .
Edit manage.py module and add following line of codes:

# manage.py
import os
import sys
from django.conf import settings # import Django settings
def main():
"""Run administrative tasks."""
# This line declares Django settings, so we put our codes after this line.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'CoreEngine.settings')
# check if we need to use proxy config or not
# you can also define PROXY_URI in settings.py module
if settings.PROXY_ENABLE:
proxy_uri = f"socks5h://{settings.PROXY_HOST}:{settings.PROXY_PORT}"
os.environ['http_proxy'] = proxy_uri
os.environ['https_proxy'] = proxy_uri

try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)

In your deployment area (if you’re not using docker) do the same thing base on your use case (WSGI or ASGI)

Here we just edit WSGI module:

import os

from django.core.wsgi import get_wsgi_application
from django.conf import settings # import django settings module


os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'CoreEngine.settings')
# check if we need to use proxy config or not
# you can also define PROXY_URI in settings.py module
if settings.PROXY_ENABLE:
proxy_uri = f"socks5h://{settings.PROXY_HOST}:{settings.PROXY_PORT}"
os.environ['http_proxy'] = proxy_uri
os.environ['https_proxy'] = proxy_uri

application = get_wsgi_application()

All done, now your application’s requests will pass through your proxy server.

In order to improve myself and also this article, I would like to hear any comment and optimization ideas. So feel free to leave a comment and we’ll discuss about it ASAP :)

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store