Загрузка данных


from fastapi import FastAPI, Request, Form
from fastapi.responses import HTMLResponse, RedirectResponse
from starlette.middleware.sessions import SessionMiddleware
from passlib.context import CryptContext
import pyodbc

app = FastAPI()

app.add_middleware(
    SessionMiddleware,
    secret_key="CHANGE_ME_SECRET_KEY_123"
)

pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")


def get_db():
    return pyodbc.connect(
        "DRIVER={ODBC Driver 18 for SQL Server};"
        "SERVER=localhost;"
        "DATABASE=FastapiSiteDb;"
        "Trusted_Connection=yes;"
        "TrustServerCertificate=yes;"
    )


def render_page(content: str):
    return f"""
    <!DOCTYPE html>
    <html lang="ru">
    <head>
        <meta charset="UTF-8">
        <title>Мой сайт</title>
        <style>
            body {{
                font-family: Arial, sans-serif;
                background: #f4f6fb;
                margin: 0;
                padding: 0;
            }}
            header {{
                background: #1d4ed8;
                color: white;
                padding: 24px;
                text-align: center;
            }}
            main {{
                max-width: 800px;
                margin: 40px auto;
                background: white;
                padding: 32px;
                border-radius: 16px;
                box-shadow: 0 10px 30px rgba(0,0,0,0.08);
            }}
            input {{
                display: block;
                width: 100%;
                padding: 12px;
                margin: 12px 0;
                box-sizing: border-box;
            }}
            button {{
                padding: 12px 18px;
                background: #1d4ed8;
                color: white;
                border: 0;
                border-radius: 8px;
                cursor: pointer;
            }}
            a {{
                color: #1d4ed8;
            }}
        </style>
    </head>
    <body>
        <header>
            <h1>Мой сайт-визитка</h1>
        </header>
        <main>
            {content}
        </main>
    </body>
    </html>
    """


@app.get("/", response_class=HTMLResponse)
def home(request: Request):
    user_email = request.session.get("user_email")

    if user_email:
        content = f"""
        <h2>Добро пожаловать, {user_email}</h2>
        <p>Это простой сайт на FastAPI + Microsoft SQL Server.</p>
        <p>Здесь потом можно разместить описание компании, услуги, контакты и формы заявок.</p>
        <a href="/logout">Выйти</a>
        """
    else:
        content = """
        <h2>Добро пожаловать</h2>
        <p>Это простой сайт-визитка с регистрацией и авторизацией.</p>
        <p>
            <a href="/register">Регистрация</a> |
            <a href="/login">Вход</a>
        </p>
        """

    return render_page(content)


@app.get("/register", response_class=HTMLResponse)
def register_page():
    return render_page("""
    <h2>Регистрация</h2>
    <form method="post">
        <input type="email" name="email" placeholder="Email" required>
        <input type="password" name="password" placeholder="Пароль" required>
        <button type="submit">Зарегистрироваться</button>
    </form>
    <p><a href="/">На главную</a></p>
    """)


@app.post("/register")
def register(email: str = Form(...), password: str = Form(...)):
    password_hash = pwd_context.hash(password)

    try:
        conn = get_db()
        cursor = conn.cursor()
        cursor.execute(
            "INSERT INTO users (email, password_hash) VALUES (?, ?)",
            email,
            password_hash
        )
        conn.commit()
        conn.close()
    except Exception as e:
        return HTMLResponse(render_page(f"""
        <h2>Ошибка регистрации</h2>
        <p>Возможно, такой пользователь уже существует.</p>
        <pre>{e}</pre>
        <p><a href="/register">Назад</a></p>
        """))

    return RedirectResponse("/login", status_code=303)


@app.get("/login", response_class=HTMLResponse)
def login_page():
    return render_page("""
    <h2>Вход</h2>
    <form method="post">
        <input type="email" name="email" placeholder="Email" required>
        <input type="password" name="password" placeholder="Пароль" required>
        <button type="submit">Войти</button>
    </form>
    <p><a href="/">На главную</a></p>
    """)


@app.post("/login")
def login(request: Request, email: str = Form(...), password: str = Form(...)):
    conn = get_db()
    cursor = conn.cursor()
    cursor.execute(
        "SELECT id, email, password_hash FROM users WHERE email = ?",
        email
    )
    user = cursor.fetchone()
    conn.close()

    if not user or not pwd_context.verify(password, user.password_hash):
        return HTMLResponse(render_page("""
        <h2>Ошибка входа</h2>
        <p>Неверный email или пароль.</p>
        <p><a href="/login">Попробовать снова</a></p>
        """))

    request.session["user_email"] = user.email

    return RedirectResponse("/", status_code=303)


@app.get("/logout")
def logout(request: Request):
    request.session.clear()
    return RedirectResponse("/", status_code=303)