Skip to content
This repository has been archived by the owner on Nov 6, 2022. It is now read-only.

Commit

Permalink
v1.0.9 :octocat:
Browse files Browse the repository at this point in the history
  • Loading branch information
RobertoPrevato authored May 23, 2021
1 parent 1e43db4 commit 302bf52
Show file tree
Hide file tree
Showing 9 changed files with 224 additions and 136 deletions.
44 changes: 0 additions & 44 deletions .azuredevops/build.yml

This file was deleted.

3 changes: 3 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# These are supported funding model platforms

github: RobertoPrevato
101 changes: 101 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
name: Build

on:
release:
types: [published]
push:
branches:
- main
- ci
pull_request:
branches:
- "*"

env:
PROJECT_NAME: roconfiguration

jobs:
build:
runs-on: ubuntu-18.04
strategy:
matrix:
python-version: [3.6, 3.7, 3.8, 3.9]

steps:
- uses: actions/checkout@v1
with:
fetch-depth: 9
submodules: false

- name: Use Python ${{ matrix.python-version }}
uses: actions/setup-python@v1
with:
python-version: ${{ matrix.python-version }}

- uses: actions/cache@v1
id: depcache
with:
path: deps
key: requirements-pip-${{ matrix.python-version }}-${{ hashFiles('requirements.txt') }}

- name: Download dependencies
if: steps.depcache.outputs.cache-hit != 'true'
run: |
pip download --dest=deps -r requirements.txt
- name: Install dependencies
run: |
pip install -U --no-index --find-links=deps deps/*
- name: Run tests
run: |
flake8 && pytest --doctest-modules --junitxml=junit/pytest-results-${{ matrix.python-version }}.xml --cov=$PROJECT_NAME --cov-report=xml tests/
- name: Upload pytest test results
uses: actions/upload-artifact@master
with:
name: pytest-results-${{ matrix.python-version }}
path: junit/pytest-results-${{ matrix.python-version }}.xml
if: always()

- name: Codecov
run: |
bash <(curl -s https://codecov.io/bash)
- name: Install distribution dependencies
run: pip install --upgrade twine setuptools wheel
if: matrix.python-version == 3.8 || matrix.python-version == 3.9

- name: Create distribution package
run: python setup.py sdist bdist_wheel
if: matrix.python-version == 3.8 || matrix.python-version == 3.9

- name: Upload distribution package
uses: actions/upload-artifact@master
with:
name: dist-package-${{ matrix.python-version }}
path: dist
if: matrix.python-version == 3.8 || matrix.python-version == 3.9

publish:
runs-on: ubuntu-18.04
needs: build
if: github.event_name == 'release'
steps:
- name: Download a distribution artifact
uses: actions/download-artifact@v2
with:
name: dist-package-3.9
path: dist
- name: Publish distribution 📦 to Test PyPI
uses: pypa/gh-action-pypi-publish@master
with:
skip_existing: true
user: __token__
password: ${{ secrets.test_pypi_password }}
repository_url: https://test.pypi.org/legacy/
- name: Publish distribution 📦 to PyPI
uses: pypa/gh-action-pypi-publish@master
with:
user: __token__
password: ${{ secrets.pypi_password }}
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.0.9] - 2022-05-23 :octocat:
- Completely migrates to GitHub Workflows
- Improves build to test Python 3.6 and 3.9
- Adds a changelog
- Improves badges
118 changes: 67 additions & 51 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
[![Build status](https://dev.azure.com/robertoprevato/roconfiguration/_apis/build/status/roconfiguration-CI)](https://dev.azure.com/robertoprevato/roconfiguration/_build/latest?definitionId=34) [![pypi](https://img.shields.io/pypi/v/roconfiguration.svg?color=blue)](https://pypi.org/project/roconfiguration/) [![Test coverage](https://img.shields.io/azure-devops/coverage/robertoprevato/roconfiguration/10.svg)](https://dev.azure.com/robertoprevato/roconfiguration/_build?definitionId=10) [![Python 3.7](https://img.shields.io/badge/python-3.7-blue.svg)](https://www.python.org/downloads/release/python-370/) [![Python 3.8](https://img.shields.io/badge/python-3.8-blue.svg)](https://www.python.org/downloads/release/python-380/)
![Build](https://github.com/Neoteroi/roconfiguration/workflows/Build/badge.svg)
[![pypi](https://img.shields.io/pypi/v/roconfiguration.svg)](https://pypi.python.org/pypi/roconfiguration)
[![versions](https://img.shields.io/pypi/pyversions/roconfiguration.svg)](https://github.com/Neoteroi/roconfiguration)
[![codecov](https://codecov.io/gh/Neoteroi/roconfiguration/branch/main/graph/badge.svg?token=VzAnusWIZt)](https://codecov.io/gh/Neoteroi/roconfiguration)
[![license](https://img.shields.io/github/license/Neoteroi/roconfiguration.svg)](https://github.com/Neoteroi/roconfiguration/blob/master/LICENSE)

# Python configuration utilities
Implementation of key-value pair based configuration for Python applications.
Expand All @@ -11,7 +15,7 @@ Implementation of key-value pair based configuration for Python applications.

This library is freely inspired by .NET Core `Microsoft.Extensions.Configuration` namespace and its pleasant design (_ref. [MSDN documentation](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-2.1), [Microsoft Extensions Configuration Deep Dive](https://www.paraesthesia.com/archive/2018/06/20/microsoft-extensions-configuration-deep-dive/)_).

The main class is influenced by Luciano Ramalho's example of
The main class is influenced by Luciano Ramalho`s example of
JSON structure explorer using attribute notation, in his book [Fluent Python](http://shop.oreilly.com/product/0636920032519.do).

## Supported sources:
Expand All @@ -30,31 +34,36 @@ pip install roconfiguration
# Examples

### YAML file and environmental variables
In this example, configuration will be comprised of anything inside a file `settings.yaml` and environmental variables. Settings are applied in order, so environmental variables with matching name override values from the `yaml` file.
In this example, configuration will be comprised of anything inside a file
`settings.yaml` and environmental variables. Settings are applied in order, so
environmental variables with matching name override values from the `yaml`
file.


```python
from roconfiguration import Configuration

config = Configuration()

config.add_yaml_file('settings.yaml')
config.add_yaml_file("settings.yaml")

config.add_environmental_variables()
```

### YAML file, optional file by environment
In this example, if an environmental variable with name `APP_ENVIRONMENT` and value `dev` exists, and a configuration file with name `settings.dev.yaml` is present, it is read to override values configured in `settings.yaml` file.
In this example, if an environmental variable with name `APP_ENVIRONMENT` and
value `dev` exists, and a configuration file with name `settings.dev.yaml` is
present, it is read to override values configured in `settings.yaml` file.
```python
import os
from roconfiguration import Configuration

environment_name = os.environ['APP_ENVIRONMENT']
environment_name = os.environ["APP_ENVIRONMENT"]

config = Configuration()

config.add_yaml_file('settings.yaml')
config.add_yaml_file(f'settings.{environment_name}.yaml', optional=True)
config.add_yaml_file("settings.yaml")
config.add_yaml_file(f"settings.{environment_name}.yaml", optional=True)

config.add_environmental_variables()
```
Expand All @@ -67,18 +76,19 @@ from roconfiguration import Configuration
config = Configuration()

# will read only environmental variables
# starting with 'APP_', case insensitively
config.add_environmental_variables('APP_')
# starting with "APP_", case insensitively
config.add_environmental_variables("APP_")
```

### Ini files
Ini files are parsed using the built-in `configparser` module, therefore support `[DEFAULT]` section; all values are kept as strings.
Ini files are parsed using the built-in `configparser` module, therefore
support `[DEFAULT]` section; all values are kept as strings.
```python
from roconfiguration import Configuration

config = Configuration()

config.add_ini_file('settings.ini')
config.add_ini_file("settings.ini")
```

### JSON files
Expand All @@ -88,27 +98,20 @@ from roconfiguration import Configuration

config = Configuration()

config.add_json_file('settings.json')
config.add_json_file("settings.json")
```

### Dictionaries
```python
from roconfiguration import Configuration

config = Configuration({'host': 'localhost', 'port': 8080})
config = Configuration({"host": "localhost", "port": 8080})

config.add_map({
'hello': 'world',
'example': [{
'id': 1
}, {
'id': 2
}]
})
config.add_map({"hello": "world", "example": [{"id": 1}, {"id": 2}]})

assert config.host == 'localhost'
assert config.host == "localhost"
assert config.port == 8080
assert config.hello == 'world'
assert config.hello == "world"
assert config.example[0].id == 1
assert config.example[1].id == 2
```
Expand All @@ -117,45 +120,53 @@ assert config.example[1].id == 2
```python
from roconfiguration import Configuration

config = Configuration({'host': 'localhost', 'port': 8080})
config = Configuration({"host": "localhost", "port": 8080})

config.add_value('port', 44555)
config.add_value("port", 44555)

assert config.host == 'localhost'
assert config.host == "localhost"
assert config.port == 44555
```

### Overriding nested values
```python
config = Configuration({'a': {
'b': 1,
'c': 2,
'd': {
'e': 3,
'f': 4
config = Configuration(
{
"a": {
"b": 1,
"c": 2,
"d": {
"e": 3,
"f": 4,
},
}
}
}})
)

assert config.a.b == 1
assert config.a.d.e == 3
assert config.a.d.f == 4

config.add_value('a:d:e', 5)
config.add_value("a:d:e", 5)

assert config.a.d.e == 5
assert config.a.d.f == 4
```

### Overriding nested values using env variables
```python
config = Configuration({'a': {
'b': 1,
'c': 2,
'd': {
'e': 3,
'f': 4
config = Configuration(
{
"a": {
"b": 1,
"c": 2,
"d": {
"e": 3,
"f": 4,
},
}
}
}})
)

assert config.a.b == 1
assert config.a.d.e == 3
Expand All @@ -171,21 +182,26 @@ assert config.a.d.f == 4
config.add_environmental_variables()

assert config.a.d.e == 5

```

### Overriding values in list items using env variables
```python
config = Configuration({'b2c': [
{'tenant': '1'},
{'tenant': '2'},
{'tenant': '3'}
]})
config = Configuration(
{
"b2c": [
{"tenant": "1"},
{"tenant": "2"},
{"tenant": "3"},
]
}
)

config.add_value('b2c:1:tenant', '4')
config.add_value("b2c:1:tenant", "4")

assert config.b2c[0].tenant == '1'
assert config.b2c[1].tenant == '4'
assert config.b2c[2].tenant == '3'
assert config.b2c[0].tenant == "1"
assert config.b2c[1].tenant == "4"
assert config.b2c[2].tenant == "3"
```

---
Expand Down
Loading

0 comments on commit 302bf52

Please sign in to comment.