CoolFace
Apppublic

salmareda999988/R_D

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
app.py523 linesDownload Raw Back to root
1import streamlit as st2import requests3import json4import os5import sys6import subprocess7import asyncio8import aiohttp9import logging10from datetime import datetime11from langdetect import detect12import speech_recognition as sr13from gtts import gTTS14import tempfile15import pandas as pd16import matplotlib.pyplot as plt17import base6418from transformers import AutoTokenizer, AutoModel19import torch20import numpy as np21from typing import List, Dict, Any22from dotenv import load_dotenv23 24# Import custom modules25from construction_news_fetcher import ConstructionNewsFetcher26from job_market_analyzer import JobMarketAnalyzer27 28# Set up logging29logging.basicConfig(level=logging.INFO)30 31# Load environment variables32load_dotenv()33 34# --- Gemini API Setup ---35GEMINI_AVAILABLE = False36try:37    import google.generativeai as genai38    GEMINI_AVAILABLE = True39except ImportError:40    try:41        subprocess.check_call([sys.executable, "-m", "pip", "install", "google-generativeai"])42        import google.generativeai as genai43        GEMINI_AVAILABLE = True44    except Exception as e:45        st.error("Gemini API is not available. Please install google-generativeai.")46 47GEMINI_API_KEY = os.getenv("GEMINI_API_KEY", "")48if GEMINI_AVAILABLE and GEMINI_API_KEY:49    genai.configure(api_key=GEMINI_API_KEY)50 51# Other API keys52HUGGINGFACE_API_KEY = os.getenv("HUGGINGFACE_API_KEY", "")53GNEWS_API_KEY = os.getenv("GNEWS_API_KEY", "")54 55# Set Streamlit page configuration56st.set_page_config(page_title="Construction Industry HR Trends Chatbot", page_icon="👷‍♂️", layout="wide")57 58# --- Caching for Expensive Operations ---59 60@st.cache_data(show_spinner=False)61def get_cached_embeddings(texts):62    try:63        tokenizer = AutoTokenizer.from_pretrained("xlm-roberta-base", use_auth_token=HUGGINGFACE_API_KEY)64        model = AutoModel.from_pretrained("xlm-roberta-base", use_auth_token=HUGGINGFACE_API_KEY)65        device = "cuda" if torch.cuda.is_available() else "cpu"66        model = model.to(device)67        embeddings = []68        for text in texts:69            inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True, max_length=512)70            inputs = {k: v.to(device) for k, v in inputs.items()}71            with torch.no_grad():72                outputs = model(**inputs)73            embedding = outputs.last_hidden_state[:, 0, :].cpu().numpy()74            embeddings.append(embedding[0])75        return embeddings76    except Exception as e:77        logging.error("Error in get_cached_embeddings: %s", e)78        return [np.random.rand(768) for _ in texts]79 80@st.cache_data(show_spinner=False)81def translate_text_cached(text, source_lang, target_lang):82    if source_lang == "en" and target_lang == "ar":83        model_name = "Helsinki-NLP/opus-mt-en-ar"84    elif source_lang == "ar" and target_lang == "en":85        model_name = "Helsinki-NLP/opus-mt-ar-en"86    else:87        return text88    API_URL = f"https://api-inference.huggingface.co/models/{model_name}"89    headers = {"Authorization": f"Bearer {HUGGINGFACE_API_KEY}"}90    payload = {"inputs": text}91    try:92        response = requests.post(API_URL, headers=headers, json=payload, timeout=10)93        result = response.json()94        if isinstance(result, list) and len(result) > 0:95            return result[0]["translation_text"]96        return text97    except Exception as e:98        logging.error("Translation error: %s", e)99        return text100 101# --- Asynchronous Helper for News (if needed) ---102async def fetch_news_async(url, headers):103    async with aiohttp.ClientSession() as session:104        async with session.get(url, headers=headers, timeout=10) as response:105            return await response.json()106 107# --- Construction Market Research Class ---108class ConstructionMarketResearch:109    """Handles construction market data and report generation."""110    111    def __init__(self, api_key=None):112        self.api_key = api_key113        self.session = requests.Session()114        self.session.headers.update({'User-Agent': 'Mozilla/5.0'})115        self.load_market_data()116    117    def load_market_data(self):118        self.market_growth = {119            'GCC': 5.2,120            'Middle East (other)': 3.8,121            'North Africa': 2.9,122            'Europe': 1.7,123            'Asia-Pacific': 4.5,124            'North America': 2.2125        }126        self.sector_performance = {127            'Residential': 3.7,128            'Commercial': 2.9,129            'Infrastructure': 5.4,130            'Industrial': 3.2,131            'Energy': 4.1132        }133        self.workforce_challenges = {134            'Skilled labor shortage': 8.7,135            'Safety compliance': 7.5,136            'Workforce retention': 7.2,137            'Training and certification': 6.9,138            'Remote site management': 7.8,139            'Multilingual workforce': 8.3,140            'Heat stress management': 8.6,141            'Competitive compensation': 6.5142        }143        self.salary_data = {144            'Project Manager': 85,145            'Construction Manager': 78,146            'Site Engineer': 52,147            'Safety Manager': 68,148            'Foreman': 48,149            'Skilled Tradesperson': 42,150            'HR Manager (Construction)': 72,151            'Construction Recruiter': 55152        }153    154    def analyze_keywords(self, keywords):155        results = {}156        keywords_lower = [k.lower() for k in keywords]157        regions = {158            'gcc': 'GCC', 159            'middle east': 'Middle East (other)',160            'north africa': 'North Africa', 161            'europe': 'Europe',162            'asia': 'Asia-Pacific', 163            'america': 'North America'164        }165        for key, region in regions.items():166            if any(key in kw for kw in keywords_lower):167                results['market_growth'] = {region: self.market_growth[region]}168        sectors = {169            'residential': 'Residential',170            'commercial': 'Commercial',171            'infrastructure': 'Infrastructure',172            'industrial': 'Industrial',173            'energy': 'Energy'174        }175        for key, sector in sectors.items():176            if any(key in kw for kw in keywords_lower):177                results['sector_performance'] = {sector: self.sector_performance[sector]}178        workforce_keys = {179            'skill': 'Skilled labor shortage',180            'safety': 'Safety compliance',181            'retention': 'Workforce retention',182            'training': 'Training and certification',183            'remote': 'Remote site management',184            'language': 'Multilingual workforce',185            'multilingual': 'Multilingual workforce',186            'heat': 'Heat stress management',187            'compensation': 'Competitive compensation'188        }189        for key, challenge in workforce_keys.items():190            if any(key in kw for kw in keywords_lower):191                if 'workforce_challenges' not in results:192                    results['workforce_challenges'] = {}193                results['workforce_challenges'][challenge] = self.workforce_challenges[challenge]194        if any(kw in ['salary', 'compensation', 'pay', 'wage'] for kw in keywords_lower):195            results['salary_data'] = self.salary_data196            roles = {197                'manager': ['Project Manager', 'Construction Manager', 'Safety Manager', 'HR Manager (Construction)'],198                'engineer': ['Site Engineer'],199                'safety': ['Safety Manager'],200                'hr': ['HR Manager (Construction)', 'Construction Recruiter'],201                'recruit': ['Construction Recruiter'],202                'trade': ['Skilled Tradesperson'],203                'foreman': ['Foreman']204            }205            for key, role_list in roles.items():206                if any(key in kw for kw in keywords_lower):207                    results['salary_data'] = {role: self.salary_data[role] for role in role_list}208        return results209    210    def generate_market_report(self, query):211        keywords = query.lower().split()212        analysis = self.analyze_keywords(keywords)213        report = "Construction Market Research Report\n" + "=" * 40 + "\n\n"214        if 'market_growth' in analysis:215            report += "Market Growth:\n"216            for region, growth in analysis['market_growth'].items():217                report += f"- {region}: {growth}% year-over-year growth\n"218            report += "\n"219        if 'sector_performance' in analysis:220            report += "Sector Performance:\n"221            for sector, performance in analysis['sector_performance'].items():222                report += f"- {sector}: {performance}% growth\n"223            report += "\n"224        if 'workforce_challenges' in analysis:225            report += "Workforce Challenges (scale 1-10):\n"226            for challenge, rating in analysis['workforce_challenges'].items():227                report += f"- {challenge}: {rating}/10\n"228            report += "\n"229        if 'salary_data' in analysis:230            report += "Salary Data (thousands USD):\n"231            for role, salary in analysis['salary_data'].items():232                report += f"- {role}: ${salary}k per year\n"233            report += "\n"234        if not analysis:235            report += "Overall Construction Market Overview:\n"236            report += f"- Average market growth: {sum(self.market_growth.values())/len(self.market_growth):.1f}%\n"237            report += f"- Top performing sector: {max(self.sector_performance.items(), key=lambda x: x[1])[0]}\n"238            report += f"- Most significant workforce challenge: {max(self.workforce_challenges.items(), key=lambda x: x[1])[0]}\n"239            report += f"- Average construction management salary: ${sum(self.salary_data.values())/len(self.salary_data):.0f}k\n"240        return report241 242# --- Gemini Query Function ---243def query_with_gemini(question, lang="en"):244    if not GEMINI_AVAILABLE or not GEMINI_API_KEY:245        return None246    try:247        language_prompt = "in English" if lang == "en" else "in Arabic"248        prompt = f"""You are an expert HR advisor specializing in construction industry HR trends, safety regulations, workforce management for construction projects, and skill development in the building trades. Answer the following construction HR-related question {language_prompt}. Be concise but informative. Include relevant statistics or best practices specific to the construction industry if appropriate.249        250Question: {question}251"""252        model_instance = genai.GenerativeModel('gemini-1.0-pro')253        generation_config = {254            "temperature": 0.7,255            "top_p": 0.95,256            "top_k": 40,257            "max_output_tokens": 1024,258        }259        response = model_instance.generate_content(prompt, generation_config=generation_config)260        if response and hasattr(response, 'text'):261            return response.text262        else:263            return None264    except Exception as e:265        logging.error("Gemini API error: %s", e)266        st.error(f"Gemini API error: {e}")267        return None268 269# --- HR Knowledge Base & Query Processing ---270def query_hr_knowledge_base(query, lang="en"):271    gemini_response = query_with_gemini(query, lang) if GEMINI_AVAILABLE else None272    if gemini_response:273        return gemini_response274    hr_knowledge = [275        {276            "en": "Construction safety management involves implementing safety regulations, conducting regular site inspections, and enforcing PPE compliance to protect workers on construction sites.",277            "ar": "تتضمن إدارة السلامة في البناء تطبيق لوائح السلامة، وإجراء عمليات تفتيش منتظمة للموقع، وفرض الامتثال لمعدات الحماية الشخصية لحماية العمال في مواقع البناء."278        },279        {280            "en": "Skilled trades recruitment in construction focuses on finding qualified electricians, plumbers, carpenters, welders, and equipment operators who have the necessary certifications and experience.",281            "ar": "يركز توظيف الحرفيين المهرة في قطاع البناء على العثور على كهربائيين ومُركّبي أنابيب ونجارين ولحامين ومشغلي معدات مؤهلين يمتلكون الشهادات والخبرة اللازمة."282        },283        {284            "en": "Project-based staffing in construction requires flexible HR strategies to manage crews that move between sites and adjust workforce levels based on project phases.",285            "ar": "يتطلب التوظيف على أساس المشروع في البناء استراتيجيات مرنة للموارد البشرية لإدارة الفرق التي تتنقل بين المواقع وتعديل مستويات القوى العاملة بناءً على مراحل المشروع."286        },287        {288            "en": "Construction labor compliance includes managing certified payroll, prevailing wage requirements, and adherence to local labor laws for construction projects.",289            "ar": "يشمل الامتثال لقوانين العمل في البناء إدارة كشوف المرتبات المعتمدة، ومتطلبات الأجور السائدة، والالتزام بقوانين العمل المحلية لمشاريع البناء."290        },291        {292            "en": "Safety training in construction is mandatory and includes certification, fall protection, hazard communication, and equipment-specific training to prevent workplace accidents.",293            "ar": "التدريب على السلامة في البناء إلزامي ويشمل الشهادات، والحماية من السقوط، والتوعية بالمخاطر، والتدريب الخاص بالمعدات لمنع حوادث العمل."294        },295        {296            "en": "Construction HR departments often manage multicultural workforces and must develop strategies for clear communication across language barriers to ensure safety and productivity.",297            "ar": "غالبًا ما تدير إدارات الموارد البشرية في البناء قوى عاملة متعددة الثقافات ويجب أن تطور استراتيجيات للتواصل الواضح عبر حواجز اللغة لضمان السلامة والإنتاجية."298        },299        {300            "en": "Heat stress management is a critical HR function in construction, especially in Middle Eastern countries, requiring proper hydration protocols, rest schedules, and monitoring systems.",301            "ar": "تعتبر إدارة الإجهاد الحراري وظيفة حيوية للموارد البشرية في البناء، خاصة في دول الشرق الأوسط، مما يتطلب بروتوكولات ترطيب مناسبة وجداول راحة وأنظمة مراقبة."302        },303        {304            "en": "Construction site access control systems are increasingly using biometric technology to verify worker identity, track hours accurately, and ensure only qualified personnel access restricted areas.",305            "ar": "تستخدم أنظمة التحكم في الوصول إلى مواقع البناء بشكل متزايد تقنية القياسات الحيوية للتحقق من هوية العامل، وتتبع الساعات بدقة، وضمان وصول الموظفين المؤهلين فقط إلى المناطق المقيدة."306        }307    ]308    try:309        query_embedding = get_cached_embeddings([query])[0]310        knowledge_texts = [entry[lang] for entry in hr_knowledge]311        knowledge_embeddings = get_cached_embeddings(knowledge_texts)312        similarities = []313        for emb in knowledge_embeddings:314            similarity = np.dot(query_embedding, emb) / (np.linalg.norm(query_embedding) * np.linalg.norm(emb))315            similarities.append(similarity)316        best_match_idx = np.argmax(similarities)317        best_match = hr_knowledge[best_match_idx][lang]318    except Exception as e:319        logging.error("Error in HR knowledge base matching: %s", e)320        query_terms = query.lower().split()321        best_match_idx = 0322        best_match_score = 0323        for idx, entry in enumerate(hr_knowledge):324            entry_text = entry[lang].lower()325            score = sum(1 for term in query_terms if term in entry_text)326            if score > best_match_score:327                best_match_score = score328                best_match_idx = idx329        best_match = hr_knowledge[best_match_idx][lang]330    return best_match331 332def process_query(query, lang="en"):333    base_response = query_hr_knowledge_base(query, lang)334    if lang == "en":335        response = "# Construction HR Analysis Report\n\n"336        response += "## Expert Overview\n"337        response += base_response + "\n\n"338    else:339        response = "# تقرير تحليل الموارد البشرية في قطاع البناء\n\n"340        response += "## نظرة خبير عامة\n"341        response += base_response + "\n\n"342    if "safety" in query.lower() or "سلامة" in query:343        if lang == "en":344            response += "## Safety Compliance Insights\n"345            response += "Construction industries globally are seeing increased focus on safety protocols, with:\n"346            response += "* 67% of companies implementing advanced PPE monitoring systems\n"347            response += "* 82% increase in safety training hours per worker annually\n"348            response += "* 42% reduction in incidents at sites using AI-powered safety monitoring\n\n"349        else:350            response += "## رؤى الامتثال للسلامة\n"351            response += "تشهد صناعات البناء عالميًا تركيزًا متزايدًا على بروتوكولات السلامة، مع:\n"352            response += "* 67% من الشركات تنفذ أنظمة متقدمة لمراقبة معدات الحماية الشخصية\n"353            response += "* زيادة بنسبة 82% في ساعات تدريب السلامة لكل عامل سنويًا\n"354            response += "* انخفاض بنسبة 42% في الحوادث في المواقع التي تستخدم أنظمة مراقبة السلامة المدعومة بالذكاء الاصطناعي\n\n"355    if "recruit" in query.lower() or "توظيف" in query or "talent" in query or "مواهب" in query:356        if lang == "en":357            response += "## Recruitment Strategy Best Practices\n"358            response += "Leading construction firms are revolutionizing their hiring approaches with:\n"359            response += "* Trade-specific assessment tools reducing mismatched hires by 34%\n"360            response += "* Partnerships with technical schools increasing qualified candidate pools by 58%\n"361            response += "* Apprenticeship programs showing 72% retention after 3 years vs. 41% for traditional hires\n\n"362        else:363            response += "## أفضل ممارسات استراتيجية التوظيف\n"364            response += "تقوم شركات البناء الرائدة بثورة في نهجها للتوظيف من خلال:\n"365            response += "* أدوات تقييم خاصة بالمهن تقلل من التعيينات غير المتطابقة بنسبة 34%\n"366            response += "* شراكات مع المدارس الفنية تزيد من مجموعات المرشحين المؤهلين بنسبة 58%\n"367            response += "* برامج التدريب المهني تُظهر احتفاظًا بنسبة 72% بعد 3 سنوات مقابل 41% للتوظيف التقليدي\n\n"368    # Append industry news using ConstructionNewsFetcher369    news_fetcher = ConstructionNewsFetcher(gnews_api_key=GNEWS_API_KEY)370    news_articles = news_fetcher.fetch_hr_construction_news(query=query, language=lang, max_results=3)371    news_text = ""372    if news_articles:373        if lang == "en":374            news_text = "\n## Latest Industry Developments\n"375        else:376            news_text = "\n## أحدث التطورات في الصناعة\n"377        for i, article in enumerate(news_articles, 1):378            news_text += f"{i}. **{article['title']}** - {article['description']}\n"379    response += news_text380    if lang == "en":381        response += "\n## Strategic Recommendations\n"382        response += "Based on current industry trends and your specific query, we recommend:\n"383        response += "1. **Implement digital competency training** for field supervisors\n"384        response += "2. **Develop multilingual safety protocols** to address diverse workforce needs\n"385        response += "3. **Establish structured career pathways** for skilled trades to improve retention\n"386        response += "4. **Adopt mobile-first HR tools** for better field workforce management\n"387    else:388        response += "\n## توصيات استراتيجية\n"389        response += "بناءً على اتجاهات الصناعة الحالية واستفسارك المحدد، نوصي بما يلي:\n"390        response += "1. **تنفيذ تدريب الكفاءة الرقمية** للمشرفين الميدانيين\n"391        response += "2. **تطوير بروتوكولات سلامة متعددة اللغات** لتلبية احتياجات القوى العاملة المتنوعة\n"392        response += "3. **إنشاء مسارات وظيفية منظمة** للحرف الماهرة لتحسين الاحتفاظ\n"393        response += "4. **اعتماد أدوات موارد بشرية تعتمد على الأجهزة المحمولة** لإدارة أفضل للقوى العاملة الميدانية\n"394    return response395 396# --- Voice and Text-to-Speech Functions ---397def voice_input():398    r = sr.Recognizer()399    with sr.Microphone() as source:400        st.write("Listening...")401        audio = r.listen(source)402    try:403        text = r.recognize_google(audio)404        lang = detect(text)405        if lang == "ar":406            text = r.recognize_google(audio, language="ar-AR")407        else:408            text = r.recognize_google(audio, language="en-US")409        return text, lang410    except Exception as e:411        logging.error("Voice input error: %s", e)412        st.error(f"Could not recognize speech: {e}")413        return None, "en"414 415def text_to_speech(text, lang):416    try:417        tts = gTTS(text=text, lang=lang[:2])418        with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as fp:419            tts.save(fp.name)420            return fp.name421    except Exception as e:422        logging.error("Text to speech error: %s", e)423        st.error(f"Text to speech error: {e}")424        return None425 426# --- Chat Interaction and UI Elements ---427def chat_interaction(user_input=None, is_voice=False):428    if user_input:429        lang = detect(user_input)430        st.session_state.messages.append({"role": "user", "content": user_input, "language": lang})431        response = process_query(user_input, lang)432        st.session_state.messages.append({"role": "assistant", "content": response, "language": lang})433        st.session_state.history.append({"query": user_input, "response": response, "language": lang})434        if is_voice:435            audio_file = text_to_speech(response, lang)436            if audio_file:437                st.audio(audio_file)438        st.markdown(response)439 440# --- Sidebar Options and Interactive Widgets ---441with st.sidebar:442    st.subheader("Options")443    preferred_lang = st.radio("Preferred Language:", ["English", "Arabic"])444    use_voice = st.checkbox("Enable Voice Interaction")445    if use_voice and st.button("🎤 Speak"):446        user_input, detected_lang = voice_input()447        if user_input:448            chat_interaction(user_input, is_voice=True)449    st.subheader("Data Sources")450    use_news = st.checkbox("Include News Data", value=True)451    use_job_market = st.checkbox("Include Job Market Insights", value=True)452    use_gemini = st.checkbox("Use Gemini AI", 453                             value=GEMINI_AVAILABLE and GEMINI_API_KEY,454                             disabled=not (GEMINI_AVAILABLE and GEMINI_API_KEY))455    if not GEMINI_AVAILABLE:456        st.warning("Gemini API is not available. Run 'pip install google-generativeai' to enable it.")457    elif not GEMINI_API_KEY and use_gemini:458        st.info("Gemini integration requires an API key. Please add it in your environment variables.")459    if use_job_market:460        st.subheader("Job Market Insights")461        job_market_search = st.text_input("Search for HR trends in:")462        if job_market_search and st.button("Analyze Job Market"):463            with st.spinner("Analyzing job market data..."):464                job_market_analyzer = JobMarketAnalyzer()465                job_market_data = job_market_analyzer.analyze_hr_trends(job_market_search)466                st.write("**Top Skills in Demand:**")467                for skill, count in job_market_data['top_skills'][:5]:468                    st.write(f"- {skill}: {count} mentions")469                st.write("**Top Hiring Companies:**")470                for company, count in job_market_data['top_companies'][:3]:471                    st.write(f"- {company}: {count} jobs")472                st.write("**Top Locations:**")473                for location, count in job_market_data['top_locations'][:3]:474                    st.write(f"- {location}: {count} jobs")475    st.subheader("Market Research")476    market_query = st.text_input("Research construction market:")477    if market_query and st.button("Generate Market Report"):478        with st.spinner("Generating market research report..."):479            market_research = ConstructionMarketResearch()480            report = market_research.generate_market_report(market_query)481            st.text_area("Market Research Report", report, height=300)482    st.subheader("About")483    st.markdown("""484    This specialized Construction HR chatbot combines multiple AI technologies:485    486    - XLM-RoBERTa for multilingual understanding487    - Gemini AI for advanced construction HR knowledge (when available)488    - Construction Job Market Analysis for real-world insights489    - News APIs and RSS feeds for the latest construction industry trends490    - Market Research data for construction sector analysis491    492    It supports both English and Arabic and provides voice interaction, focusing on construction-specific 493    HR challenges like safety compliance, skilled trades recruitment, project staffing, and field workforce management.494    """)495 496# --- Main Chat Interface ---497if "messages" not in st.session_state:498    st.session_state.messages = []499if "history" not in st.session_state:500    st.session_state.history = []501 502st.title("🏗️ Construction Industry HR Trends Chatbot")503st.subheader("Ask questions about construction HR trends in English or Arabic")504 505user_input = st.chat_input("Ask something about construction HR trends...")506if user_input:507    chat_interaction(user_input)508 509# --- Visualization Section: Interactive Plotly Chart ---510if st.session_state.messages and len(st.session_state.messages) > 2:511    st.subheader("Interactive HR Trends Visualization")512    data = {513        'Trend': ['Safety Technology', 'Mobile Workforce Management', 'Skilled Trades Training', 'Compliance Automation', 'Multilingual Safety Programs'],514        'Adoption Rate': [82, 71, 65, 58, 49]515    }516    df = pd.DataFrame(data)517    import plotly.express as px518    fig = px.bar(df, x='Trend', y='Adoption Rate', title="Construction HR Trends 2023-2024")519    st.plotly_chart(fig)520 521st.markdown("---")522st.markdown("Specialized for Construction Industry HR")523