Fix docker-compose (minio) and add basic logger
This commit is contained in:
+33
-7
@@ -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
@@ -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"
|
||||||
|
|||||||
@@ -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():
|
||||||
|
|||||||
@@ -34,16 +34,19 @@ 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
|
||||||
|
|||||||
@@ -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
|
||||||
Reference in New Issue
Block a user