jaimin's picture
Update app.py
236d351 verified
import streamlit as st
from crew_initializer import initialize_crew
from utils.pdf_generator import generate_pdf
import json
import logging
import re
# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
# Custom JSON Encoder
class CustomJSONEncoder(json.JSONEncoder):
def default(self, obj):
try:
# Convert objects with __dict__ attributes to dictionaries
if hasattr(obj, "__dict__"):
return obj.__dict__
return super().default(obj)
except TypeError:
return str(obj) # Fallback for unsupported types
# Hardcoded credentials
USER_CREDENTIALS = {"username": "admin", "password": "P@ssword123"}
def authenticate_user():
"""Authenticate the user with a username and password"""
st.sidebar.header("Login")
username = st.sidebar.text_input("Username")
password = st.sidebar.text_input("Password", type="password")
if st.sidebar.button("Login"):
if username == USER_CREDENTIALS["username"] and password == USER_CREDENTIALS["password"]:
st.session_state.authenticated = True
st.sidebar.success("Login successful!")
st.rerun() # Rerun to clear login form and show the app
else:
st.sidebar.error("Invalid username or password.")
def main():
"""
Main entry point for the Streamlit application.
Handles user input, executes tasks, and displays results.
"""
# Ensure authentication state is properly initialized
if 'authenticated' not in st.session_state:
st.session_state.authenticated = False
# Authenticate user if not authenticated
if not st.session_state.authenticated:
authenticate_user()
return # Exit early if not authenticated
# Once authenticated, proceed with the main application
st.title("**Company Researcher Tool**")
st.sidebar.header("Provide Company Details")
company_name = st.sidebar.text_input("Enter the Company URL:")
# Show the "Run Analysis" button if the user is authenticated
if st.session_state.authenticated:
# Show the button whether or not the company name is entered
run_analysis_button = st.sidebar.button("Run Analysis")
# Only run the analysis when the button is clicked
if run_analysis_button:
st.markdown(f"### **Running analysis for:** {company_name}", unsafe_allow_html=True)
with st.spinner("Executing tasks, please wait..."):
try:
crew = initialize_crew()
result = crew.kickoff(inputs={"company": company_name})
result_serialized = json.loads(json.dumps(result, cls=CustomJSONEncoder))
# Extracting the raw summary report
summary_report = result_serialized.get('tasks_output', [{}])[0].get('raw', '')
# Formatting the raw content into structured report
structured_report = format_report(summary_report)
st.markdown(f"### **Summary Report**", unsafe_allow_html=True)
st.markdown(structured_report, unsafe_allow_html=True)
pdf_buffer = generate_pdf(result_serialized)
st.download_button(
label="πŸ“„ Download Report (PDF)",
data=pdf_buffer,
file_name=f"{company_name}_report.pdf",
mime="application/pdf"
)
except Exception as e:
logging.error(f"Error during analysis: {str(e)}")
st.error(f"An error occurred: {str(e)}")
else:
st.info("Please enter a company name to run the analysis.")
def format_report(raw_text):
"""
Takes raw text (markdown/structured content) and formats it to
create a more readable, structured report with bold headers.
"""
# This pattern looks for headings with a number followed by bold text and a colon (e.g. 1. **Heading**:)
heading_pattern = r'(\d+\.)\s?(\*\*[^*]+\*\*):'
# Replace headings with Markdown syntax (e.g., ## **Heading**:)
formatted_report = re.sub(heading_pattern, r'## \2:', raw_text)
# Replace **bold text** with proper markdown formatting
formatted_report = re.sub(r'\*\*(.*?)\*\*', r'**\1**', formatted_report)
# Replace **bold** with HTML <strong> to control the bolding in headers only
formatted_report = re.sub(r'\*\*(.*?)\*\*', r'<strong>\1</strong>', formatted_report)
# Now use Markdown for the rest of the text, with normal text not bold
formatted_report = formatted_report.replace("\n", "<br>") # Use line breaks for formatting
return formatted_report
if __name__ == "__main__":
main()