Merge pull request 'dev [release-patch]' (#6) from dev into main
Reviewed-on: #6
This commit was merged in pull request #6.
This commit is contained in:
@@ -13,3 +13,4 @@ dist/
|
||||
.gitignore
|
||||
.env
|
||||
*.sock
|
||||
.venv
|
||||
77
.gitea/workflows/test_pr.yml
Normal file
77
.gitea/workflows/test_pr.yml
Normal file
@@ -0,0 +1,77 @@
|
||||
name: PR tests
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, edited, reopened]
|
||||
|
||||
jobs:
|
||||
build-and-smoke:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v5
|
||||
- name: Set up Python
|
||||
run: uv python install
|
||||
with:
|
||||
python-version-file: "pyproject.toml"
|
||||
- name: Install the project dependencies
|
||||
run: |
|
||||
uv sync --all-groups
|
||||
uv add pip
|
||||
uv export --format requirements.txt -o requirements.txt
|
||||
# uv run python -m pip install --upgrade pip
|
||||
# uv run python -m pip install -r requirements.txt
|
||||
- name: Build image
|
||||
run: |
|
||||
docker build -t semapform-api:test-pr .
|
||||
|
||||
- name: Start container (background)
|
||||
run: |
|
||||
# do NOT bind the container port to the host to avoid port conflicts on the runner
|
||||
docker run -d --name semapform-test semapform-api:test-pr sleep infinity
|
||||
|
||||
- name: Start server in container and smoke test HTTP (in-container)
|
||||
run: |
|
||||
set -x
|
||||
# start the server inside the container (detached)
|
||||
docker exec -d semapform-test python api_service.py || true
|
||||
|
||||
# show container status to aid debugging
|
||||
docker ps -a --filter name=semapform-test || true
|
||||
|
||||
# perform a readiness loop (try container-local /health) using small execs
|
||||
echo "waiting for service to become ready inside container"
|
||||
set -e
|
||||
READY=0
|
||||
for i in $(seq 1 20); do
|
||||
echo "ready attempt $i"
|
||||
if docker exec semapform-test python -c 'import urllib.request,sys; urllib.request.urlopen("http://127.0.0.1:8001/health", timeout=1); print("ok")' ; then
|
||||
READY=1
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
if [ "$READY" -ne 1 ]; then
|
||||
echo "service did not become ready"
|
||||
docker logs semapform-test --tail 200 || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Run the repository smoke-test script inside the container and surface its output
|
||||
echo "running test_api.py inside container"
|
||||
docker exec semapform-test python test_api.py || true
|
||||
|
||||
# dump the last 200 lines of logs so this step always displays useful output
|
||||
docker logs semapform-test --tail 200 || true
|
||||
|
||||
- name: Cleanup container
|
||||
if: always()
|
||||
run: |
|
||||
docker rm -f semapform-test || true
|
||||
@@ -6,7 +6,7 @@ RUN apt upgrade -y
|
||||
WORKDIR /app
|
||||
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
RUN pip install --no-cache-dir -r requirements.txt --extra-index-url https://git.theprivateserver.de/api/packages/PHB/pypi/simple/
|
||||
|
||||
COPY . .
|
||||
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
"""
|
||||
Lightweight Python API service for signature validation
|
||||
"""Lightweight Python API service for signature validation
|
||||
This can run independently to support the PHP application
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
from bibapi import catalogue
|
||||
# Avoid importing heavy modules at top-level to keep `import api_service` lightweight
|
||||
from fastapi import FastAPI, Query
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.responses import JSONResponse
|
||||
@@ -22,15 +21,25 @@ app.add_middleware(
|
||||
allow_headers=["*"],
|
||||
)
|
||||
|
||||
# Initialize catalogue for signature validation
|
||||
cat = catalogue.Catalogue()
|
||||
# Catalogue is expensive to initialize at import time; instantiate lazily
|
||||
cat = None
|
||||
|
||||
|
||||
def _get_catalogue():
|
||||
global cat
|
||||
if cat is None:
|
||||
# import inside function to avoid expensive work during module import
|
||||
from bibapi import catalogue as _catalogue
|
||||
|
||||
cat = _catalogue.Catalogue()
|
||||
return cat
|
||||
|
||||
|
||||
@app.get("/api/validate-signature")
|
||||
async def validate_signature(signature: str = Query(...)):
|
||||
"""Validate a book signature and return total pages"""
|
||||
try:
|
||||
book_result = cat.get_book_with_data(signature)
|
||||
book_result = _get_catalogue().get_book_with_data(signature)
|
||||
if book_result and hasattr(book_result, "pages") and book_result.pages:
|
||||
# Try to extract numeric page count
|
||||
pages_str = str(book_result.pages)
|
||||
@@ -39,7 +48,7 @@ async def validate_signature(signature: str = Query(...)):
|
||||
if match:
|
||||
total_pages = int(match.group(1))
|
||||
return JSONResponse(
|
||||
{"valid": True, "total_pages": total_pages, "signature": signature}
|
||||
{"valid": True, "total_pages": total_pages, "signature": signature},
|
||||
)
|
||||
|
||||
return JSONResponse(
|
||||
@@ -47,13 +56,13 @@ async def validate_signature(signature: str = Query(...)):
|
||||
"valid": False,
|
||||
"error": "Signatur nicht gefunden oder keine Seitenzahl verfügbar",
|
||||
"signature": signature,
|
||||
}
|
||||
},
|
||||
)
|
||||
except Exception as e:
|
||||
return JSONResponse(
|
||||
{
|
||||
"valid": False,
|
||||
"error": f"Fehler bei der Validierung: {str(e)}",
|
||||
"error": f"Fehler bei der Validierung: {e!s}",
|
||||
"signature": signature,
|
||||
},
|
||||
status_code=500,
|
||||
|
||||
@@ -4,7 +4,11 @@ version = "0.1.1"
|
||||
description = "Add your description here"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.13"
|
||||
dependencies = ["bibapi>=0.0.5", "fastapi>=0.122.0"]
|
||||
dependencies = [
|
||||
"bibapi>=0.0.5",
|
||||
"fastapi>=0.122.0",
|
||||
"uvicorn>=0.38.0",
|
||||
]
|
||||
[[tool.uv.index]]
|
||||
name = "gitea"
|
||||
url = "https://git.theprivateserver.de/api/packages/PHB/pypi/simple/"
|
||||
|
||||
8
test_api.py
Normal file
8
test_api.py
Normal file
@@ -0,0 +1,8 @@
|
||||
# test api endpoint with a signature, print the response
|
||||
import urllib.request
|
||||
|
||||
response = urllib.request.urlopen(
|
||||
"http://localhost:8001/api/validate-signature?signature=ST%20250%20U42%20%2815%29",
|
||||
)
|
||||
|
||||
print(response.read().decode("utf-8"))
|
||||
Reference in New Issue
Block a user