Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Deploy API
name: Deploy

on:
workflow_call:
Expand Down
25 changes: 0 additions & 25 deletions .github/workflows/_deploy_transcriber.yaml

This file was deleted.

59 changes: 19 additions & 40 deletions .github/workflows/pull_request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
if: github.actor != 'dependabot[bot]'
runs-on: ubuntu-latest
outputs:
api-docker-tag: ${{ steps.api-docker-tag.outputs.api-docker-tag }}
python-archetype-docker-tag: ${{ steps.python-archetype-docker-tag.outputs.python-archetype-docker-tag }}
env:
COMMON__ENVIRONMENT: Development
steps:
Expand All @@ -24,7 +24,7 @@ jobs:
- name: Install uv
uses: astral-sh/setup-uv@557e51de59eb14aaaba2ed9621916900a91d50c6 # v6.6.1
with:
version: ${{ vars.UV_VERSION }}
version: 0.8.16

- name: Install Python
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
Expand All @@ -51,58 +51,37 @@ jobs:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1

- name: Set api docker tag
id: api-docker-tag
run: echo "api-docker-tag=myregistry/api:${{ github.event.pull_request.head.sha }}" >> $GITHUB_OUTPUT
- name: Set docker tag
id: python-archetype-docker-tag
run: echo "python-archetype-docker-tag=myregistry/python-archetype:${{ github.event.pull_request.head.sha }}" >> $GITHUB_OUTPUT

- name: Build and push api
- name: Build and push
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
with:
file: api/src/api/Dockerfile
tags: ${{ steps.api-docker-tag.outputs.api-docker-tag }}
file: src/python_archetype/api/Dockerfile
tags: ${{ steps.python-archetype-docker-tag.outputs.python-archetype-docker-tag }}
push: false

deploy-api-dev:
deploy-dev:
needs: continuous-integration
uses: ./.github/workflows/_deploy_api.yaml
uses: ./.github/workflows/_deploy.yaml
with:
environment: dev
docker_tag: ${{ needs.continuous-integration.outputs.api-docker-tag }}
docker_tag: ${{ needs.continuous-integration.outputs.python-archetype-docker-tag }}
secrets: inherit

deploy-transcriber-dev:
needs: continuous-integration
uses: ./.github/workflows/_deploy_transcriber.yaml
with:
environment: dev
secrets: inherit

deploy-api-stg:
needs: [deploy-api-dev, deploy-transcriber-dev]
uses: ./.github/workflows/_deploy_api.yaml
deploy-stg:
needs: [continuous-integration, deploy-dev]
uses: ./.github/workflows/_deploy.yaml
with:
environment: stg
docker_tag: ${{ needs.continuous-integration.outputs.api-docker-tag }}
secrets: inherit

deploy-transcriber-stg:
needs: [deploy-api-dev, deploy-transcriber-dev]
uses: ./.github/workflows/_deploy_transcriber.yaml
with:
environment: stg
secrets: inherit

deploy-api-pro:
needs: [deploy-api-stg, deploy-transcriber-stg]
uses: ./.github/workflows/_deploy_api.yaml
with:
environment: pro
docker_tag: ${{ needs.continuous-integration.outputs.api-docker-tag }}
docker_tag: ${{ needs.continuous-integration.outputs.python-archetype-docker-tag }}
secrets: inherit

deploy-transcriber-pro:
needs: [deploy-api-stg, deploy-transcriber-stg]
uses: ./.github/workflows/_deploy_transcriber.yaml
deploy-pro:
needs: [continuous-integration, deploy-stg]
uses: ./.github/workflows/_deploy.yaml
with:
environment: pro
docker_tag: ${{ needs.continuous-integration.outputs.python-archetype-docker-tag }}
secrets: inherit
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"module": "fastapi",
"args": [
"dev",
"api/src/api/main.py"
"src/python_archetype/api/main.py"
],
"console": "integratedTerminal",
"justMyCode": false,
Expand Down
5 changes: 1 addition & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
# Overview

Python monorepo + uv + Vertical Slice Architecture

# Projects
`api` and `transcriber`.
Python archetype + uv + Vertical Slice Architecture

# Execute project

Expand Down
7 changes: 0 additions & 7 deletions api/pyproject.toml

This file was deleted.

43 changes: 0 additions & 43 deletions api/src/api/main.py

This file was deleted.

Empty file removed api/src/api/py.typed
Empty file.
7 changes: 0 additions & 7 deletions common/pyproject.toml

This file was deleted.

Empty file removed common/src/common/py.typed
Empty file.
7 changes: 0 additions & 7 deletions domain/pyproject.toml

This file was deleted.

Empty file removed domain/src/domain/py.typed
Empty file.
16 changes: 15 additions & 1 deletion notebooks/notebook.ipynb
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
{
"cells": [],
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from decimal import Decimal\n",
"\n",
"from python_archetype.domain.entities.product import Product\n",
"\n",
"Product(name=\"Sample Product\", price=Decimal(\"9.99\"), is_discontinued=False)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
Expand Down
30 changes: 9 additions & 21 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,45 +1,33 @@
[project]
name = "python-architecture"
name = "python-archetype"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
"aiohttp==3.12.15",
"azure-cosmos==4.9.0",
"common",
"domain",
"fastapi[standard-no-fastapi-cloud-cli]==0.116.1",
"opentelemetry-instrumentation-fastapi==0.57b0",
"poethepoet==0.37.0",
"pydantic==2.11.7",
"pydantic-settings[azure-key-vault]==2.10.1",
]

[dependency-groups]
dev = [
"api",
"jupyter==1.1.1",
"pyright[nodejs]==1.1.405",
"pytest==8.4.2",
"pytest-asyncio==1.1.0",
"pytest-cov==7.0.0",
"pytest-mock==3.15.0",
"ruff==0.12.12",
"test-utils",
"transcriber",
]

[tool.uv]
required-version = ">=0.8.11,<0.9.0"

[tool.uv.workspace]
members = ["api", "domain", "transcriber", "test_utils", "common", "scripts"]
[build-system]
requires = ["uv_build>=0.8.16,<0.9.0"]
build-backend = "uv_build"

[tool.uv.sources]
api = { workspace = true }
domain = { workspace = true }
transcriber = { workspace = true }
test-utils = { workspace = true }
common = { workspace = true }
[tool.uv]
required-version = ">=0.8.16,<0.9.0"

[tool.pyright]
typeCheckingMode = "strict"
Expand All @@ -64,12 +52,12 @@ ignore = [


[tool.pytest.ini_options]
addopts = ["--import-mode=importlib"]
pythonpath = ["src", "tests"]
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "function"
markers = ["unit: Unit tests", "integration: Integration tests"]

[tool.poe.tasks]
check-code.shell = "ruff check && ruff format --diff && pyright"
start-api-dev = "fastapi dev api/src/api/main.py"
start-api-pro.shell = "workers=$(nproc) && fastapi run --workers $workers api/src/api/main.py"
start-api-dev = "fastapi dev src/python_archetype/api/main.py"
start-api-pro.shell = "workers=$(nproc) && fastapi run --workers $workers src/python_archetype/api/main.py"
2 changes: 1 addition & 1 deletion scripts/main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from decimal import Decimal

from domain.entities.product import Product
from python_archetype.domain.entities.product import Product


def main() -> None:
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
12 changes: 5 additions & 7 deletions api/src/api/Dockerfile → src/python_archetype/api/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
# 0.8.11-python3.12-bookworm-slim
FROM astral/uv@sha256:165703e3c12d7fca3dfa15b2012b98d6e03c261a516d4bd7ca3a956c57c7abce AS builder
# 0.8.16-python3.12-bookworm-slim
FROM astral/uv@sha256:7a97137011fcda1395e1081349fb43ff5fc35953295d8b7c83b75e8829c82c9d AS builder

ENV UV_COMPILE_BYTECODE=1 UV_LINK_MODE=copy UV_PYTHON_DOWNLOADS=0

WORKDIR /app
RUN --mount=type=cache,target=/root/.cache/uv \
--mount=type=bind,source=uv.lock,target=uv.lock \
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
uv sync --frozen --no-install-workspace --no-dev
uv sync --locked --no-install-workspace --no-dev
COPY pyproject.toml uv.lock ./
COPY common common
COPY domain domain
COPY api api
COPY src src
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-dev
uv sync --locked --no-dev

# 3.12.11-slim-bookworm
FROM python@sha256:42cf2422587a3dac0e0a3674a4d86f01570d5d7260588f3845f51e6176d8134b AS final
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
SettingsConfigDict,
)

from common.application_environment import ApplicationEnvironment
from python_archetype.common.application_environment import ApplicationEnvironment


class ApplicationSettings(BaseSettings):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
from azure.cosmos import PartitionKey
from azure.cosmos.aio import CosmosClient, DatabaseProxy

from api.application_settings import ApplicationSettings
from api.workflows.products.discontinue_product.discontinue_product_workflow import (
from python_archetype.api.application_settings import ApplicationSettings
from python_archetype.api.workflows.products.discontinue_product.discontinue_product_workflow import (
DiscontinueProductWorkflow,
)
from api.workflows.products.publish_product.publish_product_workflow import (
from python_archetype.api.workflows.products.publish_product.publish_product_workflow import (
PublishProductWorkflow,
)
from common.application_environment import ApplicationEnvironment
from domain.entities.product import Product
from python_archetype.common.application_environment import ApplicationEnvironment
from python_archetype.domain.entities.product import Product


class DependencyContainer:
Expand Down
26 changes: 26 additions & 0 deletions src/python_archetype/api/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from collections.abc import AsyncGenerator
from contextlib import asynccontextmanager

from fastapi import FastAPI

from python_archetype.api.dependency_container import DependencyContainer
from python_archetype.api.workflows.products import product_router
from python_archetype.common.application_environment import ApplicationEnvironment


@asynccontextmanager
async def lifespan(_: FastAPI) -> AsyncGenerator[None]:
await DependencyContainer.initialize()
yield


openapi_url = (
"/openapi.json"
if ApplicationEnvironment.get_current() != ApplicationEnvironment.PRODUCTION
else None
)
app = FastAPI(
openapi_url=openapi_url,
lifespan=lifespan,
)
app.include_router(product_router.router)
Loading
Loading