EZHARDYNAMICS/ezhar-logic-kernel-twin
0
1import streamlit as st2import os3import time4import io5import hmac6import random7import numpy as np8import plotly.graph_objects as go9from reportlab.pdfgen import canvas10from reportlab.lib.pagesizes import letter11from typing import Dict, Any, List12 13class AppConfig:14 APP_NAME = "EZHAR DYNAMICS"15 NODE_ID = "ADGM-01"16 THEME_COLOR = "#76b900" 17 18# ===== UI & STYLING =====19class StyleManager:20 @staticmethod21 def inject_industrial_css():22 st.markdown(f"""23 <style>24 @import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&display=swap');25 html, body, [class*="css"] {{26 font-family: 'JetBrains Mono', monospace;27 background-color: #050505;28 color: #cfcfcf;29 }}30 section[data-testid="stSidebar"] {{31 background-color: #0E0E0E !important;32 border-right: 1px solid #333 !important;33 }}34 .stButton > button, .stDownloadButton > button {{35 background-color: #000;36 color: {AppConfig.THEME_COLOR};37 border: 1px solid {AppConfig.THEME_COLOR};38 border-radius: 0px !important;39 font-weight: 700;40 transition: all 0.2s;41 text-transform: uppercase;42 }}43 .stButton > button:hover, .stDownloadButton > button:hover {{44 background-color: {AppConfig.THEME_COLOR};45 color: #000;46 box-shadow: 0 0 15px rgba(118, 185, 0, 0.4);47 }}48 .stApp::before {{49 content: " ";50 display: block;51 position: absolute;52 top: 0; left: 0; bottom: 0; right: 0;53 background: linear-gradient(rgba(18, 16, 16, 0) 50%, rgba(0, 0, 0, 0.1) 50%);54 background-size: 100% 4px;55 z-index: 9999;56 pointer-events: none;57 opacity: 0.3;58 }}59 .auth-box {{ border: 1px solid {AppConfig.THEME_COLOR}; padding: 40px; text-align: center; margin-top: 10vh; }}60 #MainMenu {{visibility: hidden;}} footer {{visibility: hidden;}}61 </style>62 """, unsafe_allow_html=True)63 64# ===== 3D VISUALIZATION =====65class VisualKernel:66 @staticmethod67 def generate_neural_matrix(num_nodes=60):68 x, y, z = np.random.standard_normal((3, num_nodes))69 edge_x, edge_y, edge_z = [], [], []70 for i in range(num_nodes):71 for _ in range(2):72 j = random.randint(0, num_nodes-1)73 edge_x.extend([x[i], x[j], None])74 edge_y.extend([y[i], y[j], None])75 edge_z.extend([z[i], z[j], None])76 77 trace_edges = go.Scatter3d(x=edge_x, y=edge_y, z=edge_z, mode='lines', line=dict(color='#333', width=2), hoverinfo='none')78 trace_nodes = go.Scatter3d(x=x, y=y, z=z, mode='markers', marker=dict(size=5, color=z, colorscale=[[0, '#000'], [1, AppConfig.THEME_COLOR]], opacity=0.9))79 layout = go.Layout(scene=dict(xaxis=dict(visible=False), yaxis=dict(visible=False), zaxis=dict(visible=False), bgcolor='rgba(0,0,0,0)'), paper_bgcolor='rgba(0,0,0,0)', margin=dict(l=0, r=0, b=0, t=0), showlegend=False)80 return go.Figure(data=[trace_edges, trace_nodes], layout=layout)81 82# ===== REPORT ENGINE =====83class ReportEngine:84 @staticmethod85 def generate_gpu_requirement_pdf(sim_rows: List[Dict], sys_meta: Dict[str, Any]) -> bytes:86 buffer = io.BytesIO()87 c = canvas.Canvas(buffer, pagesize=letter)88 c.setFillColorRGB(0,0,0)89 c.setFont("Helvetica-Bold", 16)90 c.drawString(50, 750, f"{AppConfig.APP_NAME} // GPU REQUIREMENT REPORT")91 c.setFont("Courier", 10)92 c.drawString(50, 720, f"GENERATED: {time.strftime('%Y-%m-%d %H:%M:%S')}")93 c.drawString(50, 705, f"NODE ID: {sys_meta.get('node_id', 'N/A')}")94 c.drawString(50, 690, f"TARGET HARDWARE: {sys_meta.get('model', 'N/A')}")95 c.setFont("Helvetica-Bold", 10)96 y_start = 65097 c.drawString(50, y_start, "MATRIX SIZE")98 c.drawString(200, y_start, "CPU LATENCY (ms)")99 c.drawString(350, y_start, "SIM H100 (ms)")100 c.line(50, y_start-5, 500, y_start-5)101 c.setFont("Courier", 10)102 y = y_start - 20103 for r in sim_rows:104 c.drawString(50, y, str(r['matrix_size']))105 c.drawString(200, y, f"{r['cpu_ms']:.1f}")106 c.drawString(350, y, f"{r['sim_gpu_ms']:.2f}")107 y -= 15108 y -= 30109 c.setFont("Helvetica-Bold", 11)110 c.drawString(50, y, "EXECUTIVE SUMMARY:")111 c.setFont("Helvetica", 10)112 y -= 15113 c.drawString(50, y, "Migration to NVIDIA H100 Tensor Cores is projected to reduce latency by ~40x.")114 c.save()115 buffer.seek(0)116 return buffer.getvalue()117 118# ===== SECURITY GATE (FIXED) =====119class SecurityGate:120 @staticmethod121 def verify_session():122 if st.session_state.get('authenticated'): return True123 124 # --- CRITICAL FIX: Check OS ENV first to avoid Streamlit Secrets Error ---125 # Since we set ACCESS_TOKEN in docker-compose, this will be found first.126 secret = os.environ.get("ACCESS_TOKEN")127 128 # Only try accessing st.secrets if OS env is missing (Local Dev fallback)129 if not secret:130 try:131 secret = st.secrets["ACCESS_TOKEN"]132 except Exception:133 secret = "Ezhar!2025#" # Fallback134 135 col1, col2, col3 = st.columns([1, 2, 1])136 with col2:137 st.markdown(f"<div class='auth-box'><h3 style='color:{AppConfig.THEME_COLOR}'>{AppConfig.APP_NAME}</h3></div>", unsafe_allow_html=True)138 with st.form("auth"):139 token = st.text_input("ACCESS KEY", type="password")140 if st.form_submit_button("LOGIN"):141 # Use safe comparison142 if hmac.compare_digest(token, secret):143 st.session_state['authenticated'] = True144 st.rerun()145 else: st.error("ACCESS DENIED")146 st.stop()147 148inject_industrial_css = StyleManager.inject_industrial_css149generate_gpu_requirement_pdf = ReportEngine.generate_gpu_requirement_pdf150VisualKernel = VisualKernel151verify_session = SecurityGate.verify_session