django_reciprocity

Interactive web apps with Django


License
MIT
Install
pip install django_reciprocity==0.0.1

Documentation

django-reciprocity

https://travis-ci.org/mpasternak/django-reciprocity.svg?branch=develop

To make a long story short, read description of django-nginx-push-stream . This is a bit higher level, than django-nginx-push-stream - it is an implementation of an interactive web UI in JavaScript (based on jQuery and Foundation 6) and Python (Django). It sits on top of nginx-push-stream.

Running the demo

nginx and rabbitmq

Run the nginx with http-push-stream module. You can run it locally (see django-nginx-push-stream docs), you can run it using included image. In this repo's root dir:

docker-compose up webserver rabbitmq

This will boot a container running nginx with HTTP-push-stream module and a RabbitMQ node.

This nginx server is a proxy to a service running on your local machine (it loops back to docker.host.internal port 8080). It listens by default on port 9080. If you ever need to change this port, make sure to adjust variables NGINX_PUSH_STREAM_PUB_PORT and NGINX_PUSH_STREAM_SUB_PORT defined in test_project.settings.

Celery container defined in that compose file listens by default on port 45672. If you want to change it, please make sure to adjust variable CELERY_BROKER_URL in test_project.settings.

There may be more containers defined in the docker-compose.yml file. They're utilized for tests and may take more time to download, so that's why it is good to specify which containers to start when running docker-compose.

Set-up test_project with requirements

From the root directory of the repo, please:

cd test_project
yarn
pip install -r requirements.txt
export PYTHONPATH=..
python manage.py migrate

celery

It's time to launch our background worker, that will handle long-running tasks.

celery worker -A test_project.celery -E -l INFO

Celery should say something about our transport being "amqp://guest:**@localhost:45672//". The port should match the port used in docker-compose container.

Django

Now, launch another terminal window and boot up your Django part of the deal. It is IMPORTANT to run the sever listening on all interfaces of your host, so Nginx from Docker image will be able to proxy requests to it:

cd test_project
export PYTHONPATH=..
python manage.py runserver 0.0.0.0:8080

Testing

Go to http://localhost:9080/ to see your stack in action. Click the link, as web page says, to launch long running task, as defined in test_app.tasks module. The web page will pass its UUID to the long running task and in turn the task will be able to notify the web page about its progress.

Where to go now?

You can try the commands, described below in the "Command-line interface" section.

Command-line interface

Different channels

Send a message to all users:

python manage.py publish_message -q __all__ -d '{"type": "callout", "header": "Nice optional title.", "body": "Just a message.", "class": "success"}'

Send a message to all authorised (logged-in) users:

python manage.py publish_message -q __authorized__ -d '{"type": "callout", "header": "Nice optional title.", "body": "Just a message.", "class": "success"}'

Send a message to a specific session:

python manage.py publish_message -q __session__SESSION-ID -d '{"type": "callout", "header": "Nice optional title.", "body": "Just a message.", "class": "success"}'

Send a message to a specific web page:

python manage.py publish_message -q __uuid__WEB-PAGE-UUID4 -d '{"type": "callout", "header": "Nice optional title.", "body": "Just a message.", "class": "success"}'

Command-line interface

Send a message (callout) to all web browsers:

python manage.py publish_message -q __all__ -d '{"type": "callout", "header": "Nice optional title.", "body": "Just a message.", "class": "success"}'

Send a clickable message to all web browsers:

python manage.py publish_message -q __all__ -d '{"type": "callout-with-link", "href": "http://www.onet.pl", "header": "", "body": "Processing has finished. Please click this link to access report. ", "class": "success"}'

Make all web browsers visit a different web page:

python manage.py publish_message -q __all__ -d '{"type": "goto-page", "href": "http://www.onet.pl"}'

Show a modal dialog:

python manage.py publish_message -q __all__ -d '{"type": "modal-dialog", "header": "http://www.onet.pl", "lead": "lead", "paragraph": "paragraphs"}'

Close a previously shown modal dialog:

python manage.py publish_message -q __all__ -d '{"type":"close-modal-dialog"}'

Show a please-wait dialog:

python manage.py publish_message -q __all__ -d '{"type": "please-wait-dialog", "header": "Please wait patiently...", "lead": "The server is working", "paragraph": "After the operation is complete, the page will refresh."}'

Close a please-wait dialog:

python manage.py publish_message -q __all__ -d '{"type":"close-please-wait-dialog"}'

Replace HTML of a given jQuery selector:

python manage.py publish_message -q __all__ -d '{"type": "html", "selector": "body", "value": "LOL"}'

Execute JavaScript via eval:

python manage.py publish_message -q __all__ -d '{"type": "eval", "value": "console.log(123);"}'