Skip to content

Commit

Permalink
Merge pull request #3 from jordantshaw/develop
Browse files Browse the repository at this point in the history
Develop to Main
  • Loading branch information
jordantshaw authored Feb 22, 2023
2 parents 142fbe1 + 303f790 commit 22caa59
Show file tree
Hide file tree
Showing 10 changed files with 228 additions and 9 deletions.
39 changes: 39 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# This workflow will upload a Python Package using Twine when a release is created
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

name: Publish

on:
release:
types: [published]

permissions:
contents: read

jobs:
deploy:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install build
- name: Build package
run: python -m build
- name: Publish package
uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
39 changes: 39 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions

name: Test

on:
push:
branches: [ "main", "develop" ]
pull_request:
branches: [ "main", "develop" ]

jobs:
build:

runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]

steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install flake8 pytest
pip install -e .[test];
- name: Lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Test with pytest
run: |
pytest
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ description = "Test application description"
```

```python
from pydantic_config import SettingsModel
from src.pydantic_config import SettingsModel


class Settings(SettingsModel):
Expand Down Expand Up @@ -53,7 +53,7 @@ description = "Test application description"
```

```python
from pydantic_config import SettingsModel
from src.pydantic_config import SettingsModel


class Settings(SettingsModel):
Expand Down Expand Up @@ -91,7 +91,7 @@ item2 = "value2"
```

```python
from pydantic_config import SettingsModel
from src.pydantic_config import SettingsModel


class Settings(SettingsModel):
Expand Down
23 changes: 18 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
name = "pydantic-config"
description = "Support for Pydantic settings configuration file loading"
version = "0.1.0"
authors = ["Jordan Shaw"]
authors = [{name="Jordan Shaw"}]
readme = "README.md"
requires-python = ">=3.7"
classifiers = [
Expand All @@ -19,11 +19,24 @@ classifiers = [
]

dependencies = [
'pydantic',
'pyyaml',
'python-dotenv',
'toml'
'pydantic==1.10.5',
'pyyaml==6.0',
'python-dotenv==0.21.0',
'toml==0.10.2'
]

[project.optional-dependencies]
dev = [
"pytest", 'twine', 'build'
]
test = [
"pytest"
]

[project.urls]
"Homepage" = "https://github.com/jordantshaw/pydantic-config"

[tool.pytest.ini_options]
addopts = [
"--import-mode=importlib",
]
File renamed without changes.
File renamed without changes.
1 change: 0 additions & 1 deletion pydantic_config/main.py → src/pydantic_config/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ def customise_sources(
)



def config_file_settings(settings: BaseSettings) -> Dict[str, Any]:
encoding = getattr(settings.__config__, 'config_file_encoding', None)
files = getattr(settings.__config__, 'config_file', [])
Expand Down
60 changes: 60 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
from datetime import timedelta
from typing import Generator, Any

import pytest


@pytest.fixture(scope='session')
def config_toml_file(tmp_path_factory):
config = '''
[app]
description = "description from config.toml"
'''
file_path = tmp_path_factory.mktemp("data") / "config.toml"
with open(file_path, 'w') as file:
file.write(config)

return file_path


@pytest.fixture(scope='session')
def config_yaml_file(tmp_path_factory):
config = '''
app:
description: description from config.yaml
'''
file_path = tmp_path_factory.mktemp("data") / "config.yaml"
with open(file_path, 'w') as file:
file.write(config)

return file_path


@pytest.fixture(scope='session')
def config_ini_file(tmp_path_factory):
config = '''
[APP]
DESCRIPTION = description from config.ini
'''
file_path = tmp_path_factory.mktemp("data") / "config.ini"
with open(file_path, 'w') as file:
file.write(config)

return file_path


@pytest.fixture(scope='session')
def config_json_file(tmp_path_factory):
config = '''
{
"app": {
"description": "description from config.json"
}
}
'''
file_path = tmp_path_factory.mktemp("data") / "config.json"
with open(file_path, 'w') as file:
file.write(config)

return file_path

21 changes: 21 additions & 0 deletions tests/test_loaders.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from pydantic_config.loaders import toml_file_loader, ini_file_loader, yaml_file_loader, json_file_loader


def test_toml_load(config_toml_file):
data = toml_file_loader(config_toml_file)
assert data == {'app': {'description': 'description from config.toml'}}


def test_ini_load(config_ini_file):
data = ini_file_loader(config_ini_file)
assert data == {'DEFAULT': {}, 'APP': {'description': 'description from config.ini'}}


def test_yaml_load(config_yaml_file):
data = yaml_file_loader(config_yaml_file)
assert data == {'app': {'description': 'description from config.yaml'}}


def test_json_load(config_json_file):
data = json_file_loader(config_json_file)
assert data == {'app': {'description': 'description from config.json'}}
48 changes: 48 additions & 0 deletions tests/test_settings_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import pytest
from pydantic import BaseModel

from pydantic_config import SettingsModel


def test_config_file(config_toml_file):
class App(BaseModel):
name: str = 'AppName'
description: str = None

class Settings(SettingsModel):
app: App

class Config:
config_file = [config_toml_file]

settings = Settings()
assert settings.dict() == {'app': {'name': 'AppName', 'description': 'description from config.toml'}}


def test_invalid_config_file():
file = 'invalid/file/path/file.toml'

class Settings(SettingsModel):
foo: str = 'bar'

class Config:
config_file = [file]

with pytest.raises(OSError) as exc:
Settings()


def test_multiple_config_files(config_toml_file, config_yaml_file):
class App(BaseModel):
name: str = 'AppName'
description: str = None

class Settings(SettingsModel):
app: App

class Config:
config_file = [config_toml_file, config_yaml_file]

settings = Settings()
assert settings.dict() == {'app': {'name': 'AppName', 'description': 'description from config.yaml'}}

0 comments on commit 22caa59

Please sign in to comment.