PythonStreamlitGPTВеб-разработкаTutorial

Создаём веб-приложение с GPT на Python за час

Пошаговый туториал по созданию полноценного веб-приложения с ChatGPT интерфейсом используя Streamlit и API ЛЛМКИ. Код прилагается.

Дмитрий П.
14 августа 2025
10 мин

Недавно нужно было быстро сделать демо-приложение с GPT для презентации клиенту. За час создал полноценный веб-интерфейс с историей чатов и настройками. Делюсь пошаговым гайдом.


Что получится в итоге


  • Веб-интерфейс как у ChatGPT
  • История сообщений в рамках сессии
  • Выбор разных AI-моделей
  • Настройка температуры и других параметров
  • Экспорт чата в файл
  • Подсчет стоимости запросов

  • Установка зависимостей


    Код (bash):

    pip install streamlit openai

    Код (text):

    Шаг 1: Базовый интерфейс


    Создайте файл `app.py`:


    Код (python):

    import streamlit as st

    from openai import OpenAI


    # Настройка страницы

    st.set_page_config(

    page_title="GPT Chat App",

    page_icon="🤖",

    layout="wide"

    )


    # Инициализация клиента

    @st.cache_resource

    def init_client():

    return OpenAI(

    api_key=st.secrets.get("LLMKI_API_KEY", "sk-llmki-ai-..."),

    base_url="https://llmki.ru/v1"

    )


    client = init_client()

    Код (text):

    Шаг 2: История сообщений


    Код (python):

    # Инициализация истории в session_state

    if "messages" not in st.session_state:

    st.session_state.messages = []


    # Отображение истории

    for message in st.session_state.messages:

    with st.chat_message(message["role"]):

    st.markdown(message["content"])

    Код (text):

    Шаг 3: Обработка пользовательского ввода


    Код (python):

    # Поле для ввода

    if prompt := st.chat_input("Введите ваше сообщение..."):

    # Добавляем сообщение пользователя

    st.session_state.messages.append({"role": "user", "content": prompt})

    with st.chat_message("user"):

    st.markdown(prompt)


    # Отправляем запрос к GPT

    with st.chat_message("assistant"):

    with st.spinner("Думаю..."):

    response = client.chat.completions.create(

    model="openai/gpt-4o",

    messages=[

    {"role": m["role"], "content": m["content"]}

    for m in st.session_state.messages

    ],

    temperature=0.7,

    max_tokens=1000

    )


    answer = response.choices[0].message.content

    st.markdown(answer)

    st.session_state.messages.append({"role": "assistant", "content": answer})

    Код (text):

    Шаг 4: Выбор модели


    Код (python):

    # Боковая панель с настройками

    with st.sidebar:

    st.header("⚙️ Настройки")


    model = st.selectbox(

    "Выберите модель:",

    [

    "openai/gpt-4o",

    "openai/gpt-4o-mini",

    "anthropic/claude-3.5-sonnet",

    "anthropic/claude-3-haiku",

    "google/gemini-pro"

    ]

    )


    temperature = st.slider(

    "Температура (креативность):",

    min_value=0.0,

    max_value=2.0,

    value=0.7,

    step=0.1

    )


    max_tokens = st.slider(

    "Максимум токенов:",

    min_value=100,

    max_value=4000,

    value=1000,

    step=100

    )


    # Кнопка очистки истории

    if st.button("🗑️ Очистить историю"):

    st.session_state.messages = []

    st.rerun()

    Код (text):

    Шаг 5: Полный код приложения


    Код (python):

    import streamlit as st

    from openai import OpenAI

    from datetime import datetime


    # Настройка страницы

    st.set_page_config(

    page_title="GPT Chat App",

    page_icon="🤖",

    layout="wide"

    )


    # Инициализация клиента

    @st.cache_resource

    def init_client():

    api_key = st.secrets.get("LLMKI_API_KEY")

    if not api_key:

    api_key = st.text_input("Введите API ключ LLM_КИ:", type="password")

    return OpenAI(

    api_key=api_key,

    base_url="https://llmki.ru/v1"

    )


    client = init_client()


    # Боковая панель

    with st.sidebar:

    st.header("⚙️ Настройки")


    model = st.selectbox(

    "Модель:",

    [

    "openai/gpt-4o",

    "openai/gpt-4o-mini",

    "anthropic/claude-3.5-sonnet",

    "anthropic/claude-3-haiku",

    "google/gemini-pro"

    ]

    )


    temperature = st.slider("Температура:", 0.0, 2.0, 0.7, 0.1)

    max_tokens = st.slider("Максимум токенов:", 100, 4000, 1000, 100)


    if st.button("🗑️ Очистить историю"):

    st.session_state.messages = []

    st.rerun()


    # Статистика

    if st.session_state.messages:

    st.divider()

    st.metric("Сообщений", len(st.session_state.messages) // 2)


    # Главная область

    st.title("🤖 GPT Chat Application")

    st.caption("Веб-приложение для общения с AI через LLM_КИ API")


    # Инициализация истории

    if "messages" not in st.session_state:

    st.session_state.messages = []


    # Отображение истории

    for message in st.session_state.messages:

    with st.chat_message(message["role"]):

    st.markdown(message["content"])


    # Обработка ввода

    if prompt := st.chat_input("Введите ваше сообщение..."):

    # Добавляем сообщение пользователя

    st.session_state.messages.append({"role": "user", "content": prompt})

    with st.chat_message("user"):

    st.markdown(prompt)


    # Получаем ответ от AI

    with st.chat_message("assistant"):

    with st.spinner("Думаю..."):

    try:

    response = client.chat.completions.create(

    model=model,

    messages=[

    {"role": m["role"], "content": m["content"]}

    for m in st.session_state.messages

    ],

    temperature=temperature,

    max_tokens=max_tokens

    )


    answer = response.choices[0].message.content

    st.markdown(answer)

    st.session_state.messages.append({"role": "assistant", "content": answer})


    # Показываем статистику запроса

    usage = response.usage

    st.caption(f"📊 Использовано токенов: {usage.total_tokens} (вход: {usage.prompt_tokens}, выход: {usage.completion_tokens})")


    except Exception as e:

    st.error(f"Ошибка: {str(e)}")

    st.info("Проверьте API ключ и баланс на [llmki.ru](https://llmki.ru)")


    # Экспорт чата

    if st.session_state.messages:

    st.divider()

    col1, col2 = st.columns(2)


    with col1:

    if st.button("📥 Экспортировать чат"):

    chat_text = "\n\n".join([

    f"**{m['role'].upper()}:** {m['content']}"

    for m in st.session_state.messages

    ])

    st.download_button(

    label="Скачать как .txt",

    data=chat_text,

    file_name=f"chat_{datetime.now().strftime('%Y%m%d_%H%M%S')}.txt",

    mime="text/plain"

    )

    Код (text):

    Шаг 6: Запуск приложения


    Код (bash):

    streamlit run app.py

    Код (text):

    Приложение откроется в браузере по адресу `http://localhost:8501`


    Дополнительные функции


    Подсчет стоимости


    Добавьте функцию для расчета стоимости:


    Код (python):

    def calculate_cost(model, prompt_tokens, completion_tokens):

    """Расчет стоимости запроса"""

    # Примерные цены (за 1K токенов)

    prices = {

    "openai/gpt-4o": {"input": 0.30, "output": 1.20},

    "openai/gpt-4o-mini": {"input": 0.15, "output": 0.60},

    "anthropic/claude-3.5-sonnet": {"input": 0.30, "output": 1.50},

    "anthropic/claude-3-haiku": {"input": 0.08, "output": 0.40},

    }


    if model in prices:

    cost = (

    prompt_tokens / 1000 * prices[model]["input"] +

    completion_tokens / 1000 * prices[model]["output"]

    )

    return cost

    return 0


    # В обработке ответа:

    usage = response.usage

    cost = calculate_cost(model, usage.prompt_tokens, usage.completion_tokens)

    st.caption(f"💰 Стоимость: {cost:.4f}₽")

    Код (text):

    Системный промпт


    Добавьте возможность настройки системного промпта:


    Код (python):

    with st.sidebar:

    system_prompt = st.text_area(

    "Системный промпт:",

    value="Ты полезный ассистент.",

    height=100

    )


    # При отправке сообщения:

    messages = [{"role": "system", "content": system_prompt}]

    messages.extend([

    {"role": m["role"], "content": m["content"]}

    for m in st.session_state.messages

    ])

    Код (text):

    Поддержка изображений


    Добавьте загрузку изображений:


    Код (python):

    uploaded_file = st.file_uploader("Загрузить изображение", type=["png", "jpg", "jpeg"])


    if uploaded_file:

    # Отправка изображения в base64

    import base64

    image_data = base64.b64encode(uploaded_file.read()).decode()


    messages.append({

    "role": "user",

    "content": [

    {"type": "text", "text": prompt},

    {"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{image_data}"}}

    ]

    })

    Код (text):

    Деплой приложения


    Streamlit Cloud (бесплатно)


  • Загрузите код на GitHub
  • Зайдите на [share.streamlit.io](https://share.streamlit.io)
  • Подключите репозиторий
  • Добавьте секреты (API ключ)
  • Готово!

  • Heroku / Railway


    Код (bash):

    # Создайте requirements.txt

    echo "streamlit==1.28.0

    openai==1.3.0" > requirements.txt


    # Создайте Procfile

    echo "web: streamlit run app.py --server.port=$PORT --server.address=0.0.0.0" > Procfile

    Код (text):

    Заключение


    За час у вас получилось полноценное веб-приложение с ChatGPT-подобным интерфейсом. Streamlit делает создание веб-приложений на Python невероятно простым, а API LLM_КИ дает доступ ко всем топовым моделям через один интерфейс.


    Что дальше?


  • Добавьте авторизацию пользователей
  • Реализуйте сохранение чатов в базе данных
  • Добавьте поддержку голосовых сообщений
  • Интегрируйте другие возможности (генерация изображений, анализ документов)

  • Попробуйте сами и делитесь результатами!

    Другие статьи

    СтудентыУчёба
    Как LLM_КИ помогает студентам: учёба без перерасхода
    Конспекты, планы, перефраз и проверка фактов на дешёвых моделях. Готовые промпты и лайфхаки экономии.
    16 ноября 20257 мин
    Читать
    БытСемья
    Как LLM_КИ помогает мамам: быт, меню и списки дел
    Меню на неделю, списки покупок, идеи занятий и вежливые ответы в чатах. Три простых сценария с готовыми шаблонами.
    14 ноября 20256 мин
    Читать
    Статья не найдена — Блог LLM_КИ