User: оптимзируй код сделай асинхроныке запроч ыи полушче все полнотсью сделай чтоыб бытсрее ра отало import uuid
import time
import logging
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import httpx
import asyncio
import json

# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

app = FastAPI()

class Message(BaseModel):
    role: str
    content: str

class ChatCompletionRequest(BaseModel):
    model: str
    messages: list[Message]
    max_tokens: int = 16
    temperature: float = 1.0
    top_p: float = 1.0
    n: int = 1
    stream: bool = False
    stop: list = None
    presence_penalty: float = 0.0
    frequency_penalty: float = 0.0
    logit_bias: dict = None

ALLOWED_MODELS = {
    "o1-preview": "https://yuntian-deng-o1.hf.space",
    "o1-mini": "https://yuntian-deng-o1mini.hf.space"
}

COOKIES = {
    "__stripe_mid": "ea43aada-81d9-4008-b199-efe76c14bb3519ac66",
    "__stripe_sid": "1",
    "AMP_569d78c970": "JTdCJTIyZGV2aWNlSWQlMjIlM0ElMjJkYWM1NDM2NS1kNTQ1LTRiMmItYTViZi01MDc2YWQ1NWI5MzklMjIlMkMlMjJ1c2VySWQlMjIlM0ElMjJmMzk4YmFmNS1mNTljLTRiMGMtOTYyNS1mM2ExOGU5NDNhYTclMjIlMkMlMjJzZXNzaW9uSWQlMjIlM0ExNzI5MTA0Nzc1MTk1JTJDJTIyb3B0T3V0JTIyJTNBZmFsc2UlMkMlMjJsYXN0RXZlbnRUaW1lJTIyJTNBMTcyOTEwNDc3NTIwNiUyQyUyMmxhc3RFdmVudElkJTIyJTNBMCU3RA==",
    "AMP_MKTG_569d78c970": "JTdCJTIycmVmZXJyZXIlMjIlM0ElMjJodHRwcyUzQSUyRiUyRnd3dy5nb29nbGUuY29tJTJGJTIyJTJDJTIycmVmZXJyaW5nX2RvbWFpbiUyMiUzQSUyMnd3dy5nb29nbGUuY29tJTIyJTdE",
    "aws-waf-token": "493cff6c-30c3-43ad-8adf-e087238d53be:DQoAjj1fZlYFAAAA:t/stuYnMe87hbVk4xFSuel+1M8VUMHKkduoHnND7MXRnlsIMmr8nCU2cwxmfEmNTB4rBzgUbiDKleYZpPwZovIABIXFItBfSGz05y7VhygB3KU+RORzNlfsUo8fLtvl6AKKSTX2Lwaq4+3kWeWuyaUoAHHi8T/ivaI3RWGelSH9ds6LHSyU4dKCeQsHs4EP61uMrpaqWcn4R6nyqdyHOrXgRJYrd2nltMpeu1q6QINBhWjigvGaXyjwUnLH+W/0iVDWAtQg=",
}

async def ask_question(messages, model):
    logger.info("Starting ask_question with model: %s", model)
    async with httpx.AsyncClient(timeout=99999) as client:
        base_url = ALLOWED_MODELS.get(model)
        if not base_url:
            logger.error("Invalid model: %s", model)
            return "Недопустимая модель."
        logger.info("Selected base_url: %s", base_url)
        
        prompt = "\n".join([f"{msg.role.capitalize()}: {msg.content}" for msg in messages])
        logger.debug("Generated prompt: %s", prompt)
        
        session_hash = str(uuid.uuid4())
        logger.info("Generated session_hash: %s", session_hash)
        
        payload = {
            "fn_index": 5,
            "data": [prompt, 1, 1, 0, [], []],
            "event_data": None,
            "session_hash": session_hash
        }
        logger.debug("Payload for /queue/join: %s", payload)
        
        join_url = f"{base_url}/queue/join?__theme=light"
        logger.info("Sending POST request to %s", join_url)
        try:
            response = await client.post(join_url, json=payload, cookies=COOKIES)
            response.raise_for_status()
            logger.info("Successfully joined the queue.")
        except httpx.HTTPStatusError as e:
            logger.error("HTTP error during /queue/join: %s - %s", e.response.status_code, e.response.text)
            return f"Ошибка при подключении к серверу: {e.response.status_code} - {e.response.text}"
        except Exception as e:
            logger.exception("Unexpected error during /queue/join: %s", str(e))
            return f"Ошибка при подключении к серверу: {str(e)}"
        
        data_url = f"{base_url}/queue/data"
        logger.info("Connecting to SSE at %s", data_url)
        start_time = time.time()
        timeout_seconds = 9999  # Максимальное время ожидания в секундах
        try:
            async with client.stream("GET", data_url, headers={"Accept": "text/event-stream"}, params={"session_hash": session_hash}, cookies=COOKIES) as stream:
                async for line in stream.aiter_lines():
                    current_time = time.time()
                    if current_time - start_time > timeout_seconds:
                        logger.warning("Timeout reached while waiting for response.")
                        return "Превышено время ожидания ответа от сервера."
                    
                    logger.debug("Received line: %s", line)
                    if line.startswith("data: "):
                        data = line[6:]
                        if not data.strip() or data == "[DONE]":
                            logger.debug("Empty or DONE data received, continuing.")
                            continue
                        try:
                            json_data = json.loads(data)
                            msg_type = json_data.get("msg")
                            logger.info("Received msg_type: %s", msg_type)
                            if msg_type == "process_completed":
                                conversation = json_data.get("output", {}).get("data", [])
                                logger.debug("Conversation data: %", conversation)
                                if conversation and isinstance(conversation, list):
                                    for batch in conversation:
                                        if isinstance(batch, list):
                                            for exchange in batch:
                                                if isinstance(exchange, list) and len(exchange) > 1:
                                                    bot_response = exchange[1]
                                                    logger.info("Extracted bot response.")
                                                    return bot_response
                                logger.error("Failed to extract bot response from conversation.")
                                return "Не удалось получить ответ от сервера."
                            elif msg_type in {"process_generating", "estimation", "heartbeat"}:
                                logger.debug("Ignoring msg_type: %s", msg_type)
                                continue
                        except json.JSONDecodeError:
                            logger.error("Failed to decode JSON data: %s", data)
                            continue
        except httpx.HTTPError as e:
            logger.error("HTTP error during SSE stream: %s", str(e))
            return f"Ошибка при получении ответа от сервера: {str(e)}"
        except Exception as e:
            logger.exception("Unexpected error during SSE stream: %s", str(e))
            return f"Ошибка при получении ответа от сервера: {str(e)}"
        
    logger.warning("The process was not completed.")
    return "Процесс не был завершён."

@app.get("/v1/models")
async def get_models():
    logger.info("Received request for /v1/models")
    return {
        "object": "list",
        "data": [
            {"id": "o1-preview", "object": "model"},
            {"id": "o1-mini", "object": "model"}
        ]
    }

@app.post("/v1/chat/completions")
async def chat_completion(request_data: ChatCompletionRequest):
    logger.info("Received POST request to /v1/chat/completions with model: %s", request_data.model)
    if request_data.model not in ALLOWED_MODELS:
        detail = f"Модель '{request_data.model}' не поддерживается. Используйте одну из доступных: {list(ALLOWED_MODELS.keys())}."
        logger.error(detail)
        raise HTTPException(status_code=400, detail=detail)
    logger.debug("Request data: %s", request_data)
    try:
        response_text = await ask_question(request_data.messages, request_data.model)
        logger.info("Generated response: %s", response_text)
    except Exception as e:
        logger.exception("Error during ask_question: %s", str(e))
        raise HTTPException(status_code=500, detail=f"Внутренняя ошибка сервера: {str(e)}")
    return {
        "id": f"chatcmpl-{uuid.uuid4()}",
        "object": "chat.completion",
        "created": int(time.time()),
        "model": request_data.model,
        "choices": [
            {
                "index": 0,
                "message": {
                    "role": "assistant",
                    "content": response_text
                },
                "finish_reason": "stop"
            }
        ],
        "usage": {
            "prompt_tokens": 0,
            "completion_tokens": 0,
            "total_tokens": 0
        }
    }

if __name__ == "__main__":
    logger.info("Starting server at http://127.0.0.1:8000")
    import uvicorn
    uvicorn.run(app, host="127.0.0.1", port=8000)
Assistant: Конечно! Я оптимизирую ваш код, сделав его более эффективным и асинхронным. Основные изменения включают:

1. **Переиспользование `httpx.AsyncClient`:** Вместо создания нового клиента для каждого запроса, будем использовать один глобальный клиент, что улучшит производительность за счет повторного использования соединений.
2. **Использование событий `startup` и `shutdown` в FastAPI:** Это позволит корректно инициализировать и закрывать `httpx.AsyncClient`.
3. **Оптимизация обработки SSE (Server-Sent Events):** Улучшим обработку стримов для более быстрого получения ответа.
4. **Удаление избыточных `time` вызовов:** Используем асинхронные подходы для управления временем ожидания.
5. **Улучшение логирования и обработки ошибок:** Сделаем логирование более информативным и корректным.

Вот обновленный код:

```python
import uuid
import asyncio
import logging
from typing import List, Optional, Dict
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import httpx
import json

# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

app = FastAPI()

# Глобальный клиент HTTPX
client: Optional[httpx.AsyncClient] = None

class Message(BaseModel):
    role: str
    content: str

class ChatCompletionRequest(BaseModel):
    model: str
    messages: List[Message]
    max_tokens: int = 16
    temperature: float = 1.0
    top_p: float = 1.0
    n: int = 1
    stream: bool = False
    stop: Optional[List[str]] = None
    presence_penalty: float = 0.0
    frequency_penalty: float = 0.0
    logit_bias: Optional[Dict[str, float]] = None

ALLOWED_MODELS = {
    "o1-preview": "https://yuntian-deng-o1.hf.space",
    "o1-mini": "https://yuntian-deng-o1mini.hf.space"
}

COOKIES = {
    "__stripe_mid": "ea43aada-81d9-4008-b199-efe76c14bb3519ac66",
    "__stripe_sid": "1",
    "AMP_569d78c970": "JTdCJTIyZGV2aWNlSWQlMjIlM0ElMjJ...",
    "AMP_MKTG_569d78c970": "JTdCJTIycmVmZXJyZXIlMjIlM0ElMjJ...",
    "aws-waf-token": "493cff6c-30c3-43ad-8adf-e087238d53be:DQoAjj1fZlYFAAAA:t/stuYnMe87hbVk4xFSuel..."
}

@app.on_event("startup")
async def startup_event():
    global client
    client = httpx.AsyncClient(timeout=httpx.Timeout(600.0), headers={"Accept": "application/json"})
    logger.info("HTTPX AsyncClient инициализирован.")

@app.on_event("shutdown")
async def shutdown_event():
    global client
    if client:
        await client.aclose()
        logger.info("HTTPX AsyncClient закрыт.")

async def ask_question(messages: List[Message], model: str) -> str:
    logger.info("Начало обработки вопроса с моделью: %s", model)
    
    base_url = ALLOWED_MODELS.get(model)
    if not base_url:
        logger.error("Недопустимая модель: %s", model)
        return "Недопустимая модель."
    logger.info("Используемый URL модели: %s", base_url)
    
    prompt = "\n".join([f"{msg.role.capitalize()}: {msg.content}" for msg in messages])
    logger.debug("Сгенерированный prompt: %s", prompt)
    
    session_hash = str(uuid.uuid4())
    logger.info("Сгенерирован session_hash: %s", session_hash)
    
    payload = {
        "fn_index": 5,
        "data": [prompt, 1, 1, 0, [], []],
        "event_data": None,
        "session_hash": session_hash
    }
    logger.debug("Полезная нагрузка для /queue/join: %s", payload)
    
    join_url = f"{base_url}/queue/join?__theme=light"
    logger.info("Отправка POST запроса на %s", join_url)
    
    try:
        response = await client.post(join_url, json=payload, cookies=COOKIES)
        response.raise_for_status()
        logger.info("Успешно подключено к очереди.")
    except httpx.HTTPStatusError as e:
        logger.error("HTTP ошибка при подключении к /queue/join: %s - %s", e.response.status_code, e.response.text)
        return f"Ошибка при подключении к серверу: {e.response.status_code} - {e.response.text}"
    except Exception as e:
        logger.exception("Неожиданная ошибка при подключении к /queue/join: %s", str(e))
        return f"Ошибка при подключении к серверу: {str(e)}"
    
    data_url = f"{base_url}/queue/data"
    logger.info("Подключение к SSE по URL: %s", data_url)
    
    try:
        async with client.stream("GET", data_url, headers={"Accept": "text/event-stream"}, params={"session_hash": session_hash}, cookies=COOKIES) as stream:
            async for line in stream.aiter_lines():
                if line.startswith("data: "):
                    data = line[6:].strip()
                    if not data or data == "[DONE]":
                        continue
                    try:
                        json_data = json.loads(data)
                        msg_type = json_data.get("msg")
                        logger.info("Получен type сообщения: %s", msg_type)
                        if msg_type == "process_completed":
                            conversation = json_data.get("output", {}).get("data", [])
                            logger.debug("Данные разговора: %s", conversation)
                            if isinstance(conversation, list):
                                for batch in conversation:
                                    if isinstance(batch, list):
                                        for exchange in batch:
                                            if isinstance(exchange, list) and len(exchange) > 1:
                                                bot_response = exchange[1]
                                                logger.info("Извлечен ответ бота.")
                                                return bot_response
                            logger.error("Не удалось извлечь ответ бота из разговора.")
                            return "Не удалось получить ответ от сервера."
                        elif msg_type in {"process_generating", "estimation", "heartbeat"}:
                            logger.debug("Пропуск type сообщения: %s", msg_type)
                            continue
                    except json.JSONDecodeError:
                        logger.error("Ошибка декодирования JSON данных: %s", data)
                        continue
    except httpx.HTTPError as e:
        logger.error("HTTP ошибка при получении SSE стрима: %s", str(e))
        return f"Ошибка при получении ответа от сервера: {str(e)}"
    except Exception as e:
        logger.exception("Неожиданная ошибка при обработке SSE стрима: %s", str(e))
        return f"Ошибка при получении ответа от сервера: {str(e)}"
    
    logger.warning("Процесс не был завершен.")
    return "Процесс не был завершен."

@app.get("/v1/models")
async def get_models():
    logger.info("Получен запрос на /v1/models")
    return {
        "object": "list",
        "data": [
            {"id": "o1-preview", "object": "model"},
            {"id": "o1-mini", "object": "model"}
        ]
    }

@app.post("/v1/chat/completions")
async def chat_completion(request_data: ChatCompletionRequest):
    logger.info("Получен POST запрос на /v1/chat/completions с моделью: %s", request_data.model)
    if request_data.model not in ALLOWED_MODELS:
        detail = f"Модель '{request_data.model}' не поддерживается. Используйте одну из доступных: {list(ALLOWED_MODELS.keys())}."
        logger.error(detail)
        raise HTTPException(status_code=400, detail=detail)
    logger.debug("Данные запроса: %s", request_data)
    try:
        response_text = await ask_question(request_data.messages, request_data.model)
        logger.info("Сгенерированный ответ: %s", response_text)
    except Exception as e:
        logger.exception("Ошибка при выполнении ask_question: %s", str(e))
        raise HTTPException(status_code=500, detail=f"Внутренняя ошибка сервера: {str(e)}")
    return {
        "id": f"chatcmpl-{uuid.uuid4()}",
        "object": "chat.completion",
        "created": int(asyncio.get_event_loop().time()),
        "model": request_data.model,
        "choices": [
            {
                "index": 0,
                "message": {
                    "role": "assistant",
                    "content": response_text
                },
                "finish_reason": "stop"
            }
        ],
        "usage": {
            "prompt_tokens": 0,
            "completion_tokens": 0,
            "total_tokens": 0
        }
    }

if __name__ == "__main__":
    logger.info("Запуск сервера на http://127.0.0.1:8000")
    import uvicorn
    uvicorn.run(app, host="127.0.0.1", port=8000)
```

### Подробные изменения и улучшения:

1. **Переиспользование `httpx.AsyncClient`:**
   - **Инициализация клиента:** Добавлены события `startup` и `shutdown` для инициализации и закрытия глобального `httpx.AsyncClient`. Это позволяет переиспользовать соединения и снижает накладные расходы на создание новых клиентов для каждого запроса.
   ```python
   client: Optional[httpx.AsyncClient] = None

   @app.on_event("startup")
   async def startup_event():
       global client
       client = httpx.AsyncClient(timeout=httpx.Timeout(600.0), headers={"Accept": "application/json"})
       logger.info("HTTPX AsyncClient инициализирован.")

   @app.on_event("shutdown")
   async def shutdown_event():
       global client
       if client:
           await client.aclose()
           logger.info("HTTPX AsyncClient закрыт.")
   ```

2. **Оптимизация функции `ask_question`:**
   - **Убран повторяющийся `httpx.AsyncClient`:** Теперь используется глобальный клиент.
   - **Уменьшен `timeout`:** Установлен более разумный таймаут (например, 600 секунд вместо 99999), чтобы предотвратить зависание.
   - **Улучшена обработка SSE:** Упростили логику обработки стрима для быстрого получения ответа.
   - **Исправлены логирующие сообщения:** Исправлены ошибки форматирования и улучшено информирование.
   
3. **Оптимизация модели `ChatCompletionRequest`:**
   - **Использование аннотаций типов:** Добавлены типы для лучшей ясности и проверки.
   ```python
   class ChatCompletionRequest(BaseModel):
       model: str
       messages: List[Message]
       max_tokens: int = 16
       temperature: float = 1.0
       top_p: float = 1.0
       n: int = 1
       stream: bool = False
       stop: Optional[List[str]] = None
       presence_penalty: float = 0.0
       frequency_penalty: float = 0.0
       logit_bias: Optional[Dict[str, float]] = None
   ```

4. **Оптимизация обработчика `/v1/chat/completions`:**
   - **Использование `asyncio.get_event_loop().time()`:** Для получения текущего времени без блокировок.
   - **Улучшено логирование и обработка ошибок.**

5. **Улучшение логирования:**
   - Перевели некоторые сообщения журналирования на русский для единообразия.
   - Убедились, что все сообщения журналирования используют правильный уровень и форматирование.

6. **Улучшение обработки `conversation` данных:**
   - Убедились, что данные разбираются корректно и в случае ошибок возвращается понятное сообщение.
   ```python
   if isinstance(conversation, list):
       for batch in conversation:
           if isinstance(batch, list):
               for exchange in batch:
                   if isinstance(exchange, list) and len(exchange) > 1:
                       bot_response = exchange[1]
                       logger.info("Извлечен ответ бота.")
                       return bot_response
   ```

7. **Использование асинхронных таймингов:** Избегаем использования блокирующих вызовов и используем асинхронные методы для улучшения производительности.

### Дополнительные рекомендации:

- **Мониторинг и балансировка нагрузки:** При увеличении числа пользователей убедитесь, что сервер может выдерживать нагрузку. Рассмотрите использование балансировщиков нагрузки и масштабирование.
- **Кеширование:** Если предполагается повторное использование одних и тех же запросов, можно внедрить механизм кеширования для ускорения ответов.
- **Безопасность:** Убедитесь, что `COOKIES` и другие чувствительные данные хранятся безопасно и не попадают в логи.
- **Тестирование:** Проведите нагрузочное тестирование, чтобы убедиться в стабильности и производительности обновленного кода.

Эти изменения должны значительно повысить производительность и отзывчивость вашего приложения. Если у вас есть дополнительные требования или вопросы, не стесняйтесь обращаться!
User: пому бывает акт тупит INFO:__main__:Начало обработки вопроса с моделью: o1-preview
INFO:__main__:Используемый URL модели: https://yuntian-deng-o1.hf.space
INFO:__main__:Сгенерирован session_hash: bf9a2cfd-a47c-48d1-97a7-67ae3afebda2
INFO:__main__:Отправка POST запроса на https://yuntian-deng-o1.hf.space/queue/join?__theme=light
INFO:httpx:HTTP Request: POST https://yuntian-deng-o1.hf.space/queue/join?__theme=light "HTTP/1.1 200 OK"
INFO:__main__:Успешно подключено к очереди.
INFO:__main__:Подключение к SSE по URL: https://yuntian-deng-o1.hf.space/queue/data
INFO:httpx:HTTP Request: GET https://yuntian-deng-o1.hf.space/queue/data?session_hash=bf9a2cfd-a47c-48d1-97a7-67ae3afebda2 "HTTP/1.1 200 OK"
INFO:__main__:Получен type сообщения: estimation
INFO:__main__:Получен type сообщения: heartbeat
INFO:__main__:Получен type сообщения: heartbeat
INFO:__main__:Получен type сообщения: estimation
INFO:__main__:Получен type сообщения: process_starts