1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
|
# expandvars
Expand system variables Unix style
[](https://pypi.org/project/expandvars)
[](https://codecov.io/gh/sayanarijit/expandvars)
## Inspiration
This module is inspired by [GNU bash's variable expansion features](https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html). It can be used as an alternative to Python's [os.path.expandvars](https://docs.python.org/3/library/os.path.html#os.path.expandvars) function.
A good use case is reading config files with the flexibility of reading values from environment variables using advanced features like returning a default value if some variable is not defined.
For example:
```toml
[default]
my_secret_access_code = "${ACCESS_CODE:-default_access_code}"
my_important_variable = "${IMPORTANT_VARIABLE:?}"
my_updated_path = "$PATH:$HOME/.bin"
my_process_id = "$$"
my_nested_variable = "${!NESTED}"
```
> NOTE: Although this module copies most of the common behaviours of bash,
> it doesn't follow bash strictly. For example, it doesn't work with arrays.
## Installation
### Pip
```
pip install expandvars
```
### Conda
```
conda install -c conda-forge expandvars
```
## Usage
```python
from expandvars import expandvars
print(expandvars("$PATH:${HOME:?}/bin:${SOME_UNDEFINED_PATH:-/default/path}"))
# /bin:/sbin:/usr/bin:/usr/sbin:/home/you/bin:/default/path
```
## Examples
For now, [refer to the test cases](https://github.com/sayanarijit/expandvars/blob/master/tests) to see how it behaves.
## TIPs
### nounset=True
If you want to enable strict parsing by default, (similar to `set -u` / `set -o nounset` in bash), pass `nounset=True`.
```python
# All the variables must be defined.
expandvars("$VAR1:${VAR2}:$VAR3", nounset=True)
# Raises UnboundVariable error.
```
> NOTE: Another way is to use the `${VAR?}` or `${VAR:?}` syntax. See the examples in tests.
### EXPANDVARS_RECOVER_NULL="foo"
If you want to temporarily disable strict parsing both for `nounset=True` and the `${VAR:?}` syntax, set environment variable `EXPANDVARS_RECOVER_NULL=somevalue`.
This helps with certain use cases where you need to temporarily disable strict parsing of critical env vars, e.g. in testing environment, without modifying the code.
e.g.
```bash
EXPANDVARS_RECOVER_NULL=foo myapp --config production.ini && echo "All fine."
```
> WARNING: Try to avoid `export EXPANDVARS_RECOVER_NULL` because that will disable strict parsing permanently until you log out.
### Customization
You can customize the variable symbol, escape character, whether to expand non-surrounded variables and data used for the expansion by using the more general `expand` function.
```python
from expandvars import expand
print(expand("%PATH:$HOME/bin:%{SOME_UNDEFINED_PATH:-D:\\default\\path}", environ={"PATH": "/example"}, var_symbol="%", surrounded_vars_only=True, escape_char=""))
# %PATH:$HOME/bin:D:\default\path
```
## Contributing
To contribute, setup environment following way:
Then
```bash
# Clone repo
git clone https://github.com/sayanarijit/expandvars && cd expandvars
# Setup virtualenv
python -m venv .venv
source ./.venv/bin/activate
# Install as editable including test dependencies
pip install -e ".[tests]"
```
- Follow [general git guidelines](https://git-scm.com/book/en/v2/Distributed-Git-Contributing-to-a-Project).
- Keep it simple. Run `black .` to auto format the code.
- Test your changes locally by running `pytest` (pass `--cov --cov-report html` for browsable coverage report).
- If you are familiar with [tox](https://tox.readthedocs.io), you may want to use it for testing in different python versions.
## Alternatives
- [environs](https://github.com/sloria/environs) - simplified environment variable parsing.
|