From 8369d3cec76b0b131fcc5d42dcd937583ebca2f3 Mon Sep 17 00:00:00 2001 From: Alexander Piskun <13381981+bigcat88@users.noreply.github.com> Date: Thu, 4 Jul 2024 20:24:42 +0300 Subject: [PATCH] applied linters, fixed CI Signed-off-by: Alexander Piskun --- .gitattributes | 19 ++++++++++----- .pre-commit-config.yaml | 29 +++++++++++++++++++++++ ex_app/lib/main.py | 52 ++++++++++++++++++++++------------------- pyproject.toml | 38 ++++++++++++++++++++++++++++++ 4 files changed, 108 insertions(+), 30 deletions(-) create mode 100644 .pre-commit-config.yaml create mode 100644 pyproject.toml diff --git a/.gitattributes b/.gitattributes index 7134b9f..ec3a634 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,12 +2,19 @@ * text eol=lf # Denote all files that are truly binary and should not be modified -js/* binary -screenshots/* binary -locales/* binary -translationfiles/* binary -*.png binary +*.heif binary +*.heic binary *.hif binary +*.avif binary +*.png binary +*.gif binary +*.webp binary +*.tiff binary +*.jpeg binary +*.jpg binary +*.svg binary +*.phar binary # Files to exclude from GitHub Languages statistics -l10n/* linguist-vendored=true +*.h linguist-vendored=true +*.Dockerfile linguist-vendored=true diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..0c53979 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,29 @@ +ci: + skip: [pylint] + +exclude: '^ex_app/(img|js)/|.*\.phar' +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.6.0 + hooks: + - id: check-yaml + - id: end-of-file-fixer + - id: trailing-whitespace + - id: mixed-line-ending + +- repo: https://github.com/PyCQA/isort + rev: 5.13.2 + hooks: + - id: isort + files: ex_app/lib/ + +- repo: https://github.com/psf/black + rev: 24.4.0 + hooks: + - id: black + files: ex_app/lib/ + +- repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.5.0 + hooks: + - id: ruff diff --git a/ex_app/lib/main.py b/ex_app/lib/main.py index eef11a5..b21d533 100644 --- a/ex_app/lib/main.py +++ b/ex_app/lib/main.py @@ -1,23 +1,17 @@ import os import typing -from pathlib import Path from contextlib import asynccontextmanager +from contextvars import ContextVar +from gettext import translation +from pathlib import Path import httpx -from starlette.responses import Response, FileResponse -from fastapi import FastAPI, responses, Request, Depends, BackgroundTasks, status -from starlette.middleware.base import BaseHTTPMiddleware - +from fastapi import BackgroundTasks, Depends, FastAPI, Request, responses, status from nc_py_api import NextcloudApp -from nc_py_api.ex_app import ( - run_app, - AppAPIAuthMiddleware, - nc_app, -) +from nc_py_api.ex_app import AppAPIAuthMiddleware, nc_app, run_app from nc_py_api.ex_app.integration_fastapi import fetch_models_task -from contextvars import ContextVar - -from gettext import translation +from starlette.middleware.base import BaseHTTPMiddleware +from starlette.responses import FileResponse, Response LOCALE_DIR = os.path.join(os.path.dirname(os.path.dirname(__file__)), "locale") current_translator = ContextVar("current_translator") @@ -30,14 +24,11 @@ def _(text): class LocalizationMiddleware(BaseHTTPMiddleware): async def dispatch(self, request: Request, call_next): - request_lang = request.headers.get('Accept-Language', 'en') + request_lang = request.headers.get("Accept-Language", "en") print(f"DEBUG: lang={request_lang}") - translator = translation( - os.getenv("APP_ID"), LOCALE_DIR, languages=[request_lang], fallback=True - ) + translator = translation(os.getenv("APP_ID"), LOCALE_DIR, languages=[request_lang], fallback=True) current_translator.set(translator) - response = await call_next(request) - return response + return await call_next(request) @asynccontextmanager @@ -78,12 +69,15 @@ def enabled_callback(enabled: bool, nc: typing.Annotated[NextcloudApp, Depends(n return responses.JSONResponse(content={"error": enabled_handler(enabled, nc)}) -@APP.api_route("/api/{path:path}", methods=["GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "PATCH", "TRACE"]) +@APP.api_route( + "/api/{path:path}", + methods=["GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "PATCH", "TRACE"], +) async def proxy_backend_requests(request: Request, path: str): # print(f"proxy_BACKEND_requests: {path} - {request.method}\nCookies: {request.cookies}", flush=True) async with httpx.AsyncClient() as client: url = f"http://127.0.0.1:8288/api/{path}" - headers = {key: value for key, value in request.headers.items() if key.lower() not in ("host", 'cookie')} + headers = {key: value for key, value in request.headers.items() if key.lower() not in ("host", "cookie")} # print(f"proxy_BACKEND_requests: method={request.method}, path={path}, status={response.status_code}") if request.method == "GET": response = await client.get( @@ -106,12 +100,22 @@ async def proxy_backend_requests(request: Request, path: str): # ) response_header = dict(response.headers) response_header.pop("transfer-encoding", None) - return Response(content=response.content, status_code=response.status_code, headers=response_header) + return Response( + content=response.content, + status_code=response.status_code, + headers=response_header, + ) -@APP.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "PATCH", "TRACE"]) +@APP.api_route( + "/{path:path}", + methods=["GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "PATCH", "TRACE"], +) async def proxy_requests(_request: Request, path: str): - print(f"proxy_requests: {path} - {_request.method}\nCookies: {_request.cookies}", flush=True) + print( + f"proxy_requests: {path} - {_request.method}\nCookies: {_request.cookies}", + flush=True, + ) if path.startswith("ex_app"): file_server_path = Path("../../" + path) elif not path: diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..9b1f8c5 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,38 @@ +[tool.black] +line-length = 120 +target-versions = ["py310"] +preview = true + +[tool.ruff] +line-length = 120 +target-version = "py310" +select = ["A", "B", "C", "E", "F", "G", "I", "S", "SIM", "PIE", "Q", "RET", "RUF", "UP" , "W"] +extend-ignore = ["I001", "RUF100", "D400", "D415"] + +[tool.isort] +profile = "black" + +[tool.pylint] +master.py-version = "3.10" +master.extension-pkg-allow-list = ["pydantic"] +design.max-attributes = 8 +design.max-locals = 16 +design.max-branches = 16 +design.max-returns = 8 +design.max-args = 7 +basic.good-names = [ + "a", "b", "c", "d", "e", "f", "i", "j", "k", "r", "v", + "ex", "_", "fp", "im", "nc", "ui", +] +reports.output-format = "colorized" +similarities.ignore-imports = "yes" +similarities.min-similarity-lines = 6 +messages_control.disable = [ + "missing-class-docstring", + "missing-function-docstring", + "line-too-long", + "too-few-public-methods", + "too-many-public-methods", + "global-statement", + "broad-exception-caught", +]