Django services app
Project description
About
This package provides services for django applications. The servitin service is an asynchronous standalone application.
Installation
pip install servitin
Howto
Add servitin
to settings.INSTALLED_APPS
Make sure you have LOGGING
settings in your project - servitin needs this.
Let's say you have a django app myapp
.
Make myapp
a servitin service by adding the line is_servitin = True
in myapp/apps.py
:
from django.apps import AppConfig
class MyappConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'myapp'
is_servitin = True
Create file myapp/servitin.py
:
from servitin.base import BaseService
class Service(BaseService):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.log.info(f"Myapp service ready.")
(Not necessary) Give the version myapp
, write in the file myapp/__init__.py
:
__version__ = '1.0'
Start service:
./manage.py run_servitin
If all is ok you will see in the log Myapp service ready.
Logging
To configure the built-in logger for each service, Servitin looks for a logger named servitin_myservice_logger
for the myservice
app,
similarly for the my_other_service
app it will look for servitin_my_other_service_logger
.
Buil-in logger is used like this:
self.log.info(f"Myapp service ready.")
in the example above
Request handling
Edit myapp/servitin.py
to make the service as the ZeroMQ server:
from servitin.base import BaseService
from servitin.lib.zmq.server import ZMQServer
class Service(ZMQServer, BaseService):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.log.info(f"Myapp service ready.")
Create myapp/settings.py
:
from django.conf import settings
settings.SERVITIN_MYAPP_ZMQ = getattr(settings, 'SERVITIN_MYAPP_ZMQ', {
'BIND_ADDRESS': 'tcp://*:5555',
'CONNECT_ADDRESS': 'tcp://127.0.0.1:5555',
'SECRET': ''
})
Create file myapp/zmq.py
:
import asyncio
from servitin.lib.zmq.server import zmq, Response
from asgiref.sync import sync_to_async
from django.core import serializers
from django.contrib.auth.models import User
from servitin.utils import serializable
@zmq
async def get_users(request):
order_by = request.data['order_by']
# use built-in logger
request.log.info(f'request order: {order_by}', name='@get_users')
def get_data():
# data with datetime objects, so it no serializable
data = serializers.serialize('python', User.objects.all().order_by(order_by), fields=('username', 'date_joined'))
# so make it serializable (you can use your own serializer)
return serializable(data)
return Response(request, await sync_to_async(get_data)())
@zmq
async def heavy_task(request):
""" emulate heavy task endpoint for timeout test """
await asyncio.sleep(5)
request.log.info(f'data: {request.data}', id=request.request_id, name='@heavy_task')
return Response(request, f'complete: {request.data}')
Here we have created two endpoints: get_users
, heavy_task
.
The service is ready to handle requests, let's test it.
Create django management command myapp/management/commands/test_myapp_service.py
:
import asyncio
from django.core.management import BaseCommand
from servitin.lib.zmq.client import Servitin
import myapp.settings # import our service settings
class Command(BaseCommand):
def handle(self, *args, **options):
async def do():
async with Servitin('myapp').connect() as my_service:
print(await my_service.get_users({'order_by': 'username'}))
asyncio.run(do())
In this example servitin client configured via myapp/settings.py
.
Run it:
./manage.py test_myapp_service
Calls
It is also possible to use the servitin client outside of django.
Create file test_calls.py
:
from servitin.lib.zmq.client import Servitin
import asyncio
loop = asyncio.get_event_loop()
params = {'connect': 'tcp://127.0.0.1:5555', 'secret': ''}
# ASYNC CALLS
async def do():
# manual close connection
my_service = Servitin(**params)
results = await asyncio.gather(*[
my_service.get_users({'order_by': 'username'}),
my_service.get_users({'order_by': 'id'})
])
print(results)
my_service.close() # close connection
# auto close connection via context manager
async with Servitin(**params).connect() as my_service:
print(await my_service.get_users({'order_by': 'username'}))
# timeout
# you can specify timeout by passing it to Servitin():
# async with Servitin(connect='tcp://127.0.0.1:5555', secret='', timeout=1).connect() as my_service:
async with Servitin(**params).connect() as my_service:
try:
# or pass it directly in call
print(await my_service.heavy_task({'data': 'context manager, timeout call'}, timeout=1))
except asyncio.TimeoutError as e:
print(e.__repr__())
loop.run_until_complete(do())
# SYNC CALLS
params = {'connect': 'tcp://127.0.0.1:5555', 'secret': '', 'async_mode': False}
# manual
my_service = Servitin(**params)
print(my_service.get_users({'order_by': 'username'}))
my_service.close()
# via context manager
with Servitin(**params).sync_connect() as my_service:
print(my_service.get_users({'order_by': 'username'}))
loop.close()
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file servitin-1.0.4.tar.gz
.
File metadata
- Download URL: servitin-1.0.4.tar.gz
- Upload date:
- Size: 13.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.4.2 importlib_metadata/4.8.1 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.5
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | b0e4cc757d217ffe86a01f22cc3e079ecf556e7d263045fdf18b51ba76106dcb |
|
MD5 | f0a9131487563f6e92331cd256d4c386 |
|
BLAKE2b-256 | f6ea6f96e73f439f6aab7933e748c63ad8a16ac294604c47603e8c68ebf36c21 |
File details
Details for the file servitin-1.0.4-py3-none-any.whl
.
File metadata
- Download URL: servitin-1.0.4-py3-none-any.whl
- Upload date:
- Size: 14.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.4.2 importlib_metadata/4.8.1 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.5
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | f2f15605f2230483542dabbd0660129ea833c183be32748868071a152b240bb6 |
|
MD5 | 7e939241f9b2616deabf0548814ba16a |
|
BLAKE2b-256 | ed1c859c0f6c43c9bfe1de21dbfd5782f485c27e15be671d9c023676cda7b42e |