Zato provides a Django plugin that lets your Django applications invoke Zato services directly from views, models, or any other Python code.
This means your Django application can delegate all integration work to Zato. Instead of writing code in Django to connect to external APIs, databases, message queues, or other systems, you call a Zato service that handles it for you.

Install the plugin from PyPI:
Add the following settings to your Django settings.py. By default, use the same password that you use to log in to your Zato Dashboard, i.e. the one from the Zato_Password environment variable.
ZATO_URL = 'http://localhost:17010/django'
ZATO_USERNAME = 'django'
ZATO_PASSWORD = 'your-zato-password'
| Setting | Description | Default |
|---|---|---|
ZATO_URL | URL of the Zato Django channel endpoint | http://localhost:17010/django |
ZATO_USERNAME | Username for authentication | django |
ZATO_PASSWORD | Password for authentication | (none) |
/django channel when the server startsZato_Django_Password in both Django's settings.py and in the Zato containerThe plugin provides a single method to call any Zato service:
| Parameter | Type | Description |
|---|---|---|
service | string | Name of the Zato service to invoke |
data | dict or None | Request data to send to the service |
The method returns a dictionary containing the response from the Zato service.
The method raises requests.HTTPError if the request fails.
Import the client and call invoke with the service name and request data:
from django_zato import client
response = client.invoke('my.service', {'key': 'value'})
print(response)
A typical pattern is to call Zato services from Django views:
from django.http import JsonResponse
from django_zato import client
def get_customer(request, customer_id):
response = client.invoke('crm.customer.get', {'customer_id': customer_id})
return JsonResponse(response)
The response is a dictionary. Access fields directly:
from django.http import JsonResponse
from django_zato import client
def create_order(request):
order_data = {
'customer_id': request.POST['customer_id'],
'product_id': request.POST['product_id'],
'quantity': int(request.POST['quantity']),
}
response = client.invoke('orders.create', order_data)
order_id = response['order_id']
total = response['total']
return JsonResponse({
'order_id': order_id,
'total': total,
})
Wrap calls in try/except to handle errors:
from django.http import JsonResponse
from django_zato import client
from requests import HTTPError
def get_customer(request, customer_id):
try:
response = client.invoke('crm.customer.get', {'customer_id': customer_id})
return JsonResponse(response)
except HTTPError as e:
return JsonResponse({'error': str(e)}, status=e.response.status_code)
This example shows a security operations dashboard that coordinates blocking malicious IPs across a firewall and logging incidents in a SIEM system.
# views.py
from django.http import JsonResponse
from django_zato import client
def block_ip(request):
# Extract the request ..
ip_address = request.POST['ip_address']
reason = request.POST['reason']
# .. block on firewall and get the response ..
firewall_response = client.invoke('firewall.block-ip', {'ip_address': ip_address})
rule_id = firewall_response['rule_id']
# .. log incident in SIEM ..
siem_response = client.invoke('siem.log-incident', {
'ip_address': ip_address,
'reason': reason,
'action': 'blocked',
'firewall_rule_id': rule_id,
})
# .. Extract the response from SIEM ..
incident_id = siem_response['incident_id']
# .. and return the response to the frontend.
return JsonResponse({
'status': 'ok',
'firewall_rule_id': rule_id,
'siem_incident_id': incident_id,
})
This example shows a flight status board that retrieves real-time flight data and gate assignments.
from django.http import JsonResponse
from django_zato import client
def get_flight_status(request, flight_no):
# Get flight status from the airline operations system
flight = client.invoke('flights.status', {'flight_no': flight_no})
# Get gate assignment
gate = client.invoke('gates.assignment', {'flight_no': flight_no})
return JsonResponse({
'flight_no': flight_no,
'origin': flight['origin'],
'destination': flight['destination'],
'status': flight['status'],
'scheduled_departure': flight['scheduled_departure'],
'estimated_departure': flight['estimated_departure'],
'gate': gate['gate_number'],
'terminal': gate['terminal'],
})
def get_departures(request):
terminal = request.GET.get('terminal')
# Get all departures for the next 4 hours
departures = client.invoke('flights.departures', {
'terminal': terminal,
'hours_ahead': 4,
})
return JsonResponse({
'terminal': terminal,
'flights': departures['flights'],
})
Views don't have to return JSON - you can return HTML pages just like any other Django view.
# views.py
from django.shortcuts import render
from django_zato import client
def customer_profile(request, customer_id):
# Get customer data from CRM
customer = client.invoke('crm.customer.get', {'customer_id': customer_id})
# Get recent orders
orders = client.invoke('orders.list', {'customer_id': customer_id, 'limit': 10})
# Render an HTML template
return render(request, 'customers/profile.html', {
'customer': customer,
'orders': orders['items'],
})
The plugin includes optional middleware that automatically propagates context from Django requests to Zato services. This is useful for:
Add the middleware to your Django settings.py:
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django_zato.middleware.ZatoMiddleware', # Add this line
]
When the middleware is installed, every call to client.invoke automatically includes these headers:
| Header | Description |
|---|---|
X-Zato-User | Username of the authenticated Django user |
X-Zato-Correlation-Id | Unique ID for request tracing (generated if not present) |
X-Zato-Forwarded-For | Client IP address from REMOTE_ADDR |
In your Zato services, access the propagated context via self.wsgi_environ:
from zato.server.service import Service
class MyService(Service):
def handle(self):
ctx = self.wsgi_environ.get('zato.request_ctx', {})
django_user = ctx.get('django_user')
correlation_id = ctx.get('correlation_id')
client_ip = ctx.get('forwarded_for')
self.logger.info('Request from user %s (IP: %s, CID: %s)',
django_user, client_ip, correlation_id)
If you don't want to use the middleware, you can pass the Django request explicitly:
from django.http import JsonResponse
from django_zato import client
def my_view(request):
# Pass the request explicitly for context propagation
result = client.invoke('my.service', {'key': 'value'}, request=request)
return JsonResponse(result)
Book a demo with an expert who will help you build meaningful systems that match your ambitions
"For me, Zato Source is the only technology partner to help with operational improvements."