149 lines
No EOL
4.7 KiB
Python
149 lines
No EOL
4.7 KiB
Python
import streamlit as st
|
|
import json
|
|
|
|
from functions import cosing_request
|
|
from functions_ui import download_pdf
|
|
|
|
st.title("CosIng Database Viewer")
|
|
|
|
st.set_page_config(
|
|
page_title="CosIng",
|
|
page_icon="🧪",
|
|
layout="wide"
|
|
)
|
|
|
|
def display_ingredient(data: dict, level: int = 0):
|
|
"""Display ingredient information using containers and metrics."""
|
|
|
|
# Get names
|
|
name = data.get("commonName") or data.get("inciName") or "Unknown"
|
|
chemical_name = data.get("chemicalName", "")
|
|
item_type = data.get("itemType", "ingredient")
|
|
|
|
# Header
|
|
if level == 0:
|
|
st.title(f"🧪 {name}")
|
|
else:
|
|
st.markdown(f"### {name}")
|
|
|
|
# Type badge and chemical name
|
|
col_header1, col_header2 = st.columns([1, 3])
|
|
with col_header1:
|
|
if item_type == "substance":
|
|
st.caption("🔬 Substance")
|
|
else:
|
|
st.caption("🧴 Ingredient")
|
|
with col_header2:
|
|
if chemical_name and chemical_name.upper() != name.upper():
|
|
st.caption(f"*{chemical_name}*")
|
|
|
|
# Identifiers container
|
|
cas_numbers = data.get("casNo", [])
|
|
ec_numbers = data.get("ecNo", [])
|
|
ref_no = data.get("refNo", "")
|
|
|
|
if cas_numbers or ec_numbers or ref_no:
|
|
with st.container(border=True):
|
|
cols = st.columns(3)
|
|
|
|
with cols[0]:
|
|
if cas_numbers:
|
|
st.metric("CAS", ", ".join(cas_numbers))
|
|
else:
|
|
st.metric("CAS", "—")
|
|
|
|
with cols[1]:
|
|
if ec_numbers:
|
|
st.metric("EC", ", ".join(ec_numbers))
|
|
else:
|
|
st.metric("EC", "—")
|
|
|
|
with cols[2]:
|
|
if ref_no:
|
|
st.metric("Ref. No.", ref_no)
|
|
else:
|
|
st.metric("Ref. No.", "—")
|
|
|
|
# Functions
|
|
functions = data.get("functionName", [])
|
|
if functions:
|
|
with st.container(border=True):
|
|
st.markdown("**Functions**")
|
|
func_cols = st.columns(len(functions))
|
|
for i, func in enumerate(functions):
|
|
with func_cols[i]:
|
|
st.success(func.title())
|
|
|
|
# Regulatory info
|
|
restrictions = data.get("otherRestrictions", [])
|
|
annex = data.get("annexNo", [])
|
|
regulations = data.get("otherRegulations", [])
|
|
opinions = data.get("sccsOpinion", [])
|
|
opinion_urls = data.get("sccsOpinionUrls", [])
|
|
|
|
if restrictions or annex or regulations or opinions or opinion_urls:
|
|
with st.container(border=True):
|
|
st.markdown("**Regulatory Information**")
|
|
|
|
if annex:
|
|
st.info(f"📋 **Annex {', '.join(annex)}**")
|
|
|
|
if restrictions:
|
|
for r in restrictions:
|
|
st.warning(f"⚠️ {r}")
|
|
|
|
if regulations:
|
|
st.write("Other regulations: " + "; ".join(regulations))
|
|
|
|
if opinions:
|
|
for opinion in opinions:
|
|
st.write(f"📄 {opinion}")
|
|
|
|
if opinion_urls:
|
|
for url in opinion_urls:
|
|
st.link_button("View SCCS Opinion", url)
|
|
|
|
# Source link
|
|
cosing_url = data.get("cosingUrl", "")
|
|
if cosing_url:
|
|
st.link_button("🔗 View on CosIng", cosing_url)
|
|
|
|
|
|
# Identified Ingredients (recursive)
|
|
identified = data.get("identifiedIngredient", [])
|
|
if identified:
|
|
st.divider()
|
|
|
|
# Check if it's a list of IDs or full objects
|
|
if identified and isinstance(identified[0], dict):
|
|
st.subheader(f"🔬 Related Substances ({len(identified)})")
|
|
for idx, ing in enumerate(identified):
|
|
ing_name = ing.get("commonName") or ing.get("inciName") or f"Substance {idx + 1}"
|
|
with st.expander(ing_name):
|
|
display_ingredient(ing, level=level + 1)
|
|
else:
|
|
# List of IDs only
|
|
st.subheader(f"🔬 Related Substances ({len(identified)} IDs)")
|
|
with st.expander("Show substance IDs"):
|
|
# Display in a grid
|
|
id_text = ", ".join(str(i) for i in identified[:20])
|
|
if len(identified) > 20:
|
|
id_text += f"... and {len(identified) - 20} more"
|
|
st.code(id_text)
|
|
|
|
|
|
|
|
|
|
def main():
|
|
if st.session_state.get('selected_cas', None) is None:
|
|
st.warning("Nessun CAS Number selezionato. Torna alla pagina principale per effettuare una ricerca.")
|
|
st.stop()
|
|
else:
|
|
cas_number = st.session_state.selected_cas
|
|
|
|
DATA = cosing_request(cas_number)
|
|
display_ingredient(DATA)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main() |