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.