{"id":3469,"date":"2023-08-14T19:32:34","date_gmt":"2023-08-15T02:32:34","guid":{"rendered":"https:\/\/ioflood.com\/blog\/?p=3469"},"modified":"2024-02-07T10:39:41","modified_gmt":"2024-02-07T17:39:41","slug":"python-dotenv-guide-how-to-use-environment-variables-in-python","status":"publish","type":"post","link":"https:\/\/ioflood.com\/blog\/python-dotenv-guide-how-to-use-environment-variables-in-python\/","title":{"rendered":"Python Dotenv Guide | Using Python Environment Variables"},"content":{"rendered":"<div class=\"wp-block-image\">\n<figure class=\"alignright size-full is-resized\"><img decoding=\"async\" src=\"https:\/\/ioflood.com\/blog\/wp-content\/uploads\/2023\/08\/Digital-illustration-showing-the-use-of-python-dotenv-focusing-on-managing-environment-variables-in-Python-applications-300x300.jpg\" alt=\"Digital illustration showing the use of python dotenv focusing on managing environment variables in Python applications\" width=\"300\" height=\"300\" title=\"\"><\/figure>\n<\/div>\n<p>Are you wrestling with the task of managing sensitive data in your Python application? Do you feel like you&#8217;re treading on thin ice when it comes to handling confidential information? You&#8217;re not alone.<\/p>\n<p>We have a powerful solution for you &#8211; the python-dotenv library. This library is a game-changer for securely managing environment variables in Python applications.<\/p>\n<p>In this comprehensive guide, we will plunge into the world of python-dotenv, exploring its capabilities, peeling back the layers of its advanced features, and demonstrating how to use it to keep your sensitive data secure.<\/p>\n<h2>TL;DR: What is python-dotenv and how does it secure Python applications?<\/h2>\n<blockquote><p>\n  Python-dotenv is a library that enables secure management of environment variables in Python applications. It allows you to separate sensitive information from your application code, enhancing security. With python-dotenv, you can store sensitive data in a .env file in the user&#8217;s home directory, and access it when needed, keeping your code clean and maintainable. For a more advanced understanding and methods, continue reading the article.\n<\/p><\/blockquote>\n<p>Example usage for loading &#8220;SECRET KEY&#8221;:<\/p>\n<pre><code class=\"language-python line-numbers\">from dotenv import load_dotenv\nimport os\n\nload_dotenv()\n\nsecret_key = os.getenv('SECRET_KEY')\nprint(secret_key)\n<\/code><\/pre>\n<h2>Python-dotenv Basics<\/h2>\n<p>By keeping your secure data in your .env environment variable file, you can avoid accidentally including passwords, API keys, and other secrets in your program code. This is essential for making sure these secrets don&#8217;t accidentally get leaked on github, for example.<\/p>\n<blockquote><p>\n  Python-dotenv allows you to separate sensitive information from your application code, providing an additional layer of security. This separation ensures that even if your code is compromised, your sensitive data remains protected.\n<\/p><\/blockquote>\n<p>In addition to enhanced security, python-dotenv also brings convenience to the table. The installation is straightforward, setting up the .env file is a breeze, and the separation of sensitive data makes your code cleaner and more maintainable.<\/p>\n<h3>Installing Python-dotenv<\/h3>\n<p>The first step in our journey is the installation of python-dotenv. It&#8217;s a straightforward process that only requires pip, Python&#8217;s package installer. Here&#8217;s how you do it:<\/p>\n<pre><code class=\"language-bash line-numbers\">pip install python-dotenv\n<\/code><\/pre>\n<p>With just one command, you&#8217;ve successfully installed python-dotenv. Simple, isn&#8217;t it?<\/p>\n<h3>Setting Up the .env File<\/h3>\n<p>After installing python-dotenv, the next step is to set up the .env file. This file will act as a safe where you store your sensitive information. Here&#8217;s how you can append a secret to a .env file:<\/p>\n<pre><code class=\"language-bash line-numbers\">echo SECRET_KEY=my_secret_key &gt;&gt; .env\n<\/code><\/pre>\n<p>In the command above, &#8216;SECRET_KEY&#8217; is the name of the environment variable, and &#8216;my_secret_key&#8217; is the value. You can replace these with your own variables and values.<\/p>\n<blockquote><p>\n  By default, Python will load the .env file in <code>\/home\/username\/.env<\/code>, and Python will have access to the .env file associated with the user running the Python script.\n<\/p><\/blockquote>\n<p>Example of using .env file in a Python application:<\/p>\n<pre><code class=\"language-python line-numbers\">from dotenv import load_dotenv\nimport os\n\nload_dotenv()\n\nsecret_key = os.getenv('SECRET_KEY')\nprint(secret_key)\n<\/code><\/pre>\n<h3>The Advantages of Separation<\/h3>\n<p>By storing sensitive information in a separate .env file, you&#8217;re enhancing security and also making your code cleaner and more maintainable. You no longer have to hard-code sensitive data into your application code. Instead, you can store it in the .env file and access it when needed.<\/p>\n<blockquote><p>\n  This separation also allows you to share your code without revealing your secrets.\n<\/p><\/blockquote>\n<h2>Using the load_dotenv() Function<\/h2>\n<p>Having set up our .env file, the next step is to integrate it into our application. This is where the <code>load_dotenv()<\/code> function comes into play. This function loads the variables from the .env file into the environment, making them accessible to our application.<\/p>\n<p>For example, if your .env file looks like this:<\/p>\n<pre><code class=\"language-bash line-numbers\">DATABASE_URL=postgresql:\/\/localhost\/db\nSECRET_KEY=YourSecretKey\n<\/code><\/pre>\n<p>You can access these values like this:<\/p>\n<pre><code class=\"language-python line-numbers\">import os\nfrom dotenv import load_dotenv\n\n# Load the dotenv file\nload_dotenv()\n\n# Access variables\ndatabase_url = os.getenv('DATABASE_URL', 'default_value_if_not_found')\nsecret_key = os.getenv('SECRET_KEY')\n\n# Use these values in your application\nprint(f'Database URL: {database_url}')\nprint(f'Secret Key: {secret_key}')\n<\/code><\/pre>\n<p>In this script, &#8216;DATABASE_URL&#8217; and &#8216;SECRET_KEY&#8217; are strings that match the names of variables in your .env file.<\/p>\n<blockquote><p>\n  If you think the .env file might have changed, you can refresh the variables inside of Python by running <code>load_dotenv()<\/code> again.\n<\/p><\/blockquote>\n<h3>Loading All Environment Variables as a Dictionary<\/h3>\n<p>What if you want to load all the environment variables at once? Python-dotenv has a solution for that too. You can load all the variables from your .env file as a dictionary. Here&#8217;s how:<\/p>\n<pre><code class=\"language-python line-numbers\">from dotenv import dotenv_values\n\n# Get a dictionary of .env variables\nconfig = dotenv_values()\n\n# Get 'SECRET_KEY'\nsecret_key = config.get('SECRET_KEY')\n\n# Now you can use the secret_key variable in your application\nprint(f'Secret Key: {secret_key}')\n<\/code><\/pre>\n<p>The <code>dotenv_values()<\/code> function returns a dictionary containing all the environment variables from the specified .env file.<\/p>\n<p>In the code snippet above, &#8216;SECRET_KEY&#8217; is the name of the variable. You can replace it with the name of the variable you wish to refer to.<\/p>\n<blockquote><p>\n  <code>dotenv_values()<\/code> will load the .env file when you run it, making it unnecessary to run <code>load_dotenv()<\/code>, and also takes the place of running <code>os.getenv<\/code>\n<\/p><\/blockquote>\n<h3>Loading Environment Variables via Streams<\/h3>\n<p>Python-dotenv goes a step further by supporting loading variables via streams. This means you can source your environment variables from non-filesystem entities, like network streams or in-memory files. This allows you to store your configurations in a database or a remote server and python-dotenv can still load them.<\/p>\n<p>Example of loading variables via streams:<\/p>\n<pre><code class=\"language-python line-numbers\">from dotenv import dotenv_values\nfrom io import StringIO\n\nstream = StringIO('SECRET_KEY=my_secret_key')\nconfig = dotenv_values(stream=stream)\nprint(config)\n<\/code><\/pre>\n<h2>Advanced Uses of dotenv()<\/h2>\n<p>Although the basic uses outlined above are already powerful, there are many ways to get more out of dotenv() with advanced use cases.<\/p>\n<h3>Loading Different Environment Variable Files<\/h3>\n<p>During the development of a Python application, it&#8217;s common to require different environment variables for different environments.<\/p>\n<p>For instance, you might need to use a different database for development and production. Here&#8217;s how you can employ it:<\/p>\n<pre><code class=\"language-python line-numbers\">import platform\n\nif platform.node() == 'dev-machine':\n    load_dotenv('.env.dev')\nelse:\n    load_dotenv('.env.prod')\n<\/code><\/pre>\n<p>In the code snippet above, <code>platform.node()<\/code> returns the network name of the machine. If the network name is &#8216;dev-machine&#8217;, the development environment variables are loaded. Otherwise, the production environment variables are loaded.<\/p>\n<p>Example of loading different .env files based on the machine&#8217;s network name:<\/p>\n<pre><code class=\"language-python line-numbers\">import platform\nfrom dotenv import load_dotenv\n\nif platform.node() == 'dev-machine':\n    load_dotenv('.env.dev')\nelse:\n    load_dotenv('.env.prod')\n<\/code><\/pre>\n<p>The capability to load different sets of variables based on the code environment can be a game-changer. It enables you to segregate your development and production environments, minimizing the risk of errors and enhancing the robustness of your application.<\/p>\n<h3>Excluding .env Files from Version Control<\/h3>\n<p>To further bolster security, it&#8217;s recommended to exclude your .env file from your version control system. This can be achieved by creating a .gitignore file. Here&#8217;s how you can do it:<\/p>\n<pre><code class=\"language-bash line-numbers\">echo .env &gt;&gt; .gitignore\n<\/code><\/pre>\n<p>The above command adds &#8216;.env&#8217; to your .gitignore file, ensuring that your .env file is not tracked by Git.<\/p>\n<h3>Delving into Variable Expansions in Python-dotenv<\/h3>\n<p>Python-dotenv takes the management of environment variables a step further with the feature of variable expansions. This capability allows you to use the value of one environment variable within another. Here&#8217;s an illustrative example:<\/p>\n<pre><code class=\"language-bash line-numbers\">APP_PATH=\/usr\/app\nLOG_PATH=${APP_PATH}\/logs\n<\/code><\/pre>\n<p>In the example above, <code>LOG_PATH<\/code> utilizes the value of <code>APP_PATH<\/code>. This is referred to as variable expansion, and it&#8217;s an influential feature that can render your .env files more dynamic and flexible.<\/p>\n<p>Example of variable expansion:<\/p>\n<pre><code class=\"language-python line-numbers\">from dotenv import load_dotenv\nimport os\n\nload_dotenv()\n\napp_path = os.getenv('APP_PATH')\nlog_path = os.getenv('LOG_PATH')\n\nprint(app_path) # Output: \/usr\/app\nprint(log_path) # Output: \/usr\/app\/logs\n<\/code><\/pre>\n<blockquote><p>\n  Python-dotenv extends support for POSIX variable expansion, paving the way for dynamic configuration. This means you can use special characters like <code>$<\/code> and <code>:<\/code> in your environment variables, offering even more flexibility.\n<\/p><\/blockquote>\n<h3>Integrating Python-dotenv in Django Projects<\/h3>\n<p>Python-dotenv isn&#8217;t limited to just standalone Python applications &#8211; it can also be integrated into Django projects. By adding <code>load_dotenv()<\/code> to your Django settings.py file, you can load your environment variables directly into your Django project.<\/p>\n<p>Example of integrating python-dotenv into a Django project:<\/p>\n<pre><code class=\"language-python line-numbers\"># settings.py\nfrom dotenv import load_dotenv\nimport os\n\nload_dotenv()\n\nSECRET_KEY = os.getenv('SECRET_KEY')\n<\/code><\/pre>\n<h2>Python-dotenv&#8217;s Command-Line Interface<\/h2>\n<p>Python-dotenv also provides a command-line interface, enabling you to interact with your .env files directly from the command line. This can be a potent tool for managing your environment variables, particularly in development environments.<\/p>\n<p>Here&#8217;s an example of how you can use it:<\/p>\n<pre><code class=\"language-bash line-numbers\"># Commands within your terminal\n\n# Load the .env file\ndotenv -f \/path\/to\/your\/.env list\n\n# Set a new variable\ndotenv -f \/path\/to\/your\/.env set NEW_VARIABLE \"New Value\"\n\n# Get a variable value\ndotenv -f \/path\/to\/your\/.env get VARIABLE_NAME\n\n# Unset (delete) a variable\ndotenv -f \/path\/to\/your\/.env unset VARIABLE_NAME\n<\/code><\/pre>\n<p>You can replace <code>\/path\/to\/your\/.env<\/code> with the path to your .env file, <code>VARIABLE_NAME<\/code> with the name of the variable you want to print or delete, and <code>NEW_VARIABLE<\/code> and <code>\"New Value\"<\/code> with the name and value of the variable you want to set.<\/p>\n<blockquote><p>\n  If you have installed Python-dotenv and it&#8217;s available in your system&#8217;s PATH, then you should be able to utilize it as a command-line tool just like any other shell command.\n<\/p><\/blockquote>\n<p>However, on some systems, depending on how your Python environment is set up, you might need to use it via the python -m switch from the command line, like so:<\/p>\n<pre><code class=\"language-bash line-numbers\"># Load the .env file\npython -m dotenv list\n\n# Set a new variable\npython -m dotenv set NEW_VARIABLE \"New Value\"\n\n# Get a variable value\npython -m dotenv get VARIABLE_NAME\n\n# Unset (delete) a variable\npython -m dotenv unset VARIABLE_NAME\n<\/code><\/pre>\n<p>This will ensure that you&#8217;re using the <code>dotenv<\/code> module that&#8217;s associated with the particular Python interpreter you&#8217;re invoking.<\/p>\n<h2>Python-dotenv Summary: Flexibility, Security, and Convenience<\/h2>\n<p>As we&#8217;ve seen in this article, python-dotenv offers a high degree of flexibility when it comes to handling environment variables. Whether you want to load variables individually, load them all at once, or load them from diverse sources, python-dotenv has got you covered.<\/p>\n<p>But python-dotenv is not just about flexibility &#8211; it&#8217;s also about security and convenience.<\/p>\n<table>\n<thead>\n<tr>\n<th>Feature<\/th>\n<th>Description<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Flexibility<\/td>\n<td>Load variables individually, load them all at once, or load them from diverse sources<\/td>\n<\/tr>\n<tr>\n<td>Security<\/td>\n<td>Separate sensitive data from application code and load it only when needed<\/td>\n<\/tr>\n<tr>\n<td>Convenience<\/td>\n<td>Simple and intuitive API for managing environment variables<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>By allowing you to separate your sensitive data from your application code and load it only when needed, python-dotenv enhances the security of your application. Its simple and intuitive API makes managing your environment variables a breeze.<\/p>\n<h3>Further Resources for Environment Variables<\/h3>\n<p>For more info on Environment Variables, <a class=\"wp-editor-md-post-content-link\" href=\"https:\/\/ioflood.com\/blog\/python-command-line-arguments\/\">Click Here<\/a> for info on Python CLI best practices for clean interfaces, which can help further your usage of Environment Variables.<\/p>\n<p>To further your understanding of Environment Variables we have sourced some resources that will assist you in deepening your knowledge:<\/p>\n<ul>\n<li><a class=\"wp-editor-md-post-content-link\" href=\"https:\/\/ioflood.com\/blog\/python-args\/\">Function Definitions with args in Python<\/a> &#8211; Learn how args simplifies passing multiple arguments to functions.<\/p>\n<\/li>\n<li>\n<p><a class=\"wp-editor-md-post-content-link\" href=\"https:\/\/ioflood.com\/blog\/python-kwargs\/\">Function Parameter Handling with kwargs in Python<\/a> &#8211; Learn how **kwargs simplifies passing keyword arguments.<\/p>\n<\/li>\n<li>\n<p><a class=\"wp-editor-md-post-content-link\" href=\"https:\/\/blog.enterprisedna.co\/python-dotenv\/\" target=\"_blank\" rel=\"noopener\">Managing Environment Variables with Python-dotenv<\/a> &#8211; Understand the concepts of managing environment variables using python-dotenv.<\/p>\n<\/li>\n<li>\n<p><a class=\"wp-editor-md-post-content-link\" href=\"https:\/\/pypi.org\/project\/python-dotenv\/\" target=\"_blank\" rel=\"noopener\">Python-dotenv on PyPi<\/a> &#8211; Learn about python-dotenv, a module that allows you to specify environment variables.<\/p>\n<\/li>\n<li>\n<p>Pieran Training&#8217;s <a class=\"wp-editor-md-post-content-link\" href=\"https:\/\/pieriantraining.com\/python-tutorial-how-to-use-environment-variables-in-python\/\" target=\"_blank\" rel=\"noopener\">Tutorial on Environment Variables<\/a> is a guide on how to effectively use environment variables in Python.<\/p>\n<\/li>\n<\/ul>\n<h2>Final Thoughts<\/h2>\n<p>In this comprehensive guide, we&#8217;ve journeyed through the world of python-dotenv, an influential library for managing environment variables in Python applications. We&#8217;ve highlighted how python-dotenv assists you in safeguarding your sensitive data, keeping it separate from your application code, and loading it only when necessary, thereby enhancing the security and integrity of your applications.<\/p>\n<p>We&#8217;ve also ventured into the advanced features of python-dotenv, from variable expansions and dynamic configurations to its command-line interface and integration with Django projects. These features underscore python-dotenv as a versatile and flexible tool, capable of handling an extensive range of use cases.<\/p>\n<blockquote><p>\n  To master Python&#8217;s subtleties, <a class=\"wp-editor-md-post-content-link\" href=\"https:\/\/ioflood.com\/blog\/python-syntax-cheat-sheet\/\">click here<\/a> for a treasure trove of tips and tricks.\n<\/p><\/blockquote>\n<p>Whether you&#8217;re a novice just embarking on your Python development journey or a seasoned developer managing a large-scale project, python-dotenv is a tool you&#8217;ll want to have in your repertoire. So, why hold back? Start using python-dotenv today and experience the difference for yourself!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Are you wrestling with the task of managing sensitive data in your Python application? Do you feel like you&#8217;re treading on thin ice when it comes to handling confidential information? You&#8217;re not alone. We have a powerful solution for you &#8211; the python-dotenv library. This library is a game-changer for securely managing environment variables in [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":17145,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[121,123],"tags":[],"class_list":["post-3469","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-programming-coding","category-python","cat-121-id","cat-123-id","has_thumb"],"_links":{"self":[{"href":"https:\/\/ioflood.com\/blog\/wp-json\/wp\/v2\/posts\/3469","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ioflood.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ioflood.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ioflood.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ioflood.com\/blog\/wp-json\/wp\/v2\/comments?post=3469"}],"version-history":[{"count":13,"href":"https:\/\/ioflood.com\/blog\/wp-json\/wp\/v2\/posts\/3469\/revisions"}],"predecessor-version":[{"id":17155,"href":"https:\/\/ioflood.com\/blog\/wp-json\/wp\/v2\/posts\/3469\/revisions\/17155"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ioflood.com\/blog\/wp-json\/wp\/v2\/media\/17145"}],"wp:attachment":[{"href":"https:\/\/ioflood.com\/blog\/wp-json\/wp\/v2\/media?parent=3469"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ioflood.com\/blog\/wp-json\/wp\/v2\/categories?post=3469"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ioflood.com\/blog\/wp-json\/wp\/v2\/tags?post=3469"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}