Spaces:
Sleeping
Sleeping
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() | |