haiway 0.10.14__tar.gz → 0.10.16__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- haiway-0.10.16/.github/workflows/ci.yml +38 -0
- haiway-0.10.16/.github/workflows/publish.yml +33 -0
- haiway-0.10.16/Makefile +89 -0
- {haiway-0.10.14 → haiway-0.10.16}/PKG-INFO +1 -1
- haiway-0.10.16/config/pre-push +57 -0
- haiway-0.10.16/examples/fastAPI/.dockerignore +5 -0
- haiway-0.10.16/examples/fastAPI/Dockerfile +37 -0
- haiway-0.10.16/examples/fastAPI/Makefile +86 -0
- haiway-0.10.16/examples/fastAPI/README.md +1 -0
- haiway-0.10.16/examples/fastAPI/config/.env.example +11 -0
- haiway-0.10.16/examples/fastAPI/config/unit.json +50 -0
- haiway-0.10.16/examples/fastAPI/docker-compose.yml +44 -0
- haiway-0.10.16/examples/fastAPI/pyproject.toml +65 -0
- haiway-0.10.16/examples/fastAPI/src/features/todos/__init__.py +5 -0
- haiway-0.10.16/examples/fastAPI/src/features/todos/calls.py +16 -0
- haiway-0.10.16/examples/fastAPI/src/features/todos/config.py +1 -0
- haiway-0.10.16/examples/fastAPI/src/features/todos/state.py +12 -0
- haiway-0.10.16/examples/fastAPI/src/features/todos/types.py +15 -0
- haiway-0.10.16/examples/fastAPI/src/features/todos/user_tasks.py +17 -0
- haiway-0.10.16/examples/fastAPI/src/integrations/__init__.py +0 -0
- haiway-0.10.16/examples/fastAPI/src/integrations/postgres/__init__.py +12 -0
- haiway-0.10.16/examples/fastAPI/src/integrations/postgres/client.py +146 -0
- haiway-0.10.16/examples/fastAPI/src/integrations/postgres/config.py +19 -0
- haiway-0.10.16/examples/fastAPI/src/integrations/postgres/state.py +64 -0
- haiway-0.10.16/examples/fastAPI/src/integrations/postgres/types.py +27 -0
- haiway-0.10.16/examples/fastAPI/src/server/__init__.py +10 -0
- haiway-0.10.16/examples/fastAPI/src/server/__main__.py +10 -0
- haiway-0.10.16/examples/fastAPI/src/server/application.py +54 -0
- haiway-0.10.16/examples/fastAPI/src/server/config.py +11 -0
- haiway-0.10.16/examples/fastAPI/src/server/middlewares/__init__.py +5 -0
- haiway-0.10.16/examples/fastAPI/src/server/middlewares/context.py +133 -0
- haiway-0.10.16/examples/fastAPI/src/server/routes/__init__.py +7 -0
- haiway-0.10.16/examples/fastAPI/src/server/routes/technical.py +21 -0
- haiway-0.10.16/examples/fastAPI/src/server/routes/todos.py +26 -0
- haiway-0.10.16/examples/fastAPI/src/solutions/__init__.py +0 -0
- haiway-0.10.16/examples/fastAPI/src/solutions/user_tasks/__init__.py +12 -0
- haiway-0.10.16/examples/fastAPI/src/solutions/user_tasks/calls.py +54 -0
- haiway-0.10.16/examples/fastAPI/src/solutions/user_tasks/config.py +1 -0
- haiway-0.10.16/examples/fastAPI/src/solutions/user_tasks/postgres.py +106 -0
- haiway-0.10.16/examples/fastAPI/src/solutions/user_tasks/state.py +25 -0
- haiway-0.10.16/examples/fastAPI/src/solutions/user_tasks/types.py +70 -0
- haiway-0.10.16/examples/fastAPI/uv.lock +435 -0
- haiway-0.10.16/guidelines/functionalities.md +252 -0
- haiway-0.10.16/guidelines/packages.md +321 -0
- haiway-0.10.16/junit/test-results.xml +1 -0
- {haiway-0.10.14 → haiway-0.10.16}/pyproject.toml +1 -28
- haiway-0.10.16/src/haiway/py.typed +0 -0
- haiway-0.10.16/tests/__init__.py +0 -0
- haiway-0.10.16/tests/test_async_queue.py +111 -0
- haiway-0.10.16/tests/test_attribute_path.py +250 -0
- haiway-0.10.16/tests/test_auto_retry.py +297 -0
- haiway-0.10.16/tests/test_cache.py +192 -0
- haiway-0.10.16/tests/test_context.py +63 -0
- haiway-0.10.16/tests/test_state.py +242 -0
- haiway-0.10.16/tests/test_streaming.py +125 -0
- haiway-0.10.16/tests/test_timeout.py +53 -0
- haiway-0.10.16/uv.lock +318 -0
- haiway-0.10.14/hatch_version.py +0 -20
- {haiway-0.10.14 → haiway-0.10.16}/.gitignore +0 -0
- {haiway-0.10.14 → haiway-0.10.16}/LICENSE +0 -0
- {haiway-0.10.14 → haiway-0.10.16}/README.md +0 -0
- /haiway-0.10.14/haiway/py.typed → /haiway-0.10.16/examples/fastAPI/src/features/__int__.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/__init__.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/context/__init__.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/context/access.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/context/disposables.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/context/identifier.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/context/logging.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/context/metrics.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/context/state.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/context/tasks.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/context/types.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/helpers/__init__.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/helpers/asynchrony.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/helpers/caching.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/helpers/metrics.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/helpers/retries.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/helpers/throttling.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/helpers/timeouted.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/helpers/tracing.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/state/__init__.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/state/attributes.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/state/path.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/state/requirement.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/state/structure.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/state/validation.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/types/__init__.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/types/default.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/types/frozen.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/types/missing.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/utils/__init__.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/utils/always.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/utils/collections.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/utils/env.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/utils/freezing.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/utils/logs.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/utils/mimic.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/utils/noop.py +0 -0
- {haiway-0.10.14 → haiway-0.10.16/src}/haiway/utils/queue.py +0 -0
@@ -0,0 +1,38 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- main
|
7
|
+
|
8
|
+
pull_request:
|
9
|
+
branches:
|
10
|
+
- "*"
|
11
|
+
|
12
|
+
jobs:
|
13
|
+
test:
|
14
|
+
runs-on: ${{ matrix.os }}
|
15
|
+
strategy:
|
16
|
+
matrix:
|
17
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
18
|
+
python-version: ["3.12", "3.13"]
|
19
|
+
|
20
|
+
steps:
|
21
|
+
- uses: actions/checkout@v4
|
22
|
+
|
23
|
+
- name: Install uv and set the python version
|
24
|
+
uses: astral-sh/setup-uv@v5
|
25
|
+
with:
|
26
|
+
python-version: ${{ matrix.python-version }}
|
27
|
+
|
28
|
+
- name: Install
|
29
|
+
run: uv sync --all-groups --all-extras --frozen --no-python-downloads
|
30
|
+
|
31
|
+
- name: Lint
|
32
|
+
run: uv run ruff check --output-format=github ./src ./tests && uv run pyright --project ./
|
33
|
+
|
34
|
+
- name: Test
|
35
|
+
run: uv run pytest --rootdir= ./tests --doctest-modules --junitxml=junit/test-results.xml
|
36
|
+
|
37
|
+
- name: Build
|
38
|
+
run: uv build
|
@@ -0,0 +1,33 @@
|
|
1
|
+
name: publish
|
2
|
+
|
3
|
+
on:
|
4
|
+
release:
|
5
|
+
types:
|
6
|
+
- released
|
7
|
+
|
8
|
+
jobs:
|
9
|
+
publish:
|
10
|
+
runs-on: ubuntu-latest
|
11
|
+
permissions:
|
12
|
+
id-token: write
|
13
|
+
steps:
|
14
|
+
- uses: actions/checkout@v4
|
15
|
+
with:
|
16
|
+
ref: ${{ github.event.release.tag_name }}
|
17
|
+
|
18
|
+
- name: Install uv and set the python version
|
19
|
+
uses: astral-sh/setup-uv@v5
|
20
|
+
with:
|
21
|
+
python-version: 3.12
|
22
|
+
|
23
|
+
- name: Install
|
24
|
+
run: uv sync --all-groups --all-extras --frozen --no-python-downloads
|
25
|
+
|
26
|
+
- name: Lint
|
27
|
+
run: uv run ruff check --output-format=github ./src ./tests && uv run pyright --project ./
|
28
|
+
|
29
|
+
- name: Test
|
30
|
+
run: uv run pytest --rootdir= ./tests --doctest-modules --junitxml=junit/test-results.xml
|
31
|
+
|
32
|
+
- name: Publish
|
33
|
+
run: uv build && uv publish
|
haiway-0.10.16/Makefile
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
SHELL := sh
|
2
|
+
.ONESHELL:
|
3
|
+
.SHELLFLAGS := -eu -c
|
4
|
+
.DELETE_ON_ERROR:
|
5
|
+
|
6
|
+
SOURCES_PATH := src
|
7
|
+
TESTS_PATH := tests
|
8
|
+
|
9
|
+
# load environment config from .env if able
|
10
|
+
-include .env
|
11
|
+
|
12
|
+
ifndef UV_VERSION
|
13
|
+
UV_VERSION := 0.6.4
|
14
|
+
endif
|
15
|
+
|
16
|
+
.PHONY: uv_check venv sync update format lint test release
|
17
|
+
|
18
|
+
# Check installed UV version and install if needed
|
19
|
+
uv_check:
|
20
|
+
@echo 'Checking uv version...'
|
21
|
+
|
22
|
+
# Install if not present
|
23
|
+
@if ! command -v uv > /dev/null; then \
|
24
|
+
echo '...installing uv...'; \
|
25
|
+
curl -LsSf https://github.com/astral-sh/uv/releases/download/$(UV_VERSION)/uv-installer.sh | sh; \
|
26
|
+
if [ $$? -ne 0 ]; then \
|
27
|
+
echo "...installing uv failed!"; \
|
28
|
+
exit 1; \
|
29
|
+
fi; \
|
30
|
+
fi
|
31
|
+
|
32
|
+
# Check version and update if needed
|
33
|
+
@if command -v uv > /dev/null; then \
|
34
|
+
CURRENT_VERSION=$$(uv --version | head -n1 | cut -d" " -f2); \
|
35
|
+
if [ "$$(printf "%s\n%s" "$(UV_VERSION)" "$$CURRENT_VERSION" | sort -V | head -n1)" != "$(UV_VERSION)" ]; then \
|
36
|
+
echo '...updating uv...'; \
|
37
|
+
curl -LsSf https://github.com/astral-sh/uv/releases/download/$(UV_VERSION)/uv-installer.sh | sh; \
|
38
|
+
if [ $$? -ne 0 ]; then \
|
39
|
+
echo "...updating uv failed!"; \
|
40
|
+
exit 1; \
|
41
|
+
fi; \
|
42
|
+
else \
|
43
|
+
echo '...uv version is up-to-date!'; \
|
44
|
+
fi; \
|
45
|
+
fi
|
46
|
+
|
47
|
+
# Setup virtual environment for local development.
|
48
|
+
venv: uv_check
|
49
|
+
@echo '# Preparing development environment...'
|
50
|
+
@echo '...cloning .env...'
|
51
|
+
@cp -n ./config/.env.example ./.env || :
|
52
|
+
@echo '...preparing git hooks...'
|
53
|
+
@cp -n ./config/pre-push ./.git/hooks/pre-push || :
|
54
|
+
@echo '...preparing venv...'
|
55
|
+
@uv sync --all-groups --all-extras --frozen --reinstall
|
56
|
+
@echo '...development environment ready! Activate venv using `. ./.venv/bin/activate`.'
|
57
|
+
|
58
|
+
# Sync environment with uv based on constraints
|
59
|
+
sync: uv_check
|
60
|
+
@echo '# Synchronizing dependencies...'
|
61
|
+
@uv sync --all-groups --all-extras --frozen
|
62
|
+
@echo '...finished!'
|
63
|
+
|
64
|
+
# Update and lock dependencies from pyproject.toml
|
65
|
+
update:
|
66
|
+
@echo '# Updating dependencies...'
|
67
|
+
@uv sync --all-groups --all-extras --upgrade
|
68
|
+
@echo '...finished!'
|
69
|
+
|
70
|
+
# Run formatter.
|
71
|
+
format:
|
72
|
+
@ruff check --quiet --fix $(SOURCES_PATH) $(TESTS_PATH)
|
73
|
+
@ruff format --quiet $(SOURCES_PATH) $(TESTS_PATH)
|
74
|
+
|
75
|
+
# Run linters and code checks.
|
76
|
+
lint:
|
77
|
+
@bandit -r $(SOURCES_PATH)
|
78
|
+
@ruff check $(SOURCES_PATH) $(TESTS_PATH)
|
79
|
+
@pyright --project ./
|
80
|
+
|
81
|
+
# Run tests suite.
|
82
|
+
test:
|
83
|
+
@python -B -m pytest -v --cov=$(SOURCES_PATH) --rootdir=$(TESTS_PATH)
|
84
|
+
|
85
|
+
release: lint test
|
86
|
+
@echo '# Preparing release...'
|
87
|
+
@uv build
|
88
|
+
@uv publish
|
89
|
+
@echo '...finished!'
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: haiway
|
3
|
-
Version: 0.10.
|
3
|
+
Version: 0.10.16
|
4
4
|
Summary: Framework for dependency injection and state management within structured concurrency model.
|
5
5
|
Project-URL: Homepage, https://miquido.com
|
6
6
|
Project-URL: Repository, https://github.com/miquido/haiway.git
|
@@ -0,0 +1,57 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
if git rev-parse --verify HEAD >/dev/null 2>&1
|
4
|
+
then
|
5
|
+
against=HEAD
|
6
|
+
else
|
7
|
+
against=$(git hash-object -t tree /dev/null)
|
8
|
+
fi
|
9
|
+
|
10
|
+
remote="$1"
|
11
|
+
url="$2"
|
12
|
+
|
13
|
+
zero=$(git hash-object --stdin </dev/null | tr '[0-9a-f]' '0')
|
14
|
+
|
15
|
+
while read local_ref local_oid remote_ref remote_oid
|
16
|
+
do
|
17
|
+
if test "$local_oid" = "$zero"
|
18
|
+
then
|
19
|
+
# Handle delete
|
20
|
+
:
|
21
|
+
else
|
22
|
+
if test "$remote_oid" = "$zero"
|
23
|
+
then
|
24
|
+
# New branch, examine all commits
|
25
|
+
range="$local_oid"
|
26
|
+
else
|
27
|
+
# Update to existing branch, examine new commits
|
28
|
+
range="$remote_oid..$local_oid"
|
29
|
+
fi
|
30
|
+
|
31
|
+
# Check for WIP commit
|
32
|
+
commit=$(git rev-list -n 1 --grep '^WIP' "$range")
|
33
|
+
if test -n "$commit"
|
34
|
+
then
|
35
|
+
echo >&2 "Found WIP commit in $local_ref, not pushing"
|
36
|
+
exit 1
|
37
|
+
fi
|
38
|
+
fi
|
39
|
+
done
|
40
|
+
|
41
|
+
. ./.venv/bin/activate
|
42
|
+
|
43
|
+
make lint
|
44
|
+
|
45
|
+
if test $? != 0
|
46
|
+
then
|
47
|
+
cat <<\EOF
|
48
|
+
|
49
|
+
Error: Linting failed.
|
50
|
+
|
51
|
+
Ensure project quality and make all linting rules pass!
|
52
|
+
|
53
|
+
EOF
|
54
|
+
exit 1
|
55
|
+
fi
|
56
|
+
|
57
|
+
exec git diff-index --check --cached $against --
|
@@ -0,0 +1,37 @@
|
|
1
|
+
ARG PYTHON_TAG=3.12
|
2
|
+
ARG UNIT_TAG=1.32.1-python${PYTHON_TAG}
|
3
|
+
|
4
|
+
# SERVER #
|
5
|
+
|
6
|
+
FROM unit:${UNIT_TAG} AS server_builder
|
7
|
+
|
8
|
+
# copy only the parts needed for production
|
9
|
+
COPY ./src/integrations ./src/integrations
|
10
|
+
COPY ./src/solutions ./src/solutions
|
11
|
+
COPY ./src/features ./src/features
|
12
|
+
COPY ./src/server ./src/server
|
13
|
+
|
14
|
+
# install dependencies and packages
|
15
|
+
COPY --from=ghcr.io/astral-sh/uv:0.5.14 /uv /uvx /bin/
|
16
|
+
|
17
|
+
ENV UV_PROJECT_ENVIRONMENT="/usr/local/"
|
18
|
+
|
19
|
+
RUN --mount=type=bind,source=./uv.lock,target=./uv.lock --mount=type=bind,source=./pyproject.toml,target=./pyproject.toml uv sync --python python${PYTHON_TAG} --locked --no-editable --no-python-downloads --link-mode copy --compile-bytecode --only-group server
|
20
|
+
|
21
|
+
FROM server_builder AS server
|
22
|
+
|
23
|
+
# allow access to home directory for asyncpg library
|
24
|
+
RUN chgrp -R unit ${HOME} && chmod -R 050 ${HOME}
|
25
|
+
|
26
|
+
RUN apt-get update \
|
27
|
+
&& apt-get upgrade -y \
|
28
|
+
&& apt-get -y autoremove \
|
29
|
+
&& apt-get clean \
|
30
|
+
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
31
|
+
|
32
|
+
# copy configuration
|
33
|
+
COPY ./config/unit.json /docker-entrypoint.d/config.json
|
34
|
+
|
35
|
+
CMD ["unitd", "--no-daemon", "--log", "/dev/stdout"]
|
36
|
+
|
37
|
+
# port 80 is already exposed by nginx unit image, can't change it...
|
@@ -0,0 +1,86 @@
|
|
1
|
+
SHELL := sh
|
2
|
+
.ONESHELL:
|
3
|
+
.SHELLFLAGS := -eu -c
|
4
|
+
.DELETE_ON_ERROR:
|
5
|
+
|
6
|
+
SOURCES_PATH := src
|
7
|
+
|
8
|
+
# load environment config from .env if able
|
9
|
+
-include .env
|
10
|
+
|
11
|
+
ifndef UV_VERSION
|
12
|
+
UV_VERSION := 0.5.14
|
13
|
+
endif
|
14
|
+
|
15
|
+
.PHONY: uv_check venv sync update format lint run docker_run
|
16
|
+
|
17
|
+
# Check installed UV version and install if needed
|
18
|
+
uv_check:
|
19
|
+
@echo 'Checking uv version...'
|
20
|
+
|
21
|
+
# Install if not present
|
22
|
+
@if ! command -v uv > /dev/null; then \
|
23
|
+
echo '...installing uv...'; \
|
24
|
+
curl -LsSf https://github.com/astral-sh/uv/releases/download/$(UV_VERSION)/uv-installer.sh | sh; \
|
25
|
+
if [ $$? -ne 0 ]; then \
|
26
|
+
echo "...installing uv failed!"; \
|
27
|
+
exit 1; \
|
28
|
+
fi; \
|
29
|
+
fi
|
30
|
+
|
31
|
+
# Check version and update if needed
|
32
|
+
@if command -v uv > /dev/null; then \
|
33
|
+
CURRENT_VERSION=$$(uv --version | head -n1 | cut -d" " -f2); \
|
34
|
+
if [ "$$(printf "%s\n%s" "$(UV_VERSION)" "$$CURRENT_VERSION" | sort -V | head -n1)" != "$(UV_VERSION)" ]; then \
|
35
|
+
echo '...updating uv...'; \
|
36
|
+
curl -LsSf https://github.com/astral-sh/uv/releases/download/$(UV_VERSION)/uv-installer.sh | sh; \
|
37
|
+
if [ $$? -ne 0 ]; then \
|
38
|
+
echo "...updating uv failed!"; \
|
39
|
+
exit 1; \
|
40
|
+
fi; \
|
41
|
+
else \
|
42
|
+
echo '...uv version is up-to-date!'; \
|
43
|
+
fi; \
|
44
|
+
fi
|
45
|
+
|
46
|
+
# Setup virtual environment for local development.
|
47
|
+
venv: uv_check
|
48
|
+
@echo '# Preparing development environment...'
|
49
|
+
@echo '...cloning .env...'
|
50
|
+
@cp -n ./config/.env.example ./.env || :
|
51
|
+
@echo '...preparing git hooks...'
|
52
|
+
@cp -n ./config/pre-push ./.git/hooks/pre-push || :
|
53
|
+
@echo '...preparing venv...'
|
54
|
+
@uv sync --all-groups --all-extras --frozen --reinstall
|
55
|
+
@echo '...development environment ready! Activate venv using `. ./.venv/bin/activate`.'
|
56
|
+
|
57
|
+
# Sync environment with uv based on constraints
|
58
|
+
sync: uv_check
|
59
|
+
@echo '# Synchronizing dependencies...'
|
60
|
+
@uv sync --all-groups --all-extras --frozen
|
61
|
+
@echo '...finished!'
|
62
|
+
|
63
|
+
# Update and lock dependencies from pyproject.toml
|
64
|
+
update:
|
65
|
+
@echo '# Updating dependencies...'
|
66
|
+
@uv sync --all-groups --all-extras --upgrade
|
67
|
+
@echo '...finished!'
|
68
|
+
|
69
|
+
# Run formatter.
|
70
|
+
format:
|
71
|
+
@ruff check --quiet --fix $(SOURCES_PATH)
|
72
|
+
@ruff format --quiet $(SOURCES_PATH)
|
73
|
+
|
74
|
+
# Run linters and code checks.
|
75
|
+
lint:
|
76
|
+
@bandit -r $(SOURCES_PATH)
|
77
|
+
@ruff check $(SOURCES_PATH)
|
78
|
+
@pyright --project ./
|
79
|
+
|
80
|
+
# Run the server
|
81
|
+
run:
|
82
|
+
@python -m server
|
83
|
+
|
84
|
+
# Run all services locally using docker-compose.
|
85
|
+
docker_run:
|
86
|
+
@docker compose up --force-recreate --build server
|
@@ -0,0 +1 @@
|
|
1
|
+
## Haiway FastAPI Example
|
@@ -0,0 +1,50 @@
|
|
1
|
+
{
|
2
|
+
"listeners": {
|
3
|
+
"*:80": {
|
4
|
+
"pass": "routes/api"
|
5
|
+
}
|
6
|
+
},
|
7
|
+
"routes": {
|
8
|
+
"api": [
|
9
|
+
{
|
10
|
+
"match": {
|
11
|
+
"uri": "/health"
|
12
|
+
},
|
13
|
+
"action": {
|
14
|
+
"return": 204
|
15
|
+
}
|
16
|
+
},
|
17
|
+
{
|
18
|
+
"match": {
|
19
|
+
"uri": "/*"
|
20
|
+
},
|
21
|
+
"action": {
|
22
|
+
"pass": "applications/server"
|
23
|
+
}
|
24
|
+
}
|
25
|
+
]
|
26
|
+
},
|
27
|
+
"applications": {
|
28
|
+
"server": {
|
29
|
+
"type": "python",
|
30
|
+
"protocol": "asgi",
|
31
|
+
"path": "/",
|
32
|
+
"module": "server",
|
33
|
+
"callable": "app",
|
34
|
+
"processes": 1,
|
35
|
+
"environment": {
|
36
|
+
"PYTHONOPTIMIZE": "2",
|
37
|
+
"HOME": "."
|
38
|
+
}
|
39
|
+
}
|
40
|
+
},
|
41
|
+
"access_log": {
|
42
|
+
"path": "/dev/stdout",
|
43
|
+
"format": "$time_local [ACCESS] $request_line -> $status"
|
44
|
+
},
|
45
|
+
"settings": {
|
46
|
+
"http": {
|
47
|
+
"server_version": false
|
48
|
+
}
|
49
|
+
}
|
50
|
+
}
|
@@ -0,0 +1,44 @@
|
|
1
|
+
services:
|
2
|
+
server:
|
3
|
+
depends_on:
|
4
|
+
postgres:
|
5
|
+
condition: service_healthy
|
6
|
+
links:
|
7
|
+
- postgres
|
8
|
+
build:
|
9
|
+
context: .
|
10
|
+
dockerfile: Dockerfile
|
11
|
+
target: server
|
12
|
+
ports:
|
13
|
+
- ${SERVER_PORT:-8080}:80
|
14
|
+
restart: no
|
15
|
+
environment:
|
16
|
+
PYTHONOPTIMIZE: ${PYTHONOPTIMIZE:-2}
|
17
|
+
DEBUG_LOGGING: ${DEBUG_LOGGING}
|
18
|
+
POSTGRES_DATABASE: ${POSTGRES_DATABASE}
|
19
|
+
POSTGRES_HOST: postgres
|
20
|
+
POSTGRES_PORT: 5432
|
21
|
+
POSTGRES_USER: ${POSTGRES_USER}
|
22
|
+
POSTGRES_SSLMODE: ${POSTGRES_SSLMODE:-prefer}
|
23
|
+
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
24
|
+
|
25
|
+
postgres:
|
26
|
+
image: postgres:16.3-alpine3.20
|
27
|
+
restart: always
|
28
|
+
environment:
|
29
|
+
POSTGRES_USER: ${POSTGRES_USER}
|
30
|
+
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
31
|
+
POSTGRES_DB: ${POSTGRES_DATABASE}
|
32
|
+
volumes:
|
33
|
+
- postgres_data:/var/lib/postgresql/data
|
34
|
+
ports:
|
35
|
+
- ${POSTGRES_PORT}:5432
|
36
|
+
healthcheck:
|
37
|
+
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DATABASE}"]
|
38
|
+
interval: 10s
|
39
|
+
start_period: 10s
|
40
|
+
timeout: 10s
|
41
|
+
retries: 3
|
42
|
+
|
43
|
+
volumes:
|
44
|
+
postgres_data:
|
@@ -0,0 +1,65 @@
|
|
1
|
+
[build-system]
|
2
|
+
requires = ["setuptools"]
|
3
|
+
build-backend = "setuptools.build_meta"
|
4
|
+
|
5
|
+
[project]
|
6
|
+
name = "haiway_fastapi"
|
7
|
+
description = "Example of haiway usage with fastapi."
|
8
|
+
version = "0.1.0"
|
9
|
+
readme = "README.md"
|
10
|
+
maintainers = [
|
11
|
+
{ name = "Kacper Kaliński", email = "kacper.kalinski@miquido.com" },
|
12
|
+
]
|
13
|
+
requires-python = ">=3.12"
|
14
|
+
dependencies = [
|
15
|
+
"haiway @ git+https://github.com/miquido/haiway@main",
|
16
|
+
"asyncpg~=0.30",
|
17
|
+
"httpx~=0.28.0",
|
18
|
+
]
|
19
|
+
|
20
|
+
[project.urls]
|
21
|
+
Homepage = "https://miquido.com"
|
22
|
+
|
23
|
+
[dependency-groups]
|
24
|
+
server = [
|
25
|
+
"haiway_fastapi",
|
26
|
+
"fastapi-slim~=0.115",
|
27
|
+
]
|
28
|
+
dev = [
|
29
|
+
"haiway_fastapi",
|
30
|
+
"uvicorn~=0.30",
|
31
|
+
"ruff~=0.8.0",
|
32
|
+
"pyright~=1.1",
|
33
|
+
"bandit~=1.7",
|
34
|
+
]
|
35
|
+
|
36
|
+
[tool.ruff]
|
37
|
+
target-version = "py312"
|
38
|
+
line-length = 100
|
39
|
+
extend-exclude = [".venv", ".git", ".cache"]
|
40
|
+
lint.select = ["E", "F", "A", "I", "B", "PL", "W", "C", "RUF", "UP"]
|
41
|
+
lint.ignore = []
|
42
|
+
|
43
|
+
[tool.ruff.lint.per-file-ignores]
|
44
|
+
"__init__.py" = ["F401", "E402"]
|
45
|
+
"./tests/*.py" = ["PLR2004"]
|
46
|
+
|
47
|
+
[tool.pyright]
|
48
|
+
pythonVersion = "3.12"
|
49
|
+
venvPath = "."
|
50
|
+
venv = ".venv"
|
51
|
+
include = ["./src"]
|
52
|
+
exclude = ["**/node_modules", "**/__pycache__"]
|
53
|
+
ignore = []
|
54
|
+
stubPath = "./stubs"
|
55
|
+
reportMissingImports = true
|
56
|
+
reportMissingTypeStubs = true
|
57
|
+
typeCheckingMode = "strict"
|
58
|
+
userFileIndexingLimit = -1
|
59
|
+
useLibraryCodeForTypes = true
|
60
|
+
|
61
|
+
[tool.setuptools]
|
62
|
+
include-package-data = true
|
63
|
+
|
64
|
+
[tool.setuptools.packages.find]
|
65
|
+
where = ["src"]
|
@@ -0,0 +1,16 @@
|
|
1
|
+
from uuid import UUID
|
2
|
+
|
3
|
+
from haiway import ctx
|
4
|
+
|
5
|
+
from features.todos.state import Todos
|
6
|
+
|
7
|
+
__all__ = [
|
8
|
+
"complete_todo",
|
9
|
+
]
|
10
|
+
|
11
|
+
|
12
|
+
async def complete_todo(
|
13
|
+
*,
|
14
|
+
identifier: UUID,
|
15
|
+
) -> None:
|
16
|
+
await ctx.state(Todos).complete(identifier=identifier)
|
@@ -0,0 +1 @@
|
|
1
|
+
# empty
|
@@ -0,0 +1,17 @@
|
|
1
|
+
from uuid import UUID
|
2
|
+
|
3
|
+
from haiway import ctx
|
4
|
+
|
5
|
+
from solutions.user_tasks import UserTask, UserTasks
|
6
|
+
|
7
|
+
__all__ = [
|
8
|
+
"complete_todo_task",
|
9
|
+
]
|
10
|
+
|
11
|
+
|
12
|
+
async def complete_todo_task(
|
13
|
+
*,
|
14
|
+
identifier: UUID,
|
15
|
+
) -> None:
|
16
|
+
task: UserTask = await ctx.state(UserTasks).fetch(identifier=identifier)
|
17
|
+
await ctx.state(UserTasks).update(task=task.updated(completed=True))
|
File without changes
|
@@ -0,0 +1,12 @@
|
|
1
|
+
from integrations.postgres.client import PostgresClient
|
2
|
+
from integrations.postgres.state import Postgres, PostgresConnection
|
3
|
+
from integrations.postgres.types import PostgresException, PostgresRow, PostgresValue
|
4
|
+
|
5
|
+
__all__ = [
|
6
|
+
"Postgres",
|
7
|
+
"PostgresClient",
|
8
|
+
"PostgresConnection",
|
9
|
+
"PostgresException",
|
10
|
+
"PostgresRow",
|
11
|
+
"PostgresValue",
|
12
|
+
]
|