Django Channels HTTP/WebSocket server

Related tags

WebSocket daphne
Overview

daphne

Daphne is a HTTP, HTTP2 and WebSocket protocol server for ASGI and ASGI-HTTP, developed to power Django Channels.

It supports automatic negotiation of protocols; there's no need for URL prefixing to determine WebSocket endpoints versus HTTP endpoints.

Running

Simply point Daphne to your ASGI application, and optionally set a bind address and port (defaults to localhost, port 8000):

daphne -b 0.0.0.0 -p 8001 django_project.asgi:application

If you intend to run daphne behind a proxy server you can use UNIX sockets to communicate between the two:

daphne -u /tmp/daphne.sock django_project.asgi:application

If daphne is being run inside a process manager, you might want it to bind to a file descriptor passed down from a parent process. To achieve this you can use the --fd flag:

daphne --fd 5 django_project.asgi:application

If you want more control over the port/socket bindings you can fall back to using twisted's endpoint description strings by using the --endpoint (-e) flag, which can be used multiple times. This line would start a SSL server on port 443, assuming that key.pem and crt.pem exist in the current directory (requires pyopenssl to be installed):

daphne -e ssl:443:privateKey=key.pem:certKey=crt.pem django_project.asgi:application

Endpoints even let you use the txacme endpoint syntax to get automatic certificates from Let's Encrypt, which you can read more about at http://txacme.readthedocs.io/en/stable/.

To see all available command line options run daphne with the -h flag.

HTTP/2 Support

Daphne supports terminating HTTP/2 connections natively. You'll need to do a couple of things to get it working, though. First, you need to make sure you install the Twisted http2 and tls extras:

pip install -U 'Twisted[tls,http2]'

Next, because all current browsers only support HTTP/2 when using TLS, you will need to start Daphne with TLS turned on, which can be done using the Twisted endpoint syntax:

daphne -e ssl:443:privateKey=key.pem:certKey=crt.pem django_project.asgi:application

Alternatively, you can use the txacme endpoint syntax or anything else that enables TLS under the hood.

You will also need to be on a system that has OpenSSL 1.0.2 or greater; if you are using Ubuntu, this means you need at least Ubuntu 16.04.

Now, when you start up Daphne, it should tell you this in the log:

2017-03-18 19:14:02,741 INFO     Starting server at ssl:port=8000:privateKey=privkey.pem:certKey=cert.pem, channel layer django_project.asgi:channel_layer.
2017-03-18 19:14:02,742 INFO     HTTP/2 support enabled

Then, connect with a browser that supports HTTP/2, and everything should be working. It's often hard to tell that HTTP/2 is working, as the log Daphne gives you will be identical (it's HTTP, after all), and most browsers don't make it obvious in their network inspector windows. There are browser extensions that will let you know clearly if it's working or not.

Daphne only supports "normal" requests over HTTP/2 at this time; there is not yet support for extended features like Server Push. It will, however, result in much faster connections and lower overheads.

If you have a reverse proxy in front of your site to serve static files or similar, HTTP/2 will only work if that proxy understands and passes through the connection correctly.

Root Path (SCRIPT_NAME)

In order to set the root path for Daphne, which is the equivalent of the WSGI SCRIPT_NAME setting, you have two options:

  • Pass a header value Daphne-Root-Path, with the desired root path as a URLencoded ASCII value. This header will not be passed down to applications.
  • Set the --root-path commandline option with the desired root path as a URLencoded ASCII value.

The header takes precedence if both are set. As with SCRIPT_ALIAS, the value should start with a slash, but not end with one; for example:

daphne --root-path=/forum django_project.asgi:application

Python Support

Daphne requires Python 3.6 or later.

Contributing

Please refer to the main Channels contributing docs.

To run tests, make sure you have installed the tests extra with the package:

cd daphne/
pip install -e '.[tests]'
pytest

Maintenance and Security

To report security issues, please contact [email protected]. For GPG signatures and more security process information, see https://docs.djangoproject.com/en/dev/internals/security/.

To report bugs or request new features, please open a new GitHub issue.

This repository is part of the Channels project. For the shepherd and maintenance team, please see the main Channels readme.

Comments
  • KeyError from create_application

    KeyError from create_application

    Since upgrading to Channels 2, I get a number of these errors. I suspect this happens when restarting the deployed instance:

    Traceback (most recent call last):
      File "/usr/local/lib/python3.6/site-packages/daphne/http_protocol.py", line 160, in process
        "server": self.server_addr,
      File "/usr/local/lib/python3.6/site-packages/twisted/internet/defer.py", line 1386, in _inlineCallbacks
        result = g.send(result)
      File "/usr/local/lib/python3.6/site-packages/daphne/server.py", line 191, in create_application
        ), loop=asyncio.get_event_loop())
    KeyError: <WebRequest at 0x7ff738677710 method=GET uri=/api/internal/projects/21/managed_objects/ clientproto=HTTP/1.1>
    

    Unfortunately, it doesn't help that there is a lot happening on this line, and I am not sure what part causes this error.

    bug exp/beginner 
    opened by brianmay 26
  • Doc: deploying with multiple daphne processes (v1 -> v2)

    Doc: deploying with multiple daphne processes (v1 -> v2)

    Hi,

    With v1, I could run a single Daphne process and several workers, so that I could bind Daphne directly to a port number.

    With v2, the worker and the server share the same Daphne process, so that the number of daphne processes must be increased to reach a similar situation. The Channels doc mentions using a process supervisor to increase the number of processes, but it doesn't state how a port can be shared between the Daphne processes.

    I use Circus (http://circus.readthedocs.io/en/latest/tutorial/step-by-step/) as a process supervisor. Their doc mentions using Circus to create a socket bound to the desired port and to run multiple servers (Chaussette in the case) with the resulting (and common) socket file descriptor. Chaussette's doc explicitly mentions that:

    The particularity of Chaussette is that it can either bind a socket on a port like any other server does or run against already opened sockets.

    Is that also true for Daphne? Can Daphne processes share the same socket file descriptor? If yes, could that be mentionned in the doc?

    Thanks in advance!

    opened by jxrossel 21
  • ASGI_THREADS environment variable has no effect since 2.4.1

    ASGI_THREADS environment variable has no effect since 2.4.1

    Channels documentation mentions that:

    By default, the number of threads is set to “the number of CPUs * 5”, so you may see up to this number of threads. If you want to change it, set the ASGI_THREADS environment variable to the maximum number you wish to allow.

    This behaviour used to work correctly before Daphne v2.4.1.

    Since 2.4.1 setting ASGI_THREADS envvar has no effect.

    My Setup

    Python 3.7.5, on Ubuntu 19.10 with following packages:

    asgiref==3.2.7
    channels==2.4.0
    channels-redis==2.4.2
    daphne==2.4.1
    Django==2.2.12
    

    Startup:

    daphne -b 0.0.0.0 -p 8000 api.config.asgi:application
    

    How to replicate

    • Set ASGI_THREADS to 1.
    • Install packages above, with Daphne v2.40
    • Start daphne
    • Navigate through website and open a few pages
    • Check number of threads with htop.
    • Thread count never exceeds 1
    • Now install daphne v2.41
    • Start server and browse website
    • Thread count is not limited to 1, keeps increasing. Possibly capped to 5*CPU count, but can't tell for sure.
    opened by revoteon 19
  • Hot idling when in subthread (runserver)

    Hot idling when in subthread (runserver)

    When Daphne is embedded as a subthread inside something else (such as channels' runserver) it idles very hot, using a full CPU core on my machine, even with a Twisted-native ASGI backend.

    It looks like the Twisted reactor might be the cause, but can't be sure yet.

    bug exp/intermediate 
    opened by andrewgodwin 19
  • Auto-reload on code change

    Auto-reload on code change

    It would be great if daphne had a feature to auto reload whenever code changes similar to what gunicorn does with the reload flag.

    I know the runworker is an option but this would allow for an much easier deploy for me. Now I have to give my development servers a separate run command and it creates a different environment which could cause problems.

    enhancement maybe 
    opened by wolph 19
  • Version 2.1.2 breaks websocket connections with AssertionError

    Version 2.1.2 breaks websocket connections with AssertionError

    Hi!

    The newly released version 2.1.2 breaks my websocket connections with the following error:

    2018-05-24 16:00:48,563 ERROR    Traceback (most recent call last):
      File "/root/.local/share/virtualenvs/lh8-tools-QNwECfds/lib/python3.6/site-packages/daphne/ws_protocol.py", line 56, in onConnect
        self.client_addr
      File "/root/.local/share/virtualenvs/lh8-tools-QNwECfds/lib/python3.6/site-packages/daphne/utils.py", line 49, in parse_x_forwarded_for
        assert all(isinstance(name, bytes) for name in headers.keys())
    AssertionError
    

    Would be nice if it told us what was wrong instead of just raising an AssertionError :)

    Javascript websocket-client. Daphne proxied behind nginx or caddy.

    Reverting to 2.1.1 fixes the issue.

    Related commit: https://github.com/django/daphne/commit/b3c097aabdc477ed7e666a4a0d87250db1b2a9d2

    opened by xolan 18
  • --proxy-headers error

    --proxy-headers error

    Hi,

    I just tested daphne with --proxy-headers behind a nginx server, and got the following exception when my browser initiates the websocket connection:

    2017-02-07 15:13:43,115 ERROR    Traceback (most recent call last):
      File "/path/ve/local/lib/python2.7/site-packages/daphne/ws_protocol.py", line 62, in onConnect
        self.requestHeaders,
    AttributeError: 'WebSocketProtocol' object has no attribute 'requestHeaders'
    

    I'm using the channels-examples/databinding app with the following virtualenv content:

    appdirs==1.4.0
    asgi-redis==1.0.0
    asgiref==1.0.0
    autobahn==0.17.1
    channels==1.0.3
    constantly==15.1.0
    daphne==1.0.2
    Django==1.10.5
    incremental==16.10.1
    msgpack-python==0.4.8
    packaging==16.8
    pyparsing==2.1.10
    redis==2.10.5
    six==1.10.0
    Twisted==16.6.0
    txaio==2.6.0
    uWSGI==2.0.14
    zope.interface==4.3.3
    

    Is it a version compatibility issue, or a bug maybe ?

    Thanks !

    opened by NotSqrt 17
  • daphne with django 3

    daphne with django 3

    When i ran daphne with unix socket and django version 3 i get this error Django can only handle ASGI/HTTP connections, not websocket.

    I try to run the django channels tutorial with nginx gunicorn supervisor and daphne

    opened by dimkoug 16
  • CRITICAL Listen failure: [Errno 88] Socket operation on non-socket

    CRITICAL Listen failure: [Errno 88] Socket operation on non-socket

    I have made a server using Django REST framework and Django channels but I am unable to configure supervisor to run with it. My supervisor config is as follow:

    [program:frnd_django]
    socket=tcp://localhost:8000
    directory=/home/coldbrewtech/frnd/backend/dating-app-backend/django-server/cbproj/
    environment=DJANGO_SETTINGS_MODULE=cbproj.dev_settings
    command=/home/coldbrewtech/frnd/backend/env/bin/daphne -u /run/daphne/daphne%(process_num)d.sock --fd 0 --access-log - --proxy-headers cbproj.asgi:application
    stdout_logfile=/home/coldbrewtech/frnd/backend/dating-app-backend/django-server/cbproj/logs/django_out.log
    stderr_logfile=/home/coldbrewtech/frnd/backend/dating-app-backend/django-server/cbproj/logs/django_err.log
    numprocs=4
    process_name=asgi%(process_num)d
    autostart=true
    autorestart=true
    user=root
    startsecs=10
    stopwaitsecs=600
    stopasgroup=true
    stopsignal=KILL
    

    And the error that I am getting is as follow:

    2019-05-21 18:03:50,111 INFO     Starting server at fd:fileno=0, unix:/run/daphne/daphne3.sock
    2019-05-21 18:03:50,121 INFO     HTTP/2 support not enabled (install the http2 and tls Twisted extras)
    2019-05-21 18:03:50,125 INFO     Configuring endpoint fd:fileno=0
    2019-05-21 18:03:50,130 INFO     Starting server at fd:fileno=0, unix:/run/daphne/daphne1.sock
    2019-05-21 18:03:50,131 INFO     Starting server at fd:fileno=0, unix:/run/daphne/daphne0.sock
    2019-05-21 18:03:50,132 INFO     HTTP/2 support not enabled (install the http2 and tls Twisted extras)
    2019-05-21 18:03:50,133 INFO     Configuring endpoint fd:fileno=0
    2019-05-21 18:03:50,134 INFO     HTTP/2 support not enabled (install the http2 and tls Twisted extras)
    2019-05-21 18:03:50,145 INFO     Configuring endpoint fd:fileno=0
    2019-05-21 18:03:50,154 INFO     Starting server at fd:fileno=0, unix:/run/daphne/daphne2.sock
    2019-05-21 18:03:50,158 CRITICAL Listen failure: [Errno 88] Socket operation on non-socket
    2019-05-21 18:03:50,159 INFO     HTTP/2 support not enabled (install the http2 and tls Twisted extras)
    2019-05-21 18:03:50,160 INFO     Configuring endpoint fd:fileno=0
    2019-05-21 18:03:50,163 CRITICAL Listen failure: [Errno 88] Socket operation on non-socket
    2019-05-21 18:03:50,160 INFO     Configuring endpoint unix:/run/daphne/daphne3.sock
    2019-05-21 18:03:50,168 CRITICAL Listen failure: [Errno 88] Socket operation on non-socket
    2019-05-21 18:03:50,177 INFO     Configuring endpoint unix:/run/daphne/daphne0.sock
    2019-05-21 18:03:50,181 INFO     Configuring endpoint unix:/run/daphne/daphne1.sock
    2019-05-21 18:03:50,192 CRITICAL Listen failure: [Errno 88] Socket operation on non-socket
    2019-05-21 18:03:50,204 INFO     Configuring endpoint unix:/run/daphne/daphne2.sock
    

    I am not sure whether this is daphne issue or some supervisor issue

    opened by hardikbansal 16
  • Support HTTP/2 ✨

    Support HTTP/2 ✨

    Twisted 16.3.0 landed today, with HTTP/2 support (thanks @lukasa!). This requires:

    a) #10, so that it can negotiate it over TLS b) Daphne's Site adding h2 as a supported protocol.

    enhancement exp/advanced epic-project 
    opened by hawkowl 16
  • Reverse proxy limitations

    Reverse proxy limitations

    What limitations exist for running daphne behind a reverse proxy such as:

    • nginx
    • apache
    • AWS ELB
    • haproxy
    • heroku routing layer (nginx, probably)

    Can daphne be used as an (almost) drop in replacement for e.g. gunicorn?

    opened by yuvadm 16
  • how to set websocket send buffersize in daphne

    how to set websocket send buffersize in daphne

    i want to send camera captured image by websocket in daphne django channel

    when the image is big size for base64, websocket go in error,

    so how to large the websocket send buffersize?

    opened by wynshiter 0
  • Root path for websockets

    Root path for websockets

    As discussed in https://github.com/django/daphne/issues/125, this adds root_path handing to Daphne's websocket protocol, similar to how it's handled in http.

    opened by asedeno 0
  • UnicodeDecodeError on journalctl log

    UnicodeDecodeError on journalctl log

    When django raise a 500 error (f.e. following a ValueError), instead of exception stacktrace on journalctl log there is an UnicodeDecodeError.

    Environment: Debian 10.12, Python 3.7.3, Django 3.2.5, Daphne 3.0.2, Apache 2.4.38

    Systemd Unit File:

    [Unit]
    Description=baskerville Daphne Service
    Requires=srv.mount
    After=network.target 
    After=srv.mount
     
    [Service]
    Type=simple 
    User=chiara
    WorkingDirectory=/srv/projects/baskerville.mygor.xyz/baskervilleweb
    ExecStart=daphne --access-log /var/log/daphne/daphne-baskerville.log -b 127.0.0.1 -p 9000 baskervilleweb.asgi:application  Environment=PYTHONUNBUFFERED=1
       
    [Install]
    WantedBy=multi-user.target
    

    Sample output

    In a queryset, I define an annotation with the same name as a field:

    class FoodDiaryEntryManager(models.Manager):
        def get_queryset(self):
            qset=models.Manager.get_queryset(self)
            return qset.annotate(
                qta=models.F("quantity")*models.F("measure_unit__factor"),
                ratio=models.F("quantity")*models.F("measure_unit__factor")/100
            ).annotate(
                 kcal=models.F("ratio")*models.F("product__kcal")
            )
    
    class FoodDiaryEntry(models.Model):
        ...
        product = models.ForeignKey(Product,on_delete=models.PROTECT)
        measure_unit = models.ForeignKey(MeasureUnit,on_delete=models.PROTECT)
        quantity = models.FloatField(validators=[validators.MinValueValidator(0.0)])
        ...
        kcal          = models.FloatField(editable=False)
        ...
        objects = FoodDiaryEntryManager()
    

    The expected behaviour on journalctl log is an exception stacktrace with something like (from django console):

    Traceback (most recent call last):
      File "<console>", line 1, in <module>
      File "/usr/local/lib/python3.7/dist-packages/django/db/models/query.py", line 1091, in annotate
        return self._annotate(args, kwargs, select=True)
      File "/usr/local/lib/python3.7/dist-packages/django/db/models/query.py", line 1126, in _annotate
        "the model." % alias)
    ValueError: The annotation 'kcal' conflicts with a field on the model.
    

    Instead I have:

    # journalctl -f -u daphne-baskerville.service
    ...
    Jul 19 10:47:24 parsifal daphne[26088]: --- Logging error ---
    Jul 19 10:47:24 parsifal daphne[26088]: Traceback (most recent call last):
    Jul 19 10:47:24 parsifal daphne[26088]:   File "/usr/lib/python3.7/logging/__init__.py", line 1034, in emit
    Jul 19 10:47:24 parsifal daphne[26088]:     msg = self.format(record)
    Jul 19 10:47:24 parsifal daphne[26088]:   File "/usr/lib/python3.7/logging/__init__.py", line 880, in format
    Jul 19 10:47:24 parsifal daphne[26088]:     return fmt.format(record)
    Jul 19 10:47:24 parsifal daphne[26088]:   File "/usr/lib/python3.7/logging/__init__.py", line 627, in format
    Jul 19 10:47:24 parsifal daphne[26088]:     record.exc_text = self.formatException(record.exc_info)
    Jul 19 10:47:24 parsifal daphne[26088]:   File "/usr/lib/python3.7/logging/__init__.py", line 577, in formatException
    Jul 19 10:47:24 parsifal daphne[26088]:     traceback.print_exception(ei[0], ei[1], tb, None, sio)
    Jul 19 10:47:24 parsifal daphne[26088]:   File "/usr/lib/python3.7/traceback.py", line 104, in print_exception
    Jul 19 10:47:24 parsifal daphne[26088]:     type(value), value, tb, limit=limit).format(chain=chain):
    Jul 19 10:47:24 parsifal daphne[26088]:   File "/usr/lib/python3.7/traceback.py", line 521, in __init__
    Jul 19 10:47:24 parsifal daphne[26088]:     self._load_lines()
    Jul 19 10:47:24 parsifal daphne[26088]:   File "/usr/lib/python3.7/traceback.py", line 533, in _load_lines
    Jul 19 10:47:24 parsifal daphne[26088]:     self.__context__._load_lines()
    Jul 19 10:47:24 parsifal daphne[26088]:   File "/usr/lib/python3.7/traceback.py", line 533, in _load_lines
    Jul 19 10:47:24 parsifal daphne[26088]:     self.__context__._load_lines()
    Jul 19 10:47:24 parsifal daphne[26088]:   File "/usr/lib/python3.7/traceback.py", line 533, in _load_lines
    Jul 19 10:47:24 parsifal daphne[26088]:     self.__context__._load_lines()
    Jul 19 10:47:24 parsifal daphne[26088]:   [Previous line repeated 5 more times]
    Jul 19 10:47:24 parsifal daphne[26088]:   File "/usr/lib/python3.7/traceback.py", line 531, in _load_lines
    Jul 19 10:47:24 parsifal daphne[26088]:     frame.line
    Jul 19 10:47:24 parsifal daphne[26088]:   File "/usr/lib/python3.7/traceback.py", line 285, in line
    Jul 19 10:47:24 parsifal daphne[26088]:     self._line = linecache.getline(self.filename, self.lineno).strip()
    Jul 19 10:47:24 parsifal daphne[26088]:   File "/usr/lib/python3.7/linecache.py", line 16, in getline
    Jul 19 10:47:24 parsifal daphne[26088]:     lines = getlines(filename, module_globals)
    Jul 19 10:47:24 parsifal daphne[26088]:   File "/usr/lib/python3.7/linecache.py", line 47, in getlines
    Jul 19 10:47:24 parsifal daphne[26088]:     return updatecache(filename, module_globals)
    Jul 19 10:47:24 parsifal daphne[26088]:   File "/usr/lib/python3.7/linecache.py", line 137, in updatecache
    Jul 19 10:47:24 parsifal daphne[26088]:     lines = fp.readlines()
    Jul 19 10:47:24 parsifal daphne[26088]:   File "/usr/lib/python3.7/codecs.py", line 322, in decode
    Jul 19 10:47:24 parsifal daphne[26088]:     (result, consumed) = self._buffer_decode(data, self.errors, final)
    Jul 19 10:47:24 parsifal daphne[26088]: UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd7 in position 4907: invalid continuation byte
    Jul 19 10:47:24 parsifal daphne[26088]: Call stack:
    Jul 19 10:47:24 parsifal daphne[26088]:   File "/usr/local/bin/daphne", line 8, in <module>
    Jul 19 10:47:24 parsifal daphne[26088]:     sys.exit(CommandLineInterface.entrypoint())
    Jul 19 10:47:24 parsifal daphne[26088]:   File "/usr/local/lib/python3.7/dist-packages/daphne/cli.py", line 170, in entrypoint
    Jul 19 10:47:24 parsifal daphne[26088]:     cls().run(sys.argv[1:])
    Jul 19 10:47:24 parsifal daphne[26088]:   File "/usr/local/lib/python3.7/dist-packages/daphne/cli.py", line 285, in run
    Jul 19 10:47:24 parsifal daphne[26088]:     self.server.run()
    Jul 19 10:47:24 parsifal daphne[26088]:   File "/usr/local/lib/python3.7/dist-packages/daphne/server.py", line 143, in run
    Jul 19 10:47:24 parsifal daphne[26088]:     reactor.run(installSignalHandlers=self.signal_handlers)
    Jul 19 10:47:24 parsifal daphne[26088]:   File "/usr/local/lib/python3.7/dist-packages/twisted/internet/asyncioreactor.py", line 255, in run
    Jul 19 10:47:24 parsifal daphne[26088]:     self._asyncioEventloop.run_forever()
    Jul 19 10:47:24 parsifal daphne[26088]:   File "/usr/lib/python3.7/asyncio/base_events.py", line 539, in run_forever
    Jul 19 10:47:24 parsifal daphne[26088]:     self._run_once()
    Jul 19 10:47:24 parsifal daphne[26088]:   File "/usr/lib/python3.7/asyncio/base_events.py", line 1775, in _run_once
    Jul 19 10:47:24 parsifal daphne[26088]:     handle._run()
    Jul 19 10:47:24 parsifal daphne[26088]:   File "/usr/lib/python3.7/asyncio/events.py", line 88, in _run
    Jul 19 10:47:24 parsifal daphne[26088]:     self._context.run(self._callback, *self._args)
    Jul 19 10:47:24 parsifal daphne[26088]:   File "/usr/local/lib/python3.7/dist-packages/twisted/internet/asyncioreactor.py", line 271, in _onTimer
    Jul 19 10:47:24 parsifal daphne[26088]:     self.runUntilCurrent()
    Jul 19 10:47:24 parsifal daphne[26088]:   File "/usr/local/lib/python3.7/dist-packages/twisted/internet/base.py", line 991, in runUntilCurrent
    Jul 19 10:47:24 parsifal daphne[26088]:     call.func(*call.args, **call.kw)
    Jul 19 10:47:24 parsifal daphne[26088]:   File "/usr/local/lib/python3.7/dist-packages/daphne/server.py", line 293, in application_checker
    Jul 19 10:47:24 parsifal daphne[26088]:     exc_info=exception,
    Jul 19 10:47:24 parsifal daphne[26088]: Message: 'Exception inside application: %s'
    Jul 19 10:47:24 parsifal daphne[26088]: Arguments: (UnicodeDecodeError('utf-8', b'from django.db import models\nfrom django.core import validators\nfrom django.core.exceptions import ValidationError\nfrom django.utils import timezone\nfrom django.conf import settings\n\nimport datetime\n\nUser=settings.AUTH_USER_MODEL\n\n# Create your models here.\n\nclass AbstractName(models.Model):\n    name = models.CharField(max_length=1024)\n\n    def __str__(self): return str(self.name)\n\n    class Meta:\n        ordering = [ \'name\' ]\n        abstract = True\n\nclass Vendor(AbstractName): pass\nclass MicroNutrientClass(AbstractName): pass\n\nclass MicroNutrient(AbstractName):\n    nutrient_class = models.ForeignKey(MicroNutrientClass,on_delete=models.PROTECT)\n    rda = models.FloatField(validators=[validators.MinValueValidator(0.0)],\n                            verbose_name=\'rda (mg)\',default=0.0)\n    rda_max = models.FloatField(validators=[validators.MinValueValidator(0.0)],\n                                verbose_name=\'rda max (mg)\',default=0.0)\n\nclass ProductCategory(AbstractName): pass\n    \nclass Product(models.Model):\n    name = models.CharField(max_length=1024)\n    note = models.TextField(blank=True,null=True)\n    category = models.ForeignKey(ProductCategory,on_delete=models.PROTECT)\n    vendor = models.ForeignKey(Vendor,on_delete=models.PROTECT)\n    value_for = models.CharField(max_length=128,default=\'100 g\',\n                                 choices = ( ( "100 g", "100 g" ),\n                                             ( "100 ml", "100 ml" ) ))\n    high_processed = models.BooleanField(default=False)\n    kcal           = models.PositiveIntegerField()\n    fat            = models.FloatField(validators=[validators.MinValueValidator(0.0)])\n    saturated_fat  = models.FloatField(validators=[validators.MinValueValidator(0.0)],blank=True,default=0.0)\n    carbohydrate   = models.FloatField(validators=[validators.MinValueValidator(0.0)])\n    sugar          = models.FloatField(validators=[validators.MinValueValidator(0.0)],blank=True,default=0.0)\n    added_sugar    = models.FloatField(validators=[validators.MinValueValidator(0.0)],blank=True,default=0.0)\n    protein        = models.FloatField(validators=[validators.MinValueValidator(0.0)])\n    alcohol         = models.FloatField(validators=[validators.MinValueValidator(0.0)],blank=True,default=0.0)\n    alcohol_content = models.FloatField(validators=[validators.MinValueValidator(0.0),\n                                                    validators.MaxValueValidator(100.0)],\n                                        verbose_name="alcohol content (%)",\n                                        blank=True,default=0.0)\n    salt           = models.FloatField(validators=[validators.MinValueValidator(0.0)],\n                                       verbose_name="salt (g)",blank=True,default=0.0)\n    sodium         = models.FloatField(validators=[validators.MinValueValidator(0.0)],\n                                       verbose_name="sodium (g)",blank=True,default=0.0)\n    potassium      = models.FloatField(validators=[validators.MinValueValidator(0.0)],\n                                       verbose_name="potassium (g)",blank=True,default=0.0)\n    fiber          = models.FloatField(validators=[validators.MinValueValidator(0.0)],\n                                       verbose_name="fiber (g)",blank=True,default=0.0)\n    water          = models.FloatField(validators=[validators.MinValueValidator(0.0)],\n                                       verbose_name="water (ml)",blank=True,default=0.0)\n\n    micro_nutrients = models.ManyToManyField(MicroNutrient,through=\'ProductMicroNutrient\',blank=True)\n\n    class Meta:\n        ordering = [ \'name\',\'vendor\' ]\n\n    def save(self,*args,**kwargs):\n        if self.salt == 0 and self.sodium > 0:\n            self.salt=self.sodium/0.4\n        if self.sodium == 0 and self.salt > 0:\n            self.sodium=self.salt*0.4\n        if self.alcohol == 0 and self.alcohol_content > 0:\n            WATER_DENS=1\n            ALCOHOL_DENS=0.79\n            alcohol_factor=self.alcohol_content/100\n\n            if self.value_for == "100 ml":\n                tot_vol=100\n            else:\n                tot_dens=( (1-alcohol_factor)*WATER_DENS + alcohol_factor*ALCOHOL_DENS )\n                tot_vol=100/tot_dens\n            alcohol_vol=alcohol_factor*tot_vol\n            self.alcohol=ALCOHOL_DENS*alcohol_vol\n                \n        super(Product, self).save(*args,**kwargs)\n\n    def __str__(self): \n        return "%s (%s)" %(str(self.name),str(self.vendor))\n\nclass ProductMicroNutrient(models.Model):\n    product = models.ForeignKey(Product,on_delete=models.PROTECT)   \n    micro_nutrient = models.ForeignKey(MicroNutrient,on_delete=models.PROTECT)\n    quantity = models.FloatField(validators=[validators.MinValueValidator(0.0)],verbose_name=\'quantity (mg)\')\n\n    def __str__(self): return str(self.micro_nutrient)\n    \nclass MeasureUnit(AbstractName):\n    base = models.CharField(max_length=128,default=\'g\',choices = ( ( "g", "g" ),\n                                                                   ( "ml", "ml" ) ))\n    factor = models.FloatField(validators=[validators.MinValueValidator(0.0)])\n\nclass FoodDiaryEntryManager(models.Manager):\n    def get_queryset(self):\n        qset=models.Manager.get_queryset(self)\n        return qset.annotate(\n            qta=models.F("quantity")*models.F("measure_unit__factor"),\n            ratio=models.F("quantity")*models.F("measure_unit__factor")/100\n        ).annotate(\n             kcal=models.F("ratio")*models.F("product__kcal")\n        )\n\nclass FoodDiaryEntry(models.Model):\n    user = models.ForeignKey(User,on_delete=models.PROTECT)\n    time = models.DateTimeField(default=timezone.now)\n    product = models.ForeignKey(Product,on_delete=models.PROTECT)\n    measure_unit = models.ForeignKey(MeasureUnit,on_delete=models.PROTECT)\n    quantity = models.FloatField(validators=[validators.MinValueValidator(0.0)])\n    future = models.BooleanField(default=False)\n\n    objects=FoodDiaryEntryManager()\n\n    kcal          = models.FloatField(editable=False)\n    fat           = models.FloatField(editable=False)\n    saturated_fat = models.FloatField(editable=False)\n    carbohydrate  = models.FloatField(editable=False)\n    sugar         = models.FloatField(editable=False)\n    protein       = models.FloatField(editable=False)\n    alcohol       = models.FloatField(editable=False)\n    added_sugar   = models.FloatField(editable=False)\n    salt          = models.FloatField(editable=False)\n    sodium        = models.FloatField(editable=False)\n    potassium     = models.FloatField(editable=False)\n    fiber         = models.FloatField(editable=False)\n    water         = models.FloatField(editable=False)\n\n\n    def __str__(self): return str(self.product)\n\n    class Meta:\n        ordering = [ \'time\' ]\n\n    def save(self,*args,**kwargs):\n        self.kcal=self._kcal()\n        self.fat=self._fat()\n        self.carbohydrate=self._carbohydrate()\n        self.sugar=self._sugar()\n        self.protein=self._protein()\n        self.added_sugar=self._added_sugar()\n        self.alcohol=self._alcohol()\n        self.saturated_fat=self._saturated_fat()\n        self.salt=self._salt()\n        self.sodium=self._sodium()\n        self.potassium=self._potassium()\n        self.fiber=self._fiber()\n        self.water=self._water()\n        super(FoodDiaryEntry,self).save(*args,**kwargs)\n\n    def quantity_real(self):\n        return self.quantity*self.measure_unit.factor\n\n    def measure_unit_real(self):\n        return self.measure_unit.base\n\n    def _kcal(self): return self.product.kcal*self.quantity_real()/100.0\n    def _fat(self): return self.product.fat*self.quantity_real()/100.0\n    def _alcohol(self): return self.product.alcohol*self.quantity_real()/100.0\n    def _carbohydrate(self): return self.product.carbohydrate*self.quantity_real()/100.0\n    def _sugar(self): return self.product.sugar*self.quantity_real()/100.0\n    def _added_sugar(self): return self.product.added_sugar*self.quantity_real()/100.0\n    def _protein(self): return self.product.protein*self.quantity_real()/100.0\n    def _saturated_fat(self): return self.product.saturated_fat*self.quantity_real()/100.0\n    def _salt(self): return self.product.salt*self.quantity_real()/100.0\n    def _sodium(self): return self.product.sodium*self.quantity_real()/100.0\n    def _potassium(self): return self.product.potassium*self.quantity_real()/100.0\n    def _fiber(self): return self.product.fiber*self.quantity_real()/100.0\n    def _water(self): return self.product.water*self.quantity_real()/100.0\n\nclass WeightDiaryEntry(models.Model):\n    user = models.ForeignKey(User,on_delete=models.PROTECT)\n    time = models.DateTimeField(default=timezone.now)\n    weight = models.FloatField(validators=[validators.MinValueValidator(0.0)],verbose_name=\'weight (kg)\')\n    base = models.FloatField(editable=False)\n    need = models.FloatField(editable=False)\n\n    ## QUI\n    def save(self,*args,**kwargs):\n        # https://en.wikipedia.org/wiki/Harris%E2%80%93Benedict_equation\n        # Men \tBMR = (10 \xd7 weight in kg) + (6.25 \xd7 height in cm) - (5 \xd7 age in years) + 5\n        # Women BMR = (10 \xd7 weight in kg) + (6.25 \xd7 height in cm) - (5 \xd7 age in years) - 161 \n        self.need=2000\n        self.base=1000\n        #age=self.time-self.user.date_of_birth\n        year=self.time.year-self.user.date_of_birth.year\n        #age=self.time - datetime.datetime.combine(self.user.date_of_birth, datetime.time())\n        #year=age.days/365.0\n\n        print("SAVE",year)\n\n        base=(10*self.weight) + (6.25*self.user.height) - (5*year)\n        if self.user.gender=="male":\n            base+=5\n        else:\n            base-=161\n\n        self.base=base\n\n        print("SAVE",base)\n\n            \n        # self.base=base\n\n        if self.user.lifestyle=="sedentary":\n            need=1.53*base\n        elif self.user.lifestyle=="active":\n            need=1.76*base\n        else:\n            need=2.25*base\n\n        self.need=need\n        # print("SAVE",base,need)\n\n        super(WeightDiaryEntry,self).save(*args,**kwargs)\n\nclass Restaurant(AbstractName):  pass\n\nclass RestaurantDishQuerySet(models.QuerySet):\n    def with_kcal(self):\n        prods=RestaurantDishProduct.objects.filter(dish=models.OuterRef("pk")).values("dish")\n        total_prods=prods.annotate(total=models.Sum("kcal")).values("total")\n        return self.annotate(kcal=models.Subquery(total_prods))\n\nclass RestaurantDishManager(models.Manager):\n    def get_queryset(self):\n        qset=models.Manager.get_queryset(self)\n        prods=RestaurantDishProduct.objects.filter(dish=models.OuterRef("pk")).values("dish")\n        total_prods=prods.annotate(total=models.Sum("kcal")).values("total")\n        return qset.annotate(kcal=models.Subquery(total_prods))\n\nclass RestaurantDish(AbstractName):\n    restaurant = models.ForeignKey(Restaurant,on_delete=models.PROTECT)\n\n    objects=RestaurantDishManager.from_queryset(RestaurantDishQuerySet)()\n    \n    def __str__(self): \n        return "%s (%s)" %(str(self.name),str(self.restaurant))\n\n# class RestaurantDishProductQuerySet(models.QuerySet):\n#     def with_ratio(self):\n#         return self.annotate(\n#             qta=models.F("quantity")*models.F("measure_unit__factor"),\n#             ratio=models.F("quantity")*models.F("measure_unit__factor")/100\n#         )\n\n#     def with_kcal(self):\n#         return self.annotate(\n#             kcal=models.F("ratio")*models.F("product__kcal")\n#         )\n\nclass RestaurantDishProductManager(models.Manager):\n    def get_queryset(self):\n        qset=models.Manager.get_queryset(self)\n        return qset.annotate(\n            qta=models.F("quantity")*models.F("measure_unit__factor"),\n            ratio=models.F("quantity")*models.F("measure_unit__factor")/100\n        ).annotate(\n            kcal=models.F("ratio")*models.F("product__kcal")\n        )\n\nclass RestaurantDishProduct(models.Model):\n    dish = models.ForeignKey(RestaurantDish,on_delete=models.PROTECT)\n    product = models.ForeignKey(Product,on_delete=models.PROTECT)\n    measure_unit = models.ForeignKey(MeasureUnit,on_delete=models.PROTECT)\n    quantity = models.FloatField(validators=[validators.MinValueValidator(0.0)])\n\n    objects=RestaurantDishProductManager() #.from_queryset(RestaurantDishProductQuerySet)()\n\n\n    def __str__(self): return str(self.product)\n\n    def quantity_real(self):\n        return self.quantity*self.measure_unit.factor\n\nclass RecipeQuerySet(models.QuerySet):\n    def with_kcal(self):\n        prods=RecipeProduct.objects.filter(recipe=models.OuterRef("pk")).values("recipe")\n        total_prods=prods.annotate(total=models.Sum("kcal")).values("total")\n        return self.annotate(kcal=models.Subquery(total_prods))\n\nclass RecipeManager(models.Manager):\n    def get_queryset(self):\n        qset=models.Manager.get_queryset(self)\n        prods=RecipeProduct.objects.filter(recipe=models.OuterRef("pk")).values("recipe")\n        total_prods=prods.annotate(total=models.Sum("kcal")).values("total")\n        return qset.annotate(kcal=models.Subquery(total_prods))\n\n\nclass Recipe(AbstractName):\n    time = models.DateTimeField(default=timezone.now)\n    final_weight = models.PositiveIntegerField(default=0)\n    total_weight = models.PositiveIntegerField(editable=False)\n\n    objects=RecipeManager.from_queryset(RecipeQuerySet)()\n\n    class Meta:\n        ordering = [ "-time" ]\n    \n    def _total_weight(self):\n        total=0\n        for rp in self.recipeproduct_set.all():\n            total+=rp.quantity_real()\n        return total\n\n    def save(self,*args,**kwargs):\n        self.total_weight=self._total_weight()\n        if self.final_weight==0:\n            self.final_weight=self.total_weight\n        super(Recipe,self).save(*args,**kwargs)\n\nclass RecipeProductManager(models.Manager):\n    def get_queryset(self):\n        qset=models.Manager.get_queryset(self)\n        return qset.annotate(\n            qta=models.F("quantity")*models.F("measure_unit__factor"),\n            ratio=models.F("quantity")*models.F("measure_unit__factor")/100\n        ).annotate(\n            kcal=models.F("ratio")*models.F("product__kcal")\n        )\n\n\nclass RecipeProduct(models.Model):\n    recipe = models.ForeignKey(Recipe,on_delete=models.PROTECT)\n    product = models.ForeignKey(Product,on_delete=models.PROTECT)\n    measure_unit = models.ForeignKey(MeasureUnit,on_delete=models.PROTECT)\n    quantity = models.FloatField(validators=[validators.MinValueValidator(0.0)])\n\n    objects=RecipeProductManager()\n\n    def __str__(self): return str(self.product)\n\n    def quantity_real(self):\n        return self.quantity*self.measure_unit.factor\n\nclass FrequentDiaryEntry(models.Model):\n    product = models.ForeignKey(Product,on_delete=models.PROTECT)\n    measure_unit = models.ForeignKey(MeasureUnit,on_delete=models.PROTECT)\n    quantity = models.FloatField(validators=[validators.MinValueValidator(0.0)])\n\n    def __str__(self): return str(self.product)+" ("+str(self.quantity)+" "+str(self.measure_unit)+")"\n\n\n#####\n\n\nclass UsdaNndFoodGroup(AbstractName):\n    usda_id = models.CharField(max_length=1024)\n    \nclass UsdaNndFood(models.Model):\n    usda_id = models.CharField(max_length=1024)\n    food_group = models.ForeignKey(UsdaNndFoodGroup,on_delete=models.PROTECT)\n    long_description = models.CharField(max_length=1024)\n    short_description = models.CharField(max_length=1024)\n    common_name = models.CharField(max_length=1024)\n    manufacturer_name = models.CharField(max_length=1024)\n    survey = models.BooleanField()\n    refuse_desc = models.CharField(max_length=1024)\n    refuse_perc = models.FloatField(validators=[validators.MinValueValidator(0.0)])\n    scientific_name = models.CharField(max_length=1024)\n    nitrogen_factor = models.FloatField(validators=[validators.MinValueValidator(0.0)])\n    protein_factor = models.FloatField(validators=[validators.MinValueValidator(0.0)])\n    fat_factor = models.FloatField(validators=[validators.MinValueValidator(0.0)])\n    carbohydrate_factor = models.FloatField(validators=[validators.MinValueValidator(0.0)])\n\n    def __str__(self): return str(self.short_description)\n\nclass UsdaNndLangual(models.Model):\n    usda_id = models.CharField(max_length=1024)\n    description = models.CharField(max_length=1024)\n\n    def __str__(self): return str(self.description)\n\nclass UsdaNndFoodLangualRelation(models.Model):\n    food    = models.ForeignKey(UsdaNndFood,on_delete=models.PROTECT)\n    langual = models.ForeignKey(UsdaNndLangual,on_delete=models.PROTECT)\n    \n    def __str__(self): return str(self.langual.description)\n    \n', 9003, 9004, 'invalid continuation byte'),)
    
    opened by chiara-paci 2
  • Improve max-worker sync-to-async handling.

    Improve max-worker sync-to-async handling.

    #422 ports the old ASGI_THREADS logic from asgiref. (C.f. #319)

    Improvements:

    • Move the initialisation of the default executor into Server.run() (when configuring the loop).
    • Adjust the test from #422 to set up the Server instance, so that's put into effect.
    • Add a --max-workers CLI flag, with tests etc., to apply this.
    • Deprecate the env var approach.
    enhancement exp/beginner 
    opened by carltongibson 0
  • minor: ansi codes in log output

    minor: ansi codes in log output

    I use Rich as my Django logger, as described here: https://www.willmcgugan.com/blog/tech/post/richer-django-logging/

    Everything worked fine with runserver, however once I started using Daphene there were ansi codes in the output.

    image

    I opened an issue in the Rich repo, but was advised that the issue is likely with Daphne https://github.com/Textualize/rich/issues/2127.

    opened by mustafa0x 2
Owner
Django
Django
Chat app for Django, powered by Django Channels, Websockets & Asyncio

Django Private Chat2 New and improved https://github.com/Bearle/django-private-chat Chat app for Django, powered by Django Channels, Websockets & Asyn

Bearle 205 Dec 30, 2022
Websockify is a WebSocket to TCP proxy/bridge. This allows a browser to connect to any application/server/service. Implementations in Python, C, Node.js and Ruby.

websockify: WebSockets support for any application/server websockify was formerly named wsproxy and was part of the noVNC project. At the most basic l

noVNC 3.3k Jan 3, 2023
WebSocket emulation - Python server

SockJS-tornado server SockJS-tornado is a Python server side counterpart of SockJS-client browser library running on top of Tornado framework. Simplif

Serge S. Koval 854 Nov 19, 2022
This websocket program is for data transmission between server and client. Data transmission is for Federated Learning in Edge computing environment.

websocket-for-data-transmission This websocket program is for data transmission between server and client. Data transmission is for Federated Learning

null 9 Jul 19, 2022
Benchmark a WebSocket server's message throughput ⌛

?? WebSocket Benchmarker ⌚ Message throughput is how fast a WebSocket server can parse and respond to a message. Some people consider this to be a goo

Andrew Healey 24 Nov 17, 2022
image stream publish server over websocket

Image Stream Push Server 简介 通过浏览器网页实时查看图像处理结果。 环境 运行程序需要安装一下python依赖: tornado: 用于创建http及websocket服务; opencv-contrib-python: 用于图像数据源获取及图像处理。 使用 进入到src目

MrError404 1 Nov 4, 2021
Synci - Learning project to create a websocket based client server messaging application

Synci Learning project to create a websocket based client server messaging appli

null 2 Jan 13, 2022
WebSocket and WAMP in Python for Twisted and asyncio

Autobahn|Python WebSocket & WAMP for Python on Twisted and asyncio. Quick Links: Source Code - Documentation - WebSocket Examples - WAMP Examples Comm

Crossbar.io 2.4k Jan 4, 2023
Library for building WebSocket servers and clients in Python

What is websockets? websockets is a library for building WebSocket servers and clients in Python with a focus on correctness and simplicity. Built on

Aymeric Augustin 4.3k Jan 4, 2023
WebSocket client for Python

websocket-client The websocket-client module is a WebSocket client for Python. It provides access to low level APIs for WebSockets. All APIs are for s

null 3.1k Jan 2, 2023
一款为 go-cqhttp 的正向 WebSocket 设计的 Python SDK

Nakuru Project 一款为 go-cqhttp 的正向 WebSocket 设计的 Python SDK 在 kuriyama 的基础上改动 项目名来源于藍月なくる,图标由せら绘制 食用方法 将 nakuru 文件夹移至 Python 的 Lib/site-packages 目录下。

null 35 Dec 21, 2022
Using python-binance to provide websocket data to freqtrade

The goal of this project is to provide an alternative way to get realtime data from Binance and use it in freqtrade despite the exchange used. It also uses talipp for computing

null 58 Jan 1, 2023
WebSocket implementation in Python built on top of websockets python library. Similar to Node.js's ws.

ws WebSocket implementation in Python built on top of websockets python library. Similar to Node.js's ws. Basic usage. server.py import ws server = w

AceExpert 7 Jun 27, 2022
wssh ("wish") is a command-line utility/shell for WebSocket inpsired by netcat.

wssh ("wish") is a command-line utility/shell for WebSocket inspired by netcat

Jeff Lindsay 256 Nov 16, 2022
Minecraft WebSocket

Minecraft-WebSocket Pythonでマインクラフトと通信します。 紹介動画 推奨設定 Minecraft Windows Edition (Education Edition) 1.17 以上 Python 3系(3.8.2で動作確認済み) 必要なモジュール ・asyncio ・w

Roii.py 2 Jul 7, 2022
Tetri5 - Multiplayer Websocket Backend

Tetri5 - Multiplayer Websocket Backend This repository is the backend of the multiplayer portion of the Tetri5 game client. It uses the python websock

Giovani Rodriguez 1 Dec 10, 2022
alien.py - Python interface to websocket endpoint of ALICE Grid Services

alien.py - Python interface to websocket endpoint of ALICE Grid Services Quick containerized testing: singularity

Adrian Sevcenco 6 Dec 14, 2022
AWS API Gateway Websocket Asynchronous Notifications Pusher

AWS API Gateway Websocket Asynchronous Pusher Fast AWS API Gateway websockets notifications' pusher using Python AsyncIO for managing asynchronous and

OBytes 5 May 15, 2022
Discord.py Connect to Discord voice call with websocket

Discord.py Connect to Discord voice call with websocket

WoahThatsHot 3 Apr 22, 2022