Почему когда я в чате нажимаю отправить сообщение то получаю текст на странице: {"detail":"Method Not Allowed"}




Вот код
import logging
import sys

from aiotdlib.api import MessageSenderChat, MessageSenderUser
from fastapi import FastAPI, Request, Depends, Form, UploadFile, File, HTTPException, status
from fastapi.templating import Jinja2Templates
from fastapi.responses import RedirectResponse, StreamingResponse
from fastapi.staticfiles import StaticFiles

import models
from database import database, engine, metadata
from auth import router as auth_router, manager
from models import Base
from schemas import User
from tdlib_manager import get_client, close_client
import os
import aiofiles

# Base.metadata.create_all(bind=engine)
app = FastAPI()
logging.basicConfig(level=logging.CRITICAL)

app.mount("/static", StaticFiles(directory="static"), name="static")

templates = Jinja2Templates(directory="templates")
auth_manager = manager

app.include_router(auth_router, prefix='/auth')


@app.on_event("startup")
async def startup():
    await database.connect()
    metadata.create_all(engine)


@app.on_event("shutdown")
async def shutdown():
    await database.disconnect()


@app.get('/')
async def index(request: Request, user=Depends(manager)):
    user_id = user['id']
    client = await get_client(user_id, phonenumber=user['phone_number'])

    # auth_state = await client.get_authorization_state()
    # if auth_state['@type'] != 'authorizationStateReady':
    #     return RedirectResponse(url='/start')

    chats = await client.get_main_list_chats(limit=50)
    return templates.TemplateResponse('index.html', {'request': request, 'chats': chats, 'user': user})


@app.get('/start')
async def start_page(request: Request, user=Depends(manager)):
    user_id = user['id']
    client = await get_client(user_id)
    auth_state = await client.get_authorization_state()

    if auth_state['@type'] == 'authorizationStateWaitPhoneNumber':
        return templates.TemplateResponse('auth/login_phone.html', {'request': request})
    elif auth_state['@type'] == 'authorizationStateWaitCode':
        return templates.TemplateResponse('auth/login_code.html', {'request': request})
    elif auth_state['@type'] == 'authorizationStateWaitPassword':
        return templates.TemplateResponse('auth/login_password.html', {'request': request})
    elif auth_state['@type'] == 'authorizationStateReady':
        return RedirectResponse(url='/')
    else:
        return 'Неизвестное состояние авторизации.'


@app.post('/start')
async def start(request: Request, user=Depends(manager), phone_number: str = Form(None), code: str = Form(None), password: str = Form(None)):
    user_id = user['id']
    client = await get_client(user_id)
    auth_state = await client.get_authorization_state()

    try:
        if auth_state['@type'] == 'authorizationStateWaitPhoneNumber':
            await client.set_authentication_phone_number(phone_number)
        elif auth_state['@type'] == 'authorizationStateWaitCode':
            await client.check_authentication_code(code)
        elif auth_state['@type'] == 'authorizationStateWaitPassword':
            await client.check_authentication_password(password)
    except Exception as e:
        error = str(e)
        if auth_state['@type'] == 'authorizationStateWaitPhoneNumber':
            return templates.TemplateResponse('auth/login_phone.html', {'request': request, 'error': error})
        elif auth_state['@type'] == 'authorizationStateWaitCode':
            return templates.TemplateResponse('auth/login_code.html', {'request': request, 'error': error})
        elif auth_state['@type'] == 'authorizationStateWaitPassword':
            return templates.TemplateResponse('auth/login_password.html', {'request': request, 'error': error})

    return RedirectResponse(url='/start')


@app.get('/chat/{chat_id}')
async def chat_page(request: Request, chat_id: int, user=Depends(manager)):
    # auth_state = await client.get_authorization_state()
    # if auth_state['@type'] != 'authorizationStateReady':
    #     return RedirectResponse(url='/start')
    user_id = user['id']
    client = await get_client(user_id, phonenumber=user['phone_number'])

    # Initialize variables for storing interlocutor's information
    other_user_id = None
    other_username = None
    other_first_name = None
    other_last_name = None

    chat_info = await client.api.get_chat(chat_id=chat_id)

    # Check if the chat is a private chat
    if chat_info.type_.ID == 'chatTypePrivate':
        other_user_id = chat_info.type_.user_id

        if other_user_id != user_id:
            # Get user information
            other_user_info = await client.api.get_user(user_id=other_user_id)

            # other_username = other_user_info.username
            other_username = other_user_info.usernames.active_usernames[0]
            other_first_name = other_user_info.first_name
            # other_last_name = other_user_info.last_name
        else:
            # If the user IDs match, handle appropriately (e.g., get the other participant's info)
            pass
    else:
        # Handle group chats or channels appropriately
        pass

    # Your code to get messages
    messages = []
    async for message in client.iter_chat_history(chat_id=chat_id, limit=50):
        messages.append(message)

    current_user = await client.api.get_me()
    current_user_id = current_user.id

    return templates.TemplateResponse('chat.html', {
        'request': request,
        'messages': messages,
        'chat_id': chat_id,
        'user_id': current_user_id,
        'other_username': other_username,
        'other_first_name': other_first_name,
        'other_last_name': other_last_name,
        'other_user_id': other_user_id,
    })



@app.get('/download/{user_id}/{filename}')
async def download_file(user_id: int, filename: str):
    file_path = os.path.join('uploads', str(user_id), filename)
    if os.path.exists(file_path):
        async def iterfile():
            async with aiofiles.open(file_path, 'rb') as f:
                while True:
                    chunk = await f.read(1024)
                    if not chunk:
                        break
                    yield chunk
        return StreamingResponse(iterfile(), media_type='application/octet-stream', headers={
            "Content-Disposition": f"attachment; filename={filename}"
        })
    else:
        raise HTTPException(status_code=404, detail="Файл не найден")





Вот шаблон:

{% extends "base.html" %}
{% block content %}
<h1 class="mb-4">Чат с {{ other_username }}</h1>
<a href="{{ url_for('index') }}" class="btn btn-secondary mb-3">⬅ Вернуться к списку чатов</a>

<div class="d-flex flex-column" style="height: 80vh;">
    <div class="card flex-grow-1 mb-3 overflow-auto" id="message-container">
        <div class="card-body d-flex flex-column-reverse">
            {% for message in messages %}
                <div class="d-flex {% if message.sender_id.user_id == user_id %}justify-content-end{% else %}justify-content-start{% endif %} mb-3">
                    <div class="message-box {% if message.sender_id.user_id == user_id %}bg-primary text-white{% else %}bg-light{% endif %} p-3 rounded">
                        {% if message.content.ID == 'messageText' %}
                            {{ message.content.text.text }}
                        {% elif message.content['@type'] == 'messagePhoto' %}
                            <div class="mt-2">
                                <img src="{{ url_for('download_file', user_id=user.id, filename=message.content.photo.sizes[-1].photo.remote.unique_id) }}" class="img-fluid" alt="Фото">
                            </div>
                        {% elif message.content['@type'] == 'messageDocument' %}
                            <div class="mt-2">
                                <a href="{{ url_for('download_file', user_id=user.id, filename=message.content.document.file_name) }}" class="btn btn-link">📎 {{ message.content.document.file_name }}</a>
                            </div>
                        {% else %}
                            <small class="text-muted">Тип сообщения не поддерживается для отображения.</small>
                        {% endif %}
                    </div>
                </div>
            {% endfor %}
        </div>
    </div>

    <form method="post" enctype="multipart/form-data" class="mt-2">
        <div class="input-group">
            <textarea id="message" name="message" class="form-control" placeholder="Введите сообщение..." rows="1"></textarea>
            <input type="file" id="file" name="file" class="form-control" style="max-width: 150px;">
            <button type="submit" class="btn btn-primary">Отправить</button>
        </div>
    </form>
</div>

<script>
    // Автопрокрутка до последнего сообщения
    var messageContainer = document.getElementById('message-container');
    messageContainer.scrollTop = messageContainer.scrollHeight;
</script>
{% endblock %}