Submind YouTube summaries
Thumbnail for How to best package your library? - Bernát Gábor - PyLondinium19

How to best package your library? - Bernát Gábor - PyLondinium19

Watch on YouTube

Video summary

The video features Bernát Gábor, a senior software engineer at Bloomberg and a member of the Python Packaging Authority, discussing best practices for packaging Python libraries. He explains that the primary goal of packaging is to make a library developed on one machine available for installation on another by transferring both the business logic code and essential metadata into the user's site-packages folder. To achieve this, developers typically create either source distributions or wheel files. Source distributions contain all project files including tests, allowing users to build the package locally if necessary, whereas wheels are pre-compiled binary files that can be installed directly without requiring a local build process. Wheels are generally preferred because they simplify the installation on the user's machine, provided that the target platform is known and compatible with the compiled extensions. A significant portion of the talk addresses the historical evolution of packaging tools and the shift toward reproducible builds to avoid dependency conflicts. Gábor highlights the transition from the flexible but error-prone `setup.py` script to more modern standards like PEP 517 and PEP 518, which allow for declarative build environments. He argues that relying on legacy `setup.py` scripts often leads to cryptic errors when users lack specific versions of build tools or dependencies. To solve this, the community is moving toward using front-end tools like Poetry or pip-tools alongside back-end builders that guarantee a consistent environment during the wheel generation process. This separation ensures that the build happens with the exact dependencies required, eliminating the need for users to manually install obscure build utilities just to get a package working. The speaker also touches upon security considerations and practical advice for corporate environments. Regarding security, he notes that while PyPI performs some inspections, it does not execute code from packages; however, Python 3.8 introduced an API that allows developers to inspect what a library actually runs before importing it. For organizations looking to manage their own distribution, Gábor recommends setting up an internal pip server rather than relying solely on the public PyPI or direct git submodule pulls. An internal server offers better control over versions, caching capabilities to speed up downloads, and improved communication protocols compared to pulling directly from external sources. Ultimately, he advocates for adopting modern packaging standards that declare dependencies explicitly, ensuring that libraries install correctly across different machines without requiring users to troubleshoot complex build environments.
Read the full video transcript
welcome back down to the ground floor hope you're enjoying your day so far and need to keep the time so quick introduction of burner number another senior engineer here at Bloomberg this time from our data technologies department helping all of our global data analysts get data onto the system as quickly and efficiently as possible he's big-time contributor to tox and various other packaging tools so he's gonna take an opportunity here today to talk to us about how best to package our libraries thank you thank you very much so yeah earlier about how you install some packages this talk will gonna be more about how do you get to that phase where you can actually install stuff and hopefully also understand what actually happens under the hood when you actually say to people whatever other tool you're saying okay install this package okay so the sake the has a lot of let's say not the nicest things so I brought a few nice puppies to cheer you up a wee bit so yeah just who am i yes I said I work at Bloomberg our senior software engineer I'm also the maintaining of the virtual I'm stool which makes me a member of the Python packaging authority and the maintainer of the talk stool so hopefully I should have a good picture of what I'm actually talking about thank you so yeah this is gonna be again as similar to lasso about the point of view of the Python package of authority meaning that will not talk about these lovely technologies such as Conda or your favorite operating system package manager which is the package or yama or whatever as Packman you're actually using but in order for me to tell my story I actually need some example project so I brought this lovely little project this is how let's say a basic Python library kind of like works nowadays it basically has some kind of logic whatever you want to implement it after the logic you write some tests cuz you don't know it actually does what you want before you write some tests and then you have some packaging information these are just does okay this is kind of how I want you to package stuff and then some additional files which are basic just maintain yours therefore your CI information or your git repository and all that kind of stuff okay so this little library this in the question is the the only thing it does it tells you lovely quote from the point of view of the elaborate parks like in this question it tells you that the lighted Park knows how to make the best of whatever he has to work with so let's try to make the best of whatever we have to work it in the Python packaging so the question is how do we make if I have a right project how do I make it available for someone else running on a totally different machine on the other side of dirt now the way we do is basically when I say make it available I want them to type in this import box I think discuss the library and I run them to be able to do the same thing I'm able to do on my machine and in this case it's basically just calling that code generator okay so whenever someone I actually type in this import box if I actually look at the representation of these bugs module you see that it actually is a representation of a file on the file system somewhere now this file system is something that's called by the side packages Python you sure doesn't really know if a package is available or not it the way it actually finds out it actually tries to do it it's in kind of like a monitor of the Python try first as forgiveness later it just tries to import it and if it manages to import it it will give it back to you that package now the way it does this it actually has a few package loaders registered and this package loaders have some configurations on it and one of these configuration is the suspect and the suspect basically just tells your location where the file system loader will actually try to look for existing packages or not okay so going from this the way we actually can what it means for us to make it available to rather developer another machine it'll basically we have to put it to other that other machine side packages somehow okay and this is basically the goal of the Python packaging how do we take something from my developer source tree packaged it up ship it up to some cloud from where some other people can actually pull down the package and install it into their side packages folder okay so you can see a few tools which like you probably used it if you doing this by the set up to assist have usually packaged stuff then we use the twine to actually go to the PI API which is live it is shop inside Python and then we use peat mostly both to download and install into the assigned packages and discover this kind of additional packages that the user might want to use now so if you actually look into the side packages folder you will see that inside the side packages first we have two things one of the things that we have the actual package files this is like my business logic with some additional compiled file generated there but more importantly we also have some additional metadata okay so when we talk about we want to install a package we want these two things we want to pull in the business logic and we want to pull in also the additional metadata into that folder in their side packages folder so the question is how do we generate this ok now the way we have two options here one of the options is we make available our library as a storage distribution or we make it available as a video distributions and there are some differences between these so what is the source or distribution so so distribution basically is whatever you have in your working directory - the project management file and the maintain your files these are like the CI files your actual git repository that kind of thing okay and still has all the business logic the packaging and the test okay now basically if you take in this project we receive just remove this special information but kept everything else which allows the user to both still actually do our packaging and the reason why we should always also package tests is that whenever the user of the packaging he needs something to validate that the packaging succeeded that's why you should always include your testing your distribution okay it's a validation for the people on the other side actually then try to do the packet the more installation packaging so a will is basically you no longer care about the test the only thing you actually care is about Billy CLE your binary files your business logic okay we're basically it one on one taking just this information like the actual business logic and in the fastings actually whatever actually gets put in its present their insider system side package okay now if you look for the read how do we actually ship or generate a storage solution the way we actually do this is basically like this we first start with developer store three we collect some files from the file system we package it up inside for example like zip it in a file we package it up passive to the pipe I and then the other side how the installation actually now has to work is that the total solution gets pulled down you extract it to a folder you generate those metadata but our metadata is also like for example we saw in the real case you had this additional information about the package plus pulled basically the business logic and put it copy it over to the user machine side package folder okay so this is what you want to end up in the end everything the metadata and the other file now how do you how do you actually ship a will compare to this in case of the wheel the only difference is that now all these building operations generating this metadata and selecting the business logic happens on the user machine ok the user machine meaning that here on the developers or three I directly generate exactly that information that what I want so at this point whenever I get the user machine I literally has to wear it basically I just have to extract whatever I get in that wheel and just copy it over to the site package of the user now you can already see that this means that the operation that we perform in this case on the user machine is very simple it's a lot less that can go over drunk and that's why this is kind like the preferred way how you should do it the body are cases when you this is not not going to be possible I'm going to see later so how do we generate the wheel as I say just generated is generated by C files and this is the reason this for blood point is the reason why it might not be always possible if you actually have C extensions in this case you actually have to know the target platform to be able to generate the binary files and in this case you might not have access to all the platforms that you want to ship to your users so if you are having the C extensions you always most likely will try to shape a few wheels which is the most important main platforms and leave the soul discipline bare as anyone else who doesn't have your main platform to actually fall back and generate their own installation packages okay now this is where the Python packaging Authority and the Condor differs condo sales peeps a that we are not responsible for actually providing you the C++ tool change at least up-to-date maybe this will change in the future what kinda actually takes up and himself to actually also if this build operation is like a compiler actually provide that compiler or actually provide even more dependencies library's header files orders of cooling basically the approach of that the moment of the Python package culture it is that it's up to the user to provide it okay so now there's an initial constraint right for example you actually have to generate wheels in this format widget based specified that from the file name an installer should already know if that is compatible with my platform or not this is just a technicality detail for required using the life for the packages so let's see what you actually need to make this actually this operation happen correctly on the user machine you see that to in order to select a copy files you require if you use setup tools or your packaging you care the correct version of the setup tools if you to generate the metadata you need the wheels package which is on the pipe I this is what actually knows what format to generate this metadata files that you have to put into side packages it also knows what kind of fighting you're targeting because for example it might need to know how to generate any kind of paisa files and also you have the other information like you need to know the art actually actual F C C++ first that you actually compile again tit but more importantly you require that in any case in order for this operation to succeed you need to provide correct setup tools and build version now the way historically worked what actually and the reason why did sees me that is for example that if you're using the feature of setup tools that was added in a new version if you try to run it with an older version basically it's undefined if what's going to happen because you using new features which are not available there so it might work it might not work if it doesn't work if actually if they actually work it actually worked and it doesn't work then you're not sure if actually succeeded or just have them to succeed and you have late and box into your software so it's important that whenever you actually perform this installation you generate your dis build exactly with the right versions of both your packaging ecosystem meaning in this case setup tools or ways that we're using in this example project okay so short history packages have the actual Python packaging ecosystem developed so it all starts basically back in 2000 when it was enough project started to get shared rounded people were like in the core system that maybe we should have some kind of way of defining how we actually package stuff and when you're just starting out and you don't know how you actually and what you what you actually need what's the best way to wing you just basically it seems a great idea that for now we're not standardized what we actually can do we'll just give you basically a script file where you can specify what you want to do and this is how it this could you started out the interview the setup I hear you they provided a core framework of what packaging gives but you could write anything at the setup dot file this mean that you could easily iterate extended base iteration and adapt it to what exactly you needed now set up tools the disabuse was kind of like baking the sea Python which means that it had a long turnaround like if you needed a new feature it took a while to get it out but in 2004 set up to squared around and add a lot of sugar syntax on top of discourteous and made it just a lot nicer to use it be quickly been adopted and it became so much de-facto standard that people I started assuming that it was already there and that's why if you go to the secular Florence you have some packaging issues you can see so the first step is to OB your setup tools if something doesn't work but in 2008 we had people to suppress it installed then we had in 2014 wheels this is very worked the first approach was they saw this problem of not having the correct set up with versus maybe let's not require the set of tools and the user machine we just build exactly what was needed there but even as I said this doesn't necessarily cause maybe you have C extension that kind of stuff is required still to me build in that gives you these are still kind of like assume that you know what order your bill dependencies or the dependent versions of your blender tools okay now one thing is that set up tools and we will still use the set up that pipe which basically allows you to run arbitrary code which is great for flexibility it's horrible to actually use the ability because whatever people who are less experienced coming to the ecosystem and they start writing random Python code into the setup file is basically the great recipe to actually mess up things and people start complaining it's not good so fleet in 2015 while the initially introduced it's kind of like the first attempt to have a decorative or dynamic build system and it uses the PI project on text should define what are your dependencies and this kind of like seemed to work so this is where we actually because it was easier to understand and was order harder to get wrong we try to see how we can move more into this direction having how we can allow the ecosystem to actually have builder tools which are nicer interface than what setup tools usually has okay so how does a build work well a build in the previous aim where I see the actual typical details is that you basically call this set up by eldest and then you are plotted by using the set up by upload which with the bracket deprecated concerned out there is no safe way to actually make this work and HTTP so instead we created a separate tool called twine which is kind of like guaranteed to do it over a safe network protocol and whenever you basically do a pip install what actually happens in the background that peep goes to the pipe I discovers that package pulls it down and after it develop these tracks it it basically calls the setup I install command which basically then use the setup tools to actually generate and copy over the forest into that target that side packages folder okay so now the thing is in this case what happens if the user doesn't have the correct versions of setup to resolve Revere's what actually happens is if we basically end up with this cryptic errors that the Installer starts complaining that I don't have this no module name sleep item build you can see this is kind of like error message targeted at the programmer we actually knows what is an important how what is using this definitely is not a message for the front end user to what is wrong so how we can solve this one so the way we can actually solve this problem and the way we desert it okay maybe let's have a decorative way to define our built environment dependent heat instead of just assuming that the user machine knows what kind of set of tools or wheels we actually need or other or other kind of dual dependently we should allow them ship them tell them exactly this is what this package needs to be able to build okay so what happens in this case what would happen this can virtually we can create a virtual environment if the user machine knows our dependencies we can actually exactly in store that will depend s internet environment and then we basically call this generation of the wheel by using this is a little built environment and this allows us that we always can guarantee that on the user side machine we exactly run with the same versions as we run as we are required in the production now this is what per five on eight is about it's about allowing you to specify exactly what kind of packages you want for the built to perform correctly and if uses the PI project that Tom and Tom mainly cuz we did not have any other better alternatives and yes yam was not considered a better alternative neither Innes so moving on from this basically at this point you see that now we have actually have two jobs we have to do one of the jobs like in this side you can see that now we instead of just actually running the build operation and copying we have two one these we actually first have to generate this easily to build environment and then we have to generate the actual wheel and then install it now the question is who will actually do this kind of is related build generation and the decision has been made that this should not be the actual build I can't and the bill back NT in this case is like set up to fill through poetry instead people will be the one responsible who actually do this operation and people actually consider the build front-end meaning it will not do any build operations but it will provision the environment for the backend to do its job and it will guarantee that that the dependency declaration specified for that back-end or met when its current okay so yay we have one we no longer have this awkward errors that the user will say that hey the installation is Nestor should sit on my machine but there's another problem here if you see in our operation we're still calling basically set up that pi okay so this meant like in case of fleet do have a fleet actually managed to work is that they had to basically derive everything back to the setup PI and the set of tools ecosystem cuz that's the only good thing that people actually understands to call and we have now another standard which basically is pair five on seventeen and this defines okay let's throw away the setup by legacy which is kind of like release there from all the voltages which allows the user to run arbitrary code but instead we should be able to just generate the wheels by having a proper API and this is the API we came up with basically you can actually see the same PI project on file you can actually specify this is my back-end and this is its builder API endpoint which you can actually use so you can see in this case now we actually have some programmatic API and the other advantages of this is that now we can actually have really nice way of calling it from applications which hopefully means that the front-end has a better communication protocol to talk with the backend rather than using basically textual now we actually have more pythonic way of speaking with things so this various back and start adopting this kind of new way of interfaces and set up to provide it from 40.8 flip provides it basically where the early ages and poetry is another builder that provides it for a long time already now and we have also have front-end supports like people 19 already comes with a five on seven so if you have people 19 on your system you literally can use any of these backends you no longer need to set up tools and your bills will or guarantee that never will be having a bad build dependencies unless you specify this wrongly so and toxic another tool or like a front-end which actually does this there are a few caveat though so one thing is our pair five or seven eight of five one eight so the two perhaps did not really address editable instance this was kind of like well initially the powerful design was like this draws a lot of country a lot of non agreement let's just drop the subject and let's not focus on this this is something that hopefully will manage to address in the next year meaning that you can actually use editable in stores cue in the future it requires a fairly new peep which may be a problem array now do you P problem for you it requires happily it only requires a new peep only on developer machine if you actually be sued as a will but if you actually have a dis restores it would acquire the new people only on the user side machine ok so there is a big build comment press called the question is because ok so how do I now because my real stress contributions to upload to pi PI there is a ppl comment hoped slash planned if anyone willing to implement it but in the meantime you actually can use the peph five on several library directly this is basically something you can just install and this actually has an interface to generate binaries or generate source solutions with this single comment and this is what you should prefer using going ahead okay now the benefit that we have reproducible decorative builds no more need for setup by well at least that once we have editable instance ironed out and it should be a lot less simpler now there's one caveat for talks talks at the moment if using it in your CI it doesn't actually enable it by default this is mostly for backward compatibility reasons so you should actually have to specify by using this lovely flag - you want this is related build environment and more importantly going ahead we have this to pepper on 8 + 5 & 7 which ensure that you no longer have all setup we know are going to use this at all legacy set up that PI and we also ensure that we have declare a represents the environment and this should make us a happier hopefully every one of us and in future if you want to build google source solutions please check out this lovely backends you don't have to set up to set up which is very powerful but you it's not the only option you have poetry which may be more simple and much harder to get it wrong and consider setup tools especially in these setup that by format more like something that only ended when you have are something complicated something advantage but not for simple use cases and use the lovely per file 170 library to actually build your source solutions and we this should mean that you have a lot less errors even if you change machines it will automatically pull in all the correct dependencies for the build to succeed correctly so if I talk with anyway you look got lost I have this article blog article which I've wrote it's basically explain this in much more long hoarded and much more in detail and yeah I'll take some questions now Thank You panel will make sure that gets onto the attendees chat on slack if anyone needs a invite slack let me know have we got any questions for Bona before we break for lunch oh right in the corners you just want to see me run yeah thank you for the talk I had one question is there any layer of security or do you all pip install packages in our own risk as in between us uploading packages to PI and then pulling them back down there is a security letter on the pi PI itself like pi PI does some inspections you don't should expect like actual checking what get imported what gets run now the Python 3.8 does have a security API which means that you can actually inspect whatever is running on your application so kind of like you can do some evaluation I mean so that's something that you should look on if you actually want to check what running that library would do to you but otherwise there's only or is like pi PI does have like if they detect anything is done in something horrible they'll remove the package but that's more like if you have to report it and flag it as being a bad package okay I think we've got time for one more question yeah and thanks we talked just in terms of do you have any insights to share any tips kind of running this system let's say in production or in like a practical point of view would you have an internal PIP server or get sub-module well kind of best ways to get it from the history to let's say let's rather than distributing it to the world it may be a controlled manner for organizations or corporates that kind of thing I think we're running it from like like pulling directly the get models I would not say it's horrible it kind of like works the problem is you don't have a way to like easily change it and you like pulling it into version control and you don't need it I generally definitely recommend having some kind of piper server run it locally on your company's machine something that already take care of lot more features for example it automatically allows you to cache whatever you're downloading that kind of stuff because if you're pulling from get every time it's going to be even the pulling down is going to take a lot of operations while if using the pi PI server in its protocol it allows for various improvements over each communication with people cool thank you very much better [Applause] you