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

Commit 302bf52

Browse files
v1.0.9 :octocat:
1 parent 1e43db4 commit 302bf52

9 files changed

Lines changed: 224 additions & 136 deletions

File tree

.azuredevops/build.yml

Lines changed: 0 additions & 44 deletions
This file was deleted.

.github/FUNDING.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# These are supported funding model platforms
2+
3+
github: RobertoPrevato

.github/workflows/build.yml

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
name: Build
2+
3+
on:
4+
release:
5+
types: [published]
6+
push:
7+
branches:
8+
- main
9+
- ci
10+
pull_request:
11+
branches:
12+
- "*"
13+
14+
env:
15+
PROJECT_NAME: roconfiguration
16+
17+
jobs:
18+
build:
19+
runs-on: ubuntu-18.04
20+
strategy:
21+
matrix:
22+
python-version: [3.6, 3.7, 3.8, 3.9]
23+
24+
steps:
25+
- uses: actions/checkout@v1
26+
with:
27+
fetch-depth: 9
28+
submodules: false
29+
30+
- name: Use Python ${{ matrix.python-version }}
31+
uses: actions/setup-python@v1
32+
with:
33+
python-version: ${{ matrix.python-version }}
34+
35+
- uses: actions/cache@v1
36+
id: depcache
37+
with:
38+
path: deps
39+
key: requirements-pip-${{ matrix.python-version }}-${{ hashFiles('requirements.txt') }}
40+
41+
- name: Download dependencies
42+
if: steps.depcache.outputs.cache-hit != 'true'
43+
run: |
44+
pip download --dest=deps -r requirements.txt
45+
46+
- name: Install dependencies
47+
run: |
48+
pip install -U --no-index --find-links=deps deps/*
49+
50+
- name: Run tests
51+
run: |
52+
flake8 && pytest --doctest-modules --junitxml=junit/pytest-results-${{ matrix.python-version }}.xml --cov=$PROJECT_NAME --cov-report=xml tests/
53+
54+
- name: Upload pytest test results
55+
uses: actions/upload-artifact@master
56+
with:
57+
name: pytest-results-${{ matrix.python-version }}
58+
path: junit/pytest-results-${{ matrix.python-version }}.xml
59+
if: always()
60+
61+
- name: Codecov
62+
run: |
63+
bash <(curl -s https://codecov.io/bash)
64+
65+
- name: Install distribution dependencies
66+
run: pip install --upgrade twine setuptools wheel
67+
if: matrix.python-version == 3.8 || matrix.python-version == 3.9
68+
69+
- name: Create distribution package
70+
run: python setup.py sdist bdist_wheel
71+
if: matrix.python-version == 3.8 || matrix.python-version == 3.9
72+
73+
- name: Upload distribution package
74+
uses: actions/upload-artifact@master
75+
with:
76+
name: dist-package-${{ matrix.python-version }}
77+
path: dist
78+
if: matrix.python-version == 3.8 || matrix.python-version == 3.9
79+
80+
publish:
81+
runs-on: ubuntu-18.04
82+
needs: build
83+
if: github.event_name == 'release'
84+
steps:
85+
- name: Download a distribution artifact
86+
uses: actions/download-artifact@v2
87+
with:
88+
name: dist-package-3.9
89+
path: dist
90+
- name: Publish distribution 📦 to Test PyPI
91+
uses: pypa/gh-action-pypi-publish@master
92+
with:
93+
skip_existing: true
94+
user: __token__
95+
password: ${{ secrets.test_pypi_password }}
96+
repository_url: https://test.pypi.org/legacy/
97+
- name: Publish distribution 📦 to PyPI
98+
uses: pypa/gh-action-pypi-publish@master
99+
with:
100+
user: __token__
101+
password: ${{ secrets.pypi_password }}

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [1.0.9] - 2022-05-23 :octocat:
9+
- Completely migrates to GitHub Workflows
10+
- Improves build to test Python 3.6 and 3.9
11+
- Adds a changelog
12+
- Improves badges

README.md

Lines changed: 67 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
[![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/)
1+
![Build](https://github.com/Neoteroi/roconfiguration/workflows/Build/badge.svg)
2+
[![pypi](https://img.shields.io/pypi/v/roconfiguration.svg)](https://pypi.python.org/pypi/roconfiguration)
3+
[![versions](https://img.shields.io/pypi/pyversions/roconfiguration.svg)](https://github.com/Neoteroi/roconfiguration)
4+
[![codecov](https://codecov.io/gh/Neoteroi/roconfiguration/branch/main/graph/badge.svg?token=VzAnusWIZt)](https://codecov.io/gh/Neoteroi/roconfiguration)
5+
[![license](https://img.shields.io/github/license/Neoteroi/roconfiguration.svg)](https://github.com/Neoteroi/roconfiguration/blob/master/LICENSE)
26

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

1216
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/)_).
1317

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

1721
## Supported sources:
@@ -30,31 +34,36 @@ pip install roconfiguration
3034
# Examples
3135

3236
### YAML file and environmental variables
33-
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.
37+
In this example, configuration will be comprised of anything inside a file
38+
`settings.yaml` and environmental variables. Settings are applied in order, so
39+
environmental variables with matching name override values from the `yaml`
40+
file.
3441

3542

3643
```python
3744
from roconfiguration import Configuration
3845

3946
config = Configuration()
4047

41-
config.add_yaml_file('settings.yaml')
48+
config.add_yaml_file("settings.yaml")
4249

4350
config.add_environmental_variables()
4451
```
4552

4653
### YAML file, optional file by environment
47-
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.
54+
In this example, if an environmental variable with name `APP_ENVIRONMENT` and
55+
value `dev` exists, and a configuration file with name `settings.dev.yaml` is
56+
present, it is read to override values configured in `settings.yaml` file.
4857
```python
4958
import os
5059
from roconfiguration import Configuration
5160

52-
environment_name = os.environ['APP_ENVIRONMENT']
61+
environment_name = os.environ["APP_ENVIRONMENT"]
5362

5463
config = Configuration()
5564

56-
config.add_yaml_file('settings.yaml')
57-
config.add_yaml_file(f'settings.{environment_name}.yaml', optional=True)
65+
config.add_yaml_file("settings.yaml")
66+
config.add_yaml_file(f"settings.{environment_name}.yaml", optional=True)
5867

5968
config.add_environmental_variables()
6069
```
@@ -67,18 +76,19 @@ from roconfiguration import Configuration
6776
config = Configuration()
6877

6978
# will read only environmental variables
70-
# starting with 'APP_', case insensitively
71-
config.add_environmental_variables('APP_')
79+
# starting with "APP_", case insensitively
80+
config.add_environmental_variables("APP_")
7281
```
7382

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

7989
config = Configuration()
8090

81-
config.add_ini_file('settings.ini')
91+
config.add_ini_file("settings.ini")
8292
```
8393

8494
### JSON files
@@ -88,27 +98,20 @@ from roconfiguration import Configuration
8898

8999
config = Configuration()
90100

91-
config.add_json_file('settings.json')
101+
config.add_json_file("settings.json")
92102
```
93103

94104
### Dictionaries
95105
```python
96106
from roconfiguration import Configuration
97107

98-
config = Configuration({'host': 'localhost', 'port': 8080})
108+
config = Configuration({"host": "localhost", "port": 8080})
99109

100-
config.add_map({
101-
'hello': 'world',
102-
'example': [{
103-
'id': 1
104-
}, {
105-
'id': 2
106-
}]
107-
})
110+
config.add_map({"hello": "world", "example": [{"id": 1}, {"id": 2}]})
108111

109-
assert config.host == 'localhost'
112+
assert config.host == "localhost"
110113
assert config.port == 8080
111-
assert config.hello == 'world'
114+
assert config.hello == "world"
112115
assert config.example[0].id == 1
113116
assert config.example[1].id == 2
114117
```
@@ -117,45 +120,53 @@ assert config.example[1].id == 2
117120
```python
118121
from roconfiguration import Configuration
119122

120-
config = Configuration({'host': 'localhost', 'port': 8080})
123+
config = Configuration({"host": "localhost", "port": 8080})
121124

122-
config.add_value('port', 44555)
125+
config.add_value("port", 44555)
123126

124-
assert config.host == 'localhost'
127+
assert config.host == "localhost"
125128
assert config.port == 44555
126129
```
127130

128131
### Overriding nested values
129132
```python
130-
config = Configuration({'a': {
131-
'b': 1,
132-
'c': 2,
133-
'd': {
134-
'e': 3,
135-
'f': 4
133+
config = Configuration(
134+
{
135+
"a": {
136+
"b": 1,
137+
"c": 2,
138+
"d": {
139+
"e": 3,
140+
"f": 4,
141+
},
142+
}
136143
}
137-
}})
144+
)
138145

139146
assert config.a.b == 1
140147
assert config.a.d.e == 3
141148
assert config.a.d.f == 4
142149

143-
config.add_value('a:d:e', 5)
150+
config.add_value("a:d:e", 5)
144151

145152
assert config.a.d.e == 5
146153
assert config.a.d.f == 4
147154
```
148155

149156
### Overriding nested values using env variables
150157
```python
151-
config = Configuration({'a': {
152-
'b': 1,
153-
'c': 2,
154-
'd': {
155-
'e': 3,
156-
'f': 4
158+
config = Configuration(
159+
{
160+
"a": {
161+
"b": 1,
162+
"c": 2,
163+
"d": {
164+
"e": 3,
165+
"f": 4,
166+
},
167+
}
157168
}
158-
}})
169+
)
159170

160171
assert config.a.b == 1
161172
assert config.a.d.e == 3
@@ -171,21 +182,26 @@ assert config.a.d.f == 4
171182
config.add_environmental_variables()
172183

173184
assert config.a.d.e == 5
185+
174186
```
175187

176188
### Overriding values in list items using env variables
177189
```python
178-
config = Configuration({'b2c': [
179-
{'tenant': '1'},
180-
{'tenant': '2'},
181-
{'tenant': '3'}
182-
]})
190+
config = Configuration(
191+
{
192+
"b2c": [
193+
{"tenant": "1"},
194+
{"tenant": "2"},
195+
{"tenant": "3"},
196+
]
197+
}
198+
)
183199

184-
config.add_value('b2c:1:tenant', '4')
200+
config.add_value("b2c:1:tenant", "4")
185201

186-
assert config.b2c[0].tenant == '1'
187-
assert config.b2c[1].tenant == '4'
188-
assert config.b2c[2].tenant == '3'
202+
assert config.b2c[0].tenant == "1"
203+
assert config.b2c[1].tenant == "4"
204+
assert config.b2c[2].tenant == "3"
189205
```
190206

191207
---

0 commit comments

Comments
 (0)