Giter Site home page Giter Site logo

channels's Introduction

Django

Django is a high-level Python web framework that encourages rapid development and clean, pragmatic design. Thanks for checking it out.

All documentation is in the "docs" directory and online at https://docs.djangoproject.com/en/stable/. If you're just getting started, here's how we recommend you read the docs:

  • First, read docs/intro/install.txt for instructions on installing Django.
  • Next, work through the tutorials in order (docs/intro/tutorial01.txt, docs/intro/tutorial02.txt, etc.).
  • If you want to set up an actual deployment server, read docs/howto/deployment/index.txt for instructions.
  • You'll probably want to read through the topical guides (in docs/topics) next; from there you can jump to the HOWTOs (in docs/howto) for specific problems, and check out the reference (docs/ref) for gory details.
  • See docs/README for instructions on building an HTML version of the docs.

Docs are updated rigorously. If you find any problems in the docs, or think they should be clarified in any way, please take 30 seconds to fill out a ticket here: https://code.djangoproject.com/newticket

To get more help:

To contribute to Django:

To run Django's test suite:

Supporting the Development of Django

Django's development depends on your contributions.

If you depend on Django, remember to support the Django Software Foundation: https://www.djangoproject.com/fundraising/

channels's People

Contributors

adamchainz avatar andrewgodwin avatar apollo13 avatar asmaps avatar bastbnl avatar blueyed avatar carltongibson avatar dgilge avatar erwinjunge avatar fcurella avatar ftxrc avatar furious-luke avatar hawkowl avatar hishnash avatar johnthagen avatar jpic avatar krukov avatar linuxlewis avatar lukasa avatar maiksprenger avatar matthiask avatar michael-k avatar ostcar avatar proofit404 avatar raiderrobert avatar readevalprint avatar sachinrekhi avatar smithdc1 avatar smorokin avatar vikalpj avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

channels's Issues

Python 3.4; twisted vs. asyncio in txaio

We migrated from channels 0.8 to 0.9.x (currently on master).
(So maybe I missed sth. that changed from 0.8 to 0.9.x)
Daphne is updated and on master too.
Django 1.9.4
Python 3.4.3

runserver with --noasgi works as expected.
but with asgi every websocket connection results in:

  File "/usr/local/lib/python3.4/dist-packages/twisted/python/log.py", line 101, in callWithLogger
    return callWithContext({"system": lp}, func, *args, **kw)
  File "/usr/local/lib/python3.4/dist-packages/twisted/python/log.py", line 84, in callWithContext
    return context.call({ILogContext: newCtx}, func, *args, **kw)
  File "/usr/local/lib/python3.4/dist-packages/twisted/python/context.py", line 118, in callWithContext
    return self.currentContext().callWithContext(ctx, func, *args, **kw)
  File "/usr/local/lib/python3.4/dist-packages/twisted/python/context.py", line 81, in callWithContext
    return func(*args,**kw)
--- <exception caught here> ---
  File "/usr/local/lib/python3.4/dist-packages/twisted/internet/posixbase.py", line 597, in _doReadOrWrite
    why = selectable.doRead()
  File "/usr/local/lib/python3.4/dist-packages/twisted/internet/tcp.py", line 209, in doRead
    return self._dataReceived(data)
  File "/usr/local/lib/python3.4/dist-packages/twisted/internet/tcp.py", line 215, in _dataReceived
    rval = self.protocol.dataReceived(data)
  File "/usr/local/lib/python3.4/dist-packages/twisted/protocols/basic.py", line 571, in dataReceived
    why = self.lineReceived(line)
  File "/usr/local/lib/python3.4/dist-packages/twisted/web/http.py", line 1720, in lineReceived
    self.allContentReceived()
  File "/usr/local/lib/python3.4/dist-packages/twisted/web/http.py", line 1799, in allContentReceived
    req.requestReceived(command, path, version)
  File "/usr/local/lib/python3.4/dist-packages/twisted/web/http.py", line 832, in requestReceived
    self.process()
  File "/usr/local/lib/python3.4/dist-packages/daphne/http_protocol.py", line 67, in process
    protocol = self.factory.ws_factory.buildProtocol(self.transport.getPeer())
  File "/usr/local/lib/python3.4/dist-packages/twisted/internet/protocol.py", line 135, in buildProtocol
    p = self.protocol()
  File "/usr/local/lib/python3.4/dist-packages/autobahn/websocket/protocol.py", line 665, in __init__
    self.is_closed = txaio.create_future()
  File "/usr/local/lib/python3.4/dist-packages/txaio/_unframework.py", line 43, in _throw_usage_error
    "To use txaio, you must first select a framework "
builtins.RuntimeError: To use txaio, you must first select a framework with .use_twisted() or .use_asyncio()

How can we set use_twisted() or use_asyncio() ?
Daphne seems to require twisted. Why use twisted if there is asyncio (py3.4+)?

Doc issue: specifying redis backend

I love this project! It solves a couple of big problems I've been having.

This is a nit, but when specifying the redis backend, the current docs say:
CHANNEL_BACKENDS = {
"default": {
"BACKEND": "channels.backends.redis.RedisChannelBackend",

I had to use:
"BACKEND": "channels.backends.redis_py.RedisChannelBackend",

How can I send message from views ?

I'm very new. I like to fire message from view. How to do that ?

After finishing Running with Channels I checked with javascript socket.send("hello world") and its working but what I want is using python how to send ?

i.e)

def bot_submit(request):
    bot_result =  request.POST
    # I need bot_result content on frontend how to do that ?
    return HttpResponse('ok')

Implement streaming HTTP responses

Plus chunking for large responses to keep messages under a megabyte. Already spec'd out, just needs support in the request encoder and decoder.

"path" regex doesn't accept strings on Python 3

Using a string for the path regex argument to route() under Python leads to the following exception:

Traceback (most recent call last):
  File "/Users/ulo/.pythonz/pythons/CPython-3.4.3/lib/python3.4/threading.py", line 920, in _bootstrap_inner
    self.run()
  File "/Users/ulo/Envs/dali/lib/python3.4/site-packages/channels/management/commands/runserver.py", line 152, in run
    worker.run()
  File "/Users/ulo/Envs/dali/lib/python3.4/site-packages/channels/worker.py", line 69, in run
    match = self.channel_layer.router.match(message)
  File "/Users/ulo/Envs/dali/lib/python3.4/site-packages/channels/routing.py", line 50, in match
    match = route.match(message)
  File "/Users/ulo/Envs/dali/lib/python3.4/site-packages/channels/routing.py", line 133, in match
    match = re.match(value, message[name])
  File "/Users/ulo/Envs/dali/lib/python3.4/re.py", line 160, in match
    return _compile(pattern, flags).match(string)
TypeError: can't use a string pattern on a bytes-like object

Changing the value of path to bytes appears to fix the problem.

Edit: This also leads to any captured keyword arguments becoming bytes as well.

Versions used:

  • Python 3.4.3
  • django 1.9.4
  • channels 0.10.0
  • asgi-redis 0.9.0

Exception on runserver - default configuration

I'm getting the following with runserver:

Traceback (most recent call last):
  File "/Users/mva/.virtualenvs/spam/lib/python3.5/site-packages/django/utils/autoreload.py", line 226, in wrapper
    fn(*args, **kwargs)
  File "/Users/mva/.virtualenvs/spam/lib/python3.5/site-packages/channels/management/commands/runserver.py", line 37, in inner_run
    self.channel_layer = channel_layers[DEFAULT_CHANNEL_LAYER]
  File "/Users/mva/.virtualenvs/spam/lib/python3.5/site-packages/channels/asgi.py", line 53, in __getitem__
    self.backends[key] = self.make_backend(key)
  File "/Users/mva/.virtualenvs/spam/lib/python3.5/site-packages/channels/asgi.py", line 33, in make_backend
    raise InvalidChannelLayerError("No BACKEND specified for %s" % name)
channels.asgi.InvalidChannelLayerError: No BACKEND specified for default

I was reading http://channels.readthedocs.org/en/latest/getting-started.html#first-consumers where it mentions that, by default, Channels effectively delegates to Django via WSGI.

Environment

  • Python 3.5.1
  • django==1.9.4
  • channels==0.9.4

Is not clear how to hookup Django's URL routing to the channel routing, or if it even possible?

While it is not that complicated to write routes for the CHANNEL_LAYERS['ROUTING'] setting, the Django Admin and some 3rd party apps (like Django Rest Framework) generate routes to be included into a URLConf.

Is it possible to just hook up Django's URL resolving system into Channel's routing system? Like:

channel_routing = {
    'http.request': DjangoURLConfConsumer(),

    # Websocket stuff:
    'websocket.connect': consumers.ws_connect,
    'websocket.receive': consumers.ws_receive,
    'websocket.disconnect': consumers.ws_disconnect,
}

where DjangoURLConfConsumer is a function/class that would load Django's URLConf and dispatch the message to the traditional (as in synchronous) views.

Maybe Channels already does this?

error handling on websocket connect

I'm currently a bit unhappy with the error handling in the messages.

The websocket connect message for example... any error or exception happening in there will keep the connection open and the client will be able to continue sending messages.

It should be possible to drop the connection attempt by raising permission denied for example or it should fail with a error 500 on other exceptions.

Bastian

nginx websocket proxy

Hi,

I'm currently playing with django channels and it looks really great. I have tried several other websocket stuff in the last weeks, like crossbar (http://crossbar.io) and something I have build with tornado.

I have added following snippet to my nginx configuration:

    location /ws/ {
       rewrite  ^/(.*)  /$1 break;
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_set_header Host $http_host;
       proxy_redirect off;

       proxy_pass http://localhost:8080/;
       proxy_http_version 1.1;
       proxy_set_header Upgrade $http_upgrade;
       proxy_set_header Connection "upgrade";
    }

which works fine with other websocket servers, but it looks like it won't work with runwsserver.
(I tried asyncio and twisted).
The error I see in the browser is: WebSocket connection to 'ws://localhost/ws/asd' failed: Error during WebSocket handshake: Unexpected response code: 400
I can see that the websocket server is reached since it prints some debug lines:

INFO asyncio poll 1.000 took 1.001 seconds
DEBUG asyncio poll 1.000 took 0.817 seconds
DEBUG asyncio poll 0.000 took 0.000 seconds
DEBUG asyncio poll 0.000 took 0.000 seconds
DEBUG asyncio poll 0.000 took 0.000 seconds
DEBUG asyncio poll 0.181 took 0.182 seconds

but thats not really helpful ;)

I'll try to dig into the code at the weekend, but maybe someone can help me before that ;)

Thanks,
Bastian

Sessions not working

Looks like something is picking up query parameters as lists instead of strings, which is messing up the inbuilt sessions.

For example the session key in the url

localhost:8000?session_key=33tj3gak0cnu0fur11arxga3mklgwa27

is actually getting picked up as "['33tj3gak0cnu0fur11arxga3mklgwa27']" in the message content instead of "33tj3gak0cnu0fur11arxga3mklgwa27".

So when the http_session tries to import from the Session Store it returns an empty session:

session = session_engine.SessionStore(session_key=session_key)

I've had a dig around, but I can't see what actually creates the message.content so I'm not sure how to troubleshoot this further.

Consistent hashing and "prefetch count"

Hi,
I've played around with channels a few weeks back, but I can see that a lot have changed since then :-)

I have a use case in which I must assure that only a single command is executed per account at a given time.

Can I leverage the response channels (!account1,!account2), in a way that the matching workers will process them one at a time and in orders?

Will this use case be addressed as a part of the channels framework?

Best,
Erik.

seperating locking and messages backend?

I wonder if it makes sense to seperate the locking and messages backend. I think if you would want to use rabbitmq for example for messages you might still want to use redis or memcache for locking?

Use WebRTC data channel instead of Websockets

I think we should make a paradigm shift and move to use WebRTC instead of Websockets. This allows many interesting properties:

  • connections can be based on SCTP
  • have multi-path routing
  • you can have data packets which are reliable or unreliable
  • you can even have backpressure support (imagine that you could push back on Meteor publish because client cannot handle observes as quickly as server is pushing)

There is a great open source project already available which provides both client server suppor: https://github.com/feross/simple-peer

Some interesting links to read:

Avoid adding more auto-imported modules.

Adding stuff to registries as an import-time side-effect of decorators is an anti-pattern. It impedes testability, and it causes behavior changes depending on which modules have been imported.

Django already contains this anti-pattern (for signals and for admin, and in even more convoluted fashion for models), and django-channels requires expanding it to even more modules in order to catch decorated consumers.

I think there are two better options:

  1. Relying an decorators and import side effects for signal registration has been deprecated in favor of explicitly registering signal handlers in AppConfig.ready. The same technique could be recommended here (instead of using decorators).

  2. If the convenience of a decorator is important, we could rely on the venusian package (http://venusian.readthedocs.org/en/latest/), which solves this problem. A venusian-based decorator doesn't have any side effects, all it does is annotate the decorated function with some metadata. Then you run a venusian "scan" at a well-defined point in your code, which walks the module tree and imports all modules, looking for functions which have been annotated with venusian metadata and running a callback on them. That callback can do whatever needs to be done (e.g. put the function in a registry). This avoids import-time side effects and changes in behavior depending on the timing of module imports. All modules are checked for decorated functions, and the scan happens at a clearly-defined point (which would fit in well with the new django.setup() in 1.7+). Venusian is a solid and battle-tested solution to this problem (all decorators in the Pyramid web framework use it).

What is the best way to push dict from server ?

Hi... Currently I'm doing this.. I need more efficient way to pass dict and get it from frontend .. thanks

In my django views file I have this

messenger['content'] = '{' + '"name" :"{}", "ip_address" :"{}"'.format(name, ip_address) + '}'
result['message'] = "Ip Address associated with {} deleted".format(name)
Group("chat").send(messenger) 

And in the html I have this to parse the string ...

var result = JSON.parse(e.data);
console.log(result);

So I guess this is not the correct way. Then what is the good way ?

IndexError: deque index out of range

According to this similar thread, this issue might be an "inherent issue with multi-threading." So I'm not sure if it requires attention, but I figured it might be good to put on the radar.

[2016/03/03 17:04:54] WebSocket CONNECT /liveblog [127.0.0.1:62988]
Exception in thread Thread-4:
Traceback (most recent call last):
  File "/usr/local/Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 810, in __bootstrap_inner
    self.run()
  File "/Users/cbodkin/.virtualenvs/p2p-liveblog/lib/python2.7/site-packages/channels/management/commands/runserver.py", line 151, in run
    worker.run()
  File "/Users/cbodkin/.virtualenvs/p2p-liveblog/lib/python2.7/site-packages/channels/worker.py", line 29, in run
    channel, content = self.channel_layer.receive_many(channels, block=True)
  File "/Users/cbodkin/.virtualenvs/p2p-liveblog/lib/python2.7/site-packages/asgiref/inmemory.py", line 47, in receive_many
    self._clean_expired()
  File "/Users/cbodkin/.virtualenvs/p2p-liveblog/lib/python2.7/site-packages/asgiref/inmemory.py", line 109, in _clean_expired
    while queue and queue[0][0] < time.time():
IndexError: deque index out of range

Error response when using django login - Using channels 0.8

Error processing message with consumer <channels.adapters.UrlConsumer object at 0x7f9d09c81f10>:
Traceback (most recent call last):
File "/home/yyy/xxx/local/lib/python2.7/site-packages/channels/worker.py", line 34, in run
consumer(message)
File "/home/yyy/xxx/local/lib/python2.7/site-packages/channels/adapters.py", line 24, in call
message.reply_channel.send(response.channel_encode())
File "/home/yyy/xxx/local/lib/python2.7/site-packages/channels/response.py", line 11, in encode_response
"content": response.content,
File "/home/yyy/xxx/local/lib/python2.7/site-packages/django/http/response.py", line 409, in content
"Use streaming_content instead." % self.class.name)
AttributeError: This FileResponse instance has no content attribute. Use streaming_content instead.

Make channel_session handle simultaneous connect and data

It's possible that a request could open and immediately send data, such that the connect message is still being handled when the receive message gets handled. The channel_session decorator should be able to handle this; current idea is that it sets a value when first encountered with data and then the other ones check/wait for this value to appear.

django-debug-toolbar tries accessing META['wsgi.multiprocess'] on requests

Which crashes with the following stack trace:

Traceback:
File "path/venv/lib/python3.5/site-packages/django/core/handlers/base.py" in get_response
  223.                 response = middleware_method(request, response)
File "path/venv/lib/python3.5/site-packages/debug_toolbar/middleware.py" in process_response
  131.             bits[-2] += toolbar.render_toolbar()
File "path/venv/lib/python3.5/site-packages/debug_toolbar/toolbar.py" in render_toolbar
  60.         if not self.should_render_panels():
File "path/venv/lib/python3.5/site-packages/debug_toolbar/toolbar.py" in should_render_panels
  81.             render_panels = self.request.META['wsgi.multiprocess']

Exception Type: KeyError at /api/v1/path
Exception Value: 'wsgi.multiprocess'

Running the chat tutorial does not seem to work

Hey,

I have a local Redis server running and the following configurations - trying to follow the chat tutorial

settings.py:

CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "asgi_redis.RedisChannelLayer",
        "ROUTING": "App.routing.channel_routing",
    },
}

routing.py

channel_routing = {
    "websocket.connect": ws_connect,
    "websocket.receive": ws_message,
    "websocket.disconnect": ws_disconnect,
}

and the consumer.py is identical to the tutorial code in http://channels.readthedocs.org/en/latest/getting-started.html#persisting-data

connecting seems to work fine, I see redis being updated etc. but when trying to send a message - this line will run but no message will be received by the client
Group("chat-%s" % message.channel_session['room']).send(message.content)

I am connecting to ws://localhost:8000/lmao

Any idea why or how I can troubleshoot it?

HttpRequest._stream

Django REST Framework (version 3.3.1) tries to access the _stream attribute on HttpRequests, which crashes with the following stack trace:

Traceback (most recent call last):
  File "path/venv/lib/python3.5/site-packages/rest_framework/request.py", line 357, in __getattribute__
    return getattr(self._request, attr)
AttributeError: 'HttpRequest' object has no attribute 'data'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "path/venv/lib/python3.5/site-packages/django/core/handlers/base.py", line 132, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "path/venv/lib/python3.5/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File "path/venv/lib/python3.5/site-packages/django/views/generic/base.py", line 71, in view
    return self.dispatch(request, *args, **kwargs)
  File "path/venv/lib/python3.5/site-packages/rest_framework/views.py", line 466, in dispatch
    response = self.handle_exception(exc)
  File "path/venv/lib/python3.5/site-packages/rest_framework/views.py", line 463, in dispatch
    response = handler(request, *args, **kwargs)
  File "path/venv/lib/python3.5/site-packages/rest_framework/generics.py", line 262, in patch
    return self.partial_update(request, *args, **kwargs)
  File "path/venv/lib/python3.5/site-packages/rest_framework/mixins.py", line 78, in partial_update
    return self.update(request, *args, **kwargs)
  File "path/venv/lib/python3.5/site-packages/rest_framework/mixins.py", line 68, in update
    serializer = self.get_serializer(instance, data=request.data, partial=partial)
  File "path/venv/lib/python3.5/site-packages/rest_framework/request.py", line 359, in __getattribute__
    six.reraise(info[0], info[1], info[2].tb_next)
  File "path/venv/lib/python3.5/site-packages/django/utils/six.py", line 658, in reraise
    raise value.with_traceback(tb)
  File "path/venv/lib/python3.5/site-packages/rest_framework/request.py", line 183, in data
    self._load_data_and_files()
  File "path/venv/lib/python3.5/site-packages/rest_framework/request.py", line 243, in _load_data_and_files
    self._data, self._files = self._parse()
  File "path/venv/lib/python3.5/site-packages/rest_framework/request.py", line 289, in _parse
    parsed = parser.parse(stream, media_type, self.parser_context)
  File "path/venv/lib/python3.5/site-packages/djangorestframework_camel_case/parser.py", line 15, in parse
    data = stream.read().decode(encoding)
  File "path/venv/lib/python3.5/site-packages/django/http/request.py", line 293, in read
    return self._stream.read(*args, **kwargs)
AttributeError: 'HttpRequest' object has no attribute '_stream'

Can't really serve static files with channels

I try to transition an existing django app to channel, in dev/debug mode.

Apparently serving static files with the default DatabaseChannelLayer quickly hogs the database, my sqlite file makes a few 10s of Megs only after a few request ( I am serving my static files through django .. default debug/dev mode .. ).
My understanding is that all my static assets ( large js/css app) is copied at each request in the database. Fine . But then daphne fails with : ( purging the database solve this for the next 2 requests ..).

daphne/http_protocol.py", line 136, in serverResponse
    raise ValueError("Got multiple Response messages!")

I can see why channels should not be used for static files and a proper production setup will use a proper webserver for static assets, but is there a hidden usable "quick and dirty for dev mode" way of serving static files with channels that I could not see in the help ?
I guess we could have runserver spawning a separate static file server, but at least I think it should be mentionned in the doc somewhere like "DON'T serve statics with channels / DatabaseChannelLayer"

Let me know how I could help.

Preferred location for discussion about django-channels

After the initial discussion on django-developers, and with django-channels progressing but not yet in django itself. Is there a preferred location for discussing django-channels or since the plan is to move django-channels into django itself, should the discussion just take place in django-developers?

Work out what to do with file uploads

Especially large ones, that won't fit in the 1MB message limit. Not sure they can be chunked like the responses can, given that would need perfect ordering.

patched runserver cutting query parameters from HttpRequest.build_absolute_uri()

I noticed that oauth login was not working with the modified runserver because HttpRequest.build_absolute_uri(location) (https://docs.djangoproject.com/en/1.9/ref/request-response/#django.http.HttpRequest.build_absolute_uri) cuts all query parameters.

when the expected result ist http://localhost:9000/api/callback/?code=Z7VNafOdj5oYuri2yD1OvKH&state=zEpKuXdqldmo with the modifed runserver it's only http://localhost:9000/api/callback/

HTTP2 support

Likely via a new interface server - perhaps one that can also support WebSockets and HTTP1 all in one big go. Needs some research into the current state of python HTTP2 support.

Exception when using daphne / runworker

Environment:

Request Method: GET
Request URL: http://localhost:8000/admin/jsi18n/

Django Version: 1.9.4
Python Version: 3.5.1
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'channels']
Installed 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.auth.middleware.SessionAuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']

Traceback:

File "/Users/mva/.virtualenvs/spam/lib/python3.5/site-packages/django/core/handlers/base.py" in get_response
  149.                     response = self.process_exception_by_middleware(e, request)

File "/Users/mva/.virtualenvs/spam/lib/python3.5/site-packages/channels/handler.py" in process_exception_by_middleware
  194.             return super(AsgiHandler, self).process_exception_by_middleware(exception, request)

File "/Users/mva/.virtualenvs/spam/lib/python3.5/site-packages/django/core/handlers/base.py" in get_response
  147.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/Users/mva/.virtualenvs/spam/lib/python3.5/site-packages/django/contrib/admin/sites.py" in wrapper
  265.                 return self.admin_view(view, cacheable)(*args, **kwargs)

File "/Users/mva/.virtualenvs/spam/lib/python3.5/site-packages/django/utils/decorators.py" in _wrapped_view
  149.                     response = view_func(request, *args, **kwargs)

File "/Users/mva/.virtualenvs/spam/lib/python3.5/site-packages/django/contrib/admin/sites.py" in inner
  244.             return view(request, *args, **kwargs)

File "/Users/mva/.virtualenvs/spam/lib/python3.5/site-packages/django/contrib/admin/sites.py" in i18n_javascript
  359.         return javascript_catalog(request, packages=['django.conf', 'django.contrib.admin'])

File "/Users/mva/.virtualenvs/spam/lib/python3.5/site-packages/django/views/i18n.py" in javascript_catalog
  326.     locale = _get_locale(request)

File "/Users/mva/.virtualenvs/spam/lib/python3.5/site-packages/django/views/i18n.py" in _get_locale
  294.     return to_locale(language)

File "/Users/mva/.virtualenvs/spam/lib/python3.5/site-packages/django/utils/translation/__init__.py" in to_locale
  195.     return _trans.to_locale(language)

File "/Users/mva/.virtualenvs/spam/lib/python3.5/site-packages/django/utils/translation/trans_real.py" in to_locale
  71.     p = language.find('-')

Exception Type: AttributeError at /admin/jsi18n/
Exception Value: 'NoneType' object has no attribute 'find'

Environment

Python 3.5.1
django==1.9.4
channels==0.9.5

Plugable JSON encoder?

Since the core of channels are JSON messages it'd be cool if we could swap the JSON encoder of the default backends.

My use-case for this is using an encoder that supports inlining the bytes of a pre-encoded JSON objects into a larger dynamic JSON structure (we use metamagic.json package). This saves a cubic ton of CPU cycles on JSON decoding/encoding if you re-use a lot of cachable sub-structures.

Anyway, maybe a json.dumps setting would be good, like a importable path to a callable (defaulting to standard json.dumps). Alternately we could override the default backends but that's a bit too much.

A bonus this also saves the project from the endless json/simplejson/ujson/whateverfastestjsonoftheday debates. 😉

runserver and daphne gives error after upgrade

I upgraded the channels version today. And look like multiple things not working correctly. After reading the docs and I found need to update asgi.py file and running daphne gives me below error..

(venv)simon@simon-OptiPlex-780:~/Workspace/buildsys$ daphne -b 127.0.0.1 -p 9000 buildsys.asgi:channel_layer 
Traceback (most recent call last):
  File "/home/simon/Workspace/venv/bin/daphne", line 9, in <module>
    load_entry_point('daphne==0.9', 'console_scripts', 'daphne')()
  File "/home/simon/Workspace/venv/local/lib/python2.7/site-packages/daphne/cli.py", line 53, in entrypoint
    cls().run(sys.argv[1:])
  File "/home/simon/Workspace/venv/local/lib/python2.7/site-packages/daphne/cli.py", line 74, in run
    channel_layer = importlib.import_module(module_path)
  File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
  File "./buildsys/asgi.py", line 6, in <module>
    channel_layer = get_channel_layer()
  File "/home/simon/Workspace/venv/local/lib/python2.7/site-packages/channels/asgi.py", line 83, in get_channel_layer
    django.setup(set_prefix=False)
TypeError: setup() takes no arguments (1 given)

And running runserver also gives me below error :>

Unhandled Error
Traceback (most recent call last):
  File "/home/simon/Workspace/venv/local/lib/python2.7/site-packages/channels/management/commands/runserver.py", line 81, in inner_run
    action_logger=self.log_action,
  File "/home/simon/Workspace/venv/local/lib/python2.7/site-packages/daphne/server.py", line 23, in run
    reactor.run(installSignalHandlers=self.signal_handlers)
  File "/home/simon/Workspace/venv/local/lib/python2.7/site-packages/twisted/internet/base.py", line 1194, in run
    self.mainLoop()
  File "/home/simon/Workspace/venv/local/lib/python2.7/site-packages/twisted/internet/base.py", line 1203, in mainLoop
    self.runUntilCurrent()
--- <exception caught here> ---
  File "/home/simon/Workspace/venv/local/lib/python2.7/site-packages/twisted/internet/base.py", line 825, in runUntilCurrent
    call.func(*call.args, **call.kw)
  File "/home/simon/Workspace/venv/local/lib/python2.7/site-packages/daphne/server.py", line 40, in backend_reader
    self.factory.dispatch_reply(channel, message)
  File "/home/simon/Workspace/venv/local/lib/python2.7/site-packages/daphne/http_protocol.py", line 197, in dispatch_reply
    self.reply_protocols[channel].serverResponse(message)
  File "/home/simon/Workspace/venv/local/lib/python2.7/site-packages/daphne/http_protocol.py", line 136, in serverResponse
    raise ValueError("Got multiple Response messages!")
exceptions.ValueError: Got multiple Response messages!

Admin login intermittently failing

Pardon - I accidentally hit CTRL + Return and submitted this without info...

With default settings for the http.request channel, when I try to log into the admin using my test user whose username and password are both admin, I sometimes run into this situation where I can't login, no matter how many times I enter or copy/paste the username / password in. I can hard-refresh the page, ensuring there isn't a cached version of CSRF or something fishy going on. The funny part is that is actually logging me in, but then redirecting me back to the login screen immediately thereafter.

This is me trying over and over again, to see if perhaps this was some sort of "client needs to connect to the same process on the GET after the POST login" type of bug:

[2016/03/13 15:48:37] HTTP POST /admin/login/ 302 [0.10, 127.0.0.1:53134]
[2016/03/13 15:48:37] HTTP GET /admin/ 302 [0.05, 127.0.0.1:53134]
[2016/03/13 15:48:37] HTTP GET /admin/login/ 200 [0.04, 127.0.0.1:53134]
[2016/03/13 15:48:42] HTTP POST /admin/login/ 302 [0.10, 127.0.0.1:53134]
[2016/03/13 15:48:42] HTTP GET /admin/ 302 [0.05, 127.0.0.1:53134]
[2016/03/13 15:48:42] HTTP GET /admin/login/ 200 [0.04, 127.0.0.1:53134]
[2016/03/13 15:48:53] HTTP POST /admin/login/ 302 [0.10, 127.0.0.1:53134]
[2016/03/13 15:48:53] HTTP GET /admin/ 302 [0.05, 127.0.0.1:53134]
[2016/03/13 15:48:53] HTTP GET /admin/login/ 200 [0.05, 127.0.0.1:53134]
[2016/03/13 15:48:58] HTTP POST /admin/login/ 302 [0.10, 127.0.0.1:53134]
[2016/03/13 15:48:58] HTTP GET /admin/ 302 [0.05, 127.0.0.1:53134]
[2016/03/13 15:48:58] HTTP GET /admin/login/ 200 [0.05, 127.0.0.1:53134]
[2016/03/13 15:49:01] HTTP POST /admin/login/ 302 [0.10, 127.0.0.1:53134]
[2016/03/13 15:49:01] HTTP GET /admin/ 302 [0.05, 127.0.0.1:53134]
[2016/03/13 15:49:01] HTTP GET /admin/login/ 200 [0.05, 127.0.0.1:53134]

settings.py

CHANNEL_LAYERS = {
    'default': {
        'BACKEND': 'asgiref.inmemory.ChannelLayer',
        'ROUTING': 'spam.routing.channel_routing'
    }
}

routing.py

channel_routing = {
    'websocket.connect': 'spam.apps.spams.consumers.connect',
    'websocket.receive': 'spam.apps.spams.consumers.receive',
    'websocket.disconnect': 'spam.apps.spams.consumers.disconnect'
}

Environment

Python 3.5.1
django==1.9.4
channels==0.9.5

EDIT

I just reproduced it with channel_routing = {} in routing.py.

I'm not able to reproduce when I remove the CHANNEL_LAYERS setting.

Serving static files with Daphne

I noticed during my quick testing of daphne / runworker that there is no automatic support for static files. I know that, in the ideal world, static files are served from a CDN, but over the past few years it's become very common practice to serve static files from your application's front-end server (e.g., using WhiteNoise - also see their IAQ).

With that said, is there a way to serve static in production with Daphne? Or, is that something you'd be interested in merging, if I was to find a reasonable way to add WhiteNoise-like functionality in a fork?

Messagepack support?

Just for the conversation and to poll interest, would it be possible to allow the use of messagepack as an alternative to json encoding?
http://msgpack.org/

Messagepack (or msgpack) is a compact json protocol where values like true or «file element list» are encoded so the final and global value size is reduced.

There is a good python encoder and it could improve channel performance overall.

I will consider doing this myself but I would love some feedback to know if it is interesting or just some crazy idea.

redis:// URL host & port configuration

A redis:// URL is a great shorthand for redis hostname & port settings, and it can easily be stored in an environment variable. It's very handy for Docker/Dokku deployments and is used in other Django + redis libraries (Celery, django-redis)

Rather than:

...
        "HOSTS": [("redis-channel-1", 6379), ("redis-channel-2", 6379)],
...

It would look like this:

...
        "HOSTS": ["redis://redis-channel-1:6379/0", "redis://redis-channel-2:6379/0"],
...

linearize error with redis backend (maybe python3 related)

while continuing the getting startet tutorial I stumbled when I added the linearize decorator:

ERROR django.channels Error processing message with consumer cm_base.consumers.ws_message:
Traceback (most recent call last):
  File "/home/vagrant/pyenv/src/channels/channels/worker.py", line 37, in run
    consumer(message)
  File "/home/vagrant/pyenv/src/channels/channels/decorators.py", line 26, in inner
    locked = message.channel_backend.lock_channel(message.reply_channel)
  File "/home/vagrant/pyenv/src/channels/channels/backends/redis_py.py", line 177, in lock_channel
    return bool(self.connection(self.consistent_hash(channel)).setnx(key, "1"))
  File "/home/vagrant/pyenv/src/channels/channels/backends/redis_py.py", line 41, in consistent_hash
    bigval = binascii.crc32(value) & 0xffffffff
TypeError: 'Channel' does not support the buffer interface

Ptyhon 3 compatibility error with RedisBackend

Using the Redis backend with Python 3 seems to break channels. My project is set up as follows:

CHANNEL_BACKENDS = {
    "default": {
        "BACKEND": "channels.backends.redis_py.RedisChannelBackend",
        "HOST": "localhost",
        "ROUTING": "project.routing.channel_routing",
    },
}

Trying to access any page via HTTP raises the following error:

Stacktrace 
    Traceback (most recent call last):
      File "/usr/lib/python3.4/wsgiref/handlers.py", line 137, in run
        self.result = application(self.environ, self.start_response)
      File "/home/user/.local/share/virtualenvs/project/lib/python3.4/site-packages/django/contrib/staticfiles/handlers.py", line 63, in __call__
        return self.application(environ, start_response)
      File "/home/user/.local/share/virtualenvs/project/lib/python3.4/site-packages/django/core/handlers/wsgi.py", line 189, in __call__
        response = self.get_response(request)
      File "/home/user/.local/share/virtualenvs/project/lib/python3.4/site-packages/channels/interfaces/wsgi.py", line 19, in get_response
        Channel("http.request", channel_backend=self.channel_backend).send(request.channel_encode())
      File "/home/user/.local/share/virtualenvs/project/lib/python3.4/site-packages/channels/channel.py", line 35, in send
        self.channel_backend.send(self.name, content)
      File "/home/user/.local/share/virtualenvs/project/lib/python3.4/site-packages/channels/backends/redis_py.py", line 31, in send
        key = self.prefix + uuid.uuid4().get_hex()
    AttributeError: 'UUID' object has no attribute 'get_hex'

A dumb search for that error shows me it's probably a Python 2/3 compat issue, and
replacing get_hex() with hex should solve the problem.

Also, I wanted to thank you for the quality of this project : I tried to integrate it on one of my project and it works exactly as shown in the docs. I really like your approach to solve this problem and even if I probably won't use it in production until it's ready, it's nice to know there is a clean solution around that support WebSockets directly in Django.

Running scheduled jobs

Hi,
Kudos for the great job!
This will be definitely take django to the next level!

Are you planning to include support for scheduled jobs? Like celery beat?

Any suggested workarounds?

Best,
Erik.

Invalid Call to InMemoryChannelBackend

After installing channels and creating a shell Django website I am unable to get a basic runserver started due to the following error:

Unhandled exception in thread started by <pydev_monkey._NewThreadStartupWithTrace instance at 0x7f69673e13f8>
Traceback (most recent call last):
  File "/usr/lib/pycharm-4.5.3/helpers/pydev/pydev_monkey.py", line 427, in __call__
    return self.original_func(*self.args, **self.kwargs)
  File "/home/ricomoss/.virtualenvs/dc2/local/lib/python2.7/site-packages/django/utils/autoreload.py", line 229, in wrapper
    fn(*args, **kwargs)
  File "/home/ricomoss/workspace/channels/channels/management/commands/runserver.py", line 25, in inner_run
    self.channel_backend = channel_backends[DEFAULT_CHANNEL_BACKEND]
  File "/home/ricomoss/workspace/channels/channels/backends/__init__.py", line 32, in __getitem__
    self.backends[key] = self.make_backend(key)
  File "/home/ricomoss/workspace/channels/channels/backends/__init__.py", line 26, in make_backend
    instance = backend_class(**{k.lower(): v for k, v in self.configs[name].items() if k != "BACKEND"})
TypeError: __init__() takes at least 2 arguments (1 given)

After investigating I was able to see that the default channel backend is going to be channels.backends.memory.InMemoryChannelBackend, which expects a route to instantiate. The dictionary comprehension above is empty.

I'd love to contribute to this project but have just started and do not have the full context of intent here. Can you please provide some guidance as to what can be done to fix this problem?

DatabaseChannelBackend is broken

In the master branch, channels.backends.database.DatabaseChannelBackend inherits from BaseChannelBackend, which appears not to exist anymore.

Error in python3

Traceback (most recent call last):
  File ".../lib/python3.4/site-packages/channels/worker.py", line 34, in run
    consumer(message)
  File ".../lib/python3.4/site-packages/channels/decorators.py", line 54, in inner
    session_key = "skt" + hashlib.md5(reply_name[:-24]).hexdigest()[:8] + reply_name[-24:]
TypeError: Unicode-objects must be encoded before hashing

I'll try to send a merge request for you

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.