 Yeah, everything looks incredible. So yeah, and you are already start So Again, hi everyone for those who just joined my name is marching and today I'm gonna talk about building graph QL in Python and Django So my talk is called real world graph in lessons learned from building graphical API on top of Django up Yeah, so to quickly introduce myself, my name is marching as I said I come from road sof in Poland I Work as a Python developer here at company called Mirumi software. We are a software house Specializing in e-commerce, but we also do other web apps with graph QL and react We use Python as a backend mostly And for the last two years, I had the pleasure to be a lead developer at projects called sailor Which is like one of our most important projects right now Yeah, so what's also important here in road sof we are doing a graph QL road sof as well I Didn't mention that before but this is also something that you might be interested in Every anyone listening to this to this event. So yeah, we have our own meetup here as well We have quite many members there like on every meetup. We have like 150 people so it's it's really big community of developers here in road sof in Poland. So If there is anybody else like interested in joining us and speaking at our event, it would be great. Just contact me yeah, so I Want to introduce you to sailor because this is pretty important in the context of my presentation because like This this project is where we start the journey graph QL So sailor is basically an e-commerce platform. It's open source. So we can find it on github and Well, I am it's you know, it depends how much familiar you are with e-commerce But I'm sure that's many people heard about Shopify or Magento who commerce stuff like this. So sailor is something similar you can think about sailor as Shopify but open source or for example Magento, but Built with a little bit different technology because like we use Python Which is at the very core of our platform We believe that this makes our product like better in terms of Code quality for example because this is open source product. So it's it's really important to have good code quality there So this this entire platform consists of few parts. So this is a screenshot of the dashboard application So this is where you manage your shop. Basically, this is a front end up built-in react It's using graph QL underneath Here we have the storefront application So this is a kind of template of a shop that you can take from github as well and build your shop using using this template And few facts about our API because all of that is powered by GraphQL API, so we have now about 50 queries 200 mutations and 500 types So this is like few statistics to give you an overview about size of the API currently We have JSON web tokens based authentication and permissions system From like the more cool features we have service accounts and webhooks So this means that you can not only use that API for your front-end apps, but you can also build integrations like other services that can authenticate in our API and fetch some data or get some notification by webhooks so this is really cool and What we really like about our API is also that we have pretty unified way of filtering sorting and search in all top-level queries, so These are a few facts Actually, I have Like they're running up on my machine So I I think it can be interesting to see how it looks like. So this is the dashboard application This is where you manage your shop Here's for example the list of your products you can go to product details and do some kind of Management here. We have orders management customers management and all kinds of features that you might need in e-commerce What might be interesting for you is that as I said It's all running on GraphQL. So if I reload this Then you can see that there are some GraphQL requests underneath Like for example here. Yes, that's that's data from our e-commerce API So in this case we are getting for example customers data Yeah, so this is pretty exciting. This is like huge huge react app that works really well here with GraphQL Here is our storefront application. So as I said before This is just a template of the shop that you can customize and it's also a single page up It's using GraphQL underneath and Here we have also the playground. So if you don't need any front end You can just use this API for example to get data of your products. So for example, here is a query to get products from my shop So for example, I have apple juice and here I have a bunch of variants of that product So yeah, so this API gives you access to all kinds of e-commerce operations that you might need So you can use it standalone or you can integrate that with your existing solutions. So if you are interested We have so this is all open source as I said So go to github.com slash mirumi slash sailor if you are interested in using this We also have public demo. So if you want to just try out without installing it locally then Use that demo to play with with the platform. So I'm talking about this entire application because that's where our journey with graphql has started So this entire app was initially built as Django like purely Django project. So for those who are not familiar with Django, this is like classic Framework where like you have model Model view controller pattern. So it's all a huge monolith where like both front end and back and lifts in the same code base So that was fine for us for for a few years at the beginning But at some point you start to realize that if you want to introduce some interest in sorry Extensions like integrations with other services, then you might need API and we had no API before adding graphql and also you will notice that maybe those static templates that you have in Django are not enough to build first-class user interface with you know dynamic features and Like modern apps have really complex UI and this is not achievable with static HTML templates So after having this Django based architecture for many years, we decided to add graphql layer on top So this is what we've actually ended up with so on top of our Django ORM logic and all the Python logic that does the business stuff we've added graphql layer So it's built with graph in and we've moved all of our like two of our front-end apps Outside of the project of the core and now they are separate apps built-in react and Apollo and they they use graphql As you've seen in this short demo before So this is like the new headless architecture, which also allows us to build external integrations around the platform. So this is a really great benefit of having API and especially graphql API here so Yeah, as I said, we are using Django for the back-end and when we started doing this transit transition it was like two years ago or something like that the only framework that was available was graphin and It's still the most popular framework for for doing graphql in Python. So we are using that currently Yeah, it's it's a code first framework. So We are building graphql with Python classes Python functions and the schema is generated from that and Yeah, graphin has support for popular Python web frameworks such as Django or flask and but you can also use its standalone, let's say If that's your use case. So in this matter, this is a pretty flexible framework So, yeah Basically now I'd like to share a few lessons that we've learned over those two years of using Graphin that sailor that you won't necessarily learn from the dogs or you wouldn't necessarily know after, you know, a few months of playing with the framework Yeah, so Let's let's start with like maybe one of the most one of the biggest benefits of graphin in my opinion So the first lesson is that Django plus plus graphin let's you rapidly build APIs So it means that this this this duo of Django and graphin is really powerful if you want to prototype Something very quickly or if you have large existing code base and you need to add graphql on top of that So, let's see. Let's see why why it's like that in graphin. So Yeah, so let's look at how we define data in Django So this is a simple class that represents our user Yeah, so so I think that it's it's pretty similar in in many other frameworks as well We have a bunch of fields here. We are using Django or ORM here to use some Fields like emails, booleans or datetime So so this this class would be later transformed to a database table, right? So this is how most frameworks work as I suppose that support ORM solution So we had a lot of models like this in our code base and now if you want to represent that In graphql, what would you do in graphin? In this framework, we are building simple classes like this one. So again, this is called user this class and This is very simple because here in this meta class we are saying that We want to map fields from the user model and by using this Django object type here. This class would magically Like use those fields from our model in our type Here we can specify which fields exactly we want to map. So this reduces the risk of accidentally leaking some private fields for example, so you need to make sure that you have only the field that you want here and Basically, that's it That would out of the box also generate all the field resolvers for us. So this is pretty pretty convenient To bind this type to the schema we need a query. So this is how we define queries in graphin again We are using object types and here We define this is it's using the user type and we also have the result users function Which just takes all data from from the database and returns that in this query So this this few these few lines of Python code would result in in this schema So that's that's how the code first approach works in graphin It's as I said, it's pretty convenient if you have existing API Sorry existing code base and you are adding graphql on top of that. So that was exactly what's what? That's what was our case For for using that so to summarize that Bapping models to types in graphin is effective if you are building on top of existing code base You have full control over the field resolvers like they are mapped automatically, but you still can control what? Like how they behave if you want to add some permissions for example to a particular resolver you can do that Easily and what's also important here is that graph in uses syntax like Style of programming that is declarative which is very similar to to what you do in Django So if your team is starting with graph graphql and uses graph in then It's it's really easy to dive in because you you have the same programming style the same patterns Patterns used in both frameworks. So this is really convenient to use So that's the first lesson about building types So Now let's let's talk about mutations. So it seems that after building all of these mutations in our API It turns out that mutations are a bit more tricky in graphin And this is not so obvious how to do that right when you start doing this So so let's see how you build mutations by default in graphin Yeah, because I'm talking about sailor which is a commerce platform. I have examples here here like this one So for example creating a product So what is going on here we have a class called create product What is important in graphin every mutation is is a class in in this framework? So here we specify the input data in the class arguments Here we specify the output of the mutation so Fields that would be returned as a result in this case we want to result a new product and Here is the actual body of the mutations. So so the resolver so here we say what should happen when this mutation is called and in this case, we are just getting data from our input we are passing that to the Model instance and saving that in the database. So this is like very very simple example of how a mutation would look like But in real life, if you have a lot of operations like this and many business rules, this is usually more complex so first of all There is no common pattern for input data validation. So like Pretty often you want to have some some business rules on on the input that you are passing to the mutation There are some constraints that you want that you need to check before saving data So there is no like easy way to do that in graphine or maybe let's say not ob it's not obvious how to do that. Well when you are starting second problem is that there is no Also, no established pattern to return errors in graphin So if we have some validation errors during the mutation execution, there is like You as a developer have to figure out how to return those errors efficiently and you have to establish your own patterns it's it's not given by by graphine like So this is kind of problematic at the beginning and if you have a lot of mutations like this And you add all of this business logic here This would result in in pretty large classes. So you would end up with a lot of boilerplate code So we had to fix this somehow and What we did is we introduced few abstractions. So these abstractions are not provided by graphine by default I mean, there are some abstractions that for example allows you to migrate from Django rest framework Which was like most popular framework for building rest APIs, but not if you are starting with pure Django app. So Here I want to show few patterns that we've developed over the last two years. So let's start with unified errors handling in mutations So we have this little abstraction called base mutation and Yeah, so here here are a few things going on first of all like We've added our own for that mutation, which is called perform mutation And as you can see here, we are calling this resolver inside the default resolver provided by graphine. So and and this this perform mutation function is wrapped with try accept log which basically looks for any validation error that could happen during Execution of that mutation and it does some job to format it nicely So we don't have to care at this point what what it does, but like this is like one of the responsibilities of of this Base mutation class and here as you can see we have the errors field So now every mutation that extends this one this base mutation pattern would get this error fields filled as One of the output fields. So if we use that constantly across our code base We have unified error handling because now every mutation has like very similar shape Which is what we want to have Yeah So for example If we take again this product create mutations as an example So you can see what we have here. We have some input data and Below we have the errors field and for every error. We are returning field message and code So field tells us which input field Resulted in in an error message is actually meant for the developer It's not to be displayed in the front end and that's what we used to do But actually it doesn't work in the long run because usually you have your Translations in the front end code and not in the back end code So you cannot show those messages in the front end simply so for that we have those error codes so front end is supposed to interpret those codes and because these are Announce so for example, here is the response the error response so for example, we have codes like unique and and some some field name There is constraint that it must be unique and now if you have a bunch of codes like this And they are in arms. So they are defined in the schema front end front end developer can handle that Easily and and display proper message in the front end. So having those base mutations allows us to do that In every mutation that we have In cellar. So this is pretty cool. And that's something that wasn't available in graphene by default Yeah, in our case you've seen we have this dashboard application, which is basically large crude up Because there is like a lot of views where where you have just, you know, create new products create new Categories and stuff like this. It's just a lot of Mutations that create and edit stuff. So And if you are building these mutations, you will quickly find out that they all follow the same pattern So first you want to clean the input data because you have some validation rules If if the if this data is is fine Then you want to create the model instance from that data Then you want to validate it validate it again, maybe and lastly you save that to the database So every like we had a lot of mutations that for followed exactly these four steps So what can we do to make it easier to add these mutations? So we've developed another abstraction called model mutation I'm not gonna show the source code of that because that would be maybe too difficult to understand on such short talk, but This is just to give you idea how it looks and how it works so we only say that this mutation uses the product model and Inside it knows how to yeah, and it also takes the input object as an argument and Inside it knows how to clean the object because we have the Validation rules defined on the model level in Django, and it does all the magic to generate this simple product create mutation And it's very powerful because if you want to override particular step of For example, this this flow that you like that we've seen on the slide before There are just a bunch of methods that you can override and customize this flow So we have types we have mutations. So what about subscriptions, which are one of the most powerful features of GraphQL? So it seems that if you are using Django, there is no native support for subscriptions unfortunately So the thing is that Django as I said is kind of classical MVC framework and it was also designed for this request response pattern So it doesn't handle very well asynchronous connections such as for example Sorry, I I lost the word Not web hooks Yeah, anyway asynchronous connections. So this is a synchronous framework basically and for example database access is synchronous and there is no way to to change that currently so that's Huge blocker. So we cannot have subscriptions because of that by default, but there is a solution called Django channels, which wraps entire Django application with additional layer that is able to process async requests and This is still pretty new thing. It's not so common to use. So not many people use that actually and Yeah, so technically it would be possible to have subscriptions with Django We haven't tried that because we yet haven't like used case for subscriptions in our application, but That's how it looks like currently in Django and graphene Yeah, so this is Database sync to async is kind of one of the tools you have to use with Django channels to have access to the database So so this is kind of possible, but it's also a third-party library. It's something unusual So, yeah, it's kind of problematic in Django to support subscriptions currently So this brings us to the fourth lesson That we've learned that if you are building fully fledged api in Graphene and Django, you need a bunch of additional libraries So for example, I said before that we support json web tokens For authentication and that's true, but it's not provided by graphene By default you need additional library for that Also to have permissions management based on json web tokens. You also need like it's the same library basically Which is fine because you can have this feature But there is always a risk with using third-party libraries because you will never know if they will be maintained because very often they are maintained by one person and or very small team and Yeah, it was problem for us a few times already that we have to be dependent on some kind of library that it's not supported The same is for apollo federation It's also not built into graphene by default, but there is one library that can give give you this this feature Also file upload, I know that file upload is kind of There is no agreement on how to do that. Well in in graphql. There are a few patterns For us we wanted to have the basic file upload through a mutation and It is possible to do that through multi-part requests in in graphql But again to support that you need another small third-party library in in your stack to to have this feature Some features are actually not implemented at all So for example query cost analysis, which is A feature available in apollo server for example, but in graphene. It's it's not not available yet And there are some open issues about that And and actually i'm not sure what's what's the state of those issues And that would be pretty useful in our case because you can use our api in the like headless solution So we need to support query cost analysis at some point and probably we will have to build support for that ourselves So, uh, these are like the four lessons that that i've prepared There would be much more stuff, but I think these are the most important ones So you've seen that there are some benefits of graphene, but there are also some downsides. So you may be wondering Why do you guys use python? Because there are some some really well solutions on the market such as apollo server, which is probably one of the best graphql servers out there um So why don't you just migrate to apollo server since you've had to migrate your entire architecture? Yeah, that's a really good question and we've been asking this question ourselves And the answer is pretty simple for us So the answer is that we are huge fans of python and basically we decided to invest more time in this, uh language and graphql support in this language and that's why we started using graphene and now we are actually developing our own framework um Yeah, and what I want to show here is also how the modern python looks like. So for example, um, this is python 2.8 so the In this version, you know, uh, so you have async await Support in python so you can do all of the asynchronous stuff right now So it wasn't available when when jango was created, for example, but now it's it's totally doable so we believe that python is is growing and Actually, there are proofs that python is growing because that's that's how it looks like compared to other languages um Because of data science machine learning stuff where python is very popular and also web development python is growing really strong Nowadays, so this makes us believe believe that it's really worth investing time in in developing developing solutions for for graphql in python so, uh Last thing that I want to show you is uh, ariadne So this is our own server for graphql that was inspired by apollo server Is a schema first framework and it has all the async features plus subscriptions It's it's still Quite early for that framework like early days because for example, there is There is only very basic integrations with jango So probably adding support for that is on our roadmap But you can use that already to build for example federations and we use that as well and Yeah, it's it's really cool Framework and we want to invest a lot of time in this so We believe that it's really worth to do in in the python uh community So that's that's all I have. Um Thanks for listening. Uh I'll be happy to answer any questions if if you if you want to know more about uh about this Um Thanks. Thanks so much martin. It was incredible incredible talk a I really liked how do you have to describe a lot of like different features about rough go with python And that's great because I do know There are not so many people that they can touch different topics In the api architecture and a like give that information to to to to us to all of us So that's that's great and thank thank you so much. So, um, we don't have a question in judo so three Sorry for the names like if I can if I can a person like correct me street ready He is asking about He has two questions or one is a how we can handle file Our bloods via graph code in jango that I think that you have Uh discuss a bit about it. But then he also has another question, which is uh, that he's using the jungle graph kill gwt for authentication How he can use the same gwt for normal jungle views of the integration I'm not sure if I I totally you can totally understand the question, but I You can give a like a general overview about your experience with file our bloods and dwt authentication So, uh, okay, let me So there is basically one library, uh for, uh file upload in Graphene, which I need to check, uh, out the name because I don't remember now It's called Probably Okay, I don't have it right now, but um If you google graphene file upload Uh, there is one library. Uh, yeah, it's basically called graphene file upload and What it does it it defines, uh, one mutation which you can use to upload files it also provides the GraphQL type Which is called upload and you can use that, uh to represent your files It's a little bit complicated to test because, uh, you need to build this multi-part request somehow And it's hard to do in Tools for like it's not possible to test in playground. For example, unfortunately um, uh, I think you can use insomnia or postman to test that or, uh You can do that in in the in the shell in console if you like but Probably people use insomnia or something like that and there you can test those multi-part requests If can I share the link somewhere here? Yeah, sure. Yeah, you might feel free to share it in youtube and also if you want to in twitter But yeah, I also zoom here. Yeah, so Because I'm not on youtube. I'm only here on zoom Yeah, I can send it so so that's the library and There are also examples of how to actually build this Sorry not in this repository, but okay, so I'll post another link Which is graphql multi-part request specification and This is a specification of how the Multi-part request should should look like Um, yeah, so so that's the problem. Yeah, like, uh, it's it's not so easy to use But it works for us for example, uh in our dashboard applications We have upload of product images and that works perfectly well The other approach of of handling Um file uploads is uploading directly to your storage for example, uh amazon s s3 So you you are not doing this through your api through your graphql api, but in some other way That that's the other approach that I know, but we haven't used that Uh in our project yet And there was also second question about json web tokens, but um I don't remember exactly what was it about But I can quickly share just one more link. Um for, uh for a library And this again if you use this, uh, it gives you access to few mutations like token create for example Uh, which creates a token based on credentials that we provided. Uh, there are also mutations to refresh the token. Um So here's the link Um And yeah, we we use use just this this library for that Awesome. Yeah, that's that sounds great. So like really good a Uh resources so I send all the links to youtube So you might link later with that person that he asked you the question And I don't know you can just have a quick chat about a python graph in a graphql, which is great. So Um, yeah, marcin. Thanks. Thanks so much for joining us from all of us at poland and a Yeah, I'm looking forward to to to knowing more about what you are doing in the community Like even talks like what you are guys are doing with eternal libraries in Solvers of that that looks super promising. So I hopefully hopefully we're gonna know Uh soon more stuff about that about that. So thanks so much for joining Okay