Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import requests | |
| from typing import List, Dict | |
| import os | |
| API_URL = os.getenv('POND_API_URL') | |
| API_TOKEN = os.getenv('POND_API_TOKEN') | |
| st.title('🌊 Pond Model Demo') | |
| st.sidebar.header('Model Selection') | |
| model_info = { | |
| 1: { | |
| 'name': 'Security Model', | |
| 'description': 'Analyze whether an account is secure by detecting and examining malicious activities within complex blockchain data structures.' | |
| }, | |
| 2: { | |
| 'name': 'Sybil Model', | |
| 'description': 'An model aims to detect on-chain "Sybil Attacks"' | |
| }, | |
| 3: { | |
| 'name': 'ZORA NFT Recommendation', | |
| 'description': 'On-Chain Recommendation System: Making Discoveries & Spread Easier for Everyone' | |
| } | |
| } | |
| selected_model = st.sidebar.selectbox( | |
| 'Choose a model', | |
| list(model_info.keys()), | |
| format_func=lambda x: model_info[x]['name'] | |
| ) | |
| # Show model description | |
| st.markdown(f"### {model_info[selected_model]['name']}") | |
| st.markdown(model_info[selected_model]['description']) | |
| # Input section | |
| st.header('Input Wallet Addresses') | |
| wallet_input = st.text_area( | |
| 'Enter wallet addresses (one per line)', | |
| height=100, | |
| help='Enter wallet addresses, one per line' | |
| ) | |
| def predict(addresses: List[str], model_id: int) -> Dict: | |
| """ | |
| Make prediction using the Pond API | |
| """ | |
| if not API_URL: | |
| st.error('API URL is not configured. Please set POND_API_URL environment variable.') | |
| return None | |
| headers = { | |
| "Content-Type": "application/json" | |
| } | |
| try: | |
| payload = { | |
| "req_type": "1", | |
| "access_token": API_TOKEN, | |
| "input_keys": addresses, | |
| "model_id": model_id | |
| } | |
| headers = { | |
| "Content-Type": "application/json" | |
| } | |
| # Make the API call with explicit method | |
| session = requests.Session() | |
| req = requests.Request('POST', | |
| API_URL, | |
| json=payload, | |
| headers=headers) | |
| prepped = req.prepare() | |
| response = session.send(prepped, | |
| allow_redirects=True) | |
| # Check response | |
| if response.status_code != 200: | |
| st.error(f"API Error: {response.status_code}") | |
| st.error(f"Response: {response.text}") | |
| return None | |
| return response.json() | |
| except Exception as e: | |
| st.error(f"Error making prediction: {str(e)}") | |
| return None | |
| def display_results(response: Dict, model_id: int): | |
| """ | |
| Display the results based on model type | |
| """ | |
| if not response or 'resp_items' not in response: | |
| return | |
| if model_id in [1, 2]: # Security and Sybil models | |
| st.header('Results') | |
| for item in response['resp_items']: | |
| score = item['score'] | |
| address = item['input_key'] | |
| # Create color coding based on score | |
| if score < 0.3: | |
| color = 'green' | |
| elif score < 0.7: | |
| color = 'orange' | |
| else: | |
| color = 'red' | |
| st.markdown(f""" | |
| **Address**: `{address}` | |
| **Score**: <span style='color: {color}'>{score:.4f}</span> | |
| """, unsafe_allow_html=True) | |
| st.markdown("") | |
| elif model_id == 3: # NFT Recommendation model | |
| st.header('NFT Recommendations') | |
| for item in response['resp_items']: | |
| address = item['input_key'] | |
| st.subheader(f'Recommendations for: `{address}`') | |
| if 'candidates' in item: | |
| for idx, candidate in enumerate(item['candidates'][:5], 1): | |
| st.markdown(f""" | |
| **{idx}. NFT ID**: `{candidate['item_id']}` | |
| **Score**: {candidate['score']:.4f} | |
| """) | |
| st.markdown("") | |
| # Process button | |
| if st.button('Get Predictions'): | |
| if wallet_input: | |
| # Process input addresses | |
| addresses = [addr.strip() for addr in wallet_input.split('\n') if addr.strip()] | |
| # Validate addresses | |
| valid_addresses = [addr for addr in addresses if addr.startswith('0x')] | |
| if not valid_addresses: | |
| st.error('Please enter valid Ethereum addresses (starting with 0x)') | |
| else: | |
| with st.spinner('Making predictions...'): | |
| response = predict(valid_addresses, selected_model) | |
| if response: | |
| display_results(response, selected_model) | |
| else: | |
| st.warning('Please enter at least one wallet address') | |
| # Footer | |
| st.markdown("---") | |
| st.markdown("ℹ️ This is a demo interface for the Pond Model API. For production use, please refer to the official documentation.") |