feat(structure): flatten padelnomics to UV workspace monorepo layout
Mirrors the quart_saas_boilerplate template's new web/ workspace structure: - git mv src/ → web/src/ - git mv tests/ → web/tests/ - git mv scripts/ → web/scripts/ - Split pyproject.toml into workspace root + web/pyproject.toml - Dockerfile: COPY src/ → web/, update CSS build + output paths, add --package padelnomics to uv sync - Makefile: update CSS input/output paths - pytest testpaths: tests/ → web/tests/ uv sync passes, 402/403 tests pass (1 pre-existing failure in test_content). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3,9 +3,9 @@ FROM debian:bookworm-slim AS css-build
|
|||||||
ADD https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-linux-x64 /usr/local/bin/tailwindcss
|
ADD https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-linux-x64 /usr/local/bin/tailwindcss
|
||||||
RUN chmod +x /usr/local/bin/tailwindcss
|
RUN chmod +x /usr/local/bin/tailwindcss
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY src/ ./src/
|
COPY web/src/ ./web/src/
|
||||||
RUN tailwindcss -i ./src/padelnomics/static/css/input.css \
|
RUN tailwindcss -i ./web/src/padelnomics/static/css/input.css \
|
||||||
-o ./src/padelnomics/static/css/output.css --minify
|
-o ./web/src/padelnomics/static/css/output.css --minify
|
||||||
|
|
||||||
# Build stage
|
# Build stage
|
||||||
FROM python:3.12-slim AS build
|
FROM python:3.12-slim AS build
|
||||||
@@ -13,9 +13,9 @@ COPY --from=ghcr.io/astral-sh/uv:0.8 /uv /uvx /bin/
|
|||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
ENV UV_COMPILE_BYTECODE=1 UV_LINK_MODE=copy
|
ENV UV_COMPILE_BYTECODE=1 UV_LINK_MODE=copy
|
||||||
COPY uv.lock pyproject.toml README.md ./
|
COPY uv.lock pyproject.toml README.md ./
|
||||||
COPY src/ ./src/
|
COPY web/ ./web/
|
||||||
RUN --mount=type=cache,target=/root/.cache/uv \
|
RUN --mount=type=cache,target=/root/.cache/uv \
|
||||||
uv sync --no-dev --frozen
|
uv sync --no-dev --frozen --package padelnomics
|
||||||
|
|
||||||
# Runtime stage
|
# Runtime stage
|
||||||
FROM python:3.12-slim AS runtime
|
FROM python:3.12-slim AS runtime
|
||||||
@@ -24,7 +24,7 @@ RUN useradd -m -u 1000 appuser
|
|||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
RUN mkdir -p /app/data && chown -R appuser:appuser /app
|
RUN mkdir -p /app/data && chown -R appuser:appuser /app
|
||||||
COPY --from=build --chown=appuser:appuser /app .
|
COPY --from=build --chown=appuser:appuser /app .
|
||||||
COPY --from=css-build /app/src/padelnomics/static/css/output.css ./src/padelnomics/static/css/output.css
|
COPY --from=css-build /app/web/src/padelnomics/static/css/output.css ./web/src/padelnomics/static/css/output.css
|
||||||
USER appuser
|
USER appuser
|
||||||
ENV PYTHONUNBUFFERED=1
|
ENV PYTHONUNBUFFERED=1
|
||||||
ENV DATABASE_PATH=/app/data/app.db
|
ENV DATABASE_PATH=/app/data/app.db
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ bin/tailwindcss:
|
|||||||
chmod +x bin/tailwindcss
|
chmod +x bin/tailwindcss
|
||||||
|
|
||||||
css-build: bin/tailwindcss
|
css-build: bin/tailwindcss
|
||||||
$(TAILWIND) -i src/padelnomics/static/css/input.css -o src/padelnomics/static/css/output.css --minify
|
$(TAILWIND) -i web/src/padelnomics/static/css/input.css -o web/src/padelnomics/static/css/output.css --minify
|
||||||
|
|
||||||
css-watch: bin/tailwindcss
|
css-watch: bin/tailwindcss
|
||||||
$(TAILWIND) -i src/padelnomics/static/css/input.css -o src/padelnomics/static/css/output.css --watch
|
$(TAILWIND) -i web/src/padelnomics/static/css/input.css -o web/src/padelnomics/static/css/output.css --watch
|
||||||
|
|||||||
@@ -1,31 +1,10 @@
|
|||||||
[project]
|
[tool.uv.workspace]
|
||||||
name = "padelnomics"
|
members = [
|
||||||
version = "0.1.0"
|
"web",
|
||||||
description = "Plan, finance, and build your padel business"
|
|
||||||
readme = "README.md"
|
|
||||||
requires-python = ">=3.11"
|
|
||||||
dependencies = [
|
|
||||||
"quart>=0.19.0",
|
|
||||||
"aiosqlite>=0.19.0",
|
|
||||||
"python-dotenv>=1.0.0",
|
|
||||||
"itsdangerous>=2.1.0",
|
|
||||||
"jinja2>=3.1.0",
|
|
||||||
"hypercorn>=0.17.0",
|
|
||||||
"paddle-python-sdk>=1.13.0",
|
|
||||||
"mistune>=3.0.0",
|
|
||||||
"resend>=2.22.0",
|
|
||||||
"weasyprint>=68.1",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[build-system]
|
[dependency-groups]
|
||||||
requires = ["hatchling"]
|
dev = [
|
||||||
build-backend = "hatchling.build"
|
|
||||||
|
|
||||||
[tool.hatch.build.targets.wheel]
|
|
||||||
packages = ["src/padelnomics"]
|
|
||||||
|
|
||||||
[tool.uv]
|
|
||||||
dev-dependencies = [
|
|
||||||
"hypothesis>=6.151.6",
|
"hypothesis>=6.151.6",
|
||||||
"playwright>=1.58.0",
|
"playwright>=1.58.0",
|
||||||
"pytest>=8.0.0",
|
"pytest>=8.0.0",
|
||||||
@@ -45,6 +24,6 @@ ignore = ["E501"]
|
|||||||
|
|
||||||
[tool.pytest.ini_options]
|
[tool.pytest.ini_options]
|
||||||
asyncio_mode = "auto"
|
asyncio_mode = "auto"
|
||||||
testpaths = ["tests"]
|
testpaths = ["web/tests"]
|
||||||
markers = ["visual: Playwright visual tests (require browser install)"]
|
markers = ["visual: Playwright visual tests (require browser install)"]
|
||||||
addopts = "-m 'not visual'"
|
addopts = "-m 'not visual'"
|
||||||
|
|||||||
40
padelnomics/uv.lock
generated
40
padelnomics/uv.lock
generated
@@ -6,6 +6,22 @@ resolution-markers = [
|
|||||||
"python_full_version < '3.13'",
|
"python_full_version < '3.13'",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[manifest]
|
||||||
|
members = [
|
||||||
|
"padelnomics",
|
||||||
|
]
|
||||||
|
|
||||||
|
[manifest.dependency-groups]
|
||||||
|
dev = [
|
||||||
|
{ name = "hypothesis", specifier = ">=6.151.6" },
|
||||||
|
{ name = "playwright", specifier = ">=1.58.0" },
|
||||||
|
{ name = "pytest", specifier = ">=8.0.0" },
|
||||||
|
{ name = "pytest-asyncio", specifier = ">=0.23.0" },
|
||||||
|
{ name = "pytest-playwright", specifier = ">=0.7.2" },
|
||||||
|
{ name = "respx", specifier = ">=0.22.0" },
|
||||||
|
{ name = "ruff", specifier = ">=0.3.0" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aiofiles"
|
name = "aiofiles"
|
||||||
version = "25.1.0"
|
version = "25.1.0"
|
||||||
@@ -667,7 +683,7 @@ wheels = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "padelnomics"
|
name = "padelnomics"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = { editable = "." }
|
source = { editable = "web" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "aiosqlite" },
|
{ name = "aiosqlite" },
|
||||||
{ name = "hypercorn" },
|
{ name = "hypercorn" },
|
||||||
@@ -681,17 +697,6 @@ dependencies = [
|
|||||||
{ name = "weasyprint" },
|
{ name = "weasyprint" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dev-dependencies]
|
|
||||||
dev = [
|
|
||||||
{ name = "hypothesis" },
|
|
||||||
{ name = "playwright" },
|
|
||||||
{ name = "pytest" },
|
|
||||||
{ name = "pytest-asyncio" },
|
|
||||||
{ name = "pytest-playwright" },
|
|
||||||
{ name = "respx" },
|
|
||||||
{ name = "ruff" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[package.metadata]
|
[package.metadata]
|
||||||
requires-dist = [
|
requires-dist = [
|
||||||
{ name = "aiosqlite", specifier = ">=0.19.0" },
|
{ name = "aiosqlite", specifier = ">=0.19.0" },
|
||||||
@@ -706,17 +711,6 @@ requires-dist = [
|
|||||||
{ name = "weasyprint", specifier = ">=68.1" },
|
{ name = "weasyprint", specifier = ">=68.1" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.metadata.requires-dev]
|
|
||||||
dev = [
|
|
||||||
{ name = "hypothesis", specifier = ">=6.151.6" },
|
|
||||||
{ name = "playwright", specifier = ">=1.58.0" },
|
|
||||||
{ name = "pytest", specifier = ">=8.0.0" },
|
|
||||||
{ name = "pytest-asyncio", specifier = ">=0.23.0" },
|
|
||||||
{ name = "pytest-playwright", specifier = ">=0.7.2" },
|
|
||||||
{ name = "respx", specifier = ">=0.22.0" },
|
|
||||||
{ name = "ruff", specifier = ">=0.3.0" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pillow"
|
name = "pillow"
|
||||||
version = "12.1.1"
|
version = "12.1.1"
|
||||||
|
|||||||
25
padelnomics/web/pyproject.toml
Normal file
25
padelnomics/web/pyproject.toml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
[project]
|
||||||
|
name = "padelnomics"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "Plan, finance, and build your padel business"
|
||||||
|
readme = "../README.md"
|
||||||
|
requires-python = ">=3.11"
|
||||||
|
dependencies = [
|
||||||
|
"quart>=0.19.0",
|
||||||
|
"aiosqlite>=0.19.0",
|
||||||
|
"python-dotenv>=1.0.0",
|
||||||
|
"itsdangerous>=2.1.0",
|
||||||
|
"jinja2>=3.1.0",
|
||||||
|
"hypercorn>=0.17.0",
|
||||||
|
"paddle-python-sdk>=1.13.0",
|
||||||
|
"mistune>=3.0.0",
|
||||||
|
"resend>=2.22.0",
|
||||||
|
"weasyprint>=68.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["hatchling"]
|
||||||
|
build-backend = "hatchling.build"
|
||||||
|
|
||||||
|
[tool.hatch.build.targets.wheel]
|
||||||
|
packages = ["src/padelnomics"]
|
||||||
@@ -8,7 +8,15 @@ from pathlib import Path
|
|||||||
|
|
||||||
from quart import Blueprint, flash, g, redirect, render_template, request, session, url_for
|
from quart import Blueprint, flash, g, redirect, render_template, request, session, url_for
|
||||||
|
|
||||||
from ..core import capture_waitlist_email, config, csrf_protect, execute, fetch_one, is_disposable_email, waitlist_gate
|
from ..core import (
|
||||||
|
capture_waitlist_email,
|
||||||
|
config,
|
||||||
|
csrf_protect,
|
||||||
|
execute,
|
||||||
|
fetch_one,
|
||||||
|
is_disposable_email,
|
||||||
|
waitlist_gate,
|
||||||
|
)
|
||||||
from ..i18n import SUPPORTED_LANGS, get_translations
|
from ..i18n import SUPPORTED_LANGS, get_translations
|
||||||
|
|
||||||
# Blueprint with its own template folder
|
# Blueprint with its own template folder
|
||||||
@@ -18,7 +18,15 @@ from ..auth.routes import (
|
|||||||
mark_token_used,
|
mark_token_used,
|
||||||
update_user,
|
update_user,
|
||||||
)
|
)
|
||||||
from ..core import config, csrf_protect, execute, fetch_one, is_disposable_email, is_plausible_phone, send_email
|
from ..core import (
|
||||||
|
config,
|
||||||
|
csrf_protect,
|
||||||
|
execute,
|
||||||
|
fetch_one,
|
||||||
|
is_disposable_email,
|
||||||
|
is_plausible_phone,
|
||||||
|
send_email,
|
||||||
|
)
|
||||||
from ..i18n import get_translations
|
from ..i18n import get_translations
|
||||||
|
|
||||||
bp = Blueprint(
|
bp = Blueprint(
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user