Django Plugin
Invoke Zato services from Django views, models or any other Python code.
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.

Installing the plugin
Install the plugin from PyPI:
Configuration
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/zato/api/invoke/django/{}'
ZATO_USERNAME = 'django'
ZATO_PASSWORD = 'your-zato-password'
Settings reference
| Setting | Description | Default |
|---|---|---|
ZATO_URL | URL of the Zato Django channel endpoint | http://localhost:17010/zato/api/invoke/django/{} |
ZATO_USERNAME | Username for authentication | django |
ZATO_PASSWORD | Password for authentication | (none) |
Zato server configuration
- Zato automatically creates the
/djangochannel when the server starts - No additional configuration is needed on the Zato side
- For production, you can use a separate password by setting
Zato_Django_Passwordin both Django'ssettings.pyand in the Zato container
Next steps
The client.invoke method
The plugin provides a single method to call any Zato service:
Parameters
| Parameter | Type | Description |
|---|---|---|
service | string | Name of the Zato service to invoke |
data | dict or None | Request data to send to the service |
request | Django request or None | Optional Django request for context propagation |
Return value
The method returns a dictionary containing the response from the Zato service.
Exceptions
The method raises requests.HTTPError if the request fails.
Basic usage
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)
Usage in views
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)
Handling responses
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,
})
Error handling
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)
Next steps
Cybersecurity automation
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,
})
Flight information display
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'],
})
Returning HTML
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'],
})
Next steps
Context propagation
The plugin includes optional middleware that automatically propagates context from Django requests to Zato services. This is useful for:
- Passing the authenticated Django user to Zato
- Tracking requests with correlation IDs
- Forwarding the client IP address
Installing the middleware
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
]
What gets propagated
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 |
Accessing context in Zato services
In your Zato services, access the propagated context via self.request.http.headers:
from zato.server.service import Service
class MyService(Service):
def handle(self):
headers = self.request.http.headers
django_user = headers.get('x-zato-user', '')
correlation_id = headers.get('x-zato-correlation-id', '')
client_ip = headers.get('x-zato-forwarded-for', '')
self.logger.info('Request from user %s (IP: %s, CID: %s)',
django_user, client_ip, correlation_id)
Manual context propagation
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)
Next steps
Schedule a meaningful demo
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."
- John Adams