504 Deadline Exceeded - Long Context

DeadlineExceeded: 504 Deadline Exceeded
Traceback:
File “/opt/render/project/src/.venv/lib/python3.11/site-packages/streamlit/runtime/scriptrunner/script_runner.py”, line 534, in _run_script
exec(code, module.dict)
File “/opt/render/project/src/app.py”, line 302, in
for chunk in model.generate_content(full_context, stream=True):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/opt/render/project/src/.venv/lib/python3.11/site-packages/google/generativeai/generative_models.py”, line 245, in generate_content
iterator = self._client.stream_generate_content(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/opt/render/project/src/.venv/lib/python3.11/site-packages/google/ai/generativelanguage_v1beta/services/generative_service/client.py”, line 852, in stream_generate_content
response = rpc(
^^^^
File “/opt/render/project/src/.venv/lib/python3.11/site-packages/google/api_core/gapic_v1/method.py”, line 131, in call
return wrapped_func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/opt/render/project/src/.venv/lib/python3.11/site-packages/google/api_core/retry/retry_unary.py”, line 293, in retry_wrapped_func
return retry_target(
^^^^^^^^^^^^^
File “/opt/render/project/src/.venv/lib/python3.11/site-packages/google/api_core/retry/retry_unary.py”, line 153, in retry_target
_retry_error_helper(
File “/opt/render/project/src/.venv/lib/python3.11/site-packages/google/api_core/retry/retry_base.py”, line 212, in _retry_error_helper
raise final_exc from source_exc
File “/opt/render/project/src/.venv/lib/python3.11/site-packages/google/api_core/retry/retry_unary.py”, line 144, in retry_target
result = target()
^^^^^^^^
File “/opt/render/project/src/.venv/lib/python3.11/site-packages/google/api_core/timeout.py”, line 120, in func_with_timeout
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File “/opt/render/project/src/.venv/lib/python3.11/site-packages/google/api_core/grpc_helpers.py”, line 174, in error_remapped_callable
raise exceptions.from_grpc_error(exc) from exc


I need to create a timeout but the parameters apparently dont exist.

Here is the full code:

import streamlit as st
import google.generativeai as genai
from PyPDF2 import PdfReader
from docx import Document
import os
import tempfile
import re
import io

# Configuração da página Streamlit
st.set_page_config(page_title="Análise de Perfil Comportamental", layout="wide")

# Configuração do tema e estilos
st.markdown("""
<style>
    /* Estilo dos headers */
    h1, h2, h3 {
        margin-bottom: 1rem;
    }
    
    /* Estilo dos tooltips */
    .tooltip {
        position: relative;
        display: inline-block;
        cursor: pointer;
        background-color: #E8F1F5;
        border: 1px solid #1E3D59;
        color: #1E3D59;
        border-radius: 50%;
        width: 20px;
        height: 20px;
        text-align: center;
        line-height: 18px;
        margin: 0 3px;
        font-size: 12px;
    }

    .tooltip .tooltiptext {
        visibility: hidden;
        width: auto;
        min-width: 120px;
        background-color: #1E3D59;
        color: #fff;
        text-align: center;
        border-radius: 6px;
        padding: 8px;
        position: absolute;
        z-index: 1;
        bottom: 125%;
        left: 50%;
        transform: translateX(-50%);
        opacity: 0;
        transition: opacity 0.2s;
    }

    .tooltip:hover .tooltiptext {
        visibility: visible;
        opacity: 1;
    }
    
    /* Estilo das mensagens */
    .chat-message {
        padding: 1rem;
        margin: 1rem 0;
        border-radius: 8px;
        line-height: 1.5;
    }
    
    /* Estilo dos uploads */
    .upload-section {
        padding: 1.5rem;
        background-color: #F7F9FB;
        border-radius: 8px;
        margin: 1rem 0;
    }
    
    /* Estilo da barra lateral */
    .sidebar .stButton>button {
        width: 100%;
    }
</style>
""", unsafe_allow_html=True)

# Configuração da chave API do Gemini
GOOGLE_API_KEY = "AIzaSyAhM39a9f_53uqs9qGXgEWMqDA_hgpetSU"
genai.configure(api_key=GOOGLE_API_KEY)

# Configuração do modelo
model = genai.GenerativeModel('gemini-2.0-flash-exp')

def extract_text_with_pages(file_content, file_type):
    """Extrai texto mantendo referência das páginas"""
    text_sections = []
    
    try:
        if file_type == "application/pdf":
            # Processar PDF
            pdf_file = io.BytesIO(file_content)
            pdf_reader = PdfReader(pdf_file)
            for page_num, page in enumerate(pdf_reader.pages, 1):
                text = page.extract_text()
                if text.strip():
                    text_sections.append({
                        'page': f'Página {page_num}',
                        'text': text
                    })
        else:
            # Processar DOCX e TXT
            if file_type == "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
                doc = Document(io.BytesIO(file_content))
                paragraphs = [p.text for p in doc.paragraphs]
            else:  # text/plain
                text_content = file_content.decode('utf-8')
                paragraphs = text_content.split('\n')
            
            # Dividir em seções
            current_section = ""
            section_count = 0
            
            for paragraph in paragraphs:
                current_section += paragraph + "\n"
                if len(current_section) >= 500:
                    section_count += 1
                    text_sections.append({
                        'page': f'Seção {section_count}',
                        'text': current_section
                    })
                    current_section = ""
            
            if current_section.strip():
                section_count += 1
                text_sections.append({
                    'page': f'Seção {section_count}',
                    'text': current_section
                })
    
    except Exception as e:
        st.error(f"Erro ao extrair texto: {str(e)}")
        return []
    
    return text_sections

def process_file_with_api(uploaded_file):
    """Processa arquivo usando a API do Gemini"""
    try:
        # Ler o conteúdo do arquivo
        file_content = uploaded_file.getvalue()
        
        # Extrair texto com referências de páginas
        text_sections = extract_text_with_pages(file_content, uploaded_file.type)
        
        # Criar objeto para o Gemini
        file_obj = {
            'mime_type': uploaded_file.type,
            'data': file_content,
            'sections': text_sections,
            'name': uploaded_file.name
        }
        
        return file_obj
            
    except Exception as e:
        st.error(f"Erro ao processar arquivo: {str(e)}")
        return None

def process_response_with_tooltips(response_text, reference_map):
    pattern = r'\[(.*?), (Página/Seção \d+|Página \d+|Seção \d+)\]'
    ref_count = 0
    
    def replace_reference(match):
        nonlocal ref_count
        ref_count += 1
        file_name = match.group(1)
        page_ref = match.group(2)
        
        tooltip = f"""<span class="tooltip">{ref_count}
            <span class="tooltiptext">
            {file_name}<br>
            {page_ref}
            </span>
        </span>"""
        
        return tooltip
    
    processed_text = re.sub(pattern, replace_reference, response_text)
    return processed_text

# Template para análise de perfil
ANALYSIS_TEMPLATE = """
Você é um analista especializado em comportamento empresarial e inteligência emocional.
Use o conhecimento da metodologia fornecida para analisar o perfil do cliente.

IMPORTANTE: Para cada informação ou conclusão relevante, cite a fonte usando o formato [Nome do Arquivo, Página/Seção X].

====================
METODOLOGIA E CONTEXTO - servirá para pautar o tipo de análise que será feito sobre o perfil do cliente com base na solitação de análise:
====================
{methodology_context}

====================
PERFIL DO CLIENTE:
====================
{user_context}

====================
SOLICITAÇÃO DE ANÁLISE:
====================
{prompt}

Por favor, forneça uma análise estruturada considerando a pergunta do usuário aplicada em uma estrutura de análise inteligente que vem da metodologia

IMPORTANTE: 
- Cite SEMPRE a fonte específica (arquivo e página/seção) que fundamenta cada ponto da sua análise
- Use o formato [Nome do Arquivo, Página/Seção X] para todas as citações
- Baseie suas conclusões apenas nos documentos fornecidos
- Mantenha a análise objetiva e fundamentada
"""

# Interface principal
st.title("Análise de Perfil Comportamental")
st.markdown("### Sistema de Análise Comportamental e Inteligência Emocional")

# Inicialização do histórico de chat e referências na sessão
if "messages" not in st.session_state:
    st.session_state.messages = []
if "reference_map" not in st.session_state:
    st.session_state.reference_map = {}
if "methodology_files" not in st.session_state:
    st.session_state.methodology_files = []

# Barra lateral para upload dos documentos de metodologia
with st.sidebar:
    st.header("Metodologia de Análise")
    st.markdown("""
    #### Documentos Necessários:
    - 📊 Diretrizes de comportamento empresarial
    - 🧠 Metodologia de análise comportamental
    - 💡 Frameworks de inteligência emocional
    """)
    
    methodology_files = st.file_uploader(
        "Carregar Documentos de Metodologia", 
        type=["pdf", "docx", "txt"], 
        accept_multiple_files=True
    )
    
    if methodology_files:
        with st.spinner("Processando documentos de metodologia..."):
            processed_files = []
            for file in methodology_files:
                file_obj = process_file_with_api(file)
                if file_obj:
                    processed_files.append(file_obj)
            
            if processed_files:
                st.session_state.methodology_files = processed_files
                st.success("✅ Metodologia atualizada com sucesso!")

# Upload do perfil do cliente
st.header("📄 Perfil do Cliente")
st.markdown("Faça upload do documento contendo o perfil do cliente a ser analisado.")

user_file = st.file_uploader("Carregar Perfil do Cliente", type=["pdf", "docx", "txt"])
if user_file:
    with st.spinner("Processando perfil do cliente..."):
        user_file_obj = process_file_with_api(user_file)
        if user_file_obj:
            st.session_state.user_file = user_file_obj
            st.success(f"✅ Perfil '{user_file.name}' processado com sucesso!")

# Interface de chat
st.header("💬 Análise e Insights")
for message in st.session_state.messages:
    with st.chat_message(message["role"]):
        if message["role"] == "assistant":
            st.markdown(process_response_with_tooltips(message["content"], st.session_state.reference_map), unsafe_allow_html=True)
        else:
            st.markdown(message["content"])

if prompt := st.chat_input("Digite sua solicitação de análise..."):
    st.session_state.messages.append({"role": "user", "content": prompt})
    with st.chat_message("user"):
        st.markdown(prompt)

    # Verificar se temos os arquivos necessários
    if st.session_state.methodology_files and hasattr(st.session_state, 'user_file'):
        try:
            # Preparar contexto estruturado
            methodology_context = ""
            for file_obj in st.session_state.methodology_files:
                methodology_context += f"\n### {file_obj['name']}\n"
                for section in file_obj['sections']:
                    methodology_context += f"[{file_obj['name']}, {section['page']}]\n{section['text']}\n\n"
            
            user_context = f"\n### {st.session_state.user_file['name']}\n"
            for section in st.session_state.user_file['sections']:
                user_context += f"[{st.session_state.user_file['name']}, {section['page']}]\n{section['text']}\n\n"
            
            # Preparar prompt completo
            full_prompt = ANALYSIS_TEMPLATE.format(
                methodology_context=methodology_context,
                user_context=user_context,
                prompt=prompt
            )
            
            # Gerar resposta com streaming
            with st.chat_message("assistant"):
                response_placeholder = st.empty()
                full_response = ""
                
                # Gerar resposta usando apenas o texto estruturado
                for chunk in model.generate_content(
                    full_prompt,
                    stream=True,
                    generation_config={
                        "max_output_tokens": 8048,
                        "temperature": 0.6,
                        "top_p": 0.8,
                        "top_k": 40
                    }
                ):
                    if chunk.text:
                        full_response += chunk.text
                        processed_response = process_response_with_tooltips(full_response, st.session_state.reference_map)
                        response_placeholder.markdown(processed_response, unsafe_allow_html=True)
                
                st.session_state.messages.append({"role": "assistant", "content": full_response})
                
        except Exception as e:
            st.error(f"Erro ao gerar resposta: {str(e)}")
    else:
        st.warning("Por favor, carregue os documentos de metodologia e o perfil do cliente antes de fazer perguntas.")

Welcome to the forum.

To increase the timeout value, use (set appropriate value for the 600)

request_options={"timeout": 600}

in your generation_config. You can see an example of how it is used in this cookbook - cookbook/quickstarts/Enum.ipynb at main · google-gemini/cookbook · GitHub