Vorbereitung Release 0.2.0 #83

Merged
tpeetz merged 178 commits from develop/0.2.0 into main 2026-01-29 22:50:42 +00:00
10 changed files with 55 additions and 18 deletions
Showing only changes of commit 4a2048c378 - Show all commits
+6 -2
View File
@@ -41,6 +41,11 @@ services:
- kontor-api:0.2.0-SNAPSHOT
image: kontor-api:0.2.0-SNAPSHOT
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://kontor-api:8800/health"]
interval: 10s
timeout: 5s
retries: 3
networks:
- database
- integration
@@ -67,7 +72,7 @@ services:
ports:
- 8200:80
depends_on:
postgres:
kontor-api:
condition: service_healthy
kontor-vue:
build:
@@ -95,4 +100,3 @@ networks:
volumes:
activemq-data:
images-data:
+3 -1
View File
@@ -1,7 +1,7 @@
## ------------------------------- Builder Stage ------------------------------ ##
FROM python:3.13-bookworm AS builder
RUN apt-get update && apt-get install --no-install-recommends -y build-essential && \
RUN apt-get update && apt-get install --no-install-recommends -y build-essential && \
apt-get clean && rm -rf /var/lib/apt/lists/*
# Download the latest installer, install it and then remove it
@@ -34,6 +34,8 @@ FROM python:3.13-slim-bookworm AS production
#RUN --mount=type=secret,id=secret-key,target=secrets.json
RUN apt-get update && apt-get install --no-install-recommends -y curl
RUN useradd --create-home appuser
USER appuser
-1
View File
@@ -7,7 +7,6 @@ from fastapi.security import OAuth2PasswordRequestForm
from src.core.config import settings
from src.core.security import create_access_token, authenticate_user, get_current_active_user
from src.db.models.admin import Profile
from src.db.session import SessionDep
from src.schema.admin import Token, ProfileModel
from src.webapps.auth.forms import LoginForm
@@ -0,0 +1,25 @@
from fastapi import APIRouter, status
from src.schema.admin import HealthCheck
health_router = APIRouter()
@health_router.get(
"/health",
tags=["healthcheck"],
summary="Perform a health check",
response_description="Return HTTP status code 200 (OK)",
status_code=status.HTTP_200_OK
)
def health_check() -> HealthCheck:
"""
## Perform a health check
Endpoint to perform a healthcheck on. This endpoint can primarily be used Docker
to ensure a robust container orchestration and management is in place. Other
services which rely on proper functioning of the API service will not deploy if this
endpoint returns any other HTTP status code except 200 (OK).
:return:
HealthCheck: Returns a JSON response with the health status
"""
return HealthCheck(status="ok")
+3 -2
View File
@@ -34,11 +34,12 @@ LOGGING_CONFIG: dict[str, Any] = {
},
"loggers": {
"root": {"handlers": ["default"], "level": "INFO", "propagate": False},
"kontor": {"handlers": ["default"], "level": "INFO", "propagate": True},
"uvicorn": {"handlers": ["default"], "level": "INFO", "propagate": False},
"uvicorn.error": {"level": "INFO"},
"uvicorn.access": {"handlers": ["default"], "level": "INFO", "propagate": False},
"uvicorn.access": {"handlers": ["default"], "level": "WARNING", "propagate": False},
},
}
logging.config.dictConfig(LOGGING_CONFIG)
logger = logging.getLogger(__name__)
logger = logging.getLogger('kontor')
+3 -3
View File
@@ -65,7 +65,7 @@ class OAuth2PasswordBearerWithCookie(OAuth2):
def authenticate_user(username: str, password: str) -> Optional[Profile]:
with SessionLocal() as db:
user = get_profile(username=username, db=db)
print(user)
logger.info(user)
if not user:
return None
if bcrypt.checkpw(password.encode(), user.password.encode()):
@@ -103,7 +103,7 @@ async def get_current_user(security_scopes: SecurityScopes, token: Annotated[str
try:
payload = jwt.decode(token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM])
username: str = payload.get("sub")
print("username/email extracted is ", username)
logger.info("username/email extracted is ", username)
if username is None:
raise credentials_exception
scope: str = payload.get("scope", "")
@@ -147,7 +147,7 @@ def get_current_user_from_token(token: str = Depends(oauth2_scheme)):
token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM]
)
username: str = payload.get("sub")
print("username/email extracted is ", username)
logger.info("username/email extracted is ", username)
if username is None:
raise credentials_exception
except JWTError:
+4 -2
View File
@@ -1,4 +1,6 @@
import databases
from src.core.log_conf import logger
from src.db.session import SQLALCHEMY_DATABASE_URL
@@ -9,7 +11,7 @@ async def check_db_connected():
if not database.is_connected:
await database.connect()
await database.execute("SELECT 1")
print("Database is connected (^_^)")
logger.info("Database is connected (^_^)")
except Exception as e:
print(
"Looks like db is missing or is there is some problem in connection,see below traceback"
@@ -23,6 +25,6 @@ async def check_db_disconnected():
database = databases.Database(SQLALCHEMY_DATABASE_URL)
if database.is_connected:
await database.disconnect()
print("Database is Disconnected (-_-) zZZ")
logger.info("Database is Disconnected (-_-) zZZ")
except Exception as e:
raise e
+3 -3
View File
@@ -1,5 +1,3 @@
import logging
import logging.config
from contextlib import asynccontextmanager
from fastapi import FastAPI
@@ -7,7 +5,8 @@ from fastapi.staticfiles import StaticFiles
from fastapi.middleware.cors import CORSMiddleware
from src.apis.base import api_router
from src.core.log_conf import LOGGING_CONFIG, logger
from src.apis.version1.healthcheck import health_router
from src.core.log_conf import logger
from src.db.session import engine
from src.db.utils import check_db_connected, check_db_disconnected
from src.webapps.base import api_router as web_app_router
@@ -24,6 +23,7 @@ async def lifespan(app: FastAPI):
def include_router(app: FastAPI):
app.include_router(api_router)
app.include_router(web_app_router)
app.include_router(health_router)
def configure_static(app: FastAPI):
app.mount("/static", StaticFiles(directory="src/static"), name="static")
+6
View File
@@ -19,3 +19,9 @@ class ProfileModel(BaseModel):
first_name: str
last_name: str
active: bool
class HealthCheck(BaseModel):
"""
Health check model
"""
status: str = "ok"
+2 -4
View File
@@ -1,12 +1,10 @@
from typing import AnyStr
from fastapi import APIRouter, Request, status, responses
from fastapi.security.utils import get_authorization_scheme_param
from fastapi.templating import Jinja2Templates
from src.core.security import get_current_user_from_token
from src.db.models.media import MediaVideo
from src.db.repository.media import create_new_video
#from src.apis.version1.admin import get_current_user_from_token
from src.db.models.admin import Profile
from src.db.session import SessionDep
from src.schema.media.video import AddLink
@@ -28,7 +26,7 @@ def get_mediavideos(db: SessionDep, request: Request, msg: str = None):
return templates.TemplateResponse("media/videos.html", {"request": request, "msg": msg, "user": None, "mediavideos": mediavideos})
@router.get("/videos/{video_id}")
def video_details(video_id: AnyStr, request: Request, db: SessionDep):
def video_details(video_id: str, request: Request, db: SessionDep):
mediavideo = db.get(MediaVideo, video_id)
return templates.TemplateResponse("media/video_detail.html", {"request": request, "mediavideo":mediavideo})