From 7876c3015972af2e08d33f6f3bdb81deb55f7341 Mon Sep 17 00:00:00 2001 From: Damir Date: Wed, 8 Apr 2026 00:17:14 +0300 Subject: [PATCH] update --- frontend/ui.py | 154 +++++++++++++++++++++++++++---------------------- 1 file changed, 86 insertions(+), 68 deletions(-) diff --git a/frontend/ui.py b/frontend/ui.py index 58be9b2..ba111d9 100644 --- a/frontend/ui.py +++ b/frontend/ui.py @@ -56,6 +56,90 @@ def _push_history(*, platform: str, model: str, prompt: str, status: str, config st.session_state.history = st.session_state.history[:50] +def _auth_headers(): + if not st.session_state.token: + return {} + return {"Authorization": f"Bearer {st.session_state.token}"} + +def _detail_or_text(resp: requests.Response) -> str: + try: + payload = resp.json() + if isinstance(payload, dict) and payload.get("detail"): + return str(payload["detail"]) + except Exception: + pass + return resp.text + + +def _show_account(): + st.subheader("Аутентификация") + + c1, c2 = st.columns(2) + with c1: + st.markdown("**Регистрация**") + reg_email = st.text_input("Email", key="reg_email") + reg_full_name = st.text_input("Имя (опционально)", key="reg_full_name") + reg_password = st.text_input("Пароль", type="password", key="reg_password") + if st.button("Создать аккаунт", key="btn_register"): + try: + r = requests.post( + f"{backend_base_url}/auth/register", + json={"email": reg_email, "password": reg_password, "full_name": reg_full_name or None}, + timeout=30, + ) + if r.status_code >= 400: + st.error(f"Ошибка регистрации: {_detail_or_text(r)}") + else: + st.success("Аккаунт создан. Теперь можно войти.") + except Exception as e: + st.error(f"Ошибка подключения к бекенду: {e}") + + with c2: + st.markdown("**Вход**") + login_email = st.text_input("Email ", key="login_email") + login_password = st.text_input("Пароль ", type="password", key="login_password") + login_col_a, login_col_b = st.columns([1, 1]) + with login_col_a: + if st.button("Войти", type="primary", key="btn_login"): + try: + r = requests.post( + f"{backend_base_url}/auth/login", + json={"email": login_email, "password": login_password}, + timeout=30, + ) + if r.status_code >= 400: + st.error(f"Ошибка входа: {_detail_or_text(r)}") + else: + st.session_state.token = r.json().get("access_token") + st.success("Успешный вход.") + st.rerun() + except Exception as e: + st.error(f"Ошибка подключения к бекенду: {e}") + with login_col_b: + if st.button("Выйти", disabled=not bool(st.session_state.token), key="btn_logout"): + st.session_state.token = None + st.rerun() + + st.divider() + if st.session_state.token: + try: + r = requests.get(f"{backend_base_url}/auth/me", headers=_auth_headers(), timeout=20) + if r.status_code >= 400: + st.session_state.token = None + st.warning("Сессия истекла или токен неверный. Войдите заново.") + st.rerun() + else: + st.json(r.json()) + except Exception as e: + st.error(f"Ошибка подключения к бекенду: {e}") + + +# Auth wall: пока пользователь не вошёл — показываем только экран входа/регистрации. +if not st.session_state.token: + _show_account() + st.stop() + + tab_overview, tab_account, tab_generator, tab_validator, tab_history = st.tabs( ["Обзор", "Аккаунт", "Pipeline generator", "Проверка YAML", "История"] ) @@ -69,77 +153,11 @@ with tab_overview: ) st.divider() st.caption(f"Backend URL: {backend_base_url}") - if st.session_state.token: - st.success("Вы вошли в систему.") - else: - st.info("Вы не авторизованы.") - - -def _auth_headers(): - if not st.session_state.token: - return {} - return {"Authorization": f"Bearer {st.session_state.token}"} + st.success("Вы вошли в систему.") with tab_account: - st.subheader("Аутентификация") - - c1, c2 = st.columns(2) - with c1: - st.markdown("**Регистрация**") - reg_email = st.text_input("Email", key="reg_email") - reg_full_name = st.text_input("Имя (опционально)", key="reg_full_name") - reg_password = st.text_input("Пароль", type="password", key="reg_password") - if st.button("Создать аккаунт"): - try: - r = requests.post( - f"{backend_base_url}/auth/register", - json={"email": reg_email, "password": reg_password, "full_name": reg_full_name or None}, - timeout=30, - ) - if r.status_code >= 400: - st.error(f"Ошибка регистрации: {r.text}") - else: - st.success("Аккаунт создан. Теперь можно войти.") - except Exception as e: - st.error(f"Ошибка подключения к бекенду: {e}") - - with c2: - st.markdown("**Вход**") - login_email = st.text_input("Email ", key="login_email") - login_password = st.text_input("Пароль ", type="password", key="login_password") - login_col_a, login_col_b = st.columns([1, 1]) - with login_col_a: - if st.button("Войти", type="primary"): - try: - r = requests.post( - f"{backend_base_url}/auth/login", - json={"email": login_email, "password": login_password}, - timeout=30, - ) - if r.status_code >= 400: - st.error(f"Ошибка входа: {r.text}") - else: - st.session_state.token = r.json().get("access_token") - st.success("Успешный вход.") - st.rerun() - except Exception as e: - st.error(f"Ошибка подключения к бекенду: {e}") - with login_col_b: - if st.button("Выйти", disabled=not bool(st.session_state.token)): - st.session_state.token = None - st.rerun() - - st.divider() - if st.session_state.token: - try: - r = requests.get(f"{backend_base_url}/auth/me", headers=_auth_headers(), timeout=20) - if r.status_code >= 400: - st.error(f"Не удалось получить профиль: {r.text}") - else: - st.json(r.json()) - except Exception as e: - st.error(f"Ошибка подключения к бекенду: {e}") + _show_account() with tab_generator: st.subheader("AI CI/CD Pipeline Generator")