Python How-To: Creating And Using Environment Variables Part One
Tags: python, programming, tutorial, beginners
Published: 2023-06-05 12:05:00

- [Introduction](#introduction)
- [The os Module](#the-os-module)
- [Creating Environment Variables](#creating-environment-variables)
  - [Method One: Creating Environment Variables Via The Operating System](#method-one-creating-environment-variables-via-the-operating-system)
    - [Linux and macOS](#linux-and-macos)
    - [Windows](#windows)
  - [Method Two: Creating Environment Variables Using Python](#method-two-creating-environment-variables-using-python)
- [Getting Environment Variables With The OS Module](#getting-environment-variables-with-the-os-module)
  - [Example One: Working With A String](#example-one-working-with-a-string)
  - [Example Two: Working With A Number](#example-two-working-with-a-number)
  - [Example Three: Working With A Boolean](#example-three-working-with-a-boolean)
- [Conclusion](#conclusion)
- [References](#references)

## Introduction

Environment variables are used in a program to set the values of variables or constants within that program. The environment variables exist at the operating system level. This allows for the environment variables to be fluid in that they can be changed for different stages of the software development lifecycle without storing / changing the values in the source code for each stage (dev / test / production).

From a security perspective, it means that the source code does not have the values of its variables hard-coded into them. An example of this would be storing an API key as an environment variable instead of setting the value in a variable / constant in the source code. If that happened and was then sent up to a public (or even a private) Git repository, that would be a major security threat.

## The os Module

For Python to interact with the operating system, the `os` module is used. It can perform actions such as:

- Creating and reading environment variables.
- Getting details about the operating system, such as the type of operating system it is.
- Working with files and file paths.

There are a lot more that it can do, which is covered in the [modules documentation](https://docs.python.org/3/library/os.html).

So how can environment variables be created and used?

## Creating Environment Variables

First up, let's create some environment variables to work with. There are multiple ways to do this, but this article will focus on two. The first of which is to create them via the operating system with the second being via Python using `os.environ`.

Three example environment variables will be created, each with a different data type.

For both methods:

- EXAMPLE_ONE is just a string of text. This is a typical use case for most data that would be assigned to an environment variable.
- EXAMPLE_TWO is a number. Or is it? More on that later.
- EXAMPLE_THREE is a boolean. Or perhaps not. Again, more on that later.

### Method One: Creating Environment Variables Via The Operating System

**NOTE**: On Linux / macOS, if the string has spaces in it, the string will need to be wrapped in `""`, otherwise only the text up to the first space will be assigned. Windows is fine without them.

#### Linux and macOS

Using a terminal emulator app, run:

``` console
export EXAMPLE_ONE="This is an environment variable"
export EXAMPLE_TWO=1
export EXAMPLE_THREE=False
```

If an environment variable needs to be persistent for Linux or macOS, it will need to be added to the users `.bashrc` or `.zshrc` file in their home directory using the same syntax.

#### Windows

Using the command prompt (cmd.exe), run:

``` console
set EXAMPLE_ONE=This is an environment variable
set EXAMPLE_TWO=1
set EXAMPLE_THREE=False
```

To set persistent environment variables in Windows, use the `setx` command with the syntax being:

``` console
setx EXAMPLE_ONE "This is an environment variable"
setx EXAMPLE_TWO "1"
setx EXAMPLE_THREE "False"
```

### Method Two: Creating Environment Variables Using Python

For all three operating system types, the method is the same in Python by using `os.environ`:

``` python
import os


os.environ["EXAMPLE_ONE"] = "This is an environment variable"
os.environ["EXAMPLE_TWO"] = "1"
os.environ["EXAMPLE_THREE"] = "False"
```

**NOTE**: When Python is closed, these environment variables will be removed.

## Getting Environment Variables With The OS Module

There are two methods that can be used to access an environment variable using the `os` module. The first method is via `os.environ`. It requires the environment variable name to be passed to it in a list. For example:

``` python
import os


print(os.environ["EXAMPLE_ONE"])
```

Output:

``` console
This is an environment variable
```

There is one downside to this method, which is open to interpretation. If the environment variable is not present, it will raise a `KeyError` and cause a hard stop. An example of this is shown below:

``` console
Traceback (most recent call last):
  File "/Users/neil/Documents/writing/blog-posts/code.py", line 11, in <module>
    print(os.environ["EXAMPLE_ONE"])
                ~~~~~~~~~~^^^^^^^^^^^^^^^
  File "<frozen os>", line 679, in __getitem__
KeyError: 'EXAMPLE_ONE'
```

Now, this might be what is required to happen, which is fine. But let's say that it isn't and the code needs to continue. To get around this, `os.getenv` is a useful solution. What this will do is instead of erroring out, it will set the value to `None` for any missing environment variables instead.

For the examples going forward, the `os.getenv` method will be used.

### Example One: Working With A String

The first example will get the value or the `EXAMPLE_ONE` environment variable and show its value.

``` python
import os


example_one = os.getenv("EXAMPLE_ONE")
print(f"Example One Value: {example_one}")
print(type(example_one))
```

Output:

``` console
Example One Value: This is an environment variable
<class 'str'>
```

From the output, the value of `example_one` is shown and it has a data type of `str` (string).

### Example Two: Working With A Number

This is where things get problematic. Remember how Example Two was described earlier ("EXAMPLE_TWO is a number. Or is it?"). Well, although it looks like a number, it is actually a string data type. This is because environment variables are treated as strings, no matter what the value is.

For example, let's access the `EXAMPLE_TWO` environment variable and see what data type it has:

``` python
import os


example_two = os.getenv("EXAMPLE_TWO")
print(f"Example Two Value: {example_two}")
print(type(example_two))
```

Output:

``` console
Example Two Value: 1
<class 'str'>
```

As can be seen, the data type class is `str` (string). So how can the value be used as a number, in this case an integer? It is done by enforcing the data type to the `example_two` variable using the `int` class. For example:

``` python
import os


example_two = int(os.getenv("EXAMPLE_TWO"))
print(f"Example Two Value: {example_two}")
print(type(example_two_int))
```

Output:

``` console
Example Two Value: 1
<class 'int'>
```

The output looks the same but the data type for `example_two` is now an integer (int). This will now allow it to be used for any mathematical operations.

There is one further issue. What if the environment variable is not an integer number but rather a string, float, boolean or just doesn't exist?

If it doesn't exist, the value would be set to `None`. If it did exist and is not an integer, it would be set to that value. But, as the data type is enforced as an integer, a `ValueError` would be raised for both cases.

A solution for this would be to use the `try` block to check it.

The following example will check the value of `EXAMPLE_TWO` and if it can't be set to an integer data type due to the value not being an integer, it will set `example_two` to `0`:

First, change `EXAMPLE_TWO` to a non-number-based value:

Operating system method:

``` console
export EXAMPLE_TWO="I am not a number"
```

Or via Python:

``` python
import os


os.environ["EXAMPLE_TWO"] = "I am not a number"
```

Next, use the `try` block to check and set the value of `example_two`:

``` python
import os


try:
    example_two_int = int(os.getenv("EXAMPLE_TWO"))

except ValueError:
    example_two_int = 0

print(f"Example Two Value: {example_two_int}")
print(type(example_two_int))
```

Output:

``` console
Example Two Value: 0
<class 'int'>
```

As `EXAMPLE_TWO` was not a numeric value, a `ValueError` was raised and as a result, the value of `example_two` was set to `0`.

### Example Three: Working With A Boolean

Just as in example two, an environment variable with what looks like a boolean value will have a string data type. This will mean that it cannot be used for boolean operations.

One of the additional issues with boolean values is how they can be presented. For example, in Python a boolean value is set to either `True` or `False`. In other languages, such as JavaScript, they are set to either `true` or `false`. There are others, such as yes / no, y / n, 0 / 1 or on / off.

So, how can we set a boolean data type when there are a lot of possible ways that an environment variable can be set with a boolean value? This is actually easy to do with Python. Start by putting as many of the possible ways to present a `True` value in a list and compare the value that is assigned to the environment variable. If the value matches one of the entries in the list, the value of the variable will be set to `True`. If not, it will be `False`.

For example, set a `False` boolean value:

``` python
import os


example_three = os.getenv("EXAMPLE_THREE") # --- Currently set to "False"
example_three = example_three.lower() in ["true", "1", "1.0", "y", "yes", "on"]
print(f"Example Three Value: {example_three}")
print(type(example_three))
```

Output:

``` console
Example Three Value: False
<class 'bool'>
```

In the above example, the value of `example_three` was converted to all lowercase to make it easier to check against and then compared to each entry in the list. As it didn't match, the new value of `example_three` is `False` but with a data type class of `bool`, which is what is needed.

## Conclusion

I hope that this article was useful. There will be a follow up article to this that will cover using .env files for creating environment variables.

Thank you for reading and have a nice day!

## References

[Python os module documentation.](https://docs.python.org/3/library/os.html)