From 6da41af49aaf141c595f5ede3eaa7d76986e9cae Mon Sep 17 00:00:00 2001 From: Pablo Marin Date: Thu, 9 Jan 2025 18:36:09 +0000 Subject: [PATCH] improve SSE /stream endpoint and clients --- apps/backend/fastapi/app/server.py | 8 ++++---- apps/backend/fastapi/backend.zip | Bin 1040724 -> 1045663 bytes 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/backend/fastapi/app/server.py b/apps/backend/fastapi/app/server.py index 9037c2d4..283a1fbb 100644 --- a/apps/backend/fastapi/app/server.py +++ b/apps/backend/fastapi/app/server.py @@ -5,14 +5,14 @@ import asyncio import uuid import logging -from typing import List +import json +from typing import List, Optional from contextlib import asynccontextmanager -from fastapi import FastAPI, Request, HTTPException +from fastapi import FastAPI, Request, HTTPException, BackgroundTasks from fastapi.middleware.cors import CORSMiddleware -from fastapi.responses import RedirectResponse +from fastapi.responses import RedirectResponse, JSONResponse from pydantic import BaseModel - from pathlib import Path from dotenv import load_dotenv diff --git a/apps/backend/fastapi/backend.zip b/apps/backend/fastapi/backend.zip index babe25534c4a4c8631d2501e7e40b6d344345ea0..52c3710921b76aa46909a144703c52dffb95d148 100644 GIT binary patch delta 23041 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 Dx|cZA delta 18226 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