121 lines
3.8 KiB
Python
121 lines
3.8 KiB
Python
import streamlit as st
|
||
import requests
|
||
import json
|
||
|
||
st.title("PubChem Data Viewer")
|
||
|
||
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
|
||
|
||
# Make API request
|
||
with st.spinner("Fetching data from PubChem..."):
|
||
try:
|
||
response = requests.post(
|
||
"https://api.cosmoguard.it/api/v1/common/pubchem",
|
||
json={"cas": cas_number}
|
||
)
|
||
response.raise_for_status()
|
||
result = response.json()
|
||
except requests.exceptions.RequestException as e:
|
||
st.error(f"Error fetching data: {e}")
|
||
st.stop()
|
||
|
||
# Check if request was successful
|
||
if not result.get("success", False):
|
||
st.error(f"API Error: {result.get('error', 'Unknown error')}")
|
||
st.stop()
|
||
|
||
data = result.get("data", {})
|
||
|
||
# Display substance header
|
||
st.subheader(f"{data.get('first_pubchem_name', 'Unknown').title()}")
|
||
|
||
# Basic info container
|
||
with st.container(border=True):
|
||
col1, col2, col3 = st.columns(3)
|
||
with col1:
|
||
st.caption("CAS Number")
|
||
st.write(data.get("CAS", "—"))
|
||
with col2:
|
||
st.caption("PubChem CID")
|
||
st.write(data.get("CID", "—"))
|
||
with col3:
|
||
if data.get("pubchem_link"):
|
||
st.link_button("View on PubChem", data.get("pubchem_link"))
|
||
|
||
st.divider()
|
||
|
||
# Physical/Chemical Properties
|
||
st.subheader("Physical & Chemical Properties")
|
||
|
||
with st.container(border=True):
|
||
prop_col1, prop_col2, prop_col3, prop_col4 = st.columns(4)
|
||
|
||
with prop_col1:
|
||
st.metric("Molecular Weight", f"{data.get('MolecularWeight', '—')} g/mol" if data.get('MolecularWeight') else "—")
|
||
|
||
with prop_col2:
|
||
st.metric("XLogP", data.get('XLogP', '—'))
|
||
|
||
with prop_col3:
|
||
st.metric("Exact Mass", data.get('ExactMass', '—'))
|
||
|
||
with prop_col4:
|
||
st.metric("TPSA", f"{data.get('TPSA', '—')} Ų" if data.get('TPSA') else "—")
|
||
|
||
st.divider()
|
||
|
||
# Melting Point
|
||
melting_points = data.get("Melting Point", [])
|
||
if melting_points:
|
||
st.subheader("Melting Point")
|
||
|
||
with st.expander(f"View {len(melting_points)} reference(s)", expanded=True):
|
||
for idx, mp in enumerate(melting_points):
|
||
with st.container(border=True):
|
||
st.markdown(f"**Reference {idx + 1}**")
|
||
|
||
if mp.get("Value"):
|
||
st.info(mp.get("Value"))
|
||
|
||
if mp.get("Reference"):
|
||
st.caption(f"📚 {mp.get('Reference')}")
|
||
|
||
if mp.get("Description"):
|
||
st.caption(f"ℹ️ {mp.get('Description')}")
|
||
|
||
if mp.get("ReferenceNumber"):
|
||
st.caption(f"Ref #: {mp.get('ReferenceNumber')}")
|
||
|
||
# Dissociation Constants
|
||
dissociation_constants = data.get("Dissociation Constants", [])
|
||
if dissociation_constants:
|
||
st.divider()
|
||
st.subheader("Dissociation Constants (pKa)")
|
||
|
||
with st.expander(f"View {len(dissociation_constants)} reference(s)", expanded=True):
|
||
for idx, dc in enumerate(dissociation_constants):
|
||
with st.container(border=True):
|
||
st.markdown(f"**Reference {idx + 1}**")
|
||
|
||
if dc.get("Value"):
|
||
# Check if it's a dictionary or string
|
||
value = dc.get("Value")
|
||
if isinstance(value, dict):
|
||
st.code(json.dumps(value, indent=2))
|
||
else:
|
||
st.info(value)
|
||
|
||
if dc.get("Reference"):
|
||
st.caption(f"📚 {dc.get('Reference')}")
|
||
|
||
if dc.get("ReferenceNumber"):
|
||
st.caption(f"Ref #: {dc.get('ReferenceNumber')}")
|
||
|
||
# Raw JSON viewer
|
||
st.divider()
|
||
with st.expander("View Raw JSON Response"):
|
||
st.json(result)
|