|
|
""" |
|
|
CIQ Verification App |
|
|
|
|
|
Streamlit interface to verify CIQ parameters against dump database. |
|
|
Supports 2G, 3G, and LTE verification with optional file uploads. |
|
|
""" |
|
|
|
|
|
import pandas as pd |
|
|
import streamlit as st |
|
|
|
|
|
from queries.verify_ciq import ( |
|
|
generate_verification_report, |
|
|
process_dump_gsm, |
|
|
process_dump_lte, |
|
|
process_dump_wcdma, |
|
|
read_ciq_file, |
|
|
verify_2g, |
|
|
verify_3g, |
|
|
verify_lte, |
|
|
) |
|
|
|
|
|
st.title("🔍 CIQ Verification") |
|
|
st.markdown( |
|
|
""" |
|
|
Vérifiez que les paramètres CIQ correspondent aux valeurs du dump OML. |
|
|
- **Dump** : Obligatoire (format .xlsb) |
|
|
- **CIQ** : Au moins un fichier CIQ (2G, 3G ou LTE) est requis |
|
|
""" |
|
|
) |
|
|
|
|
|
|
|
|
st.subheader("📁 Fichiers d'entrée") |
|
|
|
|
|
dump_file = st.file_uploader( |
|
|
"Upload Dump (xlsb)", type=["xlsb"], key="verify_dump", help="Fichier dump obligatoire" |
|
|
) |
|
|
|
|
|
col1, col2, col3 = st.columns(3) |
|
|
|
|
|
with col1: |
|
|
ciq_2g_file = st.file_uploader( |
|
|
"CIQ 2G (optionnel)", type=["xlsx", "xls"], key="verify_ciq_2g" |
|
|
) |
|
|
|
|
|
with col2: |
|
|
ciq_3g_file = st.file_uploader( |
|
|
"CIQ 3G (optionnel)", type=["xlsx", "xls"], key="verify_ciq_3g" |
|
|
) |
|
|
|
|
|
with col3: |
|
|
ciq_lte_file = st.file_uploader( |
|
|
"CIQ LTE (optionnel)", type=["xlsx", "xls"], key="verify_ciq_lte" |
|
|
) |
|
|
|
|
|
|
|
|
if dump_file is None: |
|
|
st.info("⬆️ Veuillez uploader le fichier dump (xlsb).") |
|
|
st.stop() |
|
|
|
|
|
if ciq_2g_file is None and ciq_3g_file is None and ciq_lte_file is None: |
|
|
st.warning("⚠️ Au moins un fichier CIQ (2G, 3G ou LTE) est requis.") |
|
|
st.stop() |
|
|
|
|
|
|
|
|
if st.button("🔎 Vérifier", type="primary"): |
|
|
try: |
|
|
results_2g = None |
|
|
results_3g = None |
|
|
results_lte = None |
|
|
|
|
|
with st.spinner("Traitement en cours..."): |
|
|
|
|
|
if ciq_2g_file is not None: |
|
|
st.text("📶 Traitement 2G...") |
|
|
dump_gsm = process_dump_gsm(dump_file) |
|
|
dump_file.seek(0) |
|
|
ciq_2g_df = read_ciq_file(ciq_2g_file) |
|
|
results_2g = verify_2g(ciq_2g_df, dump_gsm) |
|
|
|
|
|
|
|
|
if ciq_3g_file is not None: |
|
|
st.text("📶 Traitement 3G...") |
|
|
dump_wcdma = process_dump_wcdma(dump_file) |
|
|
dump_file.seek(0) |
|
|
ciq_3g_df = read_ciq_file(ciq_3g_file) |
|
|
results_3g = verify_3g(ciq_3g_df, dump_wcdma) |
|
|
|
|
|
|
|
|
if ciq_lte_file is not None: |
|
|
st.text("📶 Traitement LTE...") |
|
|
dump_lte = process_dump_lte(dump_file) |
|
|
dump_file.seek(0) |
|
|
ciq_lte_df = read_ciq_file(ciq_lte_file) |
|
|
results_lte = verify_lte(ciq_lte_df, dump_lte) |
|
|
|
|
|
|
|
|
sheets, excel_bytes = generate_verification_report( |
|
|
results_2g=results_2g, |
|
|
results_3g=results_3g, |
|
|
results_lte=results_lte, |
|
|
) |
|
|
|
|
|
st.session_state["verify_results_2g"] = results_2g |
|
|
st.session_state["verify_results_3g"] = results_3g |
|
|
st.session_state["verify_results_lte"] = results_lte |
|
|
st.session_state["verify_sheets"] = sheets |
|
|
st.session_state["verify_excel_bytes"] = excel_bytes |
|
|
|
|
|
st.success("✅ Vérification terminée!") |
|
|
|
|
|
except Exception as e: |
|
|
st.error(f"❌ Erreur: {e}") |
|
|
import traceback |
|
|
st.code(traceback.format_exc()) |
|
|
|
|
|
|
|
|
results_2g = st.session_state.get("verify_results_2g") |
|
|
results_3g = st.session_state.get("verify_results_3g") |
|
|
results_lte = st.session_state.get("verify_results_lte") |
|
|
sheets = st.session_state.get("verify_sheets") |
|
|
excel_bytes = st.session_state.get("verify_excel_bytes") |
|
|
|
|
|
|
|
|
def display_stats(stats: dict, tech: str): |
|
|
"""Display verification statistics.""" |
|
|
col1, col2, col3, col4 = st.columns(4) |
|
|
with col1: |
|
|
st.metric("Total Cells", stats["total_cells"]) |
|
|
with col2: |
|
|
st.metric("✅ OK", stats["ok_count"]) |
|
|
with col3: |
|
|
st.metric("⚠️ Mismatch", stats["mismatch_count"]) |
|
|
with col4: |
|
|
st.metric("❓ Not Found", stats["not_found_count"]) |
|
|
|
|
|
|
|
|
def style_results(df: pd.DataFrame) -> pd.DataFrame: |
|
|
"""Apply styling to highlight mismatches.""" |
|
|
def highlight_status(val): |
|
|
if val == "OK": |
|
|
return "background-color: #d4edda; color: #155724;" |
|
|
elif val == "MISMATCH": |
|
|
return "background-color: #f8d7da; color: #721c24;" |
|
|
elif val == "NOT_FOUND": |
|
|
return "background-color: #fff3cd; color: #856404;" |
|
|
return "" |
|
|
|
|
|
def highlight_match(val): |
|
|
if val is True: |
|
|
return "background-color: #d4edda;" |
|
|
elif val is False: |
|
|
return "background-color: #f8d7da;" |
|
|
return "" |
|
|
|
|
|
|
|
|
status_col = "Status" |
|
|
|
|
|
|
|
|
styled = df.style.map( |
|
|
highlight_status, subset=[status_col] |
|
|
) |
|
|
|
|
|
|
|
|
match_cols = [c for c in df.columns if c.endswith("_Match")] |
|
|
if match_cols: |
|
|
styled = styled.map(highlight_match, subset=match_cols) |
|
|
|
|
|
return styled |
|
|
|
|
|
|
|
|
if sheets: |
|
|
st.divider() |
|
|
st.subheader("📊 Résultats de la vérification") |
|
|
|
|
|
tabs = [] |
|
|
tab_names = [] |
|
|
|
|
|
if results_2g: |
|
|
tab_names.append("2G") |
|
|
if results_3g: |
|
|
tab_names.append("3G") |
|
|
if results_lte: |
|
|
tab_names.append("LTE") |
|
|
|
|
|
if tab_names: |
|
|
tabs = st.tabs(tab_names) |
|
|
tab_idx = 0 |
|
|
|
|
|
if results_2g: |
|
|
with tabs[tab_idx]: |
|
|
st.markdown("### 📶 Vérification 2G") |
|
|
display_stats(results_2g[1], "2G") |
|
|
st.dataframe( |
|
|
style_results(results_2g[0]), |
|
|
use_container_width=True, |
|
|
hide_index=True, |
|
|
) |
|
|
tab_idx += 1 |
|
|
|
|
|
if results_3g: |
|
|
with tabs[tab_idx]: |
|
|
st.markdown("### 📶 Vérification 3G") |
|
|
display_stats(results_3g[1], "3G") |
|
|
st.dataframe( |
|
|
style_results(results_3g[0]), |
|
|
use_container_width=True, |
|
|
hide_index=True, |
|
|
) |
|
|
tab_idx += 1 |
|
|
|
|
|
if results_lte: |
|
|
with tabs[tab_idx]: |
|
|
st.markdown("### 📶 Vérification LTE") |
|
|
display_stats(results_lte[1], "LTE") |
|
|
st.dataframe( |
|
|
style_results(results_lte[0]), |
|
|
use_container_width=True, |
|
|
hide_index=True, |
|
|
) |
|
|
|
|
|
if excel_bytes: |
|
|
st.divider() |
|
|
st.download_button( |
|
|
label="📥 Télécharger le rapport de vérification (Excel)", |
|
|
data=excel_bytes, |
|
|
file_name="CIQ_Verification_Report.xlsx", |
|
|
mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", |
|
|
type="primary", |
|
|
) |
|
|
|