Real-Time Django: Get Started with Django Channels
blog.heroku.com
blog.heroku.com
Bam! You immediately know it's outdated (emphasized by the headline) and switch to https://docs.djangoproject.com/en/1.9/topics/auth/default/. This might seem minor, but I highly appreciate such attention to detail. And I really like the official page's layout, look and feel which concentrates on information, rather than stupid, flashy animations. Ha, looks like I'm getting old.
But I need to expand my skill set, I need to continue working remote, and I'm interested in OSS in general. Honestly, Python and Django seem like heaven compared to the other language/framework ecosystems I investigated. Not gonna name any names there...
But the documentation for Python and Django is A++. It's just really, really good. I can't praise it enough. The whole setup is elegant, intelligent and accessible. I really appreciate that.
My rough impression is that Rails remote jobs are relatively thick on the ground, but that any OSS dev stack will be better represented in remote job postings than any enterprise stack. So since I prefer Python to Ruby, and Django to Rails, I figured I'd take a leap of faith.
JavaScript is simply not going to be my main dish, not for the time being. Things are just too crazy there. I don't have time to play whack-a-mole with my career skill set.
Django's documentation has ruined me. I took the high quality for granted. Now when I use any of these tiny NodeJS/frontend modules, I'm surprised at how barebones the documentation can be.
Such an excellent project, community and set of docs. By far my favorite framework.
I was surprised, though, by removal of the documentation for all versions preceding Django 1.7 from under docs.djangoproject.com recently. (It’s available now on Read the Docs.) The argument was that spending DSF funds on supporting docs for legacy versions can’t be justified, if I recall correctly from when in came up in the core dev mailing list. It seems to me maintaining documentation is becoming less of a priority now.
[0] jacobian.org/writing/great-documentation/
http://nando.oui.com.br/2014/04/04/why_i_sort_of_dislike_dja...
(I work in a shop which has used both, and generally try to avoid claiming one or the other is objectively better; they're not quite at the apples-and-oranges level, but pretty close)
Django is like any other framework/language. Bad programmers can make a hash of it with ill-conceived ideas.
That's not to say there are projects where another framework/language would have been better but no solution is going to save you from poor project management.
There is no boilerplate or constraint how those 'flexible' solutions should be created, thus every developer writes however he wants and if those developers have not made constraints for themselves you will have a total mess, written in so many styles as there were developers. Jeez, I've even seen messed up Django apps, where you usually must follow some patterns.
Patterns, constraints, models, architecture are for a reason and if a framework/language/library makes you use some specific styles, it's much easier to maintain such projects when there is more than 1 person working on them.
Flask provides the basics to build Web apps. It's low on opinions and flexible. I mostly use flask for systems that are very specific about their functinality and use case.
Actually a core tenet of Python is: "There should be one-- and preferably only one --obvious way to do it".
So Django couldn't be more Pythonic in this regard.
No, there are several. But all of them should strive to be Pythonic, including in the sense of offering "one, and preferably only one, obvious way to do something".
>Dumb comment.
Oh, the irony.
>I was talking about architectures not syntax.
And the Zen of Python is about architecture and APIs too, not just the syntax of the language. They are generic guidelines about how to write Pythonic programs.
It's a batteries included framework, but at the end of the day it's just Python. You can integrate with whatever library is best for the job.
I've worked on Django apps that use SQLAlchemy instead of the Django ORM, Django apps that use Mako instead of the Django template language, and I'm currently exploring using Marshmallow instead of Django forms for some cases.
Is there anything in particular that you feel you can use with Flask or Pyramid but you couldn't use with Django?
It's nice to dabble around Pyramid and/or Flask, but everytime I use, or someone I know uses them for not completely trivial microservices, they are always reinventing those 'cookie cutters' from scratch on their own (or choose a set of 'cookie cutters' made by someone else).
Django can work as a 'microframework', i.e. 'hello world' in one file and in ~10-15 LOC.
Not to mention Django's 'stability', i.e. stable releases at known time, with known ahead roadmap and forthcoming changes, great documentation, etc., whereas Flask has not been released for 2years and 9months (!!!), master is 900 commits ahead (2400 commits in total) of latest version, documentation is not the best (especially for current `master`)... Pyramid is made by true rockstar programmers, though it did not stand against hip image of flask and it suffers from the fact that I must reinvent all the 'cookie cutters'. IMHO this 'microframework' approach is good only for trivial microservices and/or completely non-trivial, crazy custom apps, where overriding Django would be just too much.
What I found is that if you can manage stay within the confines of Django, you will be rewarded and can avoid writing a ton of code. There really isn't to many situation where you can't just to things "The Django Way". If you find one, then maybe rethink your solution. I had a ton of code where I tried to fight the Django Rest Framework, when I stopped and just accepted that Django and the Rest Framework is opinionated I was able to reduce complexity and line count.
Of cause there are problems where Django is simply the wrong solution.
However, in the context of the web (the client/server boundary), I think we need to be careful about how messaging is used. The web is made up of resources with URLs. HTTP is typically used for data transfer, and for good reason.
I sometimes see webapps communicating entirely over WebSockets. I don't mean just the realtime push part, I mean everything, request/response traffic and all. I understand that HTTP is suboptimal in certain contexts, but let's not throw the baby out with the bathwater.
I can imagine a large Django app that uses mostly plain request/response but needs, say, a small customer service bot or occasional real time notifications. This new feature is perfect for that.
"Careful" == do not break urls, use pushState and make sure equivalent document is returned for GET.
If you're the sole developer of a Single Page App with no API, then this difference may not be important. But if you're working with a team, or across teams, then building a WebSocket-only app will bring pain. As another commenter mentioned, as long as equivalent actions are possible via HTTP then some of the issues are alleviated.
And even the newer stuff isn't so much Websockets as it is serving JSON to single-page apps.
I've wanted to like Django (because Python is my preferred language) but it still feels so crufty from its origins as a newspaper server.
Care to elaborate?
Source: https://en.wikipedia.org/wiki/Django_(web_framework)#History
Personally I think the templating system is less and less useful because I'm serving single page apps that I don't really benefit from serving from Django any more (or are Angular and the variable syntaxes conflict with each other)
Links or references to documented slowness?
Overall very good docs though :)
Drop in a custom user model and
a) Better be a brand new project at all
b) You need to muck with the user manager also
c) How do you fix up the admin module? I have yet to see a fully fixed up admin module for the custom user.
I am not a Django pro so happy to be proved wrong. But take a default app, and record all steps to make the user model work (including password reset, login, logout, admin page). If that doesn't feel crufty to you I am not sure what cruft is.
https://github.com/danjac/ownblock/blob/master/ownblock/ownb...
"Channels is to become a built-in feature for Django 1.10, but in order to aid adoption and to encourage community usage and support, it will also be backported to Django 1.8 and 1.9 via a third-party app."
ASGI seems to be a very important piece of this.
"Despite the name of the proposal, ASGI does not specify or design to any specific in-process async solution, such as asyncio, twisted, or gevent. Instead, the receive_many function can be switched between nonblocking or synchronous. This approach allows applications to choose what’s best for their current runtime environment; further improvements may provide extensions where cooperative versions of receive_many are provided."
I think of that as a “senior developer” skill which is easy to underestimate since it doesn't directly translate into tons of commits but is so critical to the long-term success of a project.
Can you explain what you mean by this?
When I first got into Django in 2007 the preferred container was flup, using an scgi connection to the webserver. Nowadays, it seems like uwsgi over HTTP is preferred. CGI was an option for deployment since inception, but I don't know anyone that actually ran their Django apps over CGI, since it's many times slower than using uwsgi.
Django Channels extends wsgi into asgi (ASynchronous Gateway Interface), which provides both send() and receive_many() callables to the application server. In other words, Django can now send messages, unsolicited, back to the webserver, which presumably has a websocket connection back to the browser.
Websockets was just one of those issues so it's good to see it addressed. However, with meteor's DDP there's still no comparison. Looking ahead to Reactive GraphQL that meteor is working on, django seems to be permanently one step behind for the foreseeable future.
These are just my opinions, but overall definitely great news for django developers.
If it's still tightly coupled to MongoDB then there is zero chance I can see it being used for anything more serious than an MVP or hackathon project by a company with non-trivial data requirements.
For one thing, there were some regrettable architectural decisions made from the start: MongoDB just don't cut it. If my company tried to sell apps built with Meteor and/or MongoDB to corporate clients, we'd be waiting tables and working construction for a living.
But there are other issues there, perhaps even philosophical ones. I've become disheartened at what I see happening in the JavaScript arena. Change and never-ending-newness are distorting the reality field there. It's all shiny churn, frothy and irrational.
"Remember: Channels is a general-purpose utility for running background tasks. Thus, many features that used to require Celery or Python-RQ could be done using Channels instead. Channels can’t replace dedicated task queues entirely: it has some important limitations, including at-most-once delivery, that don’t make it suitable for all use cases. Still, Channels can make common background tasks much simpler. For example, you could easily use Channels to perform image thumbnailing, send out emails, tweets, or SMSes, run expensive data calculations, and more."
In any case, I think you'll find hendrix unbelievably easy to use - here's a talk that gives some detail: https://www.youtube.com/watch?v=92VeMkjM1TQ
If 100% of integration with the system consists of sending network requests to it and receiving network responses from it, then sure, it's not going to affect you much.
But when your integration involves taking existing applications/libraries and having them share memory space and call into and be called by functions in Twisted, then you're looking at a different story. Asynchronous code is infectious -- unless everything in your codebase is written to be or play nice with async, you get no benefits from the async parts and in fact can often get a net harm as the async and non-async bits clash with each other.
To my way of thinking about these things, this is plainly a non-sequitur. Twisted and asyncio don't do, or even try to do, the same things.
The only reason that they are comparable is because, for years, Python lacked adequate primitives for expressing concurrency. Thus, Twisted, and its event loop (the reactor), handle this.
And it's true that the reactor may eventually be replaced by async IO. However, the core of what Twisted does (handle network (and other I/O) traffic in an elegant, adaptive, concurrent way) is not something that asyncio is designed to replicate.
This isn't weird esoteric packages either. Ever used requests? SQLAlchemy? Django's ORM? You can't use them with twisted.
Twisted proponents don't openly say this up front as it's not a great story, and their response is usually "just" port the library.
Or maybe, put it like this. If Django and Twisted work well together, why does Hendrix exist at all? Just use Django. Or why does klein exist? Just use werkzeug. You'll see lots of this rewriting snowflakes.
Just a quick search gives me txamqp, txmongo, txmandrill, txflask, txcelery, txdocker, txldap, txgithub, txrequests, txstripe, txzookeeper and on and on and on. Have a look: https://pypi.python.org/pypi?%3Aaction=search&term=twisted&s...
And then there's multiple ones of each to choose from. Look at amqp or reddis. There's something like four implementations of each. Even something like requests, theres treq, rxrequests, requests-twisted. Which one should I use?
And then there's Python 3. Only half of twisted works on Python 3. Which half? I guess one finds out when they give it a go.
I'm left completely scratching my head here. I use all three of these packages routinely with Twisted.
Are you saying that you are trying to share the reactor thread while blocking with, for example, requests.get()? Obviously you can't do that - why would you even try? Just run requests.get() on another thread.
On the other hand, if you, for example, use deferToThreadPool with a bunch of Django ORM calls, you can happily go on serving requests from another ThreadPool. This works like gravy.
These various adapters that you've described: in every case, their existence is not a testament to an inability to run their respective libraries' blocking I/O with Twisted; on the contrary, they provide support for actually using them with a proper Twisted protocol.
The fact that so many of them exist doesn't mean that Twisted is doing anything wrong, it means that people really like Twisted and want these various packages to be able to talk directly to a Protocol or Producer without having to maintain that code in their project.
If you want to run Django in Twisted without hendrix, go ahead: use the WSGIServer built in Twisted. However, you'll probably find that you are building lots of tooling around the awesome things you want to do with Twisted (ThreadPool tuning, websockets, concurrent functions running in views, and much more). So, instead of having to write all that yourself, hendrix ships with it.
For my practice, the Twisted ecosystem is the finest part of Python.
It's not that Twisted is bad. It's just that many Python developers are not "fluent in the Twisted dialect" like how some people find a thick Scottish accent hard to understand and other more familiar with it can understand every word.
Really? Only at a surface glance. Having used channels in both Go and in Clojure, I would say they are nothing like Django channels. The only thing they share is they are like a fifo pipe.
In Go and Clojure channels are an in-process async construct. They have nothing to do with the network at all. (There may be libraries that expose their network connections in the language as channels, but the channel itself is completely in process).
In these languages there is no 'routing' that needs to be set up. There is no 'linearisation' problem. They are first class and can be passed in and out of functions.
Also most importantly, pulling from or pushing to a channel appear to the programmer as a blocking operation, while under the hood the language inverts control to create a non-blocking situation. Send and receive on the Django channels look to be non-blocking and appear to the programmer to be non-blocking (correct me if I'm wrong, please).
Saying all this I'm not opposed to calling Django channels, channels. Channels is a generic term, and what is being done here in Django can be very much described as a channel. Just remember that they are actually very different to the "channels" as used in Go.
Meteor has that like 3 years ago :D