Django Logux integration engine https://logux.io/
Project description
Logux Django
Django Logux integration engine.
- Guide, recipes, and API
- Chat for any questions
- Issues and roadmap
- Projects inside Logux ecosystem
Installation
Install from PyPI
pip install logux-django
Install dev version from current master.
pip install -e git://github.com/logux/django.git#egg=logux_django
Add path(r'logux/', include('logux.urls')),
into your urls.py
Sets Logux settings in your settings.py
:
# Logux settings: https://logux.io/guide/starting/proxy-server/
LOGUX_CONFIG = {
'URL': 'http://localhost:31337/',
'CONTROL_SECRET': 'parole',
'AUTH_FUNC': auth_func, # auth_func(user_id: str, token: str, cookie: dict, headers: dict) -> bool
'SUBPROTOCOL': '1.0.0',
'SUPPORTS': '^1.0.0'
}
Storing passwords or secrets in settings.py
is bad practice. Use ENV.
For urls and settings examples, please checkout test_app
settings
Keep in mind: the path in your urls.py
(logux/
) and the LOGUX_CONTROL_SECRET
from the settings should be passed
into Logux Server by ENV as
LOGUX_BACKEND
and LOGUX_CONTROL_SECRET
respectively.
For example:
LOGUX_BACKEND=http://localhost:8000/logux/
LOGUX_CONTROL_SECRET=secret
Usage
Actions
For action
handling add logux_actions.py
file in your app, add ActionCommand
inheritors and implement all his
abstract methods.
Actions classes requirements:
- Set
action_type: str
- Implement all
ActionCommand
abstracts methods - Implement
resend
andprocess
methods if you need (optional) - import
logux
dispatcher:from logux.dispatchers import logux
- Register all your action handlers:
logux.actions.register(YourAction)
For example – User rename action handler:
import json
from typing import Optional, List
from logux.core import ActionCommand, Meta, Action
from logux.dispatchers import logux
from logux.exceptions import LoguxProxyException
from tests.test_app.models import User
class RenameUserAction(ActionCommand):
""" During the subscription to users/USER_ID channel sends { type: "users/name", payload: { userId, name } }
action with the latest user’s name. """
action_type = 'users/name'
def resend(self, action: Action, meta: Optional[Meta]) -> List[str]:
return [f"users/{action['payload']['userId']}"]
def access(self, action: Action, meta: Meta) -> bool:
if 'error' in self.headers:
raise LoguxProxyException(self.headers['error'])
return action['payload']['userId'] == meta.user_id
def process(self, action: Action, meta: Meta) -> None:
user = User.objects.get(pk=action['payload']['userId'])
first_name_meta = json.loads(user.first_name_meta)
if not first_name_meta or Meta(first_name_meta).is_older(meta):
user.first_name = action['payload']['name']
user.first_name_meta = meta.get_json()
user.save()
logux.actions.register(RenameUserAction)
Channels (Subscription)
For subsription
handling add logux_subsriptions.py
file in your app, and ChannelCommand
inheritors
and implement all his abstract methods.
Subscription classes requirements:
- Set
channel_pattern: str
– this is a regexp like Django's url's patters inurls.py
- Implement all
ChannelCommand
abstracts methods - import
logux
dispatcher:from logux.dispatchers import logux
- Register all your subscription handlers:
logux.channels.register(YourChannelCommand)
For example:
from typing import Optional
from logux.core import ChannelCommand, Action, Meta
from logux.dispatchers import logux
from logux.exceptions import LoguxProxyException
from tests.test_app.models import User
class UserChannel(ChannelCommand):
channel_pattern = r'^users/(?P<user_id>\w+)$'
def access(self, action: Action, meta: Meta) -> bool:
return self.params['user_id'] == meta.user_id
def load(self, action: Action, meta: Meta) -> Action:
if 'error' in self.headers:
raise LoguxProxyException(self.headers['error'])
user, created = User.objects.get_or_create(id=self.params['user_id'])
if created:
user.first_name = 'Name'
return {
'type': 'users/name',
'payload': {'userId': str(user.id), 'name': user.first_name}
}
logux.channels.register(UserChannel)
For more examples, please checkout test app
(tests/test_app)
Utils
logux.core.logux_add
logux_add(action: Action, raw_meta: Optional[Dict] = None) -> None
is low level API function to send any actions and meta into Logux server.
If raw_meta
is None
just empty Dict will be passed to Logux server.
Keep in mind, in the current version logux_add
is sync.
For more information: https://logux.io/node-api/#log-add
Development
Create dev environment
make venv
make install
make run
Type checking and linting:
make lint
Test:
make test
Integration tests (up server and run backend-test):
make integration_test
License
The package is available as open source under the terms of the MIT License.