Skip to content

Commit 401cd93

Browse files
authored
Merge pull request #366 from bj00rn/feat/read-env-from-file
Read env variables from .env file if present
2 parents 8b513ca + cff3253 commit 401cd93

File tree

5 files changed

+40
-6
lines changed

5 files changed

+40
-6
lines changed

README.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,17 @@ the [SAIC-iSmart-API Documentation](https://github.com/SAIC-iSmart-API/documenta
1414

1515
## Configuration
1616

17-
Configuration parameters can be provided as command line parameters or environment variables (this is what you typically
17+
Configuration parameters can be provided as
18+
* Command line parameters
19+
* Environment variables (this is what you typically
1820
do when you run the service from a docker container).
21+
* A local [.env file](https://saurabh-kumar.com/python-dotenv/#file-format) in current working directory (`CWD`) where the program is started from. When running in docker container the `CWD` container root is `/usr/src/app`.
22+
23+
When using combinations of configuration methods, the order of precedence is as follows.
24+
25+
1. Command line parameters
26+
2. Environment variables
27+
3. Local .env file
1928

2029
### SAIC API
2130

@@ -151,7 +160,9 @@ $ docker build -t saic-mqtt-gateway .
151160

152161
There is a [docker compose file](docker-compose.yml) that shows how to set up the service.
153162

154-
First setup the hidden ".env" file in the root directory of the project with your specific data
163+
First setup the hidden `.env` file in the root directory of the project with your specific data. The contents of this file will populate environment variables inside the container.
164+
165+
Alternatively, if you are conserned about security you can define your variables inside `.secret.env` and mount this file as `/usr/src/app/.env` in the container.
155166

156167
Test your setup with
157168
```

docker-compose.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ services:
1313
- SAIC_PASSWORD=${SAIC_PWD}
1414
- CHARGING_STATIONS_JSON=/usr/src/app/config/charging-stations.json
1515
volumes:
16+
# - ./.secret.env:/usr/src/app/.env:ro # Uncomment to use a secret environment file
1617
- ./examples:/usr/src/app/config/

poetry.lock

Lines changed: 16 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ dependencies = [
2121
'gmqtt (>=0.7.0,<0.8.0)',
2222
'inflection (>=0.5.1,<0.6.0)',
2323
'apscheduler (>=3.11.0,<4.0.0)',
24+
'python-dotenv (>=1.1.1,<2.0.0)',
2425
]
2526

2627
[project.urls]

src/configuration/argparse_extensions.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,16 @@
66
import os
77
from typing import TYPE_CHECKING, Any, override
88

9+
from dotenv import dotenv_values
10+
911
if TYPE_CHECKING:
1012
from collections.abc import Callable, Sequence
1113

1214

15+
# load .env file and merge with os.environ
16+
merged_environ = {**dotenv_values(".env"), **os.environ}
17+
18+
1319
class ArgumentHelpFormatter(argparse.RawTextHelpFormatter):
1420
"""Custom argument formatter.
1521
@@ -40,7 +46,7 @@ def _get_help_string(self, action: argparse.Action) -> str | None:
4046
_help += _("\n(default: %(default)s)")
4147
# append environment variable
4248
_help += f"\n(environment variable: {action.envvar})"
43-
# whitespace from each line
49+
# strip whitespace from each line
4450
return "\n".join([m.lstrip() for m in _help.split("\n")])
4551

4652

@@ -53,8 +59,8 @@ def __init__(
5359
**kwargs: dict[str, Any],
5460
) -> None:
5561
self.envvar = envvar
56-
if os.environ.get(envvar):
57-
default = os.environ[envvar]
62+
if merged_environ.get(envvar):
63+
default = merged_environ[envvar]
5864
if required and default:
5965
required = False
6066
super().__init__(default=default, required=required, **kwargs)

0 commit comments

Comments
 (0)