Spaces:
Sleeping
Sleeping
import streamlit as st | |
import time | |
from components.edit_model import edit_model_form | |
from components.upload_model import upload_model_form | |
def render_model_details(): | |
"""Render the model details page""" | |
if not st.session_state.selected_model: | |
st.error("No model selected. Please select a model from the sidebar.") | |
if st.button("Go back to Dashboard", use_container_width=True): | |
st.session_state.page = "home" | |
st.rerun() | |
return | |
# Get model info from Hugging Face API | |
with st.spinner("Loading model details..."): | |
try: | |
repo_id = st.session_state.selected_model | |
model_info = st.session_state.client.get_model_info(repo_id) | |
if not model_info: | |
st.error( | |
"Model not found. It may have been deleted or you don't have access." | |
) | |
if st.button("Go back to Dashboard", use_container_width=True): | |
st.session_state.page = "home" | |
st.rerun() | |
return | |
except Exception as e: | |
st.error(f"Error loading model details: {str(e)}") | |
if st.button("Go back to Dashboard", use_container_width=True): | |
st.session_state.page = "home" | |
st.rerun() | |
return | |
# Display model header | |
st.title(f"Model: {repo_id}") | |
# Display model information | |
col1, col2 = st.columns([2, 1]) | |
with col1: | |
st.markdown( | |
f""" | |
<div style="background-color: #F9FAFB; padding: 20px; border-radius: 10px; border: 1px solid #E5E7EB;"> | |
<div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px;"> | |
<h3 style="margin: 0;">{repo_id.split('/')[-1]}</h3> | |
<div> | |
<span style="background-color: #FFD21E; padding: 5px 10px; border-radius: 20px; font-size: 12px; margin-right: 5px;"> | |
{model_info.modelId.split('/')[0]} | |
</span> | |
<span style="background-color: #84ADFF; padding: 5px 10px; border-radius: 20px; font-size: 12px;"> | |
{model_info.pipeline_tag if hasattr(model_info, 'pipeline_tag') else 'model'} | |
</span> | |
</div> | |
</div> | |
<div style="margin-bottom: 10px;"> | |
<a href="https://huggingface.co/{repo_id}" target="_blank" style="color: #84ADFF; text-decoration: none;"> | |
View on Hugging Face Hub π | |
</a> | |
</div> | |
<div style="display: flex; gap: 20px; margin-top: 20px;"> | |
<div> | |
<div style="color: #6B7280; font-size: 12px;">DOWNLOADS</div> | |
<div style="font-weight: bold;">{getattr(model_info, 'downloads', 0)}</div> | |
</div> | |
<div> | |
<div style="color: #6B7280; font-size: 12px;">LIKES</div> | |
<div style="font-weight: bold;">{getattr(model_info, 'likes', 0)}</div> | |
</div> | |
<div> | |
<div style="color: #6B7280; font-size: 12px;">LAST MODIFIED</div> | |
<div style="font-weight: bold;"> | |
{getattr(model_info, 'lastModified', 'Unknown').split('T')[0] if hasattr(model_info, 'lastModified') else 'Unknown'} | |
</div> | |
</div> | |
</div> | |
</div> | |
""", | |
unsafe_allow_html=True, | |
) | |
with col2: | |
st.markdown( | |
f""" | |
<div style="background-color: #F9FAFB; padding: 20px; border-radius: 10px; border: 1px solid #E5E7EB; height: 100%;"> | |
<div style="color: #6B7280; font-size: 12px; margin-bottom: 10px;">TAGS</div> | |
<div style="display: flex; flex-wrap: wrap; gap: 5px;"> | |
{' '.join([f'<span style="background-color: #E5E7EB; padding: 5px 10px; border-radius: 20px; font-size: 12px;">{tag}</span>' for tag in (model_info.tags if hasattr(model_info, 'tags') else [])])} | |
</div> | |
</div> | |
""", | |
unsafe_allow_html=True, | |
) | |
# Tabs for different actions | |
tab1, tab2, tab3, tab4, tab5, tab6 = st.tabs(["Model Card", "Upload Files", "Edit Model", "Version Control", "Test Inference", "Auto Documentation"]) | |
with tab1: | |
st.markdown("### Model Card") | |
# Display model card iframe | |
st.markdown( | |
f""" | |
<iframe src="https://huggingface.co/{repo_id}" width="100%" height="600" style="border: 1px solid #E5E7EB; border-radius: 10px;"></iframe> | |
""", | |
unsafe_allow_html=True, | |
) | |
with tab2: | |
success = upload_model_form(model_info) | |
if success: | |
# Refresh model info after successful upload | |
time.sleep(2) # Wait for the API to update | |
st.session_state.selected_model = repo_id # Keep the same model selected | |
st.rerun() | |
with tab3: | |
success, _ = edit_model_form(model_info) | |
if success: | |
# Refresh model info after successful edit | |
time.sleep(2) # Wait for the API to update | |
st.session_state.selected_model = repo_id # Keep the same model selected | |
st.rerun() | |
with tab4: | |
from components.version_control import render_version_history | |
render_version_history(model_info) | |
with tab5: | |
from components.model_inference import model_inference_dashboard | |
model_inference_dashboard(model_info) | |
with tab6: | |
from components.documentation_generator import model_documentation_generator | |
model_documentation_generator(model_info) | |
# Delete model option | |
st.markdown("---") | |
with st.expander("β οΈ Danger Zone"): | |
st.warning( | |
"Deleting a repository is irreversible. All files and data will be permanently lost." | |
) | |
# Confirmation input | |
confirm_text = st.text_input( | |
f"Type the repository name '{repo_id.split('/')[-1]}' to confirm deletion:", | |
key="confirm_delete_input", | |
) | |
if st.button( | |
"ποΈ Delete Repository", key="delete_repo_btn", use_container_width=True | |
): | |
if confirm_text == repo_id.split("/")[-1]: | |
with st.spinner("Deleting repository..."): | |
try: | |
success, message = ( | |
st.session_state.client.delete_model_repository(repo_id) | |
) | |
if success: | |
st.success("Repository deleted successfully!") | |
# Refresh models and go back to home | |
st.session_state.models = ( | |
st.session_state.client.get_user_models() | |
) | |
st.session_state.page = "home" | |
st.session_state.selected_model = None | |
st.rerun() | |
else: | |
st.error(f"Failed to delete repository: {message}") | |
except Exception as e: | |
st.error(f"Error deleting repository: {str(e)}") | |
else: | |
st.error("Repository name doesn't match. Deletion aborted.") |