pyupgrade and dj-stripe - Building SaaS with Python and Django #91

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi welcome to building sas with python and django my name is matt lehman and on this stream we build django apps on this particular stream i'm going to be working with pi upgrade and working on dj stripe to integrate stripe into my django app so if that sounds interesting to you i hope you'll stick around i do want to share a bunch of information before we get started so if you like the content that i'm producing uh please like comment subscribe whatever on youtube or twitch wherever you're at that would be really appreciated there's tons of ways to get in touch with me they're kind of listed above and around and you can find them if you want to support me financially that would be awesome i'm on patreon.com as envylaymen and i want to thank my patrons of rupert abdulaziz patrick eric and phillip um thank you so much for your your help and um the ways that you support me so let's get into it um i have i have two overarching goals tonight one is to add a tool that i actually use today at work um which is an amazing tool that i encountered and i think i had encountered it briefly in the python community but i had never really put a lot of thought into it but it was really cool it was a good experience and i'd like to try and put it into my app and it the tool is called pi upgrade and the idea behind it is to change your code to upgrade to newer versions of python style so for example if you had old python 2 code and you were using format strings and you wanted to switch to f strings which were awesome you could do that and so pi upgrade has a bunch of these kind of common changes to help keep your styling up to date and that's the first thing that i want to add after that we will turn our attention to dj stripe so i have a my sas product that we're building is a homeschool app and it is going to be a subscription-based service but right now it has all the functionality but none of the subscription part so people can sign up but i'm not actually because i'm in this window of time where you can sign up for a free account i'm actually checking anybody against any of that right right now but i do would like to make it a paid service and so i need to integrate some kind of payment gateway so i'm going to use stripe i think and we're going to go through that together so that's what we're go what's going on you're free to ask me anything about python django or web development if you're here on the stream live if you're coming at youtube um you can check me out i'm i stream on wednesdays at 9 00 pm eastern time in the united states and uh yeah and that's where this content is coming to you from all right let's get into it so the first thing i want to do is get to pi upgrade as i mentioned so let's look at that project and it's by anthony sotilli who's who's an awesome uh developer who's really involved in the python ecosystem he does pre-commit he works on pie tests and all these other tools so anthony's a sharp guy and he's made his life easier and then made our lives easier by making all these tools that help out so pi upgrade as i mentioned is a tool that will like scan your code and look for things that it can't upgrade so what i want to do is add in a pre-commit hook so i am using pre-commit pre-commit is a tool that will as it sounds um check some stuff as um before any commits are made uh to a repository and so i'm gonna take his hook that he's got here is that the latest one or is that an old example it's a good question looks like the latest so he must he must have i bet he's got code that even keeps that up to date that's the kind of guy that he is um so what we're gonna do is come over to the code which is not over there i'm sorry i'm a little a little disheveled starting the stream today but here's my pre-commit configuration file and i'm going to copy in exactly what he had on this example and i'm going to leave it as the first thing because it's going to be modifying code and it just feels like right to have it kind of first in sequence and then all these other ones because this one is modifying stuff and some of these other ones are are checking so you don't want to like check your code and then modify and then like then the pre-commit hooks might get messed up so i'm going to put it in that order and leave it there and leave it at version 210 like he's got the other thing we're going to do that maybe he documents on his site let's find out maybe not he has some some flags that go into this tool and one of them it basically specifies which version of python you want to target and so my application is using um what is it using that's a good question i think it's using three nine so um we want to set a certain flag so that it will target three nine features so as python is evolving and making these nice refinements he's got different flags that target different versions so you can get more changes like for instance there's a version three flag but then there's also a version three six flag and you know one of the big things that happened in that time frame between just version three's release and version three six is format strings came out so if if you don't specify version 36 as your target it can't apply those fixes because that feature might not be there so we want to make some modifications uh in a couple of places actually before we add it to pre-commit let's also make sure that i have this as a just a tool that i can generally run and access so i'm going to add it to my requirements dev file and i'm going to include it alphabetically and it's called pi upgrade so i guess that would put it down here and i'm going to say 2 1 0 seem to be the version that he had listed so let's do that and then let's install that package so we're going through our package list here from the requirements files that i specified and eventually it's going to get to pi upgrade there it is and it says okay i need that and there's some other things that i hadn't updated in my local virtual environment so that's what you're seeing there and once it's done we'll have pi upgrade available it's taking its time there's a lot of packages okay so i'm going to actually deactivate my virtual environment and then reactivate it that's a quirk that i've had from z shell like it if i don't do that then the executable for some reason is not visible i can probably resource my shell and it would be fine excuse me but i don't want to go that route so now pi upgrade should be available by upgrade if i can type it if we look at the help we can see some of the arguments here so we've got um pi three pi three six pi three seven plus i thought he had more on his um on this over here pi three whoops that's a wrong window pi three eight there is a pi three eight maybe he hasn't released it yet is there pi three nine there's a pi three nine maybe he hasn't documented that um curious let's go actually go to pi p i make sure that i have the right version because i might have installed the wrong one in fact i think i did now that i it's i think it's 2.10 i think i selected two one yeah that's my problem okay oops wrong package so i i set 2.1 by accident so we're going to come back in here and we're going to go back to that requirements file and fix it up to be 2.10 that was tricky all right so let's try the same load command apologies for the delay there that's annoying to sit through this again but it doesn't take too long so i i think pi upgrade works with an abstract syntax tree um but i don't officially know that so i thought one of the packages was a token tokenize or something like that i'm not sure if anthony might actually be the author of that one for all i know um and but the nice part is is like it it really from what i saw today and i i use this at work today four hundred thousand lines of code and ran it on that and it made very what i could assess safe looking changes to to my system so um it seems like a really solid tool all right let's try it again pi upgrade and this time i don't need to source it again because i've got i should have oh i'm in a different shell all right well and deactivate and then source okay pi upgrade all right there we go he's even got 310 plus in there which is interesting because 310 to my knowledge is not out yet let's try it though so what i want to do is run i'm going to run it run with the pre-commit and i really installed this here just so you could see all the flag options i probably didn't really need it because i'm mostly going to use it with pre-commit so i can say pre-commit run and then i can give it the the name of the plugin that i want to run so its name its id is pi upgrade so we can say pi upgrade then we can use the dash a flag to give it all files so that's going to run through and check out every file and it failed because it rewrote this thing so what did i do here right so it looks like my code is actually pretty up to date which is nice so there's not a lot to change here my diff at work was much much bigger than this and what it's doing in this scenario is you can see it's it's replacing the set call with a set literal syntax so it's wrapping it in curly braces to do that and that seems to be the whole change which is okay that's nice so there's actually not too much to do but the nice part about this is now if i make let's say i used a format string or something like that something an older style so i use the a string with a dot format call and then my pre-commit plug-in is going to run and it detects that it's hey that's a format string this could be an f string it will reformat that format for me which is really nice so let's commit this so now that's running now you can see it passed and then we'll say add pi upgrade as a pre-commit hook okay that changes down now that was the the easy one for the night kind of a warm up to to get us going the next one is going to be much broader uh in fact i don't actually know where this will end i don't know how far we'll get tonight it might be as much as getting this package installed and then configuring it and then talking about it i i really don't know um excuse me so what what am i after i was thinking about payment gateways how i how can i pay for this or how can people pay me sorry for the service that i'm trying to build and there are a lot of vendors out there there's um you know off top my head there's braintree is a common one i think it's owned by paypal at this point there is stripe there is one called paddle and these these are there are many and they all have their strengths and weaknesses stripe at this point is kind of the 800 pound gorilla in the payment gateway space so if you're building a software as a service application stripe is going to be a really common answer the reason is stripe is pretty awesome they they do a ton of stuff and they do it well and because they're so big it means that there are more people that use it and because there are more people that use it it means that there's more likely more ecosystem support for it in fact there is such support and there is a django package called dj stripe so this is the tool that i'm interested in adding to my project because as i was considering different payment vendors i was really looking at between two i was looking between stripe because they're so big and this other one called paddle and i'll give a shout out to paddle because it's pretty cool i'm i think i'm opting not to go with it but it doesn't mean it's bad uh it's a different it was really a choice about i'm i'm trying to minimize some of my technical changes and some of the risk areas that i'm going in so i'm i'm going with technologies that i already have experience with but pal paddle is pretty cool and what i can from what i can tell about paddle if you choose to use them is that they seem to handle a lot more of the tax stuff they they're kind of a more complete solution than what they'll they'll handle for you and you know the trade-off with that is that they take a higher commission a higher cut of every uh charge that's made and so that's kind of where it where it lands like if you know what what do you want to get out of it so um i'm opting not to go with paddle and instead going with with stripe and part of that is because i know that this particular package dj stripe exists and what all right let's talk about what is dj stripe then dj stripe is an integration with django and stripe as you can see django plus stripe made easy that's a good good simple tagline but what i find interesting about this is dj stripe seems to replicate a lot of stripes data to your local database and then it will try to keep that data in synchronization um using the the web hook system so um stripe has the ability stripe as your payment gateway what they're they're what they're really all about i guess i have not not even explained that so if you're if you're brand new to payment stuff stripe as a vendor will be the interface that a customer can use to actually make charges with their credit card and that's important because if you were to try to do that on your own being compliant with the laws that are required um is actually really really hard it's a really complicated process and so if you can avoid having to do that yourself that's really great which is why these payment payment gateways is what they're called that's why they exist so stripe is is really good about doing all that and so the way that you interact with stripe is is through a couple different channels you either use uh some javascript that they provide there are python apis that you can use there's support in all sorts of different kinds of languages and um they will allow you to send information so you can make requests make new objects um and and over their rest apis and all that kind of stuff they can also call back to you using web hooks so in a stripe dashboard you can configure your account and say i want you to send all of the information from any of my transactions on my account to this particular url and so that information can be received by your website and then you can process it however you want the nice part about dj stripe is that includes some of the webhook stuff by default and will do a lot of that work on its own so they have created a lot of the stripe models in django so that you can synchronize your data with stripe in your local django database and and i think that's really really nice because it means that when i need to interact with a customer subscription for example i can do that through a django model in my code i don't have to use their api directly and get this object like thing and then mess with that no no all that is handled for me by dj stripe and and i can use the orm and get all the benefits out of that so that is a large part of why i'm planning to use dj stripe from my project is because a ton of this stuff is configured by them in fact as you can see they have support from strike the company themselves so this is not a project to my knowledge it's actually maintained by any stripe employees but stripe sees enough value in this particular project that they're supporting them at a financial level which is pretty awesome and i guess a kind of a it's a signal that this code will be get some help to be maintained which is great okay so that's my pitch for why i'm using dj stripe and now it comes down to use like actually adding it and going through and configuring it and then um after that that's when it gets a little murky for me is that this is my first experience using uh dj stripe i've used stripe in the past but not uh in a django app in this way it's been more at the direct api layer using their their python package so this is slightly different and i have to think about the the modeling for this so we're going to explore this together we're going to then probably plan out what is it that i'm actually trying to accomplish i don't know how much of this will just be like reading documentation and stuff so we'll see how much there is to do let's get into it so we've got our introduction and this is all this is telling you all the features that are there that's all well and good i think we're more interested in getting right to the installation bit of this so the first thing we need to do is is install the dj stripe package and i want to see what version they're on because i like to pin my versions so dj stripe is on 2.4.3 so that's what we need to go get so we're going to go to the requirements include file and we're going to go to this section right here and say i don't i don't how would i sort this with it alphabetically like i don't there's a dash come alphabetically before or after a letter i don't know i'm going to put it after so we're going to say dj stripe and then we're going to say 2 4 3 oops not 2. that'd be the second package version mistake in a day let's not do that so we've got 243 listed in the requirements file and now we can do pip compile and build a new version of our requirements file what pip compile is doing if you haven't seen it used before is it's actually building up the full set of packages that are needed and it's pinning down all of those versions and what it's going to write to the requirements file is every package that's needed it's called the transitive closure if you're looking for a fancy fancy name it's just a full dependency graph and it spits out all that information here but it's also put it into the actual requirements file so you can see dj stripe is added to this and then you can see the areas the things that it like is updating some comments um apparently it depends on json field so that's going to be a new requirement and it depends on a version of the stripey api which is not surprising but this tells me because i'm using pip compile that i did not install stripe myself it's saying hey you actually came from dj stripe so that's that's the benefit of using pip compile so now we will reinstall all the packages and it's going to go get dj stripe and install it so that we can start working with it almost done all right cool so we can return back to the documentation i think that was the in that was our version of the install step so there there says pip install this and that's fine if you're experimenting but my app is is uh more locked down than that and is using more tools so that's why there's more involved um the second piece we need to do is add dj stripe to the list of installed applications so we can go do that next and that's going to be in my settings file so we'll come down to installed apps and then i'm listing the way i normally list this is let the django apps be first and then all of the third-party apps and then all of my first party apps in my apple actual application um and then so we can put dj stripe uh right in this list of third-party stuff and i think that's that bit finally we need to actually include this part down here that this is the the set of urls that uh will be used so that um you can actually configure a web hook so dj stripe will be listening on this web hook url and then we'll go into the stripe dashboard i don't actually know that i'm going to get into stripe itself because it's related to money and i don't know there's not that much in there that you all need to see there's not like anything super important to hide in there but i don't want to slip up and have to rotate keys and stuff so i don't think we actually need to get into that level we can kind of just stay in the camp out in the code and then you can go create a stripe account for yourself if you want kind of frog in my throat tonight for some reason okay next we need to go to the project urls that's where this uh stuff was supposed to go and i'm going to just steal this line it's well formatted it's exactly what i need so let's put it in here um where should it go i guess i'm kind of looks like i'm putting in this scenario i'm putting the third party stuff at the bottom don't think it really matters but i'll continue that as well and i'll sort it to put it like that okay so now we've got dj stripe urls included we have the package installed um let's try running running the tests and see i don't actually know if if the system will blow up if you don't have the right settings maybe it will um yeah look that's looking like that case let's see if i can kill that yep so it needs some settings apparently before it's going to be happy i'm surprised it's complaining about the foreign key to field setting that's interesting i don't know what that's all about um yeah hey codellite welcome back thank you for joining tonight um gonna figure out some settings and then get going with some stuff uh so this is where like this is this is fresh territory for me all um i don't actually know exactly what's next so we're going to configure stuff and fill in the blanks and see how it goes and figure out what i need to do so uh there's some additional sinking there's some migration that maybe it's missing some migration i don't really know why it's failing so far i'm gonna just put in these next four settings and see if that will make it happy um i hope so i hope this is not that i'm not missing anything else so this is kind of a first run experience for someone who has never used this package before so let's come up and find where this will go i'm going to put this i'm going to put the settings for it here called dj stripe and what do we need we need the stripe live secret key and we'll say is equal to an empty string for the moment and [Music] the test key and if you've never i'll talk about these different keys in a minute because i do know a bit about this stuff that that i can speak to um i don't know about these settings necessarily but i do know what they're kind of looking for okay so we've got these four settings that are in the configuration but what what are these the way stripe works is they when you go and get it like api keys and stuff what your server is going to use to actually make api calls in other words interact with real money in real customers is it wants to use this live secret key which i don't have set to anything yet and if you are using a test mode then it will try and use a test key so this the stripe gives you the ability to create two different kinds of keys one that is safe that you can use like test credit cards and not charge anybody real things or be charged yourself um that's what the test key is for and then the uh the live key of course is the inverse of that when you do actually want to charge real money um create real accounts real customers and all of that and the boolean that's here um which actually i don't want to be listed as like that uh is i probably what controls which of those two keys it picks from would be my guess um this web hook secret uh i'm not super well informed about the stripe web hooks yet because it's been a long time since i've used them but i'm pretty sure what happens is there's a certain amount of shared it's like a shared token that is an authenticity check so that when stripe sends data to your web hook it wants to be able to prove that hey this is actually coming from stripe not from some phony account out there that's trying to pump data into your system so by having a shared token something that you get from stripe in their calls something that they say hey we're going to send this to you you need to go put this in your server that's that's probably what what goes here in this secret and that will allow the dj stripe web hook to to verify the integrity of that so i'm going to save those as just the empty things for now and see if that fixes this thing this is weird to me dj foreign key to field um i'm not sure why that's coming up that way so we're going to run this again and see if the setting those four things no it's the same problem that's strange so i would i don't know what this is so we're gonna have to go dig deeper to see why why this is required why why it's um i don't know why there's not a sane default i would expect that to be a default but uh does not seem to be the case so let's come down to settings maybe there it could just be that their contributing guide is out of date because clearly like look here to here it is right here um and it was introduced in a recent version you're required to set it um okay well that's strange this is this is me reading this for the first time y'all so i don't really know what's up here i'm just kind of like getting it myself so it says it's new to this version 240. okay that's cool and it could just be that i'm kind of on boarding onto dj stripe at an awkward time because it sounds like in 3.0 it will have a default and they recommend setting it so i think there i probably should open up a pr to say hey you need this in fact can we do that quickly i don't know um let me see if that was that one setting will set it correctly and then maybe we can open up the code pr here live and and just try it out so the field the setting is called what dj dj stripe foreign key to field and it needs they say it needs to be equal to id okay i don't i don't know any different so that sounds fine to me let's see if that will fix the tests or if there's some other setting we're missing well this is funky my tests do not take this long to run so something is happening all right let's kill that for a minute what i'm going to do so the easiest way to like confirm if it's dj stripe which i suspect it is is to come back up to installed settings or installed apps excuse me and comment out dj stripe and that will take dj stripe out of the equation right so let's try running the test suite again and yeah well now something else is failing what's going on here what is that dj stripe model's bass huh oh it could be because i killed my database last time and maybe it's trying to cache the database i don't know something weird is going on so let's let the let's let this run all the way through create this shouldn't be happening so i guess there's some there's some road speed bumps i suppose um in this process because i i definitely i disabled that right like there's no import to dj stripe anywhere it is an installed package now but it's not in the installed apps and so i'm really confused as to how the the model that was there can be complaining model class it's like somehow it's registering itself even though it shouldn't be able to that's pretty strange so this is not a good this does not instill confidence in me that in this package it could be a great package that tons of people depend upon but uh yeah you can see here like anything that's actually using the client for whatever reason oh you know what it is i got it got it i forgot there's another area where i added this project urls i forgot i put it in here too so it was trying to import something i was super confused about why that was going this way this should run really fast now if i did it right okay that makes me feel way better it still doesn't explain what the heck dj stripe was doing when it was getting going so that that doesn't breed confidence but that's that's something else we can get into um what can we try here so this is running pi test with some coverage stuff which we don't really need oh i guess it has migrations enabled um i wonder how many migrations are in dj stripe there might be a lot that might be why it's running so slowly because when when i'm running nor my test normally like if i'm in my actual code over here right and i've got a test file up and let's say that i'm on i'm over on here and i want to run this individual test you notice i only pass in pi test i don't pass in any extra parameters my make coverage command though is running with the dash dash migrations flag which is running migrations let's look at dj stripe and see how many migrations they have because it could just be that there are tons of migrations in here no well that's curious so there's not a ton of migrations so i don't know what's getting hung up on okay well let's um come back to the settings and let's add dj straight back in and i'm gonna this time i'm gonna run pi test and i'm not gonna use the migrations flag but i will give it i will ask it to be in verbose mode i think that's how you do it it's either dash v2 or something okay so it's running just fine okay well that's that's good that wasn't super slow or anything let's try adding the dash migrations flag in there and see if that's where it's going to hang this is kind of weird okay there it went so maybe i just didn't wait long enough last time that's possible it's kind of rough that those migrations like look how look at what my test run just went to that's insane it just went to 37 seconds when it was at um that's a good question i think uh i think your answer the answer's probably yes code ollie tape but um i'm not running their tests so i would i would be shocked if they don't have any tests maybe they don't well let's see spring beacon there's they're rude no they're here there there's plenty of tests it looks like but i'm not running any of these in my test suite so that's not what we're seeing here so something in their migration process and it could be it could just be that they have a ton of models um as i said it's trying to mirror a lot of the models that are in stripe so if we come in here i bet if we go in and look at this first initial migration it looks like they might even try and squash these periodically i bet this thing is gigantic yeah it's 5 000 lines of model changes or migration changes all right i'm almost positive that that is where all of that effort is coming from it's just got a it's gotta make a lot of models um that's rough but i can live with that that's fine it's a if if my test suite to get a full test run takes longer but i had to do no work to set up payment stuff then that's a worthwhile trade-off it at least explains things all right now that we know that it takes a long time let's see if we can add this back so now this is like minimal configuration i'll run make coverage again and i'm going to let that run so it clearly collects pretty quickly and it's uh 41 the 41st minute here locally i guess everywhere it's a 41st minute unless you're on a half hour time zone i don't know time zones are weird but while we're doing that let's see if we can make a documentation change really quickly so this is the configuration guide right or the installation guide do they have it no they don't um so let me see all right that ran and let's take this line and make a quick pr and edit this so i'm going to come down to this section and add it here get rid of the find and then we'll say mention required setting in installation guide forget you github i don't care how long that is so we installed this for the first time and the setup failed because this thing was missing when looking at the settings or what they didn't call it settings would they call it well i guess they did settings yeah okay i discovered that this setting is actually required to work to operate the docs recommend the value of id so that's what i'm listing okay we're doing our our darndest to improve open source here so um all i added was the single line i don't actually know if i'm following their contributor guidelines so but i haven't actually created a pull request yet so here's our one line change and we'll create the pull request let's see what their contributing guidelines say let's make sure we're not screwing stuff up report bugs i don't really want to check their documentation i don't think what i did is broken um okay this feels good to me i feel like i've done enough due diligence to say that i'm not being crazy here and we'll create a pull request and i can take that or not it's on them but i did my good deed by adding that okay cool um we can close these things out it looks like yep test still passed so that's all good we're ready i think to move on to move on to what i actually need this to do so even though i got the configuration going um that's barely a start if you recall this is not well i definitely don't want to just leave empty strings in those settings but my tool for using that is django environ so i've got my environment up here and we need to set some values so i need to create well i think in order to make these required we we can just ask for them or or basically use them directly this is this is one thing i'm not really crazy about on with django environment here you can put in what is a setting here right but i think the way this works is that you have to include a default if you do this so what i really want to do is declare that i'm going to need one of these settings and list its type but i don't want a default because i want to force an answer on on my configuration because i want i don't want production to like be missing keys so that's maybe there's a way maybe i can do a single element tuple let's go look really quickly because you can see here there's a default value is the second one but that's not what i want and then they tell you like well relate raise isn't improperly configured but that's like too late right or it doesn't really declare intent in my opinion so it would be nice if i could just list it it may not be a feature that's here which is okay i can live with it but just just musing [Music] um boo in give all these certain types you know some different like converters and things nope all right too bad oh well so let's come down to the dj stripe area and this now we're going to replace it so i'm going to say environment stripe live secret key i'm going to name them the same thing and i'll just do that in all four spots for a minute even though i'm going to change it so we're going to switch it to test so that's that setting and then we want to say dj stripe webhook secret and we also want live mode although live mode is one that i can set um so let's do that so let's go up to the top and say stripe live mode and i want that to be a boolean and okay so here's an important consideration for the way that i've been writing settings i am writing my settings so that these environment settings will default to do the correct thing for production that's critical in my chosen method that by having taking that stance what i effectively get is um minimal amount of configuration on my production environment and then everybody everybody else every other environment that i might have in the future has to opt into changing the behavior so you have to you have to i have to deliberately diverge from the way that my live website runs if i wanted to operate differently uh it involves a little bit more configuration for doing local development but it means that there are fewer things to do on my production site which is is a good thing i called it out because i've got stripe live mode here but that means now that i need to go to my test the sample environment file that i have which is env example and make sure that i include it here and i might have to go in and tweak some stuff in a second to add some other values and i'm going to have to hide my screen i think at that point because i've got keys and things in my other my actual environment file so we're going to come down the bottom here and say stripe uh live mode and i definitely don't want this to be live mode right now so i'm going to say off which in django environment will return or interpret as a false value so it'll override this stripe live mode here the other thing that we want is uh we need so if i run the the test tweet right now and i'm not going to use the dash dash migrations because that's slow but if i let this run it should well maybe it's not going to maybe nothing used it how can that be that doesn't seem right did i not see ah i didn't save the file okay try that again this should have blown up on me which i fully expect it to yeah there we go uh so this is more much more in line with what i expected so i i declared in that settings section that we need those keys those those uh new variables right the live secret key the live test key and the dj strength web hook secret but we don't have those provided yet so i need to come down here and make sure that they exist um so we're going to add the stripe and i can leave this to well can i leave it yeah it just cares that there's something there so it's going to be empty and that's probably fine we'll say is equal to nothing and then we'll change live to test and that should create those two values and we also need dj stripe and i keep this stuff alphabetically even though they're this separates them but it makes them easier for me to find in the future if i stick with this pattern i've tried like having like a mixed mode where you trim group stuff logically together and then you can do that but then you have to do comments like like i've actually done with my settings so in the actual environment configuration i i just keep them all separated and alphabetical all right if i run this though i'm still going to fail because this is just my example file this is like if i happen to if my computer crashes tomorrow and i can't recover my disk i need to be able to know what settings i have that's why i keep this file up to date so i can know which values to fill in if i want to to do this so what i'm going to do to do here is come to this area and turn on my super secret thing and i'm going to make sure that yeah y'all can't actually see my content right now this will just be for a moment while i take those new settings that we just added and put them in my actual environment file um so if you'll give me just a second i'll be right back with you and all i'm doing right now is taking those exact same things that you just saw and literally copying them to my other file and i have to do this because um yeah because i don't want to share my keys sorry i i think you'll you can understand so that's what i did uh now if we go over here and run pi test again this should hopefully work because all of those values even though they're empty they exist in the environment so django environment doesn't care dj stripe might care if i actually had some tests that checked it because they're going to be empty but i'm not testing anything with dj stripe right now so we've got that going and now now what now i probably need there's probably a couple more places that that needs to go um i bet ci is going to break so we need to go to the github file and we've got i've got tests in here and coming down to the bottom and these i'm almost positive is going to break if i don't include these so we need to include and i don't want it to be live mode of off so let's do all of that we'll do stripe live mode is set to a value of off put that for both of them and then i don't know that we need a real thing here but we'll keep going so we need secret key and we've got a couple keys there so let's copy those as well and then i guess i need one more for dj stripe webhook secret and let's put that alphabetically all right you probably didn't care about all those configuration stuff this is sort of the fiddly bits that come along with projects sometimes but hey it's it's sometimes good to see and i wish maybe github is a way to make an environment that applies to all the commands i'd love to just be able to set this once and forget it so what do we have we've got our example configuration we have updated ci to use those fake values so that shouldn't blow up we set a default for the live mode so the production will be true we added dj stripe we added the new settings we created a pr for the setting that was required that the configuration didn't mention we set up the web hook um now i should call out that this is not actually you know there's some stuff to do on the stripe side so we have set up the ability for my application to have a web hook that can can be called but that's not applied yet and we did some stuff to actually install dj stripe all right neat the other thing to do to finish this off is to actually run the migrate command so let's let's run that now so that should actually apply dj strike whoops [Music] let's run it from where i actually have the virtual environment activated so that will actually create all of those tables i would suspect all right well so i'm getting some warning checks here that are preventing my migrations from running there's also like all this other stuff well we haven't actually these are good warnings to resolve now because i think i'm already on three one it's my version of django i'm pretty sure so we're on django three one and the warning over here says dj stripe use native json field oh that'd be good so okay so that if you were paying attention a while ago you saw that my requirements file had a package called json field and there was a time where django did not include a json field by default so if it was available for postgres which is the database they happen to be using but it wasn't available for sql lite or mysql or some of these other things but 3-1 added kind of support for all of django's supported databases once it did that the third party package that was doing something similar was no longer needed so what there's what they're hinting at here is you can use this and in this context this is a value i want to use so let's make sure we go back in the settings see if we can see that we can understand that here it is okay so we'll go set this to uh true to continue to fill in values and i guess this is a good time to say let's look at the actual list of settings shall we because i haven't done that so i i kind of assumed that this was a minimal right thing but i think we've seen now a couple of examples where the settings aren't quite what you would think so maybe there are other things we should set all right i know that we don't actually have to set the stripe api version this is used kind of internally and they even say hey don't worry about it it doesn't matter so as as dj stripe upgrades they upgrade how they communicate to stripe and so they will set their version so i actually don't even know why that setting exists maybe it's a development feature i'm not really sure we just set the dj stripe foreign key field um item potency key callback wow all right i think i can leave this to the default i don't know why you'd set this hmm by default plans are not prorated okay i don't think i plan on supporting proration proration is like what if somebody cancels mid-month are they going to get a partial refund and i'm not going to mess with that right now if i if it came up with a customer i'd probably just say fine i'll refund you the whole amount um because it wouldn't be worth the hassle uh let's see dj stripe subscription required oh deprecated i'm going to ignore it customer key all right leave that looks like something we can leave our subscriber model if the auth user model doesn't represent the object your application's subscription folder hmm well that's interesting i might actually want to mess with this one because one of the pieces of advice that i i listen to a podcast it's from the folks that do honey badger what's the honey badger uh podcast i'm drawing a blank on the name of their podcast founder quest so honey badger if you have never heard of it it's more popular in the ruby world i believe but it is uh it's like roll bar right so i've used roll bar i've shown it on the stream it's like sentry if you've used that they're similar they capture error information reported and they have um uh podcast which i'm now struggling to find which is over here and this is basically it's a small team and there are like three founders and they talk about building software as a service products and one of the episodes that they had they talked about having disconnecting your billing from individual users so in their case they they wanted like support teams and stuff and it was a big project to make that um yeah make that disconnected so as i'm looking at this it seems like i may want to actually do this because the way that i have connected the way that i've connected my application is i plan on having users manage their subscription and all that stuff through an account so there's a user and then there's account and i'm kind of keeping the user for authentication purposes but i've got an account model to actually account track the status of whether they're in a trial whether they're active and so on and so forth so this setting is actually looking pretty like something i want to change because i don't want to connect it to users based on the advice from that other podcast so we actually might need to set this and modify the thing here to be something meaningful so what does that have gonna have to do yeah that is a good catch you're right i agree i was glad i'm like reading this before i commit this code and deploy it no that would have been a mess to go back and clean up it's one of those things that you probably can't change super easily so it must have an email field all right that's not a problem and settings auth user model is a string usually i think of the like the app label so let's go to back to the settings file let's keep that open and we'll say stripe subscriber model come on subscriber model is equal to so this is going to be the app label of accounts and account is the thing and then they say that we need to have an email prop is it a property yeah property so it needs to have access to an email account which is not not bad because we already have a user that's associated with it so i can i can definitely connect that there [Music] so it's kind of just an indirection layer i guess and as i'm staring at this my obsessiveness for alphabetic stuff is taking over so i'm resorting those all right then we can i think pretty easily do this we'll say get the email get the account holders email and this property is needed by dj stripe and we want to return self user email and we're going to test that later but no problem what the heck this is getting crazy um okay let's read this if the model referenced here okay no problem is not created in the first migration of an app do they mean initial surely they mean the initial okay it is created in there i don't know what first dunder first means that's like really bizarre to me i'm gonna assume that i'm doing this right okay moving on we've got this thing is using the native json field the web hook url this is a fine pattern that's so that's going to be the schooldesk.com or excuse me the school desk dot app slash stripe slash webhook that's fine stripe webhook secret if this is set to a non-fd value my book signatures will be verified all right oh man i think for like local testing if we if i'm not setting real values in there that i might need to like override this how yeah gosh okay we'll keep going so and then how man this this keeps getting deeper of if i don't do any validation for example uh how do i set an environment variable to be from django environment to be none can i do that cast oh that's a cast maybe i can i don't know because it's going to come back as an empty string so i'm going to have to do it if it's like equal to an empty string and set it to none wow that's goofy or did they say that they'll handle that as the setting controls what type of validation is done verify signature it's fine retrieve an event that's like a we're going to send you something but you can ask for it anyway to do an extra request that's fine or none for no validation at all which is sort of what i want with local testing maybe it doesn't matter right now though because i'm not i don't know but let's try critical to your settings yeah they're gonna complain about this critical we gotta we have to resolve that bummer okay well we'll keep going so that's uh stripe dj stripe web hook validation so let's take this come on there we go and come over to this section add a new one and we're going to say environment dj stripe webhook validation that's what we want we will do and dj stripe web hook validation equal to a string and we want the default to be this verify signature stuff so set that so that's good um now i'm going to come back to my example file and say thanks dota 2. yeah automated tests sometimes they're uh i think they're worth it overall but they're they are sometimes tricky to get get just right although right now i'm just trying to do um migration and this is just being pretty finicky so let's do this let's say like i'm gonna i'm gonna see what happens if i leave it empty and see if the check complains or if it'll interpret i'd like it to interpret empty as equivalent to none and like do no validation but maybe it won't so i'm going to have to again take the secret mode here but that's all only because i'm going into the actual env file and adding this in but i'll be i'll turn that off in just a second okay so i set that there now let's try running my grade and see if that error goes away dang it okay webhook is invalid so you have to pass it none how obnoxious okay you just guessed the combination of my luggage password um okay let's come down here and now we're gonna come down to the valen the web hook validation and we're going to say oops where was i we're going to do this so we're going to say well it's closest stupid migration is because it's just taking up so much space so we will let it use that value if it finds the value else it's going to be none so that means that if the environment value is empty like i just set it to that if statement will fail so it won't set it to the value or return it as none great we got rid of that critical and now we just have to fight with these keys one what is it saying now my book validation is disabled this is a security okay come on guys you're killing me here not you all you're all agreed dj stripe is killing me with this stuff i got it um because i feel like i'm gonna rock in a hard place because what if i set what if i set a value all right let's let's just assume that for a minute let's comment this out so we're not actually doing that anymore we should see that that critical come up so it's not giving the warning anymore fine but it's saying you have this verification set but your value is not set all right what if i go in i cannot one more time go into the well maybe not one more time another time go into the environment file and i'm going to set i'm going to put a secret to everybody the same thing that i put in the github file okay so we did that one second is going to try and verify that signature in which that would be like dumb dj stripe dj web hook secret is not set well baloney it was said you know ah shoot did i put in the wrong one i did oops secret and you you can't uh you can't call me out on it because you can't see this area i set it in the validation one all right and i was about to open that up with all my secrets for the whole world to see streaming sometimes right yeah you i can use the the or syntax i i happen to prefer the the if else style but you're right i could have used the or syntax this is rich right okay so we've got the warning still i might have to just muffle these warnings under certain circumstances [Music] or fails on number values right yeah the problem is i don't know what validation it's doing so i don't know if it's like trying to um if it's going to validate like you can see it's already kind of hinting that it looks like it it wants to do a real validation doesn't look like a real secret and i don't care at this stage but when i'm doing local development i just really don't care so the question is like what which trade-off do i live with or which which warning do it muffle because it seemed like if i turn it off it says hey warning you've turned this off but you're in danger of doing this it's like well okay that's fine i'm in development mode i don't care and then i give it a bad value and it says hey warning you have given us a bad value so feel like i'm doomed either way so um i think i would rather all right i'm gonna rationally go so here's my logic for why i'm gonna do this way i have set the dj stripe webhook validation up here and i'm not going to set this on my production environment which means it's going to come into verify signature so that means the only time that dj stripe web hook validation is ever going to be a value that is not verified signature is if i actually set it which comes down to the scenario that i just created where i put it in my environment file and left it empty which is kind of this else none block so if i run this now it should say i got to delete the webhook secret of course i do um and i'll be right back let's get rid of this webhook secret thing i think i've flipped this thing more times than i've ever flipped this on a stream that's crazy um okay so that will that should kill off that first warning because i've got this disabled now we can go to where are they do i still i might have deleted it because i recently uh here it is silenced system checks so now i want to conditionally add to silence system checks if the validation is disabled if it's so if it's none good grief this is terrible um actually let's do it down in the dj stripe settings let's keep it together so we'll say well actually we've already pulled out of the environment at this point so we'll say if dj stripe uh webhook validation is none then i'm going to go to the silenced system checks and append um what's the value dj stripe ww no w004 okay let's see did that do it did that get rid of the warning at least okay i'm going to put in some fake keys and see if those complain and then yeah i'm just trying to get rid of warnings at this point so i don't know how much farther we're going to get on the stream just kind of going through the mechanics of configuring this package which is it's useful for y'all to see if you're trying to do this yourself but wow talk about pain in the butt so i'm going back into the file i'm going to put a secret to everybody for both the live and test key now what's going to be irritating is if they come back and say this doesn't look like a stripe key yep wow they really like really really want my live key isn't crazy i like the stripe vanilla library i've used it but the downside of it is that and the benefit that dj stripe i think is offering is this ability to like have your account data there and and be able to operate with the orm and that's that's kind of hugely valuable i think otherwise you can do this but you have to anytime i'd want to interact with customer data i'd have to use something like requests to do or use the stripe library to ask for the data which is going to be in a api call which um is going to be slower because think about it like if i want what if i wanted to do this like right at that moment when a user is trying to change their account status if the web hook is constantly syncing the data from stripe and doing that successfully then all of my data about the customer is already local in my database and so i don't have to make api calls and deal with potential http failures and all that other stuff so this this kind of trade-off is that i get the benefit of the orm and local local kind of access for the app but clearly there's some some challenges with it so i'm going to try and add sk live and see if that will be enough to make this happy um i'm really my my first run experience with this i'm i'm guessing it's a good tool but my first run experience has not been favorable so far going to go to the live key and i'm going to add sk live in front of it i'm going to run that again and because i might have to modify this again so i'm going to try running the command again and what the heck my up and down there it goes all right well that apparently was enough to make this happy so let me get off of my environment file and let you all see this again so all i did was i went into my fake data and added sk live to the front and that was enough to get by the validation check i don't know um seems kind of weird to me but that's the way it is so i think that gets us the migrate that confirms that the migrations work layers of security yeah you're right i mean we're talking about money and like if somebody actually got my data they could start i don't know i think they probably start charging like doing chargebacks or i have no idea what they could do to like transfer money out of my account i'm not sure what kind of protections are on there so i i appreciate a level of security when it comes to money um i do think this warning system is tricky to navigate this is this is way harder than i expected um i'm going to come into my example now and i'm going to modify the examples to be kind of accurate to what i did so we're going to say sk live a secret to everybody this is what i typed in the other stuff that you all couldn't see and then a secret to everybody [Music] and i think i left i deliberately left validation empty so that it would pick none and i left the secret empty although i don't think it would have mattered because the validation was being skipped so you know of course if i actually wanted to test out web hooks i could set values in here and then test this out for real and then configure something like ngrok to proxy my traffic and set stripe to look at that ngrok url as a webhook but there's probably ways to do that to test locally but i don't actually want to do that i'm not really interested in talking to stripe right now anyway maybe there's there's a little comment time in the future but that's not where i am today i think this means i need to change my github stuff so let's go back to the the github test file and we'll change the live key and just to the i'll do some values that i know were correct and we'll say sk live and then we'll do um just delete these other i don't know that it matters um and i do want to have the it's called validation right yeah i don't want to do the validation during ci so i want to have that be empty which should configure it in that other way and check the security and then we can go down here in fact i think i can leave this empty well i don't know this stuff is tricky it seems all right so what do we have from our diff let's round this out we've got example settings that are added here i turned live mo load live mode off in the example we added some stuff to github ci so that it should still continue to pass i hope i picked a new subscriber account changed it from the user account and added an email property that's probably going to fail actually that's a good good point so let's let while we're reviewing the diff let's let this run in the background now that it takes longer uh this is not going to have coverage i think so we're going to test that and then we are setting the validation to be verified signature and setting the mode to be true for a production sitting and adding it and then down here we've gone through all of the settings and pulled them out of the environment added where they're needed created a different [Music] connection for the subscriber model use json field so there's a lot that we've gone over to try and get this configured and then silenced a system check that for the development stuff and then the final bits were adding the urls for the web hooks and then installing the package i think that was it yeah um so one line is missing as i expected let's go write that one test and um i'll get to your question in just a second kodaly t that's a good question um so we're going to write the one test and then we'll talk about notification systems a bit and then we can wrap up for the evening so the the test the thing was in the account model it was this email property and so i'm going to open up the accounts test models file and it has one test in it right now so we'll say test email and we'll say the account proxies the account holders email address and we'll do account is account factory and then we'll say we'll assert that the account email that's the value that were the actual value we're getting out of the property and we're just happened to be testing it against the account user email alright so that test passes so that should be the um the one bit of coverage that was missing we'll run that again and then we'll talk about your your question so your question is how would you build a notification system for the school so what kind of notification are you talking about and i ask because i already have a notification system in the app which we can look at and then if you're thinking of other kinds of notifications we can talk about those so the notifications that i have in the app currently and i can probably even bring up the application itself to take a look at them let's run run everything locally go to the app and check out the admin oh look at all this stuff cool wow all of that dj stripe stuff is new that's cool um but you can see i have a notifications app and my notifications right now are meant to be product notifications they're meant to inform users about uh changes i've made and so the way i'm doing that currently is is a not a very fancy system the concept is i create an announcement and the announcement is a model that is a link to a blog post like you can see this is all the announcement has in it it's got a status that have i done it or not and then um a url of where to go and so those are those the announcements um and then i have an action that tells me i can announce uh and so the idea is when i create an announcement because i've written a product blog post actually let's let's make this as clear as we can let's go to the website and there's a product blog that you can visit at schooldeskapp.blog which i'll share over here you want to follow along and i've just written up some kind of simple post these aren't complicated uh just shows like hey i had a documentation to help you out they're really quick little things and i can take one of these and take its url and i can put it as the announcement this is where i want to send people to and when i say announce what it does is it creates a notification instance for every active user that i have and i think we can see that in the actual notification side so here are two different notifications that i've sent to myself when i was testing this out and um the layouts is pretty simple that it's got a foreign key to the actual announcement itself it's got a foreign key to the user and it's got a status of whether i've seen it or not um and in the app i do a check in the the bar at the top um if i come back to the application and it's right next to if there was an announcement it's right next to this settings in fact i think we can let's change it really quickly so we've got this one we'll change it back to unread all right so now it's an i've got an unwritten announcement and i come over to the app and didn't do oh i'm on a different account maybe nope this is the right account oh because it's it's picking the latest one so let's do the second one i had the backwards i'm picking the latest so i have to make the latest one be unread so we can come back to here well that's curious why did that not work it should have shown a little icon here saying that i have something to read but it did not that's disturbing is that functionality not working anymore that would be super let's go check it out i think i might have broken something so i have an unread notification i ordered them by created and i get the last one so here's the view that that is triggered so if you can show a notification on that view then you'd be able to click it and then it would redirect you to the the blog post where you're supposed to read it and this in the redirection process would mark that you viewed that notification so that's how i would do it or or how i do do it what is disturbing me is i clearly have marked both of these red and neither of them are appearing in this bar there's like a little like what's new christmas present kind of image that pops up that's not popping up and i don't know why so where is my notification um i think i even it should be show what's new oh maybe i have this turned off for this account i probably did as testing that yeah all right here we go thankfully it's still working so i'm going to turn this back on now if we come back to the weak view well what the heck something isn't right what is up i would like to see it receive announcements so that's that profile setting and i have show what's new show what's new just kind of on the the week view which is the view we were on oh i don't have a school year oh wow hmm i found a bug you that's interesting i think yep yep yep that's a bug well fun we found a bug so this should be this little last bit of context to show what's new is what controls this let's move this up it's not in the right spot we can put this bug bounty with all my mad profits that i'm making from this app i'll share that bug bounty with you um okay so let's try again oh what the heck come on yo what's going on this is the dashboard view show what's new that should appear but it's not appearing i'm on the real site dang it oh my word it's too late at night i can tell let's try this again shall we hey there it is it is live this feature works oh my goodness it's getting worried um i think we still found a bug like that context would only happen here if it had gone in here so this is still the right call thank you for helping surface that bug code always but here's what happens i click what's new i haven't clicked it yet you can see from the from me hovering on it it says notifications what's new so that will launch into this views file it will launch this view it will see and this this button only appears when i have an unread notification which means that this thing is going to when it gets clicked is going to pull that unread notification it's gonna or pull all of them out and then get the last one so if you have the reason i did the last one is like if i wrote let's say i wrote you know 10 product blog posts and you haven't been on the site for six months i don't want that what's new thing to be like up there over and over and over again because i'm not gonna do a little badge i'm not gonna be annoying about and give you a number of how many things you have to read i just wanted to be okay you wanted to see something that's new here's the thing that's new i'm going to give you the last one and then i'm going to clear all of them so that's what happens um in this last step is it updates all of that to say all of them are viewed and then it actually does the redirection to whatever the url is so i can click this and so as a reminder both of these are are unread and so it's probably going to go to this second one i think that's going to be the latest and that's going to be a broken url because it's not anywhere i guess i've picked one this other one so that was a real post that i created just to write something here and now if i refresh this admin page both of these are marked as viewed so that's my notification scheme for product announcements i bet you could do something similar if you want to do other kinds of notifications like whether your system is well is that true it might it might be full crap here this is not a very this is a a passive notification system in that it's not until somebody goes to the site and sees the little what's new present picture and click it the something happens i'm not actively sending people an email or sending out a text message or anything like that i don't i don't think that this kind of notification merits that um i i could if i wanted to but it's just not not how i'm planning not what i see the speech you're doing um that is interesting you're like talking about yeah that could be possible like with um you'd have to do a bunch of time parsing and yeah that would be doable i i don't think you have to remember for my context my homeschool stuff is students don't actually use the app it's all for the parents um so it's really just for their planning purpose but i could see an application that uh that does that kind of stuff that that tells people about stuff and then come comes back to them and says hey i'm keeping track of something in that kind of context that's that's more of an active system and the way you'd have to handle that i mean there are a couple of techniques you could use um one that i would think would work the like the cheapest one is kind of a polling option where you have some sort of background worker process that is checking periodically so you if you did this kind of process unless you were checking every minute which i wouldn't recommend doing that's a lot of um wasted processing um but let's say you checked every five minutes or ten minutes and you have there are tools that can do this like if you're using celery for background working for example you can use celery beat to set it on a schedule and so the schedule could just wake up every 10 minutes and say do i have any notifications oh i do okay i'm gonna send off my my notifications and and maybe maybe you did want to do an sms system so um in that model i would probably have a let's say we're using celery just to keep the kind of conversation easier so celery is a task management system a background task and so it has workers that it uses and it has it also has a like a message bus and i could that message bus is um you think of it as a queue is is really what it is so you can use redis you can use rabbitmq there are a bunch of different transports they call them i think and so the way celery operates is you put something onto the queue onto the message bus and a worker will then pick up one of those items off the queue it's just like putting in chunks of work to do so salary beat is a process that you have to run continuously and so so if you're looking if you're trying to do research on this i don't i don't know what you're if you're just interested or if you actually have a project in mind um but uh celery beat is a process that takes a schedule that you define in your pro in your project and the schedule can accept specific times like if you have a specific time in the week you say you want something to run every monday morning at you know six in the morning you can do that it can also take repetition so do this every five minutes do this every 30 minutes whatever so celery bee would run oh you have a project like cool and so this tool would run and it would uh celery be runs and it's going to add a new task to the queue it doesn't actually talk directly to to do some to have the worker do the work it's it puts it's always about putting tasks on the queue there is also a separate worker process that is always looking for things to do is trying to find like what what am i doing next what am i doing next so celery beat would add the task to the queue to say hey look for anything that has notifications and then that worker is going to receive that task and it's going to say okay i've been told to look for the notifications and so in that worker task you would have um processing for notifications now here's where you can you have choices the let's say let's let's imagine you're doing sms notifications you're trying to send this out to people you could do like a task that um i'm not actually i'm gonna like write some pseudo code we'll do this um no let's do a new file something not buy so we're in a new file and your task is a task is basically a function so process notifications i don't know and it's not going to receive any parameters because it's being called from a schedule and doesn't really have anything to do but it's going to look for notifications so it might say notifications and then some kind of filter and this i'm just making this up right now so this is like these have not been modeled out so i'm just going to do this very crudely and hopefully it gives you the idea and the simplest version of this is to have all of the processing happen here so you could say for notification in notifications you know assuming they're in tight right time range send sms and maybe the notification has information about who to send that to you could do this this would would work kind of what's wrong with this well in this flow the this notification i imagine sending sms is going to require talking to some kind of api you're talking over the network so what happens if any of one of these breaks if there's a failure like the web the internet goes down and your code throws an exception all right well now you've got to do try and you could wrap it and do a try except on some kind of error some sort of http error i don't i don't know again i'm making this up but then what do you do in the exception clause so hopefully you're getting the idea that this gets like tricky if you try and do all this in one go so probably what i would do is uh yeah so if i had notifications that actually need to be sent out at that moment because really although i've said like all here you'd really want to be filtering for like um it'd be something like uh i don't know what what the notification the the two send like if it was a two-send time there was a time stamp you then you would do a filter um that is like greater than or equal to now where now is the times a you know date time stamp to then like to send less than anything in like let's just say 10 minutes into the future um so that would be now plus time delta um is minutes one of them i don't or s it's seconds i think is the time delta granularity you get so you can do 10 times 60. i mean you're getting the idea hopefully um that like you you get us a set of notifications and then you do something about them and you're checking over and over again and presumably in your system in your project somebody has a way to specify the time that they want to receive a notification that's where these notifications are coming from so your users are inputting the notifications on one side and your background processor is just kind of sitting and waiting to send them out on the other side the downside of this flow as i pointed out though is that if you have errors in this process for a single note a single notification this loop is going to have a problem so what you might do instead is instead of having this send it in this particular step you might have a second task so it says like um well that indented really funny that says something like process notification and it's going to say get the notification id so now this this is another task and in celery this would be um you'd use like a delay call all right i'll explain this a minute and i apologize if you've never used celery before this might be a little overwhelming but um okay so let's just clear up some error messages so you can kind of chain tasks together or trigger new tasks and in salary the call to trigger a new task is delay so i'm assuming that there's a task name process notification and the delay call would fire off a new one and you'd give it the id that you want the notification so this task about this other one about processing it is not going to be asking the question is it the right time to process it's going to assume that this kind of supervisor process this process notifications thing is doing the right thing and telling it when it needs to send so the process notification that could be the thing that calls send sms and [Music] if you fail there you don't fail all of the notifications you just fail of that one you could still and you can add like retry logic um these tasks systems usually have some retry logic so if your send sms call did fail for that one particular task you could have it retry a few seconds later and it might might work the next time so that's where you get a lot of that flexibility hopefully that gave you some inkling of of a way you could do like an active notification system um that's not a feature that i need right now um yeah so would the okay would that run on a new thread use maybe sort of so it depends on how you configure celery again calling that delay call would it's always going remember it's always going back to the message bus these things these things are never coupled together directly it's always indirect through the queue so that and i closed that file and i didn't save it so i don't have any more but that process notifications function that's calling delay all it's saying is i'm going to take this id and create a new item for the queue to to process in the future so when the workers then has the time is free it can then go get the next task and process that one now the real scenario is that you often have multiple worker processes in fact celery has some options that from the command line will let you fire up multiple workers to run in the same tree of processes so there's like one master worker process that farms out to other workers and kind of round robins the queue so celery is just one technology i do so i know i've been working i've been commenting on salary i do want to throw out some other options i i do foresee a future where on this project i will find a use case where i need to have some kind of background processing and the the one that has been picking my interest is actually this one called huey it is i think less complex than celery celery for all of its features is has got a bit of a reputation for being difficult because setting up the broker is challenging and so on and so on um so you might want to check out huey it seems like a pretty strong offering i i presume that they have some kind of scheduling system so i could actually be wrong let's see periodic tasks yeah so there's there's sort of there are ways to do periodic tasks and stuff ah they're there so here's an example all right so huey might be easier to set up than celery um now again confession like i don't have experience with qa i've just read the documentation i've been very impressed with it i'm pretty sure that i've heard dan bader i think i think real python uses huey i don't know if they still do but i believe i heard a podcast where dan was talking about this site and i'm pretty sure he mentioned um i'm pretty sure you mentioned huey so there's another option so you can check out celery and if you like it go for it um but if you're like overwhelmed by all of it then you might want to check out huey 2 as another version of this and here's just an example of how this is working so huey can apparently work with sql light um i would recommend probably well i don't know you explore what you need redness is is a popular choice and this is a popular choice for celery too it's so it's usually some kind of like uh background task tool and that would be like celery or huey and there are others and then you all but you also need some kind of the the message bus to go with it which could be uh rabbitmq or redis so those are those are choices that come across so rabbitmq while being a really robust piece of software has is harder to set up it uh has more requirements too it's actually written in erlang so it's actually just as it's just different um so it's just something to be aware of and you can see this example here you can kind of extrapolate to okay here's how a task would run i could do it in a for loop and um there's probably ways to there's probably other stuff you could read to looks like the schedule is is is huey's equivalent to the delay call or something i don't know so go right up on that that might be useful i think that's probably where i need to end things for the evening um we got through setting up dj stripe as much as i could reasonably figure it out we got through a lot of the errors in the configuration and then we talked about uh pi upgrade way back at the beginning so um that was to modernize your python to the latest version so hopefully y'all picked up on some stuff this evening and enjoyed this last little bit this random conversation uh thank you for joining in and have a great night take care
Info
Channel: Matt Layman
Views: 653
Rating: 5 out of 5
Keywords: twitch, Python, Django, SaaS, Stripe
Id: hA_TmTptUpQ
Channel Id: undefined
Length: 118min 28sec (7108 seconds)
Published: Thu Feb 11 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.