From e746634b5b1a03ae422a521ed233cb43d9d74b5e Mon Sep 17 00:00:00 2001 From: Lukas Schaefer Date: Tue, 8 Jul 2025 11:16:29 -0400 Subject: [PATCH 1/2] feat: add endpoint for downloading logs Signed-off-by: Lukas Schaefer --- appinfo/info.xml | 8 ++++++++ context_chat_backend/controller.py | 17 +++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/appinfo/info.xml b/appinfo/info.xml index 6bb2c1d..6e3db75 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -37,6 +37,14 @@ Setup background job workers as described here: https://docs.nextcloud.com/serve nextcloud/context_chat_backend 4.3.0 + + + download-logs + GET + ADMIN + [] + + EXTERNAL_DB diff --git a/context_chat_backend/controller.py b/context_chat_backend/controller.py index a976e79..b58b40c 100644 --- a/context_chat_backend/controller.py +++ b/context_chat_backend/controller.py @@ -2,6 +2,9 @@ # SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors # SPDX-License-Identifier: AGPL-3.0-or-later # +import zipfile + +from starlette.responses import FileResponse # isort: off from .chain.types import ContextException, LLMOutput, ScopeType, SearchResult @@ -12,6 +15,7 @@ import logging import multiprocessing as mp import os +import tempfile import threading from collections.abc import Callable from contextlib import asynccontextmanager @@ -492,3 +496,16 @@ def _(query: Query) -> list[SearchResult]: query.scopeType, query.scopeList, )) + + +@app.get('/download-logs') +@enabled_guard(app) +def download_logs() -> FileResponse: + with tempfile.NamedTemporaryFile('wb', delete=False) as tmp: + with zipfile.ZipFile(tmp, mode='w', compression=zipfile.ZIP_DEFLATED) as zip_file: + files = os.listdir(os.path.join(persistent_storage(), 'logs')) + for file in files: + file_path = os.path.join(persistent_storage(), 'logs', file) + if os.path.isfile(file_path): # Might be a folder (just skip it then) + zip_file.write(file_path) + return FileResponse(tmp.name, media_type='application/zip', filename='docker_logs.zip') From e5c1c1e6a2107bc69c4f4ce8d1638754bf84b617 Mon Sep 17 00:00:00 2001 From: Lukas Schaefer Date: Wed, 9 Jul 2025 12:25:51 -0400 Subject: [PATCH 2/2] implement feedback Signed-off-by: Lukas Schaefer --- appinfo/info.xml | 2 +- context_chat_backend/controller.py | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/appinfo/info.xml b/appinfo/info.xml index 6e3db75..67c6c7d 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -39,7 +39,7 @@ Setup background job workers as described here: https://docs.nextcloud.com/serve - download-logs + downloadLogs GET ADMIN [] diff --git a/context_chat_backend/controller.py b/context_chat_backend/controller.py index b58b40c..b84daab 100644 --- a/context_chat_backend/controller.py +++ b/context_chat_backend/controller.py @@ -2,9 +2,6 @@ # SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors # SPDX-License-Identifier: AGPL-3.0-or-later # -import zipfile - -from starlette.responses import FileResponse # isort: off from .chain.types import ContextException, LLMOutput, ScopeType, SearchResult @@ -17,6 +14,7 @@ import os import tempfile import threading +import zipfile from collections.abc import Callable from contextlib import asynccontextmanager from functools import wraps @@ -29,6 +27,7 @@ from nc_py_api import AsyncNextcloudApp, NextcloudApp from nc_py_api.ex_app import persistent_storage, set_handlers from pydantic import BaseModel, ValidationInfo, field_validator +from starlette.responses import FileResponse from .chain.context import do_doc_search from .chain.ingest.injest import embed_sources @@ -498,8 +497,7 @@ def _(query: Query) -> list[SearchResult]: )) -@app.get('/download-logs') -@enabled_guard(app) +@app.get('/downloadLogs') def download_logs() -> FileResponse: with tempfile.NamedTemporaryFile('wb', delete=False) as tmp: with zipfile.ZipFile(tmp, mode='w', compression=zipfile.ZIP_DEFLATED) as zip_file: