diff --git a/src/backend/base/langflow/main.py b/src/backend/base/langflow/main.py index b79f092bc..8ec1f0141 100644 --- a/src/backend/base/langflow/main.py +++ b/src/backend/base/langflow/main.py @@ -1,4 +1,5 @@ import asyncio +import gzip import json import os import warnings @@ -11,6 +12,7 @@ from urllib.parse import urlencode import nest_asyncio # type: ignore from fastapi import FastAPI, HTTPException, Request, Response from fastapi.middleware.cors import CORSMiddleware +from fastapi.middleware.gzip import GZipMiddleware from fastapi.responses import FileResponse, JSONResponse from fastapi.staticfiles import StaticFiles from loguru import logger @@ -28,7 +30,11 @@ from langflow.initial_setup.setup import ( ) from langflow.interface.types import get_and_cache_all_types_dict from langflow.interface.utils import setup_llm_caching -from langflow.services.deps import get_cache_service, get_settings_service, get_telemetry_service +from langflow.services.deps import ( + get_cache_service, + get_settings_service, + get_telemetry_service, +) from langflow.services.plugins.langfuse_plugin import LangfuseInstance from langflow.services.utils import initialize_services, teardown_services from langflow.logging.logger import configure @@ -132,9 +138,21 @@ def create_app(): allow_headers=["*"], ) app.add_middleware(JavaScriptMIMETypeMiddleware) + app.add_middleware(GZipMiddleware, minimum_size=1000, compresslevel=5) + # ! Deactivating this until we find a better solution # app.add_middleware(RequestCancelledMiddleware) + @app.middleware("http") + async def decompress_if_gzip(request: Request, call_next): + if request.headers.get("content-encoding", "") == "gzip": + # the request's body is compressed, so we need to decompress it + body = await request.body() + dec = gzip.decompress(body) + request._body = dec # <-- if only things were that easy + response = await call_next(request) + return response + @app.middleware("http") async def flatten_query_string_lists(request: Request, call_next): flattened: list[tuple[str, str]] = [] diff --git a/src/frontend/package-lock.json b/src/frontend/package-lock.json index 8cbae7c90..2217e2557 100644 --- a/src/frontend/package-lock.json +++ b/src/frontend/package-lock.json @@ -57,6 +57,7 @@ "moment": "^2.30.1", "openseadragon": "^4.1.1", "p-debounce": "^4.0.0", + "pako": "^2.1.0", "playwright": "^1.44.1", "react": "^18.3.1", "react-ace": "^11.0.1", @@ -12036,6 +12037,12 @@ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==" }, + "node_modules/pako": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", + "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==", + "license": "(MIT AND Zlib)" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", diff --git a/src/frontend/package.json b/src/frontend/package.json index eaffc748a..750f12059 100644 --- a/src/frontend/package.json +++ b/src/frontend/package.json @@ -52,6 +52,7 @@ "moment": "^2.30.1", "openseadragon": "^4.1.1", "p-debounce": "^4.0.0", + "pako": "^2.1.0", "playwright": "^1.44.1", "react": "^18.3.1", "react-ace": "^11.0.1", diff --git a/src/frontend/src/controllers/API/api.tsx b/src/frontend/src/controllers/API/api.tsx index d9b069455..a9be3a236 100644 --- a/src/frontend/src/controllers/API/api.tsx +++ b/src/frontend/src/controllers/API/api.tsx @@ -1,6 +1,7 @@ import { LANGFLOW_ACCESS_TOKEN } from "@/constants/constants"; import useAuthStore from "@/stores/authStore"; import axios, { AxiosError, AxiosInstance, AxiosRequestConfig } from "axios"; +import pako from "pako"; import { useContext, useEffect } from "react"; import { Cookies } from "react-cookie"; import { BuildStatus } from "../../constants/enums"; @@ -13,6 +14,22 @@ import { useLogout, useRefreshAccessToken } from "./queries/auth"; // Create a new Axios instance const api: AxiosInstance = axios.create({ baseURL: "", + transformRequest: (axios.defaults.transformRequest + ? Array.isArray(axios.defaults.transformRequest) + ? axios.defaults.transformRequest + : [axios.defaults.transformRequest] + : [] + ).concat(function (data, headers) { + // compress strings if over 1KB + if (typeof data === "string" && data.length > 1024) { + headers["Content-Encoding"] = "gzip"; + return pako.gzip(data); + } else { + // delete is slow apparently, faster to set to undefined + headers["Content-Encoding"] = undefined; + return data; + } + }), }); const cookies = new Cookies();