← Back to Show Notes

Transcript: API-First Architecture

Hello, and welcome to another episode of Django Chat, a weekly podcast on the Django Web Framework.

My name is Will Vincent. I'm joined as ever by Carlton Gibson. Hello, Carlton.

Hello, Will.

And this week, we are going to talk about Django REST Framework and specifically architecture,

different approaches to putting it all together. Since this is a question I get all the time,

you probably do as well. And this will only be our second episode on Django REST Framework. So

it's worth more discussion yeah what did we talk about the first one we talked like the basics i

think it was the basics yeah yeah and also that was like so that was about a year ago anyways so

um we could refresh it all changed since then what's happened in a year uh so broadly speaking

so let's just so just to tee it up so how do you structure jenga rest framework and this i mean

because i see teaching beginners there's a big leap in understanding what's the difference how

does HTTP work? So broadly speaking, so I'll talk until I tap out because you're the expert here,

but I would say there's two main ways you can structure Django REST framework. You can basically

have, so you have a front end and a back end, and you can put that all within Django, do a monolith

approach, or you can separate it out into a single page architecture where you have your back end

running normally on Heroku or wherever, and then your front end is somewhere else. But before we

get into it um let's just tee up django versus django rest framework just for people out there

because again how would you describe what's what's the difference between the two if someone comes to

you and says how are they different okay so django is is the web framework so its fundamental role

is that core web problem of turning requests into responses right you can send a web request you get

a response back you ask for an html page you get the html page back and it pops up in your browser

that's django's job and then there's a special and it does that great it's got everything you

need for all aspects and you can do everything that django rest framework offers with just

django you don't have to use django rest framework but if you're going to build what we call an api

and that normally these days it means you're serving json which is javascript object notation

which is for a machine to consume so it's like a mobile app is going to consume data from your

website it's going to it's not going to consume html it's going to consume like a schematic json

document and then turn that into something that it'll present on the screen for you

call those apis and restful apis well that we can talk about exactly what restful is meant to be but

django rest framework makes those kind of endpoints easier so it it handles um rendering to json for

instance setting the right content types um i don't know content negotiation so you might want

you might be able to send out json you might also be able to send out xml you might also be able to

send out html you might also be able to send out i know yaml or who knows what but it it has parsers

which take incoming data that could be in json format or multi-part form post like an html form

or any other format, XML data you might send across to your web server.

It will pass that data.

It does content negotiation about which types of requests you want,

which type of response you want to accept,

and it will render that back for you.

So that's the kind of core bit.

Django doesn't have that out of the box.

Right.

And I think the even baser way to say that is,

because I think sometimes people confuse URLs with endpoints,

is at the end of the day we're dealing with the web,

so it's sort of the same thing.

It's an endpoint if it's serving up JSON or data,

and it's a web page if it's serving up HTML, CSS, everything that you see.

So one of the original things in this idea of rest, being restful,

was that resources, the R was for resources,

resources were meant to be addressable,

and they had a specific URL, which was their address,

and you were able to say this address,

And then you do use the HTML verbs to retrieve the representation of the object, post to create a new one, put to update it, delete to get rid of it.

So the idea would rest, the core ideas would rest, it's an addressable resource that you can use these verbs on, more or less.

Yeah, and I think part of it is that if you're dealing with a normal website, you don't have to know about HTTP at all, really, or the verbs.

But it is a little confusing because the verbs are in the header.

So if you go to look at a page, an API endpoint, you can't necessarily just see what the verbs are on it.

I mean, you can if you use Postman or if you use Django REST framework comes with a web visualization tool.

but sometimes it's a little bit harder to see what all is happening there.

Yeah, and in the standard browser, you only really use get requests

and then post requests when you submit a form or something like that.

So they only use two of the verbs,

and it's only in a kind of API environment

that you usually use put or delete as well.

And then there's head, which just gets the sort of metadata

for the endpoint and other things, options and stuff.

So if you have, let's say, a to-do list in Django

So when you want to turn it into an API, broadly speaking, you install Django REST framework,

you need to create a serializer, which will transform it into JSON, and you need to point

to the URL you want it at.

That's basically it in terms of...

Yeah, so serializer is like a form, right?

It validates incoming data and it takes your whatever you want to send back and it serializes

it, deserializes the incoming data, turns it into a Python object representation so

that Python can do stuff with it.

And then on the way out, it will serialize it back to whichever format your renderer uses, so JSON normally.

Right, probably JSON these days, but it doesn't have to be.

Yeah, I mean, it doesn't have to be, but JSON's the sort of default.

And then you have a view, so REST Framework has some great views.

So instead of the base generic view class that Django gives you, which is just view and then detail view and list view, it has API view.

And then it'll have...

There's a whole list, API list view, generic.

A list API view, a retrieve API view, a delete API view.

api viewer create update retrieve api api view all these generic classes class-based views which

they're really fantastic i the other few weeks ago i was um cracking open a new project that

you know really excited blank slate cracked open rest framework generics which is the the module

where all of these um generic api views live and i was just like wow i love this it's just so nice

it's so it's got everything you want it it makes it makes crafting apis just just a delight and so

i was i've just had a little geek moment yeah well and um we're going to talk a little bit in

the abstract about code if you want to see real examples i have a whole book on it jingo for apis

and also if you're struggling with the drf tutorial i also will link to i have a beginner's

guide to the tutorial where i hold your hand and you build the exact same amount of code but

it's very beginner friendly it doesn't assume any sort of knowledge so those are two resources if

you're hearing what we're saying but kind of want to do it yourself um so the structure though let's

talk about the structure i mean do you agree with this saying broadly there's sort of two options

you can put the the back end the front end within django itself you basically you put it in the

the static files we can talk about that or this spa single page app where they live on different

domains you know we will dive into those but i mean i think the standard thing if someone's

talking about a single page app or they're talking about apis and front ends they're

talking about something that's living you know the back end is living at app.example.com

and it's serving up stuff to or excuse me it's living at api.example.com and it's serving stuff

up to a dedicated front end which is at you know app.example.com and then you you know you deal

with chorus headers,

but you're doing

cross-origin requests

back and forth.

Yeah, I mean,

that's common.

I think that's most common.

What would I say?

Yeah, I mean,

there seems to be

this massive,

I think because

JavaScript,

or front-end development,

has become so specialized

and so difficult

that,

there's this tendency to think, oh, the backend is just an API.

Now, there's another way of looking at it.

It doesn't matter whether you serve it to different domains or not.

You can serve it an API, an app, or whatever.

You can have your single page served at a single URL from your Django application

and the API served from the other URLs on that same.

It doesn't have to be different domains.

It's just that's a pattern that some people, that's popular.

But the way I like to think of it is, are you generating doing single-page apps where you're literally, it's, you know, you basically load a single HTML document, which is almost empty, and it just loads in the JavaScript, which then builds the application by fetching from the API.

So that's a single-page application model where, you know, and you never leave that one URL.

I mean, it might get updated, but you never refresh the page.

Right, and that's the tricky thing because with, like, React router and stuff, it, you know, it makes it look like the URL changes, but it actually doesn't.

Well, the URL changes, but you never refresh the page.

That's the point.

You never do a whole page load, right?

Because they tie into the browser history,

so you can click the back button, and that works.

Right, maybe that's a separate discussion.

You can bookmark those URLs and go back to them.

You know, if it's built well.

Yeah, it's sometimes tricky to do that.

And then contrary to the, so the distinction I make

isn't so much are you serving it on different domains

and subdomains and that.

between are you doing that kind of single-page application

or are you serving HTML pages that are server-rendered by Django, say,

and then sprinkling JavaScript on top of that, which then enhances.

And a lot of times that JavaScript will, you know,

so say you've got a form, and that form is rendered as a static HTML form,

and it's fully functional as a static HTML form.

And if you click Submit, it would do a page refresh.

But then you load some JavaScript on top of that,

which takes over that submit event

and will submit it to the API directly

without doing a page refresh.

So if you look at, I don't know,

I won't pick a particular example

because no doubt it would be false,

but a lot of sites that I think have done very well,

they will be functional

even if the JavaScript doesn't look.

Yeah, it's a best practice

because JavaScript doesn't always load.

So for various reasons.

And it's a bit more work to do it that way.

Yeah, because you're building

for both use cases basically.

But you can also be, for me, you can get remarkably far building a static HTML site and sprinkling JavaScript on it much further as a single developer, as a small team, than needing the full expertise of the heavy JavaScript frame.

And that's how it used to be when jQuery ruled the land.

It was, you know, you would sprinkle in the JavaScript and jQuery was like the library that you would use to do that.

But it was very much, you sprinkle it in as opposed to, nope, we're going to toss it all over to dedicated front-end land.

And it was, yeah.

But it was a nice evolution as well because there was, what was it, this thing called Backbone that was built on top of JavaScript.

And, I'm sorry, jQuery.

It was built on top of jQuery.

And it was great because it enabled you to maintain state of these views.

You know, they were complicated.

Yeah, state becomes the problem.

And it enabled you to sort of maintain it.

And then there was this nice slippery slope.

It just got bigger and bigger and bigger.

then you know react came along with a virtual dom and all of that and kind of changed the world

because that was a much more performant um yes once once you're however large the initial load

gets in there then it's good but there is a little bit of a bit of a load time

but so the so that's how i draw it rather than saying it's a monolith where it's deployed as

a single application versus two applications to different subdomains for me the distinction is

Are you doing SPA or are you doing largely server-side rendered

or at least the initial renderer server-side

with then JavaScript layered on top of that?

Yeah, and if you're doing the latter,

which is more the traditional Django approach,

so you have your static files and your static directory,

you use something probably white noise in production,

and, yeah, there you go.

I mean, you...

I'm trying to think.

There's one other step you need with that, I think,

but maybe I forget off the top of my head.

Maybe you don't.

well are you you um you can cache it right so you can you want to cache your static assets that

maybe gets into the performance aspect we could talk about um which actually i wanted to ask you

that's a slight tangent but since you maintain django compressor um well i've helped i don't

mean you help i've helped i've helped out in the past okay you're in i still use you're involved

with this which i believe broadly speaking third-party package it will minify your front

end and do some stuff on the images right that's basically yeah well no there's so i mean it won't

optimize your images specific to its specific task is for css and javascript so let's assume that you

so let's assume you're loading your you don't have to do it this way anymore but it still

works and it's great you can but let's say you're loading all your um css in in a single block at

the top and you might have three or four css files and it will what it will do is combine those into

a single css file and if you're using pre-processors like sass or post css or anything

like that you can run your css files through the pre-processor then it will combine them then it

will minify them and you then it will stick them in a known location so that next time it doesn't

have to do all of that all of those things and it will do the same for your javascript and you can

even load you can load your javascript at the bottom which you always used to do you used to

put it right at the bottom but you put it all together but you want it in a single file on

http1 it's not so simple on http2 but separate you know we're all still ahead we're still way

ahead of the curve just do the old stuff for now until you know the new stuff's proven yeah exactly

well so my question is i mean so but you can you can now all the all the modern browsers allow you

to use this defer attribute where you can um you can stick the javascript at the top you can start

it or async loading it is rather than defer you you can stick it at the top and it will load

parallel to your page rather than blocking it which it used to do which is why you put it at

the bottom yes because your paid loads from top to bottom um so i i think the biggest performance

thing around all this is caching and you know people not using a cdn so i guess my question

to you was if you are are using a cdn so cloudflare or something in front um does it also make sense

to use django compressor or is that a little bit of overkill yeah yeah so um the the way i run

django compressor this is this was going to be a drff well it's related because we're talking

about front end okay front end stuff we'll cut back there in a minute so the way i use compressor

is it's got a compress offline um setting where you um as part of your build step as part of your

deployment step you run the compress management command and it generates all the um compressed

files and then you can put those wherever wherever you want and there's a manifest which it will

quickly look up what they've what the finished files were called and insert the right link

element into the html as it's served but what's good is you get you get a single a conjoined

compressed minimized css file and you know if you're using other tools like purge css which

eliminates your unneeded css then you you know you get a nice small package and your page loads

loads quickly. Yeah. Well, and so to bring it back to our DRF discussion, part of, I think part of

why the, you know, the single page app structure is popular is also in part because now you do

have, it's rare to have truly full stack people, full stack teams. You have such a divide. It's

sort of nice to have separate code bases for backend and front end. Yet if you're solo or

small developer, you know, two or three, you know, maybe that's overkill, right? I mean, if it's you

or me building an API driven site, you know, I would probably start with serving it within Django.

And then if I needed to, and I really needed to, I would go SPA, even though just because it's a

little bit simpler, you know, hard to say, but the cultural thing that I think is an interesting take

on why would you choose one over the other? And, you know, you don't want JavaScript engineers

touching your backend and probably vice versa in a large setting.

Yeah. And so this is, yeah, so this is, this is another thing is JavaScript engineers don't want

and you touching the front end stuff.

want to build their app and they want to build it how dare they how dare they yeah well no that's

totally legit what i like about django compressor is it may i'm i'm i'm you know i'm i'm happy to go

all the way to you know photoshop if i have to but i'm a back-end fella when it comes right down to

it so what i like about say using django compressor is it enables me to do get to a point where if i

have to hand over hand off to somebody who's a front-end professional you know a solid front-end

professional what i hand them isn't embarrassing you know it's like you know this is fine i'm you

know i'm just i'm i'm able to use you know webpack or post css or whatever it's all separate whatever

your whatever your tool they like i'm able to do that i'm saying oh yeah here's my build steps

you know i just run it via this compressor tool which you know runs you do have but yeah you can

you are doing yeah yeah and i've got all those things and it's like yeah no it's it's fine and

they're like okay yeah well and they can go off and build their thing without me feeling that i've

You know, I've got to hide my face.

You know, I find the older I get,

I truly less, I care about how there's opinion of me,

but it is true.

It's nice to have some professional respect

for someone else.

I was going to say, if you're curious

if a site is truly an SPA or not,

if you go look at the, if you view source,

if you see just a teeny bit of HTML

and then just some long glom of JavaScript,

that's an SPA.

If you actually see HTML and elements being laid out,

that's probably more of this, you know,

javascript sprinkled in but sometimes you know if you go and look at view source because sometimes

people say oh can i i want that they want to build such and such a site or i'm just curious

if it's if you can't make any sense of it it's an spa it's just a whole glob of hopefully encrypted

but compressed javascript um or not not encrypted what do you do you um well you minimize yeah

minimize but actually for a while you were also you could do the thing where you

was you could kind of obfuscate it but you could also um it wasn't people ship source maps source

maps is the thing so when you when it's totally compressed all the variables are renamed so like

you know i've got i've got a nice meaningful variable name and it gets renamed to yeah yeah

exactly exactly yeah if you look at like facebook or google it's it doesn't mean anything because

it's all been processed but um the web inspectors they're all able to interpret source maps so if

you if you i think base camp do this i think you know they some um i think uh david had my handsome

was calling someone out for their bad i don't know single page application or something and

And someone was saying, well, but what about your JavaScript, which is all minimized and no one can make head or tail to it of?

And he was like, yeah, good point.

And they started shipping their source maps.

So you can, you know, view source on that.

And you can actually then get into the JavaScript and it will be pretty printed with the original source code rather than.

Oh, that's nice.

I don't know if I've used that.

I didn't realize browsers do that now.

Yeah.

Well, that's a great analogy of, I mean, this happens to me all the time that I'm, you know, opinionating on something or other.

someone and then that and i sort of either i think oh i should do that or they you know ask me like

oh are you doing that here and i'm like well actually i'm not but now that you mention it

i should um i do want to mention um and hat tip to hang on hang on hang on you asked the question

i didn't get to answer it was this like so i so i think that you know you are you've asked something

like um what do i think people should do and i think yeah okay i understand this whole drive

towards the single page application but there are you know four billion people on the planet who

have devices not capable of running a full react app on networks that aren't able to download them

quickly and for me server-side rendering is still the way forward and that should be your first

option and progressive enhancement on top of that which is harder to get right than it is to build a

single page app that's that's the goal um that's what you should be aiming for and it's just better

and richer and nicer and more in tune with everything you want and when you and your app

will display on an apple watch and it will display on a samsung smart television and it will display

everywhere whereas your your rich javascript application you'll suddenly find that over the

rubbish mobile network the javascript page didn't load and they get a blank page

Yes. No, it's very true. Two things I wanted to add, or not even add, just digress from what you said. So the first is, there is another option for structuring things, which I have to give credit to Jeff Triplett for mentioning this, which is if you're using Docker, which I often do, you can run it all within Docker.

So in your Docker Compose file, you can have a separate image for the web and then for the front end and run it all in one container.

So you can basically do an SPA within Docker.

I was looking for a code example or some guides on this, and I don't know of them.

If anyone does, let us know.

We'll add them to the show notes.

But since Docker is just a box around everything, you can also do it within Docker.

But I don't know if that's necessarily that much easier because then you're in Docker land.

But I want to mention that. But the other thing is, when we were talking about Django REST Framework initially, part of why what trips people up, I think, is authentication is a lot more complicated in an API world.

Basically, because traditional web app uses session authentication, we have a cookie, so user logs in, session object is created, and the ID is sent back to the user and stored as a cookie.

And then that's passed back and forth on every request.

So that basically one ID can be used to unlock, you know, 20, 40 attributes that are stored

in the server.

So the server is the source of truth.

The problem with that, of course, is if you have multiple front ends, so you have a web

app and a mobile app or two mobile apps at the same time, sessions kind of breaks down.

So then you go to tokens or JWTs and, you know, this all is confusing.

I have a whole DjangoCon talk on it, but I think that's another thing when people switch

over to drf land that they go oh my god because the official docs list four built-in ways to do

it um yeah and then there's third-party options and then there's third-party options and there's

this that and the other and yeah and actually i've um i'd love to get um yeah the the author of some

of the leading jwt package um dave i actually just invited him i don't know if he listens to

the podcast but dave come on let's talk about it it would be nice though part of it though is the

But the ecosystem of JWTs is not core Django or core DRF.

So while they work well longer term, that would be nice.

They should be rolled into Django, just as two-factor auth should be rolled into Django itself at some point.

Yeah, I mean, what can I say?

That's a powerful word.

But, you know, so I guess I just wanted to mention that in the context of what…

Okay, so here's an interesting thing with DRF.

why is it that there aren't more built-in authentication options into drf itself like

into the the core drf should ask tom when he was on well no the the answer is because it's a question

of maintenance so um there's so much capacity to maintain django rest framework and keep it going

and keep it you know largely bug free i mean you know there's 100 tickets or whatever but there's

You know, it's got a regular update cadence and it's, you know, evolves over time and it's, you know, serious bugs are few and far between now.

Most of the remaining tickets there are, you know, there's a bit of vagueness about the contract in, you know, if you get in this really specific use case, it's not quite clear how it's going to behave with nulls and, you know, full sits.

But broadly speaking, it's...

But yeah, it's a mature package now.

But what there isn't capacity to do is take every possible extension and bundle it inside Django REST Framework.

And as soon as that would start to happen, Django REST Framework would become unmaintainable.

And so it's much better that there's a third-party package for iWorth, and there's a third-party package for JWT,

And there's a third-party package for, you know, if you need to map your serializer keys to camel case, because that's what your AngularJS client requires, then, you know, there's much better, there's renderers outside of Jack and Garry's framework itself that you can use.

Yeah, no, I mean, it's, it's.

but you know it's pros and cons i mean it's better in that it's not unmaintainable but you also

are shifting the burden of maintenance to third-party apps i mean for example jwts our

friend jose padilla had the dominant one for quite a while and then his life got complicated

and then there's a new one simple jwts and this is pretty core stuff um that yes uh you know and

actually okay right but here's the thing if it is cool then it'll end up being maintained

i would say because there's a demand so there's companies using it so there's companies will

stump up developer time to make sure that the package works and we should ask if you just

asked jose a little bit about why he sort of i mean you know i know he got busy and he wasn't

monetizing it directly but he had you know the dominant jwt package for quite a while and thank

goodness there's a simple jwt one but you know there's a number of issues on jose's one that

um cropped up i mean this so that so that's attention yeah was that no but we always end

up talking about open source but it's ultimately you know lots of people opening tickets and not

so many people doing the work to fix them yeah well we're gonna at jingo con europe we're gonna

i'm gonna be at the sprints we're gonna you know get more people on board and maybe improve the

docs a little bit around that to to make that easier i i did want to add too um so i recently

well two things a lot a lot of two things for me today we haven't recorded in a while so that's

maybe that's why so one is you've got a backlog yeah i i so i i soft launched um mylearnjango.com

site um so there's some stuff on there and i'm slowly porting things over and we'll do a whole

episode on building that and things learned but i put a blog post out um actually again with jeff

triplett um on 10 most used django packages based on just pi pi for the last 30 days and um we'll

link to that but it was interesting to me and first in that so it goes django obviously django

rest framework um django cores headers which our friend adam johnson maintains because you

you know if you're using an spa you have to set the course headers yeah you have set course headers

so there you are done django filter which you are involved with as well as number four yeah

django redis is number five which i was like that's pretty high um django extensions which

makes sense pi test django django storages debug toolbar and then actually i wanted to ask you

jango app conf is was number 10 yeah yeah so that's used by jango compressor but who else is

using it that's it that's so that's quite high i mean i i i haven't used it personally i mean i

looked at it i was like oh that makes sense but what it does but it enables you to do sort of per

application so if you write a third-party reusable app and you want settings for your reusable app

jango app conf is a nice little wrapper around that so that's you somebody big must be using

that though because it's used by django compressor i don't know who else yeah maybe it's i mean maybe

it's wrapped into something it must be it just seems way too high on the face of it um no but

it's like one of those um infrastructure ones yeah well it's an infrastructure package it's used

by x package and y package and z package and they sum up to a lot of downloads hmm yeah to unravel

that uh since i'm in a publishing mood i also published my super opinionated essential third

party packages which was 18 it was 17 and then people of course the floodgates opened with

advice from people and i think i added one or two but um my personal highly biased takes on things

i build everything with that um regardless of application so anyways there's some plugs in

it's really useful i remember a post it must when i was starting out with jango it must have been on

like i don't know jacob cabman's mosses blog or something like that like some of the early people

in jango and i was like you know you're getting into jango and there was this post about you know

these five top packages and it's oh i didn't know that look um but this was a long time ago but you

know like i think jango debug toolbar was on there or something like that and i'm still using that

today so yeah well and on the on the django forum um there's a whole discussion on top five third

party packages and you know everyone of course is like well here's five but then here's another 10

so that kind of brought about because really five's not enough um so that brought about

decision for you gotta make your choose right yeah and i mean you allow five people at your

party who's it gonna be at the same time i mean i still have a awesome django repo with

where you know it's sort of like layers of curation where there's way more packages but

all ones that I think are, you know, seem valid to use in my opinion. Um, but maybe I don't use

all of them myself. So there's sort of like top five essential. And then, um, yeah, it's a good

question. And I think it's helpful. I always like to hear from people I respect in the Django

community, what they're mentioning. I mean, you know, even, um, just, just last week, uh,

you mentioned Django Sesame package by, uh, Emmerich on magic URL opening that I didn't

know about that's been around for forever and is perfect for something i need to do so there's

always more to always more to learn yeah so you just mentioned django redis there and um yes about

five minutes before that you mentioned the importance of caching and of course that's

where django redis comes in because everyone's using it for their um django cache backend right

yeah i know but i think it's a you know caching i mean how much time do we have we're going way

over that's 30 we got a couple minutes you know you so there's two types i i think of it and you

can dispel this but there's when i think of caching so one is just uh you know use it use a cdn so you

throw cloudflare in front to serve up your site if it's basically a static site so my learnjango.com

site is essentially a static site so i have heroic i mean i have jango hosted on heroku and then i

port cloudflare in front of that and it basically loads you know instantaneously the the reddest

stuff is when you're doing caching you know on your back end on your database basically um which

is a more real world use case yeah it'd be interesting i mean there is a whole discussion

of you know redis versus memcache i said i think we've talked about yeah we talked about the caching

one where basically redis is a little bit simpler these days and seems to have the mind share though

memcache works fine as well but redis i haven't seen a performance um i saw one but it's it seemed

but they've got to be basically the same no yeah yeah well it's great to it's great though to see

that Django Redis was that high because I always kind of wonder and again Django doesn't really

track anything so what you know what's the mix out there in the wild like how much is

students or beginners just tossing stuff up how much is big production companies somewhere in

the middle um it was I was not I was glad to see you know PyTest be up there Django Redis be up

there because i mean those make sense in large applications but i don't know if i'm you know

beginner intermediate people wouldn't use those um so i don't know be nice to know what the full

ecosystem looks like yeah i've what the thing i see these numbers come up and one thing that i

always want to know is how much of it is ci you know yeah well that's true pi pi because as soon

as you've got as soon as you've got people downloading off pi pi for ci it's like that

boost the numbers right right and i mean if if someone was inclined you can totally game pi pi

and there's actually um jeff jeff was going to talk to as earnest um at python because there's

some sort of another level of steps to see like the real downloads versus just the public ones or

there's some other filter you can add to get a little more accurate but yeah hard to say i mean

who knows but ballpark probably accurate so all right what else i think that's that's it hopefully

that helps people we're very open to questions i think there's probably a lot more episodes we can

do on django and apis and drf um so do let us know as ever on at chat django on twitter you

could also nobody's done this actually but if you want to send a voicemail and we could put on air

django chat podcast at gmail.com you can send us a voice memo and um if it's a good question we'll

play it and respond to it anything else carlton no no no i just i did i wasn't the episode i

thought it was going to be we've talked about front-end apps and single pages and all yeah

well we had a couple short that's okay a couple short ones so i feel like i need to you know

pad this out a little bit no that's fine good all right join us next time folks all right bye-bye

everyone