Fix docker-compose (minio) and add basic logger

This commit is contained in:
Mawoka
2025-10-25 11:03:52 +02:00
parent 7425bfebdd
commit 1b644be0e3
8 changed files with 72 additions and 22 deletions
+33 -7
View File
@@ -77,12 +77,25 @@ async def auth_middleware_wrapper(request: Request, call_next):
return await rememberme_middleware(request, call_next) return await rememberme_middleware(request, call_next)
app.include_router(moderation.router, tags=["moderation"], prefix="/api/v1/moderation", include_in_schema=True) app.include_router(
moderation.router,
tags=["moderation"],
prefix="/api/v1/moderation",
include_in_schema=True,
)
app.include_router(pixabay.router, tags=["pixabay"], prefix="/api/v1/pixabay", include_in_schema=True) app.include_router(pixabay.router, tags=["pixabay"], prefix="/api/v1/pixabay", include_in_schema=True)
app.include_router(quiztivity.router, tags=["quiztivity"], prefix="/api/v1/quiztivity", include_in_schema=True) app.include_router(
quiztivity.router,
tags=["quiztivity"],
prefix="/api/v1/quiztivity",
include_in_schema=True,
)
app.include_router( app.include_router(
box_controller.router, tags=["boxcontroller"], prefix="/api/v1/box-controller", include_in_schema=True box_controller.router,
tags=["boxcontroller"],
prefix="/api/v1/box-controller",
include_in_schema=True,
) )
app.include_router(results.router, tags=["results"], prefix="/api/v1/results", include_in_schema=True) app.include_router(results.router, tags=["results"], prefix="/api/v1/results", include_in_schema=True)
app.include_router(remote.router, tags=["remote"], prefix="/api/v1/remote", include_in_schema=True) app.include_router(remote.router, tags=["remote"], prefix="/api/v1/remote", include_in_schema=True)
@@ -94,15 +107,28 @@ app.include_router(quiz.router, tags=["quiz"], prefix="/api/v1/quiz", include_in
app.include_router(utils.router, tags=["utils"], prefix="/api/v1/utils", include_in_schema=True) app.include_router(utils.router, tags=["utils"], prefix="/api/v1/utils", include_in_schema=True)
app.include_router(stats.router, tags=["stats"], prefix="/api/v1/stats", include_in_schema=True) app.include_router(stats.router, tags=["stats"], prefix="/api/v1/stats", include_in_schema=True)
app.include_router(storage.router, tags=["storage"], prefix="/api/v1/storage", include_in_schema=True) app.include_router(storage.router, tags=["storage"], prefix="/api/v1/storage", include_in_schema=True)
app.include_router(search.router, tags=["search"], prefix="/api/v1/search", include_in_schema=True), app.include_router(search.router, tags=["search"], prefix="/api/v1/search", include_in_schema=True)
app.include_router(live.router, tags=["live"], prefix="/api/v1/live", include_in_schema=True) app.include_router(live.router, tags=["live"], prefix="/api/v1/live", include_in_schema=True)
app.include_router( app.include_router(
testing_routes.router, tags=["internal", "testing"], prefix="/api/v1/internal/testing", include_in_schema=False testing_routes.router,
tags=["internal", "testing"],
prefix="/api/v1/internal/testing",
include_in_schema=False,
) )
app.include_router(editor.router, tags=["editor"], prefix="/api/v1/editor", include_in_schema=True) app.include_router(editor.router, tags=["editor"], prefix="/api/v1/editor", include_in_schema=True)
app.include_router(eximport.router, tags=["export", "import"], prefix="/api/v1/eximport", include_in_schema=True) app.include_router(
eximport.router,
tags=["export", "import"],
prefix="/api/v1/eximport",
include_in_schema=True,
)
app.include_router(sitemap.router, tags=["sitemap"], prefix="/api/v1/sitemap", include_in_schema=True) app.include_router(sitemap.router, tags=["sitemap"], prefix="/api/v1/sitemap", include_in_schema=True)
app.include_router(community.router, tags=["community"], prefix="/api/v1/community", include_in_schema=True) app.include_router(
community.router,
tags=["community"],
prefix="/api/v1/community",
include_in_schema=True,
)
app.include_router(avatar.router, tags=["avatar"], prefix="/api/v1/avatar", include_in_schema=True) app.include_router(avatar.router, tags=["avatar"], prefix="/api/v1/avatar", include_in_schema=True)
app.include_router(admin.router, tags=["admin"], prefix="/api/v1/admin", include_in_schema=True) app.include_router(admin.router, tags=["admin"], prefix="/api/v1/admin", include_in_schema=True)
app.mount("/", ASGIApp(sio)) app.mount("/", ASGIApp(sio))
+7 -1
View File
@@ -12,9 +12,12 @@ from pydantic_settings import BaseSettings, SettingsConfigDict
import meilisearch as MeiliSearch import meilisearch as MeiliSearch
from arq import create_pool from arq import create_pool
from arq.connections import RedisSettings, ArqRedis from arq.connections import RedisSettings, ArqRedis
import logging
from classquiz.storage import Storage from classquiz.storage import Storage
LOGGER = logging.getLogger(f"uvicorn.{__name__}")
class CustomOpenIDProvider(BaseModel): class CustomOpenIDProvider(BaseModel):
scopes: str | None = "openid email profile" scopes: str | None = "openid email profile"
@@ -29,7 +32,10 @@ class Settings(BaseSettings):
""" """
model_config = SettingsConfigDict( model_config = SettingsConfigDict(
env_file=".env", extra="ignore", env_nested_delimiter="__", env_file_encoding="utf-8" env_file=".env",
extra="ignore",
env_nested_delimiter="__",
env_file_encoding="utf-8",
) )
root_address: str = "http://127.0.0.1:8000" root_address: str = "http://127.0.0.1:8000"
redis: RedisDsn = "redis://localhost:6379/0?decode_responses=True" redis: RedisDsn = "redis://localhost:6379/0?decode_responses=True"
+8 -5
View File
@@ -18,7 +18,7 @@ import xlsxwriter
from aiohttp import ClientSession from aiohttp import ClientSession
from io import BytesIO from io import BytesIO
from PIL import Image from PIL import Image
from classquiz.config import meilisearch, settings from classquiz.config import meilisearch, settings, LOGGER
from classquiz.helpers.hashcash import check as hc_check from classquiz.helpers.hashcash import check as hc_check
settings = settings() settings = settings()
@@ -147,7 +147,10 @@ async def handle_import_from_excel(data: BinaryIO, user: User) -> Quiz:
if answer is None: if answer is None:
continue continue
if len(str(answer)) > 150: if len(str(answer)) > 150:
raise HTTPException(status_code=400, detail=f"Answer {a + 1} in Question {i + 1} is longer than 150") raise HTTPException(
status_code=400,
detail=f"Answer {a + 1} in Question {i + 1} is longer than 150",
)
if len(answers) < 2: if len(answers) < 2:
raise HTTPException(status_code=400, detail=f"Less than 2 answers in Question {i + 1}") raise HTTPException(status_code=400, detail=f"Less than 2 answers in Question {i + 1}")
correct_answers: str = str(row[6]) correct_answers: str = str(row[6])
@@ -200,7 +203,7 @@ async def meilisearch_init():
classquiz_index_found = False classquiz_index_found = False
# +++ Check if the index does not exist and creates it # +++ Check if the index does not exist and creates it
if not classquiz_index_found: if not classquiz_index_found:
print("Creating MeiliSearch Index") LOGGER.debug("Creating MeiliSearch Index")
meilisearch.create_index(settings.meilisearch_index) meilisearch.create_index(settings.meilisearch_index)
await asyncio.sleep(1) await asyncio.sleep(1)
# --- END # --- END
@@ -211,7 +214,7 @@ async def meilisearch_init():
number_of_docs = i[1] number_of_docs = i[1]
break break
if number_of_docs != quiz_count: if number_of_docs != quiz_count:
print("MeiliSearch and Database got out of sync, syncthing them") LOGGER.warn("MeiliSearch and Database got out of sync, syncthing them")
meilisearch.delete_index(settings.meilisearch_index) meilisearch.delete_index(settings.meilisearch_index)
meilisearch.create_index(settings.meilisearch_index) meilisearch.create_index(settings.meilisearch_index)
quizzes = await Quiz.objects.filter(public=True).all() quizzes = await Quiz.objects.filter(public=True).all()
@@ -221,7 +224,7 @@ async def meilisearch_init():
meilisearch.index(settings.meilisearch_index).add_documents(meili_data) meilisearch.index(settings.meilisearch_index).add_documents(meili_data)
# --- END --- # --- END ---
meilisearch.index(settings.meilisearch_index).update_settings({"sortableAttributes": ["created_at"]}) meilisearch.index(settings.meilisearch_index).update_settings({"sortableAttributes": ["created_at"]})
print("Finished MeiliSearch synchronisation") LOGGER.info("Finished MeiliSearch synchronisation")
async def telemetry_ping(): async def telemetry_ping():
+12 -9
View File
@@ -4,10 +4,10 @@
services: services:
db: db:
# build: # build:
# context: pg_uuidv7 # context: pg_uuidv7
# args: # args:
# PG_MAJOR_VERSION: 16 # PG_MAJOR_VERSION: 16
image: postgres:16 image: postgres:16
environment: environment:
POSTGRES_PASSWORD: mysecretpassword POSTGRES_PASSWORD: mysecretpassword
@@ -34,21 +34,24 @@ services:
privileged: true privileged: true
restart: unless-stopped restart: unless-stopped
minio: minio:
image: bitnami/minio image: docker.io/minio/minio
environment: environment:
MINIO_ROOT_USER: fediprint MINIO_ROOT_USER: classquiz
MINIO_ROOT_PASSWORD: fediprint MINIO_ROOT_PASSWORD: classquiz
MINIO_ADDRESS: ":9000"
MINIO_CONSOLE_ADDRESS: ":9001"
volumes: volumes:
- minio:/bitnami/minio/data - minio:/data
ports: ports:
- 9000:9000 - 9000:9000
- 9001:9001 - 9001:9001
restart: unless-stopped restart: unless-stopped
command: minio server /data
redis: redis:
image: redis:alpine image: redis:alpine
restart: always restart: always
healthcheck: healthcheck:
test: [ "CMD", "redis-cli","ping" ] test: ["CMD", "redis-cli", "ping"]
ports: ports:
- 6379:6379 - 6379:6379
volumes: volumes:
@@ -0,0 +1,3 @@
SPDX-FileCopyrightText: 2025 Marlon W (Mawoka)
SPDX-License-Identifier: MPL-2.0
@@ -0,0 +1,3 @@
SPDX-FileCopyrightText: 2025 Marlon W (Mawoka)
SPDX-License-Identifier: MPL-2.0
@@ -0,0 +1,3 @@
SPDX-FileCopyrightText: 2025 Marlon W (Mawoka)
SPDX-License-Identifier: MPL-2.0
@@ -0,0 +1,3 @@
SPDX-FileCopyrightText: 2025 Marlon W (Mawoka)
SPDX-License-Identifier: MPL-2.0