Vorbereitung Release 0.2.0 #83
+6
-2
@@ -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:
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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")
|
||||
@@ -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')
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -19,3 +19,9 @@ class ProfileModel(BaseModel):
|
||||
first_name: str
|
||||
last_name: str
|
||||
active: bool
|
||||
|
||||
class HealthCheck(BaseModel):
|
||||
"""
|
||||
Health check model
|
||||
"""
|
||||
status: str = "ok"
|
||||
|
||||
@@ -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})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user