Last modified: Sep 13, 2026

Python Get Client IP Address Guide

Getting the client IP address in Python is a common task for web developers. It helps track users, prevent fraud, and manage access control.

This guide explains several methods to retrieve client IP addresses. We'll cover Flask, Django, and raw socket approaches.

Why Get Client IP Address?

There are many reasons to capture client IP addresses:

  • Security monitoring - Track suspicious activity
  • Rate limiting - Prevent API abuse
  • Analytics - Understand user geography
  • Access control - Restrict content by region

Always handle IP data responsibly due to privacy concerns.

Using Flask Framework

Flask provides simple ways to get client IP addresses through request objects.


from flask import Flask, request

app = Flask(__name__)

@app.route('/')
def get_client_ip():
    # Get IP from X-Forwarded-For header (proxy support)
    if request.headers.get('X-Forwarded-For'):
        ip = request.headers.get('X-Forwarded-For').split(',')[0]
    else:
        # Direct connection IP
        ip = request.remote_addr
    return f"Client IP: {ip}"

if __name__ == '__main__':
    app.run(debug=True)

This Flask example checks proxy headers first. Then falls back to direct connection IP.

Advanced Flask Example


from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/api/user-info')
def user_info():
    # Comprehensive IP detection
    ip_info = {
        'direct_ip': request.remote_addr,
        'forwarded_for': request.headers.get('X-Forwarded-For'),
        'real_ip': request.headers.get('X-Real-IP'),
        'client_ip': request.headers.get('CF-Connecting-IP')
    }
    
    # Determine actual client IP
    client_ip = (
        request.headers.get('X-Forwarded-For', '').split(',')[0] or
        request.headers.get('X-Real-IP') or
        request.headers.get('CF-Connecting-IP') or
        request.remote_addr
    )
    
    ip_info['detected_client_ip'] = client_ip
    return jsonify(ip_info)

if __name__ == '__main__':
    app.run(debug=True)

Output when accessing via browser:


{
  "direct_ip": "127.0.0.1",
  "forwarded_for": null,
  "real_ip": null,
  "client_ip": null,
  "detected_client_ip": "127.0.0.1"
}

Django Implementation

Django offers robust IP handling through middleware and request objects.


# views.py
from django.http import JsonResponse

def get_client_ip(request):
    # Check various headers for IP
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0]
    else:
        ip = request.META.get('REMOTE_ADDR')
    
    return JsonResponse({'client_ip': ip})

Django uses request.META dictionary for server variables.

Django Middleware Approach


# middleware.py
class ClientIPMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        # Extract client IP before processing
        x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
        
        if x_forwarded_for:
            request.client_ip = x_forwarded_for.split(',')[0].strip()
        else:
            request.client_ip = request.META.get('REMOTE_ADDR')
        
        response = self.get_response(request)
        return response

Raw Socket Method

For non-web applications, use Python's socket library directly.


import socket

def get_local_ip():
    """Get local network IP address"""
    try:
        # Create UDP socket to determine local IP
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.connect(("8.8.8.8", 80))
        local_ip = sock.getsockname()[0]
        sock.close()
        return local_ip
    except Exception as e:
        return "127.0.0.1"

print(f"Local IP: {get_local_ip()}")

Output example:


Local IP: 192.168.1.105

Handling Proxy Headers

Modern deployments often use reverse proxies like Nginx or Cloudflare.


def get_real_client_ip(request):
    """Robust IP extraction for proxied environments"""
    headers = [
        'HTTP_X_FORWARDED_FOR',
        'HTTP_X_REAL_IP',
        'HTTP_CF_CONNECTING_IP',  # Cloudflare
        'HTTP_TRUE_CLIENT_IP',     # Akamai
        'HTTP_X_CLIENT_IP'
    ]
    
    for header in headers:
        ip = request.META.get(header)
        if ip:
            # Take first IP if multiple present
            return ip.split(',')[0].strip()
    
    return request.META.get('REMOTE_ADDR', '0.0.0.0')

This function checks multiple proxy headers in priority order.

IP Validation and Security

Always validate extracted IP addresses to prevent spoofing.


import ipaddress

def validate_ip_address(ip_string):
    """Validate IP address format"""
    try:
        # Validate IPv4 or IPv6
        ip_obj = ipaddress.ip_address(ip_string)
        return True, str(ip_obj)
    except ValueError:
        return False, None

# Example usage
is_valid, clean_ip = validate_ip_address("192.168.1.1")
print(f"Valid: {is_valid}, IP: {clean_ip}")

Output:


Valid: True, IP: 192.168.1.1

Common Issues and Solutions

Developers face several challenges when retrieving IP addresses:

Localhost Returns 127.0.0.1

During development, request.remote_addr returns localhost. Test with real network connections for accurate results.

Proxy Configuration

If behind a proxy, ensure proper header forwarding in your web server configuration.


# Nginx configuration example
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

IPv6 Considerations

Some systems return IPv6 addresses. Handle both IPv4 and IPv6 formats.


def is_ipv6(ip_address):
    """Check if IP is IPv6 format"""
    try:
        return ':' in ip_address and '.' not in ip_address
    except:
        return False

Privacy Best Practices

Handle IP addresses responsibly:

  • Log minimization - Store only necessary data
  • Data retention - Define clear deletion policies
  • Encryption - Encrypt stored IP addresses
  • User consent - Inform users about IP collection

Testing Your Implementation

Use these tools to verify IP detection:

  1. Curl commands - Simulate requests with custom headers
  2. Browser developer tools - Inspect network requests
  3. Online IP checkers - Validate public IP detection

# Test with custom headers using curl
curl -H "X-Forwarded-For: 203.0.113.1" http://localhost:5000/

Conclusion

Retrieving client IP addresses in Python requires understanding your deployment environment. Use request.remote_addr for simple cases.

For production systems behind proxies, check headers like X-Forwarded-For and X-Real-IP. Always validate IP formats and follow privacy regulations.

Choose the right method based on your framework and infrastructure. Test thoroughly in both development and production environments.

Remember that IP addresses can be spoofed. Don't rely solely on them for security decisions. Combine with other authentication and authorization mechanisms for robust protection.