Transcript: Channels
Hello and welcome to another episode of Django Chat, a weekly podcast on the Django Web Framework.
This week we're going to talk about the very popular Django Channels package.
I'm Will Vincent, joined as always by Carlton Gibson.
Hi, Carlton.
Hello there.
Hi Will.
So Django Channels, this is a very popular package with a long history and ties into Bleeding Edge Django.
So let's describe So what is Cha Channels?
I'll tee that up to you.
So it's been around for a couple years, and you are currently the maintainer of it, though it was originally created by Andrew Godwin.
And really it was a a first attempt at tackling async.
Yeah, exactly.
Exactly.
And so it's now on like version two.
Um if version one was the first go at, well, how might we make bring um make Django async?
I think Andrew talked about this a little bit when we interviewed him.
Yes, and he has some.
As well, that will link to talking specifically about uh channels as well as async.
But yes, our interview with him, he talked quite a bit about async itself, modern async.
And so the the first thing it does is it enables you to um it will wrap your existing Django application in um an async handler, an ASGI handler, much like that that's going to be available in Django 3.0, almost you know, very similar.
Um and it so it'll enable you to use an ASGI server to serve your Django application.
And then on top of that, so that's the first thing, and that's you know, that's kind of interesting, that's what it will be in Django 3.0.
On top of that, it has um WebSocket support.
Yes, yeah.
Um and it also has um proper async view support, so you can write async dev views uh which will handle say HTTP but in an in a properly async way all the way down.
And it also there's another interesting bit it has, which is called a channel layer, which enables you to kind of um talk between applications.
So you you need a backing, a back for that.
So that the one that's in play is um Redis as a channel's red is Redis um package, which um sits on top of that.
And that enables you, for instance, to have say group chat.
For instance, so you open a connection um to my website, and it's we it's got a web socket that's enables you to do async web socket communication back and forward to the web server.
And I open one as well, and then the channels layer bit enables us to send messages not just back and forward to the server to ourselves but to a group, which then fans them out to everybody in the group so we could have a chat room or uh you know
user chat or uh my friend Jason Barrett has a course on building a Uber clone, so real-time with with taxis.
Um we'll link to that.
Um yeah, these are the examples.
You know, and you could you could communicate using um uh a mobile app, for instance, to the the channel server, and that might be able to talk between apps, or you know, I think an Uber driver has a has an app and you have an app and the two communicate via a server using probably WebSockets or similar tech.
Yeah, yeah, uh WebSockets.
So but the so I guess the question for people though was so what should I use now?
Because channels uh has been under very active development.
In a way, the new async stuff is a bit of a okay.
So the first so the first thing to say about that is what the status of channels.
So I've so Andrew has stepped back from channels and he's now working on async in Django, and I've stepped in and I'm just maintaining it.
And there's a massive difference between when Django um Andrew is actively developing channels and I'm I'm doing maintenance.
And I I have I doing this, it isn't part of my Django Fellow work, so it's just volunteer basis.
So I have an hour, a couple of hours each week where I triage tickets and I fix bugs over the course of the medium term.
So we have a release now, maybe two, three releases a year, just fixing one or two bugs, rather than Andrew actively developing it and pushing it forwards.
But it is maintained, it's great, and it there is there are issues, and if you want to contribute, I'm happy to help you contribute and we'll get those issues fixed, and we can put new releases out.
But it's it's good and it's there.
What should you be using?
Django 3.0 just about to come out.
If all you want to do is wrap your application in um and serve it via an ASGI server, use Django 3.0 because that's all um that's that part of channels will be in Django chords, no point using channels for that.
Um eventually we'll remove that from channels, but not until 2.2's end of life, I suppose, because that doesn't have the ASCII support.
Right.
If you want to use WebSockets, then yeah, channels is a great solution for that.
And if you at this stage want to write async views, um then still channels because 3.1 will should have that in Django core, but doesn't yet.
And if you want to play around with the um channels layer stuff, which is kind of exciting, it's you know, it's kind of like enables you to build, say something it's kind of like a proto message bus.
It's not uh it's not a full-scale one, you know.
There are some full-scale applications that you have to run, but if you just want to play around with passing messages between different clients, channels will serve that purpose.
And so it's a good um starting point for that.
And if you run into difficulties or scaling issues or whatever, then perhaps you can move up to one of these more fully fledged message bus applications at the time.
So that would be my answer.
And what should you be using?
Depends what you want to do.
As ever.
Well, and I think the history of channels is interesting just in terms of shedding a light on Django and how it's structured, because so uh channels is not part of Django, but it was added as an official Django project in 2016.
Yes.
So this is, I guess, a little bit like Django Rest Framework is actually I don't know if Rest Framework's an official project.
I don't think that it is not.
But Rest Rest Framework was originally under Tom Christie, who was the creator of Rest Framework, his um sort of um um GitHub account and his personal account, and then he created ENCODE OSS software, which is like um uh they seek to do uh sustainable open source software development.
So you can fund the projects.
So the main the the biggest project there is REST Framework, but also the new HTTPX, which is a fully async requests compatible HTTP client.
It's gonna be or library, it's gonna be yeah.
We must
have Tom on to talk about that because that's the thing you and I talk and get really excited about, but I don't think everyone else knows about it.
Yeah, I mean it's it uses UL lib3, it's fully async compatible, it's got multiple backends, um async.io and trio.
It's it it's you know it it's
it's gonna be ubiquitous it's in the future.
Yes, yeah, yeah, it's it's really hot, and also he's got um the starler as ge microframework there, and there's some other things are all under ENCODE.
So the Rest Framework's um under that, and you can sponsor ENCODE to help fund REST Framework and make that sustainable.
Um, but why is channels so but channels is an official Django project.
Uh why is that?
I think because it was clear right from day one that async was where we wanted to go.
It was clear to Andrew, certainly, and uh, you know, um, but it wasn't something that we could just bring straight into Django.
Django is mature and stable, right?
There's this this idea that it's really exciting because it's mature and stable, and you can be on the latest release because you know it isn't going to break, and it's all these wonderful things that enable you to have all the new features.
But that means we can't just bring something, uh a massive architectural redesign in um and put it straight into Django, straight from the word go, because that's not mature, stable um behavior.
And to be honest, that turned out to be very prescient because channels one looked like it was the perfect solution and it looked great, but it turned out it had scaling issues, and so that required the whole channels to rewrite.
And if we'd have had to do that inside Django Core, that would have been that would have been end of story.
Yeah, well, and I want to mention too, we'll a link.
There is a thing called uh Django enhancement proposals based on um Python has the same things, of which um having official projects is one of them, uh the new async stuff, I'll link to that.
That's that's kind of where these decisions are made, I would say, right?
Or you know, these big changes to Django.
Um so link.
So there's a whole dep on async, and that had to be discussed at length, and then that was approved, and now it's being implemented, and we're we're at stage one now with Django 3.0, where um Django speaks ASCII, and then stage two will be that you can write async devs, and stage three will be the ORM and template layer and these other.
Well, and I think it's worth repeating how how these things are structured, because I I I'm always struck by the fact that uh Django seems mysterious and otherworldly otherworldly to people when in fact it's all out there in the in the public.
And if you're curious or want to be involved in uh Django stuff, there is the Django uh uh Django Core, well not Django Core, what's it called?
Uh not Django users,
Django Developers.
Django Developers Google Group, which we'll link to.
And there's also a separate uh Django Users Google Group, though now there's a a new um discourse forum board which we'll link to, which is an effort to make it a little more beginner-friendly.
But anyways, all this is out in the open.
So the question is who decides?
Everyone and no one is basically
the answer.
If you're active, so if you want to get involved, I'd say subscribe to um Django Development.
It's not very high traffic, you know, a few emails a week.
If you haven't got the capacity to read them, don't read them.
You know, just sort of have a rule that puts them in a folder automatically, and then you can look at the folder once every so often.
Or just go to the Google group once a week and sort of browse through it and have a quick read.
It becomes more relevant as you get in, you know.
It it it the more time you spend hanging around, the more it's like, oh, I read that, you know, okay, it makes sense.
It's yeah.
And and I know that uh Andrew mentioned at DjangoCon that the there is a section on async uh in the new forum, in part because he didn't want the Django developers group to just be async issues.
So I think I think this is great to have just a better UI around discussing these things, but again, it's it's all out there in the open.
There isn't someone behind the curtain deciding.
Um if you have opinions, get involved.
Okay, and and the channels projects, like so if you go to um GitHub, um, the Django organization, there's Daphne, which is the um web server, there's channels, which is the main library, and there's channels Redis, which is the um behind one, as well as that there's ASGI Ref, which is the reference implementation of the ASGI standard, which is the async um uh standard for web servers to talk to applications like WhizGee, but ASGI.
Um those four repos, that's where the most of the discussion happens.
And if you want to watch those repos, Git GitHub will send you notifications, and then you know, you can join in the discussions.
And if you know, if you want to help get involved in channels, I'm really happy to help get you set up, help you know, help talk you through what my understanding and we you know write some tests and
yeah, well, because there are there are um I wish we had better visibility on this.
There are, I know anecdotally of places using channels um for real on you know professional projects.
I just don't know how public that is, but it's um you can definitely use it right now.
And if if you need something right now, you should use it um rather than waiting on Django itself.
Yeah, I mean, and you know, the the the even though it's um you know the c few people that help a little bit, but even though it's just me and I don't have much time, and I certainly haven't had much time this year for various personal reasons, but um it's the the number of open tickets on those three repos combined is quite low.
That there aren't many, you know, it it's not like there are loads of outstanding bugs or whatever.
There are a few and we need to chip them away over time, but it's nothing that you know, a little bit of input from the community, and we wouldn't have those all wrapped up.
So it is they are good quality packages and they do work for you, and you know, you can use them.
You can do async already.
Yeah, well, and that's the interesting thing that uh Andrew's talk at DjangoCon, he alluded to, which is that, you know, three years ago, kind of everyone thought WebSockets and all this stuff would be everywhere now.
And it turns out that the need hasn't quite matched that that isn't the case yet.
Um it's not quite as ubiquitous, you know, everything doesn't have to be real time.
Even though when WebSockets came out and you know HTTP2 and all these things, it's all kind of there now, but waiting, I would say, for use cases beyond a chat app or you know, you know, taxi riding.
Um I think these will come, but it's it's interesting that the demand isn't is more the issue than the technology, generally speaking.
It yeah, I think it is interesting.
I mean, somebody there was an email to Django developers quite recently.
I can't, you know, it doesn't it doesn't matter exactly when, but it was saying, well, why aren't WebSockets in Django core?
And it's like, well, exactly this point is it it it it turns out that they're not the silver bullet people, you know, there was a lot of excitement about it.
It was like, oh, we have to have this, we have to have this.
They're okay, they're great, they work, but there are you know other solutions.
They've got server-side events where you have a slow HTTP connection and you fire updates just down the wire.
So most of most of what people use WebSockets for is like, I just want an update from the server.
Yeah, well, it turns out you can hold an HTTP connection open, yeah, and you can just have the server push more data when it wants.
And you don't need a whole the whole WebSockets, because the trouble with WebSockets is you need client libraries, and then you've got JavaScript and you've got you know loading issues, and you've got, well, what's the quality of the JavaScript client?
And you know, so a lot of issues we get on channels turns out to be well, I'm using a broken WebSockets library.
Right.
Well, since I think we have a couple minutes, maybe can you so make the case for why HTTPX is so exciting?
What does it solve?
Well that's not channels at all.
But it's a lot of things.
No, I know, but it's but it's um related, it's a flavor, it's related ish.
Well, for instance, I don't know.
Let's say you want to um fetch web pages.
You want to, you know, you're writing a scraper.
No one writes a scraper, but let's say you wanted to write a scraper.
You could, it's fun to do.
You want to no, but okay, but if you're using requests, um, which nothing requests are great live, but it's been the cornerstone of Python development for you know many years, but you've got this this same sync versus async problem in that you're using up a whole thread, a whole worker for each request.
Whereas if you can do this using async.io, you can you that same worker can probably get throughput of a hundred times.
Yeah, I mean it's just a massive change of what's the word?
Change of scale.
It's in order to
manage for sure in your perform.
Right.
But if you but so if you wanted to do um if you wanted to make web requests at scale, you're your your massive savings.
Or if you even wanted to do it at small scale, so you you want to get some little Amazon micro thingy bob, you could probably run it using HTTPX on just a single instance, and you'd be able to make all the web requests you ever want to make, versus oh hang on, I need to scale up and eat two of these to get the throughput that I'm looking at.
Yeah, no, it's um so that's I mean that's the primary difference.
It's it's but also it's written on the new um underlying networking layer.
Um I don't know much about that.
So well, no, I don't know all the underneath, but um anecdotally, you know, Peter we'll have to get top of that, you know, we're able to talk more sensibly about this.
But request was built over a whole URL, it wasn't that great, and blah blah blah blah blah.
And so it was a nice U API on top of some kind of not very nice foundations, whereas HTTPX is built on top of the newly URL lib3, and it's all you know 100% type annotated, and it's you know, yeah.
So this is these are the exciting things.
It's it's it's it's A async and B, it's bit built on better foundations.
I would say those are the two take-home points for me.
We'll have to, as I say, we'll have to get Tom on and ask you.
Well, and I and I think one last thing I would say, it's again repeating uh Andrew's talk on the state of async and Django from DjangoCon, where he even said that you know, async is hard to reason about and hard you shouldn't just take it lightly.
I mean he was envisioning that even in an application or website that needs it, it should probably only be 10 to 20% of the uh website.
It's not that something everything needs to switch over to async.
It it's that for certain things it'll have big benefits.
And the way it's being written is you can toggle back and forth within an existing Django project, which is sort of nice.
Yeah, I mean, so yeah, exactly this.
You want to write 90% of your views just like you always have.
And then where where does async gonna help?
It's like if you're fetching out to a third-party service, or if you're um, you know, if you've got to fetch something from the database and get some other data from somewhere else and then combine them, you know, those kind of um cases where you're IO bound and you're not tying up a whole worker for this, but you'll, you know, your bog, your bog standard quickly server response, that could just might as well just be sync.
Right.
Well, and I'm again with 3-1, uh that's what I'm, you know, as a content creator teacher, that's when I'm gonna start banging out a whole bunch of tutorials because with the combination of ASGI and the views, you'll be able to demonstrate this stuff and then you know, ORM and these other cases, but I think that's that's when it really will be real uh for a lot of folks, the the built-in async stuff, I would say.
Yeah, for me that like the exciting case with async views is these kind of pro I've talked about it before, is the but these kind of proxy views.
So say um you've got a uh a REST API and you've got these endpoints, one for books, one for authors, and you want to combine them so you can get a nicely nested um response that contains lots of data for so a mobile client only has to make a single request.
Well, then a proxy endpoint, instead of creating you know a whole different API, you can have a proxy endpoint which makes these requests for you and combines them how the client needs it and then returns those.
That will always be IO bound.
So if you can use async there, for me that's a really exciting use case.
That's what we get excited about, Carlton.
Things like that.
That's what gets us out of bed in the morning.
Well, you know, that's why we brought
it up.
Um all right, everyone.
This is a this is a tech podcast, right?
Well, everyone, thanks for listening.
If you have questions, you can reach us at Chat Django on Twitter.
Uh all the new episodes are on DjangoChat.com website, and we'll see you all next week.
Bye-bye.
All right, take care.
Bye-bye.
Okay, so we thought we were done, but Carlton really wanted to get some extra points in.
Go.
Yeah, no, right.
So channels and it turns out I thought channels and HTTPX were two different topics.
It turns out they're not, because the these proxy endpoints that we were talking about, that's the perfect use case for an async um HTTP client, right?
So you've got an HTTP request comes in.
You want to proxy out to say three separate endpoints, and you want to make, but you want to make those requests to those three separate endpoints in an asynchronous way.
So if you were to just use requests, you'd block the entire worker whilst you were waiting for them to come back.
But if you were using HTTPX, you could fire off all three, they'd all cut, they'd all happen at the same time.
They'd come back together, and you can get your response compiled and sent back to the client nice and easily.
So you could do that already using channels and HTTPX.
And when Django has async defuse, you'll be able to do it in Django directly.
Boom.
Mind blown.
Boom.
That was it.
That was just like, yeah, but we're already there.
You know, these, these, these, we already have the tools in play now for um being able to write these nice async views.
Okay, everyone.
That's our last point we want we wanted to get in.
Um yeah, we really are.