Загрузка данных
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)