1 00:00:12,502 --> 00:00:17,360 >> Hello, welcome back to Curlyboi Theatre for our last talk of the day.  2 00:00:18,320 --> 00:00:23,840 Um, because this is our last talk of the day, please remember that the conference  3 00:00:23,840 --> 00:00:28,000 closing will be in this room, where we are right now, after this talk. They'll  4 00:00:28,000 --> 00:00:35,760 be a very short break in between, stick around to hear from our lovely conference organizers. 5 00:00:36,720 --> 00:00:45,840 Okay. So, we have, for us all today, Sebastian Witowski to talk about Python Versions and  6 00:00:45,840 --> 00:00:52,960 Dependencies Made Easy, if I get the title correct. Sebastian is a consultant in Poland.  7 00:00:56,960 --> 00:01:02,560 He fell in love with Python and teaching and is helping companies untangle their complicated  8 00:01:02,560 --> 00:01:07,680 architecture and build all sorts of interesting Python projects. So, if there is time at the end,  9 00:01:07,680 --> 00:01:14,000 Sebastian will be taking questions so please put your questions in the question tab in Venueless.  10 00:01:14,000 --> 00:01:19,120 You should all know where it is by now, hopefully, if not, ask away. And I'll ask  11 00:01:19,120 --> 00:01:24,560 Sebastian at the end. Over to you, Sebastian. SEBASTIAN WITOWSKI: Cool. Thank you so much. Hi,  12 00:01:24,560 --> 00:01:36,560 everyone. My name is Sebastian Witowski. I join different teams and work on different projects.  13 00:01:37,280 --> 00:01:42,800 And as I work on those different projects, I notice they often suffer from one of two problems.  14 00:01:43,920 --> 00:01:51,680 They're overengineered or stacked in the 90s. The overengineered ones involve jumping on every  15 00:01:51,680 --> 00:01:55,200 shiny, new tool that you find on the first page of Hacker News  16 00:01:56,080 --> 00:02:02,000 and then everyone gets excited because it's fun to work with something brand new. What is not fun is  17 00:02:02,000 --> 00:02:08,640 when your tool gets deprecated. Maybe the creator gets bored and stops working on it. You have to  18 00:02:10,000 --> 00:02:21,360 keep it up to date yourself or do it yourself. Some people think because it was fun to manage  19 00:02:21,360 --> 00:02:33,520 everything using bar scripts, but to be honest, when was the last time you wrote one?  20 00:02:34,880 --> 00:02:39,440 Writing them from scratch is not that bad. Maintaining a bar script that someone else  21 00:02:39,440 --> 00:02:55,840 wrote is not great. So, neither of the situations is good. You should update your tools but at the  22 00:02:55,840 --> 00:03:01,120 same time, you should choose those tools that you know that they are proven and they will be  23 00:03:01,120 --> 00:03:06,880 supported for the next few years. So that's why I've decided to make this presentation. I want  24 00:03:06,880 --> 00:03:12,880 to show you some useful Python tools, tools that I recommend to my colleagues and to my clients. 25 00:03:14,320 --> 00:03:21,680 We'll talk about things that a lot of beginner programmers struggle with at some point. First,  26 00:03:21,680 --> 00:03:28,160 I will show you how to install different Python versions and how to manage them using pyenv.  27 00:03:29,520 --> 00:03:34,800 Next, I will talk about Python dependency and I will explain you what are virtual environments,  28 00:03:34,800 --> 00:03:38,720 how they work and why you need them if you work with multiple Python projects.  29 00:03:39,440 --> 00:03:49,040 I'll compare the built in module, like Virtual and Wrapper. We will talk about pipx,  30 00:03:49,600 --> 00:03:53,680 this is a great tool if you want to install some Python package globally,  31 00:03:53,680 --> 00:03:57,040 but you still want to isolate it from other packages on your computer. 32 00:03:59,120 --> 00:04:04,000 And before we move on, I really want to highlight one thing, those are all just  33 00:04:04,000 --> 00:04:09,200 tools and there are a lot of other tools that do the same thing. If you use something else,  34 00:04:09,200 --> 00:04:16,240 that's great. My goal, here, is not to convince you that those tools are the best. No. I just  35 00:04:16,240 --> 00:04:21,280 want to show you how to solve some basic problems when you configure your development environment.  36 00:04:22,160 --> 00:04:28,560 If you are using conda and you are happy with it, the first two bullet points are  37 00:04:28,560 --> 00:04:35,680 already solved for you. But if you don't know what to use, let me show you some recommendations.  38 00:04:37,520 --> 00:04:42,000 So, first let's talk about installing Python on your computer. 39 00:04:42,000 --> 00:04:46,800 Depending on your operating system, your computer might already come with some version of Python  40 00:04:46,800 --> 00:04:58,960 installed. If you're using Mac OS, it is 2.7. In windows, you don't have any Python installed.  41 00:05:00,960 --> 00:05:04,320 Let's say that your operating system comes with some Python version,  42 00:05:04,320 --> 00:05:09,840 this Python version that is already installed on your computer is often called System Python.  43 00:05:11,920 --> 00:05:18,240 No matter what system version of Python you have, I strongly suggest you don't use it. In  44 00:05:18,240 --> 00:05:27,120 many cases, as we saw with Mac OS, it's outdated. 2.7 is not supported by the core developers so  45 00:05:27,120 --> 00:05:34,640 hopefully you are not using it since a long time. You might be tempted to update the system Python  46 00:05:34,640 --> 00:05:41,760 to Python 3, but you probably have some programs that require Python 2.7. You would be surprised  47 00:05:41,760 --> 00:05:47,520 how many programs, or even parts of the operator system still requires Python 2.7  48 00:05:48,480 --> 00:05:59,920 in Mac OS. If you change the Python version that comes pre installed, you risk your computer will  49 00:05:59,920 --> 00:06:06,640 stop working at all and that is not fun. I have done this in the past, when I didn't know much  50 00:06:06,640 --> 00:06:11,200 about programming and operating systems and I had to re install the whole operating system.  51 00:06:12,480 --> 00:06:21,040 My advice is to leave it alone and pretend that it doesn't exist. No matter what operating system you  52 00:06:21,040 --> 00:06:25,920 have, you will need to install Python and there are many different ways how you can do this. 53 00:06:27,120 --> 00:06:31,760 You can download the installer for your operating system.  54 00:06:32,880 --> 00:06:41,360 You can use a package manager like Home brew on Mac and compile Python from the source files.  55 00:06:43,680 --> 00:06:48,880 However, my favorite way of installing Python, that I have been using since a few years,  56 00:06:48,880 --> 00:06:58,240 is to use a tool called pyenv. It managing Python versions. You can install a Python version on  57 00:06:58,240 --> 00:07:03,520 your computer and quickly switch between those versions you have already installed.  58 00:07:04,480 --> 00:07:09,440 It might not be a big deal if you only use one Python version at the time. But  59 00:07:09,440 --> 00:07:14,800 if you're working with multiple Python projects that require different Python versions, this is  60 00:07:14,800 --> 00:07:25,920 extremely useful. I try to use the latest version with Python. But my clients don't usually use the  61 00:07:25,920 --> 00:07:32,240 latest version of Python. I've been using pyenv for years and it works very well. If you have  62 00:07:32,240 --> 00:07:42,560 worked with you might recognize similar tools, for example, there is Ruby and Node JS. Pyenv  63 00:07:46,480 --> 00:07:57,040 will work fine on Mac OS and Linux, check out the pyenv win. It might not have all the  64 00:07:57,040 --> 00:08:02,080 features that the standard pyenv has, but it has all the essential ones that I will talk about. 65 00:08:03,040 --> 00:08:10,480 But then again, if you are Windows and you are a happy conda user, there's actually no point  66 00:08:10,480 --> 00:08:16,320 in switching to use pyenv. One of the things conda can do is creator virtual environments.  67 00:08:30,560 --> 00:08:36,720 You can use pyenv with Home brew and use the tool called pyenv Installer. And, while this last  68 00:08:36,720 --> 00:08:41,440 option requires you to download a bar script from the internet and run it in a terminal which is a  69 00:08:41,440 --> 00:08:50,320 big security no no, it's actually very convenient. It will install some additional plugins like  70 00:08:50,320 --> 00:08:55,280 pyenv doctor that you can use to verify that your pyenv installation is working fine. 71 00:08:57,360 --> 00:09:01,760 So, once you have pyenv installed, you can use it to install new Python version.  72 00:09:01,760 --> 00:09:07,840 To see the list of all the available Python versions, you can run pyenvinstall list  73 00:09:08,880 --> 00:09:15,040 and you will see a huge list of Python available installations. We have the standard Python  74 00:09:15,040 --> 00:09:24,080 versions. Apart from that, we have Anaconda, and so on. All those different versions of Python  75 00:09:24,080 --> 00:09:29,680 can be installed with pyenv. If you ever wanted to try PyPI, now you can very easily do this. 76 00:09:31,840 --> 00:09:37,520 Once you select the version from this list, type "pyenvinstall" and the version number and  77 00:09:37,520 --> 00:09:42,240 go make yourself a coffee. I mean it. The installation usually takes a few minutes.  78 00:09:43,360 --> 00:09:53,120 There is OpenSSL that you can use. If you don't have those libraries installed, each time you  79 00:09:53,120 --> 00:09:59,200 try to download a new Python version, pyenv will try to download it and temporarily use it  80 00:09:59,200 --> 00:10:05,440 so I suggest you take a look at the GitHub page for the list of the required dependencies. 81 00:10:07,200 --> 00:10:13,760 Okay. So, once this is done, you can run pyenv versions to see if this new version is on this  82 00:10:13,760 --> 00:10:21,280 list. If you can see it there, then it means that you're all set. So, now we have to tell  83 00:10:21,280 --> 00:10:27,840 pyenv to use that version. And for that, we have to choose one of three different levels at which  84 00:10:27,840 --> 00:10:35,040 we can change the Python version. We have global, local or shell. So, what does it mean? Well,  85 00:10:36,080 --> 00:10:42,800 9 out of 10 times, you probably want to change the global Python version and to do that, you just run  86 00:10:42,800 --> 00:10:49,200 "pyenv global 3.9.0" and that changes the global Python version on your computer. 87 00:10:51,040 --> 00:10:58,480 Then we have pyenv local. So, imagine that most of the time you are working with Python 3.9, but  88 00:10:58,480 --> 00:11:04,640 you have this one project on your computer that requires Python 3.7 and for some strange reason,  89 00:11:04,640 --> 00:11:11,280 it won't work with any other Python version. So, instead of changing the global Python version  90 00:11:11,280 --> 00:11:17,520 to 3.7 when you work on this project and then changing it back to 3.9 when you stop working on  91 00:11:17,520 --> 00:11:24,400 this project you can set a local Python version. And that's where the pyenv local command comes in.  92 00:11:25,200 --> 00:11:34,160 You can run pyenv local 3.7 or 3.9 and will set that version for the current folder and  93 00:11:34,160 --> 00:11:41,040 all its subfolders. So, whenever you go inside this folder, Python version will automatically  94 00:11:41,040 --> 00:11:46,400 change and when you go outside of this folder, it will change back to the global one. 95 00:11:48,640 --> 00:11:54,000 That's very handy when you work with multiple projects that use different Python versions. So,  96 00:11:54,000 --> 00:11:59,280 instead of changing the global Python version back and forth, you just have to run pyenv local  97 00:11:59,280 --> 00:12:06,720 in one folder, pyenv local in another folder and then pyenv will automatically change the version  98 00:12:06,720 --> 00:12:13,760 when you go inside each of those folders. And then finally, we have pyenv shell. And  99 00:12:13,760 --> 00:12:18,080 this changes the Python version you use in your current shell session. You might  100 00:12:18,080 --> 00:12:22,400 want to use it, for example, when you want to temporarily change the Python version.  101 00:12:24,000 --> 00:12:33,920 You want to run code under Python 2, you run pyenv shell 2.7.18 and you can use Python 2. But once  102 00:12:33,920 --> 00:12:38,720 you open a new session in your terminal, you go back to using the previous version of Python. 103 00:12:41,520 --> 00:12:44,800 So, that's how we can easily manage Python versions on your computer.  104 00:12:45,360 --> 00:12:51,840 Let's talk about dependencies. Let's start with pypi. Pypi is a package manager for Python.  105 00:12:52,560 --> 00:12:58,000 Whenever you want to install a new package, all you need to do is to run pip install, the name  106 00:12:58,000 --> 00:13:04,560 of the package, and it's running. However, pypi has one big problem. Whenever you ask  107 00:13:04,560 --> 00:13:11,680 it to install a specific version of a package, it will uninstall the previous versions and install  108 00:13:11,680 --> 00:13:17,680 the one that you asked for. Let me show you an example of what I mean. Imagine you are a web  109 00:13:17,680 --> 00:13:27,040 developer and you want to build a Django website, you install the latest version of Django and pypi.  110 00:13:28,720 --> 00:13:37,360 Everything works great. You build an awesome website and the website is so awesome and they ask  111 00:13:37,360 --> 00:13:46,800 you, hey, you're making awesome Django websites so can you fix my Django website? As it often  112 00:13:46,800 --> 00:13:52,240 happens with clients, they are not using Django 3, they are still using, let's say, Django 2.2. 113 00:13:54,160 --> 00:13:58,560 So, you install that specific version by typing "pypi install Django"  114 00:14:00,640 --> 00:14:10,480 and you start working on this website for your client. So far, so good. But, later that day,  115 00:14:10,480 --> 00:14:19,120 you discover that your personal website, so this one, built with Django 3, has a bug. When  116 00:14:19,120 --> 00:14:24,480 you want to test it and make sure that it is working fine, you get an error message saying  117 00:14:24,480 --> 00:14:30,560 "Django 3 is not installed." Like, what? I mean, we installed it yesterday, what happened with it?  118 00:14:31,360 --> 00:14:39,200 Well, when we told pypi to install Django 2.2, pypi first checked if we already have Django  119 00:14:39,200 --> 00:14:48,880 installed and we did, it's just it wasn't Django 2.2 so pypi uninstalled that version. So we just  120 00:14:48,880 --> 00:14:55,280 run into a problem with dependencies management. We have this problem because pypi installs Python  121 00:14:55,280 --> 00:15:02,160 packages inside the side packages folder and puts each package into a separate folder  122 00:15:02,160 --> 00:15:07,920 named after that package. So, Django 3 is placed inside side package/Django.  123 00:15:08,640 --> 00:15:16,960 But when we want to install Django 2, it will also be placed inside sidepackages/Django. So, pypi has  124 00:15:16,960 --> 00:15:22,960 to first remove what's inside this Django folder and then install a different version. If you only  125 00:15:22,960 --> 00:15:28,000 work with one Python project all the time, then you're probably not affected by this problem.  126 00:15:28,560 --> 00:15:34,400 But sooner or later, you will need to install different versions of the same package and you're  127 00:15:34,400 --> 00:15:39,840 going to run into issues with pypi uninstalling some dependencies of some other packages. 128 00:15:41,280 --> 00:15:47,520 The problem with pypi is that it installs all the packages in the same folder so  129 00:15:48,080 --> 00:15:55,040 how about we tell pypi to temporarily install packages into a separate folder and then we  130 00:15:55,040 --> 00:16:01,200 tell our Python interpreter to use packages from that folder? Well, that's exactly what virtual  131 00:16:01,200 --> 00:16:08,080 environment does. A virtual environment is a folder that contains a Python installation and  132 00:16:08,080 --> 00:16:14,160 any additional packages that you install. When you activate a virtual environment, two things happen.  133 00:16:15,280 --> 00:16:21,200 So, first, you tell pypi, hey, I want you to install any new Python package in that folder and  134 00:16:21,200 --> 00:16:26,080 you tell Python interpreter, hey, I want you to use Python and Python packages from that folder.  135 00:16:27,520 --> 00:16:37,200 If we try to install Python packages, pypi won't uninstall because it's no longer using the global  136 00:16:37,200 --> 00:16:42,160 site packages. It's using side packages from this specific virtual environment. 137 00:16:43,680 --> 00:16:48,560 So, how does it look in practice? Well, first we need to create a virtual environment.  138 00:16:48,560 --> 00:17:08,320 Python has a built in module called Venv. So, in my case, I'm creating a folder called ".venv"  139 00:17:12,800 --> 00:17:19,440 are both a common name used for folders with virtual environments so it makes it obvious that  140 00:17:19,440 --> 00:17:25,680 whenever you go into some Python project and you see this folder inside, there are things  141 00:17:25,680 --> 00:17:31,840 related to virtual environment. But, it also has another benefit. Some code editors, like PyCharm  142 00:17:32,960 --> 00:17:38,880 will recognize this as a virtual environment and automatically start using it on your project. 143 00:17:41,040 --> 00:17:45,840 So, we have created a virtual environment and now we have to activate it.  144 00:17:47,840 --> 00:17:53,440 We have a bin directory and then we have the activate script. Since this is a bar script,  145 00:17:53,440 --> 00:17:57,600 we have to run it with source command and of course, if you're using a different shell,  146 00:17:57,600 --> 00:18:02,960 there are different files that you can use. For Windows users, there is activate and so on. 147 00:18:05,600 --> 00:18:09,920 Once you activate it, you should see a difference in your terminal's prompt.  148 00:18:09,920 --> 00:18:12,960 It should not display the name of the current virtual environment  149 00:18:13,680 --> 00:18:18,160 so if you see something like this venv in parenthesis, that's great because it means  150 00:18:18,800 --> 00:18:25,600 a given virtual environment is now active. And, now we do everything that we would normally do.  151 00:18:27,440 --> 00:18:31,360 It we install it with pypi, it will be installed with this virtual environment  152 00:18:32,000 --> 00:18:37,440 and it will have access to the Python packages from this virtual environment.  153 00:18:39,360 --> 00:18:43,920 If you want to stop using the virtual environment, you have to run the deactivate command.  154 00:18:44,560 --> 00:18:49,920 When you call it, it will revert all the changes that the activate did. So,  155 00:18:49,920 --> 00:18:55,840 you will go back to using the global Python version and back to global pypi packages. 156 00:18:57,600 --> 00:19:02,800 So, a typical workflow using virtual environments involves creating one virtual environment for each  157 00:19:02,800 --> 00:19:08,080 of your projects. If you're working with two Django projects, you first create a table one  158 00:19:08,080 --> 00:19:15,200 virtual environment, you work on it. Then if you want to switch to another project,  159 00:19:15,200 --> 00:19:19,680 you create another virtual environment. You activate and you work on that project. 160 00:19:22,960 --> 00:19:32,640 Venv module is perfectly fine for managing virtual environments, but I want to show you another tool  161 00:19:32,640 --> 00:19:44,160 I have been using for a long time. It's called Virtualenvwrapper. You can install it with pypi  162 00:19:44,880 --> 00:19:50,400 and of course, it works on Linux and Mac and Windows users, you have to do something else.  163 00:19:50,960 --> 00:20:01,840 There is virtualenvwrapperwindows. If you're a happy conda user, you can stick to this. 164 00:20:02,720 --> 00:20:15,440 It stores all the virtual environments inside the .virtual env folder inside your home directory and  165 00:20:15,440 --> 00:20:23,920 it provides you with useful commands. You can create a new virtual environment by typing  166 00:20:23,920 --> 00:20:33,600 "mkvirtualenv." It's not creating the virtual environment in the folder.  167 00:20:38,400 --> 00:20:47,840 If you want to activate, you have to call "work on Django to app" and then it will figure out  168 00:20:47,840 --> 00:20:54,080 where is the activation script. You don't have to type the whole path to the activate script  169 00:20:54,080 --> 00:21:09,760 and figure out in which folder it's located. You can call "lsvirtualenv." Again, it's impossible to  170 00:21:09,760 --> 00:21:19,280 get this list because venv doesn't keep track. And virtualenvwrapper stores everything in the list.  171 00:21:21,360 --> 00:21:22,880 To remove, you run "rmvirtualenv" and the virtual environment. 172 00:21:22,880 --> 00:21:43,440 You are probably wondering which is better? Both are great. I use virtualenvwrapper because I don't  173 00:21:43,440 --> 00:21:52,000 want to type this whole thing where, of course, half of the time, I'm in, like, some subfolder  174 00:21:52,800 --> 00:21:58,880 and get an error that it doesn't exist so I have to figure out where the activation script is  175 00:21:58,880 --> 00:22:10,000 located. I like to say, "work on Django 2 up" and be done with it. I create a table virtual  176 00:22:10,000 --> 00:22:17,200 environments that connected to a project. I have a bunch of data science libraries.  177 00:22:24,240 --> 00:22:31,680 Virtualenvwrapper can create temporary virtual environment. It will make a virtual environment  178 00:22:35,120 --> 00:22:40,320 and when you deactivate it, it disappears. It's nice for testing some pypi packages. 179 00:22:43,760 --> 00:22:49,520 If you store virtual environments in the same folder, your code editor will pick it up and  180 00:22:49,520 --> 00:22:55,280 start using it automatically. When you delete this project, you also delete the virtual environment. 181 00:23:05,440 --> 00:23:07,840 All right. So, we have covered how to manage Python packages  182 00:23:08,560 --> 00:23:12,240 inside your projects, what about global Python packages on your computer?  183 00:23:19,040 --> 00:23:24,000 Some tools are much more convenient to use when you install them globally instead of  184 00:23:24,000 --> 00:23:36,000 installing them in a specific virtual environment. You want to use those tools  185 00:23:36,000 --> 00:23:40,080 across all your projects, or even before you create a table a project. For example,  186 00:23:40,800 --> 00:23:47,200 with virtualenvwrapper, we would create a virtual environment.  187 00:23:49,600 --> 00:23:56,080 But then again, if two different tools require two different versions of the same dependency, we have  188 00:23:56,080 --> 00:24:01,600 a problem. You install one tool and everything is fine, you install a second tool, it changes  189 00:24:04,640 --> 00:24:07,840 dependencies of the first tool and then the first tool stops working.  190 00:24:11,120 --> 00:24:16,000 We could install each of those tools inside a separate virtual environment,  191 00:24:16,000 --> 00:24:20,160 but this is a lot of hassle to use it like that. Each time, you'd have to activate,  192 00:24:21,600 --> 00:24:36,320 run it and deactivate. We can easily solve this problem with pipx. Pipx installs Python  193 00:24:36,320 --> 00:24:42,240 packages inside separate environments, but at the same time, those packages act like if they  194 00:24:42,240 --> 00:24:47,360 were installed globally so you don't have to activate any virtual environment to use them. 195 00:24:48,800 --> 00:24:53,280 How does it look in practice? Let's say you want to install [Indiscernible] for Python code.  196 00:24:54,320 --> 00:25:01,680 I run well, we run pipx install black and after a few seconds, we get a message saying that  197 00:25:01,680 --> 00:25:08,240 Black has been installed and now we have those three commands, black, black primer and black D.  198 00:25:10,080 --> 00:25:13,920 And now we can use Black as if it was installed with pypi.  199 00:25:13,920 --> 00:25:20,960 It doesn't matter if we were inside of a virtual environment or not. We don't have to  200 00:25:20,960 --> 00:25:27,120 activate anything. We run the same commands as we would run if we weren't using pipx. 201 00:25:29,600 --> 00:25:34,160 And if we want to install a different version of Black inside of a virtual environment,  202 00:25:34,160 --> 00:25:38,800 we can still do this. This Black, from inside a virtual environment,  203 00:25:38,800 --> 00:25:47,200 will take precedence over the global Black. You'll be using Black from this virtual environment.  204 00:25:49,120 --> 00:25:54,560 What else we can do with pipx? We can install packages to see what commands they offer.  205 00:25:55,360 --> 00:26:00,080 We can uninstall a package and this will also clean up its virtual environment.  206 00:26:00,080 --> 00:26:13,520 We can upgrade with one command and pipx inject. It will install a pypi package inside of a virtual  207 00:26:13,520 --> 00:26:27,600 environment of another package. You might use it to install pytest. We can't just run pipx  208 00:26:27,600 --> 00:26:43,200 install Python Discov because it will be inside its own virtual environment. So we have to call  209 00:26:43,200 --> 00:26:51,840 pipx inject pytest and it will install it inside the virtual environment of pytest. 210 00:26:53,360 --> 00:26:57,680 And that brings us to the end of my presentation so let's quickly summarize what we saw.  211 00:26:58,880 --> 00:27:04,560 First, use pyenv to install new Python versions. Once you set it up, it's really easy to install  212 00:27:04,560 --> 00:27:13,680 new Python versions. Then use virtual environments when you want to isolate their dependencies.  213 00:27:15,200 --> 00:27:18,320 Create a separate virtual environment for each of your projects.  214 00:27:19,680 --> 00:27:28,960 It has venv and it's perfectly fine to use it. Virtualenvwrapper is also a really great choice.  215 00:27:30,240 --> 00:27:35,680 And, finally, if you want to install some tools globally, you can use pypi outside of the virtual  216 00:27:35,680 --> 00:27:41,040 environment but you risk that if there is some version conflict, they won't work together.  217 00:27:41,680 --> 00:27:48,320 So a much better tool to use is called pipx and this will install global package into a separate  218 00:27:48,880 --> 00:27:53,680 into a separate virtual environment but for you, there won't be any difference in how you use them. 219 00:27:55,760 --> 00:27:59,360 Thank you very much for listening and I think we still have some time for questions. 220 00:27:59,360 --> 00:28:07,520 >> Thank you, Sebastian. We probably have time for one question. And,  221 00:28:09,200 --> 00:28:18,800 we we have we have two questions. So, I'm going to use my use my powers to pick  222 00:28:20,000 --> 00:28:26,560 I lost it. Um, okay. So, someone asks, I'd love to know which one is used in production?  223 00:28:26,560 --> 00:28:33,360 Is there a set of best practices to follow? SEBASTIAN WITOWSKI: For production, I use yet  224 00:28:33,360 --> 00:28:40,800 another tool that I didn't have time to put in this talk. I use a tool called what was the name?  225 00:28:42,720 --> 00:28:47,520 Pypi tools. It has a command called pypi compile and you can provide a list of dependencies,  226 00:28:48,160 --> 00:28:50,400 like, you just specified, I want Django, I want pytest.  227 00:28:53,760 --> 00:28:58,080 It will take those requirement files and resolve all the dependencies and  228 00:29:01,440 --> 00:29:08,640 third party packages, dependencies that you use. You take this and you put it into a Docker image  229 00:29:09,840 --> 00:29:16,080 or venv. That's what I would use in production. >> Pypi compile is great. I use that,  230 00:29:16,080 --> 00:29:25,680 too. A lot of questions came in. We are out of time. So, Sebastian, are you would you  231 00:29:25,680 --> 00:29:31,280 like to head over to the text chat channel for a few minutes, to answer some more? 232 00:29:31,280 --> 00:29:37,120 SEBASTIAN WITOWSKI: Sure. >> Do jump into the the Curlyboi Theatre text  233 00:29:37,120 --> 00:29:43,520 chat channel and I will paste the questions over there. But, leave when you jump to the text chat,  234 00:29:43,520 --> 00:29:49,920 the stream for Curlyboi Theatre will keep playing up in the top corner, leave that playing because  235 00:29:49,920 --> 00:29:56,560 the conference closing is coming up in 15 minutes, okay, and we don't want anyone to miss that. 236 00:30:02,080 --> 00:30:05,760 All right. So, thank you, once again, Sebastian. SEBASTIAN WITOWSKI:  237 00:30:05,760 --> 00:30:07,680 Thank you so much for having me. >> I think that was really helpful.  238 00:30:07,680 --> 00:30:19,360 The chat was on fire. So, thank you. SEBASTIAN WITOWSKI: Thanks. Bye bye.