From b86de2833186f72740af1a73fde458b21b123710 Mon Sep 17 00:00:00 2001 From: "Kenneth C. Arnold" Date: Wed, 7 May 2025 15:47:38 -0400 Subject: [PATCH 1/5] Warm up backend by making dummy requests for both OpenAI and SpaCy This is not yet tested, it might even have syntax errors. --- backend/nlp.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/backend/nlp.py b/backend/nlp.py index 21d2ec20..966e55aa 100644 --- a/backend/nlp.py +++ b/backend/nlp.py @@ -24,10 +24,23 @@ api_key=openai_api_key, ) +dummy_client = AsyncOpenAI(base_url="https://localhost:8000/v1", api_key="") +# make a dummy request to make sure everything is imported +try: + dummy_client.chat.completions.create( + model=MODEL_NAME, + messages=[{"role": "user", "content": "Hello"}], + ) +except openai.APIConnectionError: + # We expect this error because we're connecting to a non-existent server + pass + # Load spaCy model for sentence splitting try: nlp = spacy.load("en_core_web_sm") # nlp = spacy.load("en_core_web_trf") + # Warm up the model + nlp("Hello world. This is a test.").sents except: print("Need to download spaCy model. Run:") print("python -m spacy download en_core_web_sm") From 3021c1ccd0c677188254895a55d5008d739002aa Mon Sep 17 00:00:00 2001 From: "Kenneth C. Arnold" Date: Tue, 10 Jun 2025 15:31:05 -0400 Subject: [PATCH 2/5] Consolidate warmup into a single function --- backend/nlp.py | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/backend/nlp.py b/backend/nlp.py index 966e55aa..7cc8c5cd 100644 --- a/backend/nlp.py +++ b/backend/nlp.py @@ -7,6 +7,7 @@ from pydantic import BaseModel import spacy +import openai from openai.types.chat.chat_completion_message_param import ChatCompletionMessageParam from openai import AsyncOpenAI @@ -24,23 +25,10 @@ api_key=openai_api_key, ) -dummy_client = AsyncOpenAI(base_url="https://localhost:8000/v1", api_key="") -# make a dummy request to make sure everything is imported -try: - dummy_client.chat.completions.create( - model=MODEL_NAME, - messages=[{"role": "user", "content": "Hello"}], - ) -except openai.APIConnectionError: - # We expect this error because we're connecting to a non-existent server - pass - # Load spaCy model for sentence splitting try: nlp = spacy.load("en_core_web_sm") # nlp = spacy.load("en_core_web_trf") - # Warm up the model - nlp("Hello world. This is a test.").sents except: print("Need to download spaCy model. Run:") print("python -m spacy download en_core_web_sm") @@ -50,6 +38,24 @@ exit() +async def warmup_nlp(): + # Warm up the OpenAI client by making a dummy request + dummy_client = AsyncOpenAI(base_url="https://localhost:8000/v1", api_key="") + # make a dummy request to make sure everything is imported + try: + await dummy_client.chat.completions.create( + model=MODEL_NAME, + messages=[{"role": "user", "content": "Hello"}], + ) + except openai.APIConnectionError: + # We expect this error because we're connecting to a non-existent server + pass + + + # Warm up the SpaCy model by processing a sample text + nlp("Hello world. This is a test.").sents + + def get_final_sentence(text): final_sentence = list(nlp(text).sents)[-1].text From 7b7953c935c9d80dea4fad3ea638acb9147e251a Mon Sep 17 00:00:00 2001 From: "Kenneth C. Arnold" Date: Mon, 30 Jun 2025 15:31:51 -0400 Subject: [PATCH 3/5] link in NLP warmup to app lifespan --- backend/server.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/backend/server.py b/backend/server.py index 79fd8103..b6d57114 100644 --- a/backend/server.py +++ b/backend/server.py @@ -3,6 +3,7 @@ import logging import os import zipfile +from contextlib import asynccontextmanager from datetime import datetime from pathlib import Path from typing import Annotated, Dict, List, Literal, Optional @@ -106,8 +107,12 @@ class ReflectionLog(Log): paragraph: str -# Initialize Server -app = FastAPI() +@asynccontextmanager +async def app_lifespan(app: FastAPI): + await nlp.warmup_nlp() + yield + +app = FastAPI(lifespan=app_lifespan) origins = ["*"] From f99f1eac7daedc5a238ec8767152627a30501d50 Mon Sep 17 00:00:00 2001 From: "Kenneth C. Arnold" Date: Mon, 30 Jun 2025 15:36:24 -0400 Subject: [PATCH 4/5] Remove now-unnecessary pinging --- frontend/src/api/index.ts | 27 ---------------------- frontend/src/pages/app/index.tsx | 39 +------------------------------- 2 files changed, 1 insertion(+), 65 deletions(-) diff --git a/frontend/src/api/index.ts b/frontend/src/api/index.ts index c6ff0d46..5c4de560 100644 --- a/frontend/src/api/index.ts +++ b/frontend/src/api/index.ts @@ -7,33 +7,6 @@ export interface LogPayload { [key: string]: any; } -export async function pingServer(): Promise { - try { - // Ping the server, which returns the server's current timestamp - const url = `${SERVER_URL}/ping`; - const response = await fetch(url, { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - } - }); - - if (!response.ok) { - // eslint-disable-next-line no-console - console.warn('Server ping failed:', response.status); - } - - const data = await response.json(); - // eslint-disable-next-line no-console - console.log('Server ping successful:', data); - } - catch (error) { - // eslint-disable-next-line no-console - console.warn('Server ping error:', error); - // Don't throw - we want to silently handle ping failures - } -} - export function log(payload: LogPayload) { const payloadWithTimestamp = { ...payload, diff --git a/frontend/src/pages/app/index.tsx b/frontend/src/pages/app/index.tsx index 67887013..639970d8 100644 --- a/frontend/src/pages/app/index.tsx +++ b/frontend/src/pages/app/index.tsx @@ -1,5 +1,4 @@ -import { useRef, useEffect, useState } from 'react'; -import { pingServer } from '@/api'; +import { useState } from 'react'; import { CgFacebook, CgGoogle, CgMicrosoft } from 'react-icons/cg'; import { useWindowSize } from '@react-hook/window-size/throttled'; @@ -27,40 +26,6 @@ export interface HomeProps { editorAPI: EditorAPI; } -function usePingServer() { - - const pingInterval = useRef(); - - // 2 minutes - const PINGINT: number = 2 * 60 * 1000; - - useEffect(() => { - function doPing() { - // eslint-disable-next-line no-console - console.log(`Pinging server at ${new Date().toISOString()}`); - - pingServer().then(() => { - // eslint-disable-next-line no-console - console.log('Warming up server'); - }).catch(error => { - // eslint-disable-next-line no-console - console.warn('Ping failed:', error); - }); - } - - // First ping the server immediately - doPing(); - // Then set up the interval - pingInterval.current = setInterval(doPing, PINGINT); - - return () => { - if (pingInterval.current) { - clearInterval(pingInterval.current); - } - }; - }, []); -} - function AppInner({ editorAPI }: HomeProps) { const mode = useAtomValue(overallModeAtom); const noAuthMode = mode !== OverallMode.full; @@ -73,8 +38,6 @@ function AppInner({ editorAPI }: HomeProps) { }); const { authErrorType } = useAccessToken(); - usePingServer(); - // Detect if the user is using the latest version of Office // https://learn.microsoft.com/en-us/office/dev/add-ins/develop/support-ie-11?tabs=ie function isOfficeLatest(): boolean { From 088c2bf35f0fbebbb1e2410fd8dfcd0cca223760 Mon Sep 17 00:00:00 2001 From: "Kenneth C. Arnold" Date: Wed, 16 Jul 2025 11:30:09 -0400 Subject: [PATCH 5/5] don't waste time waiting --- backend/nlp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/nlp.py b/backend/nlp.py index 18a92682..8d92389e 100644 --- a/backend/nlp.py +++ b/backend/nlp.py @@ -40,7 +40,7 @@ async def warmup_nlp(): # Warm up the OpenAI client by making a dummy request - dummy_client = AsyncOpenAI(base_url="https://localhost:8000/v1", api_key="") + dummy_client = openai.AsyncOpenAI(base_url="https://localhost:8000/v1", api_key="", timeout=0.01, max_retries=0) # make a dummy request to make sure everything is imported try: await dummy_client.chat.completions.create(