{"id":21688,"date":"2023-12-23T06:12:00","date_gmt":"2023-12-23T04:12:00","guid":{"rendered":"https:\/\/raspberrytips.com\/?p=21688"},"modified":"2026-07-07T00:24:05","modified_gmt":"2026-07-06T22:24:05","slug":"python-virtual-environments","status":"publish","type":"post","link":"https:\/\/raspberrytips.com\/python-virtual-environments\/","title":{"rendered":"A Beginner&#8217;s Guide to Virtual Environments in Python"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">If you&#8217;ve upgraded to Bookworm or Trixie lately, and have used Python in your projects, you couldn&#8217;t have missed this change: they do everything to make you switch to virtual environments. What is this all about, and do you need to worry about it? Let me explain.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Virtual environments in Python are isolated spaces for projects. Each virtual environment has its own dependencies and Python versions. They provide a clean, conflict-free coding environment that is critical for complex projects.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you&#8217;ve just upgraded Raspberry Pi OS or Debian and are wondering why PIP doesn&#8217;t work anymore or want to learn more about this concept, you&#8217;ve come to the right place, I&#8217;ll explain everything in this article.<\/p>\n\n\n<style>.kb-table-of-content-nav.kb-table-of-content-id19563_c031ec-35 .kb-table-of-content-wrap{padding-top:var(--global-kb-spacing-sm, 1.5rem);padding-right:var(--global-kb-spacing-sm, 1.5rem);padding-bottom:var(--global-kb-spacing-sm, 1.5rem);padding-left:var(--global-kb-spacing-sm, 1.5rem);background-color:var(--global-palette7, #EDF2F7);box-shadow:0px 0px 14px 0px rgba(0, 0, 0, 0.2);}.kb-table-of-content-nav.kb-table-of-content-id19563_c031ec-35 .kb-table-of-contents-title-wrap{padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.kb-table-of-content-nav.kb-table-of-content-id19563_c031ec-35 .kb-table-of-contents-title{font-weight:regular;font-style:normal;}.kb-table-of-content-nav.kb-table-of-content-id19563_c031ec-35 .kb-table-of-content-wrap .kb-table-of-content-list{font-size:var(--global-kb-font-size-sm, 0.9rem);font-weight:regular;font-style:normal;margin-top:var(--global-kb-spacing-sm, 1.5rem);margin-right:0px;margin-bottom:0px;margin-left:0px;}.kb-table-of-content-nav.kb-table-of-content-id19563_c031ec-35 .kb-toggle-icon-style-basiccircle .kb-table-of-contents-icon-trigger:after, .kb-table-of-content-nav.kb-table-of-content-id19563_c031ec-35 .kb-toggle-icon-style-basiccircle .kb-table-of-contents-icon-trigger:before, .kb-table-of-content-nav.kb-table-of-content-id19563_c031ec-35 .kb-toggle-icon-style-arrowcircle .kb-table-of-contents-icon-trigger:after, .kb-table-of-content-nav.kb-table-of-content-id19563_c031ec-35 .kb-toggle-icon-style-arrowcircle .kb-table-of-contents-icon-trigger:before, .kb-table-of-content-nav.kb-table-of-content-id19563_c031ec-35 .kb-toggle-icon-style-xclosecircle .kb-table-of-contents-icon-trigger:after, .kb-table-of-content-nav.kb-table-of-content-id19563_c031ec-35 .kb-toggle-icon-style-xclosecircle .kb-table-of-contents-icon-trigger:before{background-color:var(--global-palette7, #EDF2F7);}<\/style>\n\n<p class='ml_begpost' id='ml_begpost_python'>If you\u2019re like me and sometimes mix up syntax between programming languages, I\u2019ve got just the thing for you. I\u2019ve put together <a rel='noopener' href='https:\/\/raspberrytips.com\/downloads\/?source=begpost&#038;lm=3' target='_blank'>a Python cheat sheet<\/a> with all the essential syntax in one place, so you can keep it handy and avoid any confusion. <a rel='noopener' href='https:\/\/raspberrytips.com\/downloads\/?source=begpost&#038;lm=3' target='_blank'><b>Download it here for free!<\/b><\/a><\/p>\n\n\n<h2 class=\"wp-block-heading\">Understanding the Shift to Virtual Environments<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Before trying to brute force your way and find the right command to bypass virtual environments, I think it&#8217;s a good idea to take a step back to understand what has changed and how it impacts your Python projects.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">What are Virtual Environments in Python?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">After creating virtual machines to keep the main system safe, and then Docker containers to ensure compatibility, now we have to wonder about Python virtual environments. Yes, it&#8217;s the same idea:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>A special room for each Python project, keeping them separate, living on their own to avoid global problems.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In more technical terms, a virtual environment in Python is a self-contained directory that contains a Python installation for a specific version of Python, plus several additional packages. This setup allows you to:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Use different Python versions<\/strong>: If you have different projects that require different Python versions, it&#8217;s no longer a problem.<\/li>\n\n\n\n<li><strong>Have more freedom with dependencies<\/strong>: Each environment can have a different set of libraries installed with different versions. This prevents conflicts between project requirements.<\/li>\n\n\n\n<li><strong>Avoid system issues<\/strong>: You can have each project running a different version and isolated libraries, so you will no longer break an old project while working on a new one.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">It&#8217;s also better for developers and teamwork because it allows you to copy, share, or recreate environments under similar conditions for testing or deployment purposes. Yes, same kind of benefits as <a href=\"https:\/\/raspberrytips.com\/docker-on-raspberry-pi\/\" data-type=\"post\" data-id=\"11852\">Docker<\/a> or <a href=\"https:\/\/raspberrytips.com\/docker-compose-raspberry-pi\/\" data-type=\"link\" data-id=\"https:\/\/raspberrytips.com\/docker-compose-raspberry-pi\/\">Docker Compose<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Comparison with Traditional Python Setup<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>In traditional Python setups, libraries and dependencies are installed globally, and shared across all projects. Virtual environments, by contrast, are created specifically for each project, containing isolated and independent sets of libraries and dependencies.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It&#8217;s a bit like comparing a Jenga tower with Lego constructions. <\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"683\" src=\"https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/12\/traditional-setup-vs-python-virtual-env-1024x683.png\" alt=\"\" class=\"wp-image-21786\" srcset=\"https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/12\/traditional-setup-vs-python-virtual-env-1024x683.png 1024w, https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/12\/traditional-setup-vs-python-virtual-env-300x200.png 300w, https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/12\/traditional-setup-vs-python-virtual-env-768x512.png 768w, https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/12\/traditional-setup-vs-python-virtual-env.png 1200w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">In a traditional setup, as you continue to write new projects, the structures become increasingly unstable. A Python upgrade or a library that conflicts with everything else can easily crash all your projects.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In contrast, when you use virtual environments, your different projects are built from different sets of bricks, independent of each other. This creates a stable and controlled development environment, reducing the risk of a total meltdown.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Do I Really Need to Use Venvs?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Switching to virtual environments can seem overwhelming if you&#8217;re used to the old way of installing Python libraries. But in the end, it&#8217;s better for you. This method minimizes the risk of conflicts and dependency issues and provides a cleaner way to manage Python projects.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now, I understand that if you&#8217;re getting started in Python, and just want to write 5 lines of code to make a LED blink, this might feel a bit overkill.  In this case, you have a few options:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Using system packages<\/strong>: it&#8217;s still possible to install Python libraries via the system package manager, so they become available on the entire system (virtual environments or not). For example, if you install the &#8220;requests&#8221; module with:<br><code>sudo apt install python3-requests<br><\/code>It&#8217;ll be available in all your projects. By the way, the Raspberry Pi OS is still loaded with tons of packages like that by default, nothing has changed (so you probably already have most of them installed).<br><\/li>\n\n\n\n<li><strong>Forcing system-wide installation: <\/strong>If you try to install a PIP package outside a virtual environment, you&#8217;ll get an error message: &#8220;externally-managed-environment&#8221;. The system is asking you to try the previous option or create a virtual environment. <br><br>But it&#8217;s still possible to bypass that, by adding an extra parameter:<br><code>sudo pip install &lt;library&gt; --break-system-packages<br><\/code>This option is explicit, so I hope you know what you&#8217;re doing if you try it.<br><\/li>\n\n\n\n<li><strong>Creating a virtual environment:<\/strong> for a small-scale Python project, you can still try using a virtual environment. It&#8217;s a few more commands to remember, but it&#8217;s not that complicated. Read the next part to understand how it works.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">How to Use Virtual Environments in Python Projects<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">How does this work in practice? Well, it&#8217;s not that complicated. You simply create a separate folder with everything in it, and tell the system that you&#8217;re using it when you work on your Python project. Let&#8217;s get to it.<\/p>\n\n\n\n<p class=\"has-background wp-block-paragraph\" style=\"background-color:#fadce4\"><strong>Note<\/strong>: If you want to see all these steps in action, I have a video lesson available for the community members. <a href=\"https:\/\/school.raspberrytips.com\/raspberrytips-community?utm_source=raspberrytips&amp;utm_medium=website&amp;utm_campaign=inpost\" target=\"_blank\" rel=\"noreferrer noopener\">You can join here and watch it directly<\/a> if you are interested (with 20+ other lessons for Raspberry Pi and many other benefits).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Prerequisites<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">If you&#8217;re using a recent version of Raspberry Pi OS, you should be ready to get started, everything is installed by default. But on a minimal system, especially on other distributions, I recommend checking that Python is installed, and the package &#8216;python3-venv&#8217; in particular.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can check with:<br><code>sudo dpkg -l | grep venv<\/code><\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"133\" src=\"https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/11\/python-venv-installed-1024x133.jpg\" alt=\"\" class=\"wp-image-21726\" srcset=\"https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/11\/python-venv-installed-1024x133.jpg 1024w, https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/11\/python-venv-installed-300x39.jpg 300w, https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/11\/python-venv-installed-768x99.jpg 768w, https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/11\/python-venv-installed.jpg 1490w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">If this command returns something similar, it means the package is already installed.<\/figcaption><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">If it&#8217;s not the case, you can install everything with:<br><code>sudo apt update<br>sudo apt install python3-venv<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then, it&#8217;s a good practice to create a separate folder on your drive for each project. But if you are only doing basic scripts, and want to group them, it&#8217;s fine to create only one, for example:<br><code>mkdir \/home\/$USER\/python<\/code><\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"779\" height=\"123\" src=\"https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/11\/python-creating-project.jpg\" alt=\"\" class=\"wp-image-21727\" srcset=\"https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/11\/python-creating-project.jpg 779w, https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/11\/python-creating-project-300x47.jpg 300w, https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/11\/python-creating-project-768x121.jpg 768w\" sizes=\"auto, (max-width: 779px) 100vw, 779px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">I&#8217;ll use this example, but if you have several folders for different projects, you&#8217;ll need to repeat the following steps for each of them.<\/p>\n\n\n\r\n\t\t<!-- wp:paragraph -->\r\n\t<p  id=\"inpost_lm_linux_commands\"><b>Tip: <\/b> Command lines can be a pain to memorize. I put the essential Linux commands on a printable cheat sheet so you don't have to keep googling them.\u00a0You can <a rel=\"noreferrer noopener\" href=\"https:\/\/raspberrytips.com\/downloads\/?source=rb_linux&lm=4\" target=\"_blank\">grab the PDF here<\/a> if you want to save some time.<\/p>\r\n\t<!-- \/wp:paragraph -->\r\n\t\t\n\n\n<h3 class=\"wp-block-heading\">Creating a Virtual Environment<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The syntax to create a virtual environment is simple:<br><code>python3 -m venv &lt;name&gt;<br><\/code>This will create a new subfolder at your current location.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example:<br><code>cd ~\/python<br>python3 -m venv rpitips<\/code><\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"849\" height=\"157\" src=\"https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/11\/python-create-venv.jpg\" alt=\"\" class=\"wp-image-21728\" srcset=\"https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/11\/python-create-venv.jpg 849w, https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/11\/python-create-venv-300x55.jpg 300w, https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/11\/python-create-venv-768x142.jpg 768w\" sizes=\"auto, (max-width: 849px) 100vw, 849px\" \/><\/figure>\n<\/div>\n\n\n<h3 class=\"wp-block-heading\">Activating and Using the Environment<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Now, the virtual environment has been created, but it won&#8217;t be used unless you explicitly say so.<\/strong> That&#8217;s called activation, and it can be done by running the activate script, like this:<br><code>source rpitips\/bin\/activate<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Once done, your terminal prompt will have a prefix with the virtual environment name:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"911\" height=\"87\" src=\"https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/11\/python-activate-venv.jpg\" alt=\"\" class=\"wp-image-21730\" srcset=\"https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/11\/python-activate-venv.jpg 911w, https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/11\/python-activate-venv-300x29.jpg 300w, https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/11\/python-activate-venv-768x73.jpg 768w\" sizes=\"auto, (max-width: 911px) 100vw, 911px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">Now, all the Python commands I run from there will be executed from this environment.<\/p>\n\n\n\n<p class=\"has-theme-palette-7-background-color has-background wp-block-paragraph\"><strong>Note<\/strong>: if you are in a different folder, you need to set the full path to the activate script, for example:<br><code>source \/home\/pat\/python\/rpitips\/bin\/activate<br><\/code>Or<br><code>source ~\/python\/rpitips\/bin\/activate<\/code><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Working in Virtual Environments<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">If you are used to Python using a traditional setup, you&#8217;ve already completed the most complicated part. From there, it&#8217;s basically as if you were using a traditional setup, without a virtual environment.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>You can create your Python files in this project folder, as usual.<br><code>nano myscript.py<\/code><\/li>\n\n\n\n<li>You can <a href=\"https:\/\/raspberrytips.com\/pip-linux-command\/\" data-type=\"post\" data-id=\"28629\">run PIP commands<\/a>, which will only apply to this virtual environment.<br><code>pip install &lt;lib-name&gt;<\/code><\/li>\n\n\n\n<li>And, if you run a Python command from there, it will use this environment.<br><code>python myscript.py<\/code><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">As an example, let&#8217;s say I want to use the library &#8220;emoji&#8221;, that allows you to print emojis in your scripts.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A basic script may look like this:<br><code>import emoji<br>print(emoji.emojize('Python is :thumbs_up:'))<\/code><\/li>\n\n\n\n<li>The library is not installed system-wide, but I can add it to my environment with:<br><code>pip install emoji<\/code><\/li>\n\n\n\n<li>Then my script is working:<br><code>python3 emo.py<br><\/code><img loading=\"lazy\" decoding=\"async\" width=\"853\" height=\"88\" class=\"wp-image-21732\" style=\"\" src=\"https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/11\/python-emoji.jpg\" alt=\"\" srcset=\"https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/11\/python-emoji.jpg 853w, https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/11\/python-emoji-300x31.jpg 300w, https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/11\/python-emoji-768x79.jpg 768w\" sizes=\"auto, (max-width: 853px) 100vw, 853px\" \/><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">You just need to make sure you&#8217;re inside the environment to run this script. As the library is only available in it, it won&#8217;t work if you close the session and run it directly, even if you run it from the same folder:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"989\" height=\"194\" src=\"https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/11\/python-emoji-error.jpg\" alt=\"\" class=\"wp-image-21733\" srcset=\"https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/11\/python-emoji-error.jpg 989w, https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/11\/python-emoji-error-300x59.jpg 300w, https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/11\/python-emoji-error-768x151.jpg 768w\" sizes=\"auto, (max-width: 989px) 100vw, 989px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">That&#8217;s why it&#8217;s important to stay organized and have a clear structure, either with one folder per project, one folder for your small scripts, or simply by installing libraries system-wide when they are available.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Related<\/strong>: <a href=\"https:\/\/raspberrytips.com\/fix-externally-managed-environment-error\/\">Fix the \u2018externally-managed-environment\u2019 Error on Raspberry Pi<\/a><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Deactivating and Switching Between Environments<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">To exit a virtual environment, you&#8217;ll simply use this command:<br><code>deactivate<\/code><\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"861\" height=\"123\" src=\"https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/11\/python-exit-venv.jpg\" alt=\"\" class=\"wp-image-21734\" srcset=\"https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/11\/python-exit-venv.jpg 861w, https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/11\/python-exit-venv-300x43.jpg 300w, https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/11\/python-exit-venv-768x110.jpg 768w\" sizes=\"auto, (max-width: 861px) 100vw, 861px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">As you can see, the prefix disappears, and you&#8217;re no longer running commands in this environment. You can switch to another one by running the corresponding &#8220;activate&#8221; script if needed.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Virtual Environments in Practice<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">I&#8217;ve explained how you can create and use virtual environments for your Python projects via the terminal, but it&#8217;s also possible to use them from your favorite text editors.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Thonny<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Thonny is a basic text editor, that is often used for Python projects, especially on Raspberry Pi, as it&#8217;s preinstalled on Raspberry Pi OS.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The features are pretty limited, but you can still change the default interpreter to use a virtual environment:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Open Thonny as usual.<\/li>\n\n\n\n<li>Click on the Python interpreter in the bottom-right corner.<\/li>\n\n\n\n<li>You&#8217;ll get a list with the Python versions installed on your system, but you can also add a binary from a virtual environment:<br><img loading=\"lazy\" decoding=\"async\" width=\"1026\" height=\"575\" class=\"wp-image-21757\" style=\"\" src=\"https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/12\/thonny-venv.jpg\" alt=\"\" srcset=\"https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/12\/thonny-venv.jpg 1026w, https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/12\/thonny-venv-300x168.jpg 300w, https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/12\/thonny-venv-1024x574.jpg 1024w, https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/12\/thonny-venv-768x430.jpg 768w\" sizes=\"auto, (max-width: 1026px) 100vw, 1026px\" \/><\/li>\n\n\n\n<li>With a recent version of Thonny, you can even create a new virtual environment from there.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">If you don&#8217;t know, Thonny has built-in features to handle additional libraries. If you go to <strong>Tools &gt; Manage packages<\/strong>, you can install PIP modules, that will be installed automatically in the current environment:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"975\" height=\"418\" src=\"https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/12\/thonny-install-package.jpg\" alt=\"\" class=\"wp-image-21758\" srcset=\"https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/12\/thonny-install-package.jpg 975w, https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/12\/thonny-install-package-300x129.jpg 300w, https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/12\/thonny-install-package-768x329.jpg 768w\" sizes=\"auto, (max-width: 975px) 100vw, 975px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">It doesn&#8217;t work via &#8220;Manage plug-ins&#8221; (it tries to install them system-wide), but it&#8217;s working from this window.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I have an entire tutorial about <a href=\"https:\/\/raspberrytips.com\/thonny-ide-raspberry-pi\/\" data-type=\"post\" data-id=\"16956\">Thonny and its hidden features<\/a>, make sure to check it if you&#8217;re a bit lost there.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Geany<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Geany is a bit more evolved, with more features, but it can be a bit overwhelming.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I didn&#8217;t find the perfect way to use virtual environments with it, but I think you can go to <strong>Build &gt; Set build commands<\/strong> to change the execute command, and use the one in your virtual environment instead of the default:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"645\" height=\"228\" src=\"https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/12\/geany-python-command.jpg\" alt=\"\" class=\"wp-image-21760\" srcset=\"https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/12\/geany-python-command.jpg 645w, https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/12\/geany-python-command-300x106.jpg 300w\" sizes=\"auto, (max-width: 645px) 100vw, 645px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">If you have several environments, you can create Geany projects and set a different command for each of them.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you want to learn more about Geany, you can read this article: <a href=\"https:\/\/raspberrytips.com\/use-geany-on-raspberry-pi\/\" data-type=\"post\" data-id=\"7836\">How to Use Geany on Raspberry Pi? (Full guide with pictures)<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Visual Studio Code<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">With a more advanced editor, like <a href=\"https:\/\/raspberrytips.com\/install-visual-studio-code-raspberry-pi\/\" data-type=\"post\" data-id=\"17737\">Visual Studio Code<\/a>, it&#8217;s even easier. If you open a folder, it will automatically detect the virtual environment inside it, and use it by default.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"732\" height=\"262\" src=\"https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/12\/vscode-venv.jpg\" alt=\"\" class=\"wp-image-21763\" srcset=\"https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/12\/vscode-venv.jpg 732w, https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/12\/vscode-venv-300x107.jpg 300w\" sizes=\"auto, (max-width: 732px) 100vw, 732px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>Note<\/strong>: A Python extension is required to debug and run Python scripts (the IntelliSense one for example).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can also create a new virtual environment from an existing folder, directly from the interface. Press <strong><kbd>CTRL+SHIFT+P<\/kbd><\/strong> to open the palette, and search for &#8220;Create environment&#8221;:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"843\" height=\"215\" src=\"https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/12\/vscode-create-venv.jpg\" alt=\"\" class=\"wp-image-21764\" srcset=\"https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/12\/vscode-create-venv.jpg 843w, https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/12\/vscode-create-venv-300x77.jpg 300w, https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/12\/vscode-create-venv-768x196.jpg 768w\" sizes=\"auto, (max-width: 843px) 100vw, 843px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">VSCode will create it in the current folder and activate it automatically.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Once done, you can use the terminal window inside VSCode to install new PIP packages (the activate command is done automatically):<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"817\" height=\"219\" src=\"https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/12\/vscode-install-pip.jpg\" alt=\"\" class=\"wp-image-21766\" srcset=\"https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/12\/vscode-install-pip.jpg 817w, https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/12\/vscode-install-pip-300x80.jpg 300w, https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/12\/vscode-install-pip-768x206.jpg 768w\" sizes=\"auto, (max-width: 817px) 100vw, 817px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">Now that you&#8217;re a master of virtual environments, let&#8217;s try applying this in a project while it&#8217;s still fresh in your mind:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/raspberrytips.com\/python-gui-libraries-for-raspberry-pi\/\" data-type=\"post\" data-id=\"16084\">The Best Python GUI Libraries for Raspberry Pi to Try Out<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/raspberrytips.com\/python-games-raspberry-pi\/\" data-type=\"post\" data-id=\"15943\">Getting Started With Python Games On Raspberry Pi (Pygame)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/raspberrytips.com\/top-python-libraries-rasbperry-pi\/\" data-type=\"post\" data-id=\"15679\">Python on Raspberry Pi: The Top 5 Libraries for Every Developer<\/a><\/li>\n<\/ul>\n\n\n<section id=\"end-block-pi\">\r\n<div class=\"rt-community-card \">\r\n\t<div class=\"rt-community-card__inner\">\r\n\r\n\t\t<div class=\"rt-community-card__main\">\r\n\t\t\t<h3 class=\"rt-community-card__headline\">\r\n\t\t\t\tNot getting the same result?\t\t\t<\/h3>\r\n\r\n\t\t\t<p class=\"rt-community-card__description\">\r\n\t\t\t\tEven when you follow every step, small differences in OS version, hardware or config can change the outcome. Instead of wasting time guessing, get help from people who have already fixed the same kind of issue.\t\t\t<\/p>\r\n\r\n\t\t\t<div class=\"rt-community-card__actions\">\r\n\t\t\t\t<a class=\"rt-community-card__button\" href=\"https:\/\/raspberrytips.com\/school\/community\/?coupon=EBCTY\">\r\n\t\t\t\t\t<span>Ask your question now<\/span>\r\n\t\t\t\t\t<span class=\"rt-community-card__button-arrow\">\u2192<\/span>\r\n\t\t\t\t<\/a>\r\n\r\n\t\t\t\t\t\t\t\t\t<div class=\"rt-community-card__small\">\r\n\t\t\t\t\t\t<span class=\"rt-community-card__small-lock\">\ud83d\udd12<\/span>\r\n\t\t\t\t\t\tNo risk. Cancel anytime.\t\t\t\t\t<\/div>\r\n\t\t\t\t\t\t\t<\/div>\r\n\t\t<\/div>\r\n\r\n\t\t\t\t\t<div class=\"rt-community-card__side\">\r\n\t\t\t\t<ul class=\"rt-community-card__benefits\">\r\n\t\t\t\t\t\t\t\t\t\t\t<li>Get help on your exact issue<\/li>\r\n\t\t\t\t\t\t\t\t\t\t\t<li>Access step-by-step videos for tricky setups<\/li>\r\n\t\t\t\t\t\t\t\t\t\t\t<li>Browse the website without ads<\/li>\r\n\t\t\t\t\t\t\t\t\t<\/ul>\r\n\t\t\t<\/div>\r\n\t\t\r\n\t<\/div>\r\n<\/div>\r\n<\/section>\r\n\r\n<style>\r\n.rt-community-card {\r\n\t--rt-bg: #f7f7f9;\r\n\t--rt-border: #e4e4e8;\r\n\t--rt-text: #15171b;\r\n\t--rt-muted: #5b6270;\r\n\t--rt-accent: #C61E4A;\r\n\t--rt-accent-hover: #aa183f;\r\n\t--rt-shadow: 0 12px 30px rgba(0, 0, 0, 0.06);\r\n\r\n\tmargin: 36px 0;\r\n\tcolor: var(--rt-text);\r\n\tfont-family: inherit;\r\n}\r\n\r\n.rt-community-card__inner {\r\n\tdisplay: grid;\r\n\tgrid-template-columns: minmax(0, 1.55fr) minmax(260px, 0.95fr);\r\n\tgap: 34px;\r\n\talign-items: start;\r\n\tbackground: var(--rt-bg);\r\n\tborder: 1px solid var(--rt-border);\r\n\tborder-radius: 22px;\r\n\tpadding: 34px 36px;\r\n\tbox-shadow: var(--rt-shadow);\r\n}\r\n\r\n.rt-community-card__main {\r\n\tmin-width: 0;\r\n}\r\n\r\n.rt-community-card__side {\r\n\tborder-left: 1px solid #e1e1e6;\r\n\tpadding-left: 28px;\r\n}\r\n\r\n.rt-community-card__benefits {\r\n\tmargin: 6px 0 0;\r\n\tpadding: 0;\r\n\tlist-style: none;\r\n\tdisplay: grid;\r\n\tgap: 18px;\r\n}\r\n\r\n.rt-community-card__benefits li {\r\n\tposition: relative;\r\n\tpadding-left: 18px;\r\n\tfont-size: 18px;\r\n\tline-height: 1.55;\r\n\tcolor: var(--rt-text);\r\n}\r\n\r\n.rt-community-card__benefits li::before {\r\n\tcontent: \"\";\r\n\tposition: absolute;\r\n\tleft: 0;\r\n\ttop: 0.72em;\r\n\twidth: 7px;\r\n\theight: 7px;\r\n\tborder-radius: 999px;\r\n\tbackground: var(--rt-accent);\r\n\ttransform: translateY(-50%);\r\n}\r\n\r\n.rt-community-card__actions {\r\n\tdisplay: flex;\r\n\tflex-direction: column;\r\n\talign-items: flex-start;\r\n\tgap: 10px;\r\n\tmargin-top: 30px;\r\n}\r\n\r\n.rt-community-card__button {\r\n\tdisplay: inline-flex;\r\n\talign-items: center;\r\n\tjustify-content: center;\r\n\tgap: 10px;\r\n\tmin-height: 60px;\r\n\tpadding: 0 28px;\r\n\tborder-radius: 14px;\r\n\tbackground: var(--rt-accent);\r\n\tcolor: #fff !important;\r\n\ttext-decoration: none !important;\r\n\tfont-size: 21px;\r\n\tfont-weight: 700;\r\n\tline-height: 1;\r\n\tbox-shadow: 0 12px 22px rgba(198, 30, 74, 0.22);\r\n\ttransition: background .2s ease, transform .2s ease, box-shadow .2s ease;\r\n}\r\n\r\n.rt-community-card__button:hover {\r\n\tbackground: var(--rt-accent-hover);\r\n\tcolor: #fff !important;\r\n\ttransform: translateY(-1px);\r\n\tbox-shadow: 0 14px 26px rgba(198, 30, 74, 0.28);\r\n}\r\n\r\n.rt-community-card__button-arrow {\r\n\tfont-size: 20px;\r\n\tline-height: 1;\r\n}\r\n\r\n.rt-community-card__small {\r\n\tfont-size: 15px;\r\n\tline-height: 1.5;\r\n\tcolor: #6a717d;\r\n\tpadding-left: 2px;\r\n}\r\n\r\n.rt-community-card__small-lock {\r\n\tmargin-right: 6px;\r\n\tfont-size: 14px;\r\n\tvertical-align: baseline;\r\n}\r\n\r\n\/* Tablet *\/\r\n@media (max-width: 900px) {\r\n\t.rt-community-card {\r\n\t\tmargin: 28px 0;\r\n\t}\r\n\r\n\t.rt-community-card__inner {\r\n\t\tgrid-template-columns: 1fr;\r\n\t\tgap: 24px;\r\n\t\tpadding: 28px 24px;\r\n\t}\r\n\r\n\t.rt-community-card__side {\r\n\t\tborder-left: 0;\r\n\t\tborder-top: 1px solid #e1e1e6;\r\n\t\tpadding-left: 0;\r\n\t\tpadding-top: 22px;\r\n\t}\r\n\r\n\t.rt-community-card__benefits {\r\n\t\tgrid-template-columns: 1fr;\r\n\t\tgap: 12px;\r\n\t}\r\n}\r\n\r\n\/* Mobile *\/\r\n@media (max-width: 640px) {\r\n\t.rt-community-card__inner {\r\n\t\tpadding: 22px 18px;\r\n\t\tborder-radius: 18px;\r\n\t\tgap: 20px;\r\n\t}\r\n\t\r\n\t.rt-community-card__side {\r\n\t\tpadding-top: 18px;\r\n\t}\r\n\r\n\t.rt-community-card__benefits li {\r\n\t\tfont-size: 16px;\r\n\t}\r\n\r\n\t.rt-community-card__actions {\r\n\t\tmargin-top: 24px;\r\n\t\talign-items: stretch;\r\n\t}\r\n\r\n\t.rt-community-card__button {\r\n\t\twidth: 100%;\r\n\t\tmin-height: 56px;\r\n\t\tfont-size: 18px;\r\n\t\tpadding: 0 20px;\r\n\t}\r\n\r\n\t.rt-community-card__small {\r\n\t\ttext-align: center;\r\n\t\tpadding-left: 0;\r\n\t}\r\n}\r\n<\/style>\r\n\t\r\n","protected":false},"excerpt":{"rendered":"<p>If you&#8217;ve upgraded to Bookworm or Trixie lately, and have used Python in your projects, you couldn&#8217;t have missed this change: they do everything to make you switch to virtual environments. What is this all about, and do you need to worry about it? Let me explain. Virtual environments in Python are isolated spaces for&#8230;<\/p>\n","protected":false},"author":1,"featured_media":21846,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_kad_blocks_custom_css":"","_kad_blocks_head_custom_js":"","_kad_blocks_body_custom_js":"","_kad_blocks_footer_custom_js":"","_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_kad_post_classname":"","footnotes":""},"categories":[25],"tags":[],"class_list":["post-21688","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-programming"],"taxonomy_info":{"category":[{"value":25,"label":"Programming"}]},"featured_image_src_large":["https:\/\/raspberrytips.com\/wp-content\/uploads\/2023\/12\/python-virtual-environments-1024x683.jpg",1024,683,true],"author_info":{"display_name":"Patrick Fromaget","author_link":"https:\/\/raspberrytips.com\/author\/admin\/"},"comment_info":0,"category_info":[{"term_id":25,"name":"Programming","slug":"programming","term_group":0,"term_taxonomy_id":25,"taxonomy":"category","description":"","parent":0,"count":66,"filter":"raw","cat_ID":25,"category_count":66,"category_description":"","cat_name":"Programming","category_nicename":"programming","category_parent":0}],"tag_info":false,"_links":{"self":[{"href":"https:\/\/raspberrytips.com\/wp-json\/wp\/v2\/posts\/21688","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/raspberrytips.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/raspberrytips.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/raspberrytips.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/raspberrytips.com\/wp-json\/wp\/v2\/comments?post=21688"}],"version-history":[{"count":26,"href":"https:\/\/raspberrytips.com\/wp-json\/wp\/v2\/posts\/21688\/revisions"}],"predecessor-version":[{"id":53513,"href":"https:\/\/raspberrytips.com\/wp-json\/wp\/v2\/posts\/21688\/revisions\/53513"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/raspberrytips.com\/wp-json\/wp\/v2\/media\/21846"}],"wp:attachment":[{"href":"https:\/\/raspberrytips.com\/wp-json\/wp\/v2\/media?parent=21688"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/raspberrytips.com\/wp-json\/wp\/v2\/categories?post=21688"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/raspberrytips.com\/wp-json\/wp\/v2\/tags?post=21688"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}