-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 4209831
Showing
13 changed files
with
933 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
name: Lint | ||
|
||
on: | ||
push: | ||
branches: [main] | ||
pull_request: | ||
branches: [main] | ||
|
||
jobs: | ||
lint: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
|
||
- name: Install uv | ||
uses: astral-sh/setup-uv@v2 | ||
with: | ||
version: "0.4.6" | ||
|
||
- name: Set up Python | ||
uses: actions/setup-python@v5 | ||
with: | ||
python-version-file: "pyproject.toml" | ||
|
||
- name: Install dependencies | ||
run: | | ||
uv pip install -e .[dev] | ||
- name: Run pre-commit | ||
run: pre-commit run --all-files |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
# Python artifacts | ||
__pycache__/ | ||
*.py[cod] | ||
*$py.class | ||
*.egg-info/ | ||
*.egg | ||
build/ | ||
dist/ | ||
sdist/ | ||
|
||
# Test artifacts | ||
.benchmarks/ | ||
.coverage | ||
.coverage.*.* | ||
.pytest_cache/ | ||
|
||
# Type checking artifacts | ||
.mypy_cache/ | ||
.dmypy.json | ||
dmypy.json | ||
.pyre/ | ||
|
||
# IPython | ||
profile_default/ | ||
ipython_config.py | ||
*.ipynb_checkpoints/* | ||
|
||
# Profiling | ||
/prof | ||
|
||
# Environments | ||
.python-version | ||
.env | ||
.venv | ||
env/ | ||
venv/ | ||
|
||
site/ | ||
.cache/ | ||
**/node_modules | ||
|
||
# Databases | ||
*.db | ||
|
||
# Editors | ||
.idea/ | ||
.vscode/ | ||
**/.vscode/ | ||
|
||
# MacOS | ||
.DS_Store | ||
libcairo.2.dylib | ||
|
||
# setuptools-scm generated files | ||
src/**/_version.py | ||
*.log | ||
|
||
# specific to this project | ||
.bookkeeping/ | ||
python_pack.egg-info/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
repos: | ||
- repo: https://github.com/astral-sh/ruff-pre-commit | ||
rev: v0.1.8 | ||
hooks: | ||
- id: ruff-format | ||
- id: ruff | ||
args: [--fix, --exit-non-zero-on-fix] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
src = ["src"] | ||
|
||
# Use Ruff for sorting imports | ||
lint.extend-select = ["I"] | ||
|
||
lint.ignore = [] # add E501 to avoid enforcing line length | ||
|
||
[lint.per-file-ignores] | ||
# Do not enforce usage and import order rules in init files | ||
"__init__.py" = ["E402", "F401", "I"] | ||
"main.py" = ["E402", "F401", "I"] | ||
|
||
# Do not fix import in compatibility module | ||
"src/python_pack/**/compat.py" = ["F401", "I"] | ||
|
||
# Allow wild imports in conftest | ||
"tests/conftest.py" = ["F405", "E402", "F403"] | ||
|
||
# Allow fake items in __all__ for runtime | ||
"src/python_pack/utils.py" = ["F822"] | ||
|
||
# Do not enforce line length limits in migrations | ||
"src/python_pack/**/database/migrations/**/*" = ["E501"] | ||
|
||
[lint.isort] | ||
known-third-party = [] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
.DEFAULT_GOAL := install | ||
.PHONY: all install clean test dev publish | ||
|
||
UV := $(shell which uv) | ||
UV_VERSION := $(shell $(UV) --version | cut -d ' ' -f 2) | ||
VENV_DIR := .venv | ||
REQUIREMENTS := requirements.txt | ||
DEV_REQUIREMENTS := requirements-dev.txt | ||
|
||
$(info Using uv @ $(UV)) | ||
$(info - version: $(UV_VERSION)) | ||
|
||
all: install test | ||
|
||
.bookkeeping/uv-$(UV_VERSION): | ||
@if command -v uv >/dev/null 2>&1; then \ | ||
echo "(uv already installed)"; \ | ||
else \ | ||
read -p "uv is not installed. Do you want to install it? (y/N) " answer; \ | ||
if [ "$$answer" = "y" ] || [ "$$answer" = "Y" ]; then \ | ||
mkdir -p .bookkeeping; \ | ||
curl -LsSf https://astral.sh/uv/install.sh | sh; \ | ||
touch $@; \ | ||
else \ | ||
echo "Installation cancelled. Please install uv manually to proceed."; \ | ||
exit 1; \ | ||
fi; \ | ||
fi | ||
|
||
$(VENV_DIR): .bookkeeping/uv-$(UV_VERSION) | ||
$(UV) venv $(VENV_DIR) | ||
|
||
$(REQUIREMENTS): pyproject.toml | ||
$(UV) pip compile pyproject.toml -o $(REQUIREMENTS) | ||
|
||
$(DEV_REQUIREMENTS): pyproject.toml | ||
$(UV) pip compile --extra dev pyproject.toml -o $(DEV_REQUIREMENTS) | ||
|
||
dev: $(VENV_DIR) $(DEV_REQUIREMENTS) | ||
$(UV) pip sync $(DEV_REQUIREMENTS) | ||
$(UV) pip install -e .[dev] | ||
@echo "ᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖ" | ||
@echo "Virtual environment is ready." | ||
@echo "" | ||
@echo "To activate, run:" | ||
@echo "source $(VENV_DIR)/bin/activate" | ||
@echo "ᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖᨖ" | ||
|
||
install: $(VENV_DIR) $(REQUIREMENTS) | ||
$(UV) build | ||
$(UV) pip install dist/*.whl | ||
|
||
publish: install | ||
$(UV)x twine upload dist/* | ||
|
||
clean: | ||
rm -rf .bookkeeping/ $(VENV_DIR) $(REQUIREMENTS) $(DEV_REQUIREMENTS) dist/ | ||
|
||
test: | ||
$(VENV_DIR)/bin/python -m pytest |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# want a python environment that just works? | ||
here you go! | ||
|
||
``` | ||
make clean | ||
make install | ||
make test | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
[project] | ||
name = "python-pack" | ||
dynamic = ["version"] | ||
description = "A modern Python project template" | ||
readme = "README.md" | ||
requires-python = ">=3.12" | ||
|
||
dependencies = ["pydantic", "rich", "uv"] | ||
|
||
[project.optional-dependencies] | ||
|
||
tests = [ | ||
"pytest", | ||
"pytest-asyncio", | ||
"pytest-env", | ||
"pytest-rerunfailures", | ||
"pytest-sugar", | ||
"pytest-timeout", | ||
"pytest-xdist", | ||
] | ||
|
||
dev = ["ruff", "pre-commit", "python-pack[tests]"] | ||
|
||
|
||
[tool.setuptools_scm] | ||
write_to = "src/python_pack/_version.py" | ||
|
||
# pytest configuration | ||
[tool.pytest.ini_options] | ||
asyncio_mode = 'auto' | ||
asyncio_default_fixture_loop_scope = 'session' | ||
timeout = 20 | ||
testpaths = ["tests"] | ||
norecursedirs = [ | ||
"*.egg-info", | ||
".git", | ||
".mypy_cache", | ||
".pytest_cache", | ||
".ruff_cache", | ||
".vscode", | ||
"node_modules", | ||
] | ||
env = [] | ||
markers = [] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
# This file was autogenerated by uv via the following command: | ||
# uv pip compile --extra dev pyproject.toml -o requirements-dev.txt | ||
annotated-types==0.7.0 | ||
# via pydantic | ||
cfgv==3.4.0 | ||
# via pre-commit | ||
distlib==0.3.8 | ||
# via virtualenv | ||
execnet==2.1.1 | ||
# via pytest-xdist | ||
filelock==3.15.4 | ||
# via virtualenv | ||
identify==2.6.0 | ||
# via pre-commit | ||
iniconfig==2.0.0 | ||
# via pytest | ||
markdown-it-py==3.0.0 | ||
# via rich | ||
mdurl==0.1.2 | ||
# via markdown-it-py | ||
nodeenv==1.9.1 | ||
# via pre-commit | ||
packaging==24.1 | ||
# via | ||
# pytest | ||
# pytest-rerunfailures | ||
# pytest-sugar | ||
platformdirs==4.2.2 | ||
# via virtualenv | ||
pluggy==1.5.0 | ||
# via pytest | ||
pre-commit==3.8.0 | ||
# via python-pack (pyproject.toml) | ||
pydantic==2.9.0 | ||
# via python-pack (pyproject.toml) | ||
pydantic-core==2.23.2 | ||
# via pydantic | ||
pygments==2.18.0 | ||
# via rich | ||
pytest==8.3.2 | ||
# via | ||
# python-pack (pyproject.toml) | ||
# pytest-asyncio | ||
# pytest-env | ||
# pytest-rerunfailures | ||
# pytest-sugar | ||
# pytest-timeout | ||
# pytest-xdist | ||
pytest-asyncio==0.24.0 | ||
# via python-pack (pyproject.toml) | ||
pytest-env==1.1.3 | ||
# via python-pack (pyproject.toml) | ||
pytest-rerunfailures==14.0 | ||
# via python-pack (pyproject.toml) | ||
pytest-sugar==1.0.0 | ||
# via python-pack (pyproject.toml) | ||
pytest-timeout==2.3.1 | ||
# via python-pack (pyproject.toml) | ||
pytest-xdist==3.6.1 | ||
# via python-pack (pyproject.toml) | ||
pyyaml==6.0.2 | ||
# via pre-commit | ||
rich==13.8.0 | ||
# via python-pack (pyproject.toml) | ||
ruff==0.6.4 | ||
# via python-pack (pyproject.toml) | ||
termcolor==2.4.0 | ||
# via pytest-sugar | ||
typing-extensions==4.12.2 | ||
# via | ||
# pydantic | ||
# pydantic-core | ||
tzdata==2024.1 | ||
# via pydantic | ||
uv==0.4.6 | ||
# via python-pack (pyproject.toml) | ||
virtualenv==20.26.3 | ||
# via pre-commit |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
from typing import Callable, Literal, get_origin | ||
|
||
from pydantic import TypeAdapter | ||
|
||
|
||
def parse_as[T]( | ||
type_: type[T], | ||
data: object, | ||
mode: Literal["python", "json", "strings"] = "python", | ||
) -> T: | ||
"""Parse a given data structure as a Pydantic model via `TypeAdapter`. | ||
|
||
Read more about `TypeAdapter` [here](https://docs.pydantic.dev/latest/concepts/type_adapter/). | ||
|
||
Args: | ||
type_: The type to parse the data as. | ||
data: The data to be parsed. | ||
mode: The mode to use for parsing, either `python`, `json`, or `strings`. | ||
Defaults to `python`, where `data` should be a Python object (e.g. `dict`). | ||
|
||
Returns: | ||
The parsed `data` as the given `type_`. | ||
|
||
|
||
Example: | ||
```python | ||
from python_pack.utils import parse_as | ||
from pydantic import BaseModel | ||
|
||
class ExampleModel(BaseModel): | ||
name: str | ||
|
||
# parsing python objects | ||
parsed = parse_as(list[ExampleModel], [{"name": "Marvin"}, {"name": "Arthur"}]) | ||
assert isinstance(parsed, list) | ||
assert parsed[0].name == "Marvin" | ||
|
||
# parsing json strings | ||
parsed = parse_as( | ||
list[ExampleModel], | ||
'[{"name": "Marvin"}, {"name": "Arthur"}]', | ||
mode="json" | ||
) | ||
assert all(isinstance(item, ExampleModel) for item in parsed) | ||
assert parsed[0].name == "Marvin" | ||
assert parsed[1].name == "Arthur" | ||
``` | ||
|
||
""" | ||
adapter = TypeAdapter(type_) | ||
|
||
if get_origin(type_) is list and isinstance(data, dict): | ||
data = next(iter(data.values())) | ||
|
||
parser: Callable[[object], T] = getattr(adapter, f"validate_{mode}") | ||
|
||
return parser(data) |
Empty file.
Oops, something went wrong.