""" Test 4: Package Management and Dependencies (Container Runtime Compatible) Purpose: Validate package installation and dependency management within Container Runtime Fixed for older Streamlit versions without st.rerun() """ import streamlit as st import sys import importlib.util import subprocess import json import re from datetime import datetime # Page configuration st.set_page_config( page_title="Spark POC - Package Test", page_icon="๐Ÿ“ฆ", layout="wide" ) # Header st.title("๐Ÿ“ฆ Spark POC - Package Management Test (Fixed)") st.write("Testing package installation and dependency management within Container Runtime environment for TikTok music analytics POC") # Initialize session state for caching results (Container Runtime compatibility) if 'package_test_results' not in st.session_state: st.session_state.package_test_results = {} if 'package_versions' not in st.session_state: st.session_state.package_versions = {} if 'functionality_results' not in st.session_state: st.session_state.functionality_results = {} if 'last_package_check' not in st.session_state: st.session_state.last_package_check = None # Define required packages for Spark POC TikTok analytics REQUIRED_PACKAGES = { 'pandas': { 'import_name': 'pandas', 'description': 'Data manipulation and analysis framework', 'critical': True, 'min_version': '1.3.0', 'test_function': 'test_pandas' }, 'numpy': { 'import_name': 'numpy', 'description': 'Numerical computing library (pandas dependency)', 'critical': True, 'min_version': '1.20.0', 'test_function': 'test_numpy' }, 'requests': { 'import_name': 'requests', 'description': 'HTTP library for API calls', 'critical': True, 'min_version': '2.25.0', 'test_function': 'test_requests' }, 'snowflake-connector-python': { 'import_name': 'snowflake.connector', 'description': 'Snowflake database connectivity', 'critical': True, 'min_version': '2.7.0', 'test_function': 'test_snowflake' } } OPTIONAL_PACKAGES = { 'matplotlib': { 'import_name': 'matplotlib', 'description': 'Static plotting library', 'critical': False, 'min_version': '3.3.0', 'test_function': 'test_matplotlib' }, 'plotly': { 'import_name': 'plotly', 'description': 'Interactive plotting library', 'critical': False, 'min_version': '5.0.0', 'test_function': 'test_plotly' }, 'python-dateutil': { 'import_name': 'dateutil', 'description': 'Date/time utilities', 'critical': False, 'min_version': '2.8.0', 'test_function': 'test_dateutil' }, 'python-dotenv': { 'import_name': 'dotenv', 'description': 'Environment variable management', 'critical': False, 'min_version': '0.19.0', 'test_function': 'test_dotenv' } } # Built-in modules that should always be available BUILTIN_MODULES = { 'json': { 'import_name': 'json', 'description': 'JSON encoding and decoding', 'critical': True, 'test_function': 'test_json' }, 'datetime': { 'import_name': 'datetime', 'description': 'Date and time handling', 'critical': True, 'test_function': 'test_datetime' }, 're': { 'import_name': 're', 'description': 'Regular expressions', 'critical': True, 'test_function': 'test_re' } } # Test 4.1: Package Availability and Version Check st.header("Test 4.1: Package Availability and Version Check") def check_package_advanced(package_name, import_name, description, critical=True, min_version=None): """Enhanced package checking with version compatibility assessment""" try: # Check if package is findable spec = importlib.util.find_spec(import_name) if spec is None: return { 'available': False, 'version': None, 'version_compatible': False, 'error': 'Package not found in Python path', 'critical': critical, 'location': None, 'dependencies': [] } # Import and get detailed info module = importlib.import_module(import_name) # Try multiple ways to get version version = None for attr in ['__version__', 'version', 'VERSION', '__VERSION__']: if hasattr(module, attr): version_candidate = getattr(module, attr) if version_candidate and isinstance(version_candidate, str): version = version_candidate break # Check version compatibility version_compatible = True if min_version and version: try: # Simple version comparison (works for most cases) current_parts = [int(x) for x in version.split('.') if x.isdigit()] min_parts = [int(x) for x in min_version.split('.') if x.isdigit()] # Pad shorter version with zeros max_len = max(len(current_parts), len(min_parts)) current_parts += [0] * (max_len - len(current_parts)) min_parts += [0] * (max_len - len(min_parts)) version_compatible = current_parts >= min_parts except: version_compatible = None # Cannot determine # Get package location location = spec.origin if spec.origin else "Built-in" return { 'available': True, 'version': version, 'version_compatible': version_compatible, 'error': None, 'critical': critical, 'location': location, 'module': module } except ImportError as e: return { 'available': False, 'version': None, 'version_compatible': False, 'error': f'Import error: {str(e)}', 'critical': critical, 'location': None } except Exception as e: return { 'available': False, 'version': None, 'version_compatible': False, 'error': f'Unexpected error: {str(e)}', 'critical': critical, 'location': None } def get_compatibility_status(result, min_version=None): """Get compatibility status icon and message""" if not result['available']: return "โŒ", "Not available" elif result['version_compatible'] is False: return "โš ๏ธ", f"Version incompatible (need >={min_version})" elif result['version_compatible'] is None: return "โ“", "Version compatibility unknown" else: return "โœ…", "Available and compatible" col1, col2 = st.columns(2) with col1: st.subheader("๐Ÿ” Run Package Analysis") if st.button("๐Ÿ”„ Check All Packages", type="primary"): st.info("โณ Analyzing packages and dependencies...") # Check required packages st.session_state.package_test_results['required'] = {} for package, info in REQUIRED_PACKAGES.items(): result = check_package_advanced( package, info['import_name'], info['description'], info['critical'], info.get('min_version') ) st.session_state.package_test_results['required'][package] = result # Check optional packages st.session_state.package_test_results['optional'] = {} for package, info in OPTIONAL_PACKAGES.items(): result = check_package_advanced( package, info['import_name'], info['description'], info['critical'], info.get('min_version') ) st.session_state.package_test_results['optional'][package] = result # Check built-in modules st.session_state.package_test_results['builtin'] = {} for package, info in BUILTIN_MODULES.items(): result = check_package_advanced( package, info['import_name'], info['description'], info['critical'] ) st.session_state.package_test_results['builtin'][package] = result st.session_state.last_package_check = datetime.now().strftime("%H:%M:%S") st.success("โœ… Package analysis complete!") with col2: st.subheader("๐Ÿ“‹ Analysis Status") if st.session_state.last_package_check: st.write(f"**Last Check**: {st.session_state.last_package_check}") # Quick summary if 'required' in st.session_state.package_test_results: required_available = sum(1 for r in st.session_state.package_test_results['required'].values() if r['available']) total_required = len(st.session_state.package_test_results['required']) st.write(f"**Required**: {required_available}/{total_required} available") if 'optional' in st.session_state.package_test_results: optional_available = sum(1 for r in st.session_state.package_test_results['optional'].values() if r['available']) total_optional = len(st.session_state.package_test_results['optional']) st.write(f"**Optional**: {optional_available}/{total_optional} available") if 'builtin' in st.session_state.package_test_results: builtin_available = sum(1 for r in st.session_state.package_test_results['builtin'].values() if r['available']) total_builtin = len(st.session_state.package_test_results['builtin']) st.write(f"**Built-in**: {builtin_available}/{total_builtin} available") else: st.write("**Status**: Not tested yet") st.info("Click 'Check All Packages' to run analysis") # Display results if available if 'required' in st.session_state.package_test_results: st.subheader("Required Packages for TikTok Analytics POC") for package, info in REQUIRED_PACKAGES.items(): if package in st.session_state.package_test_results['required']: result = st.session_state.package_test_results['required'][package] status_icon, status_msg = get_compatibility_status(result, info.get('min_version')) version_text = "" if result['version']: version_text = f" (v{result['version']})" if info.get('min_version'): version_text += f" [need >={info['min_version']}]" elif result['error']: version_text = f" - {result['error']}" st.write(f"{status_icon} **{package}**: {info['description']}{version_text}") if result['available'] and result['location'] and result['location'] != "Built-in": st.caption(f" ๐Ÿ“ Location: {result['location']}") if 'optional' in st.session_state.package_test_results: st.subheader("Optional Packages") for package, info in OPTIONAL_PACKAGES.items(): if package in st.session_state.package_test_results['optional']: result = st.session_state.package_test_results['optional'][package] status_icon, status_msg = get_compatibility_status(result, info.get('min_version')) version_text = "" if result['version']: version_text = f" (v{result['version']})" if info.get('min_version'): version_text += f" [recommended >={info['min_version']}]" elif result['error']: version_text = f" - {result['error']}" st.write(f"{status_icon} **{package}**: {info['description']}{version_text}") if 'builtin' in st.session_state.package_test_results: st.subheader("Built-in Python Modules") for package, info in BUILTIN_MODULES.items(): if package in st.session_state.package_test_results['builtin']: result = st.session_state.package_test_results['builtin'][package] status_icon, status_msg = get_compatibility_status(result) version_text = "" if result['version']: version_text = f" (v{result['version']})" elif result['error']: version_text = f" - {result['error']}" st.write(f"{status_icon} **{package}**: {info['description']}{version_text}") # Test 4.2: Package Functionality Testing st.header("Test 4.2: Package Functionality Testing") def test_pandas(): """Test pandas functionality""" try: import pandas as pd import numpy as np # Create test DataFrame data = { 'track_id': ['track_001', 'track_002', 'track_003'], 'artist': ['Artist A', 'Artist B', 'Artist C'], 'posts_count': [1500, 2300, 890], 'date_added': pd.to_datetime(['2024-01-15', '2024-01-16', '2024-01-17']) } df = pd.DataFrame(data) # Test basic operations total_posts = df['posts_count'].sum() avg_posts = df['posts_count'].mean() latest_date = df['date_added'].max() return { 'success': True, 'note': f'DataFrame test passed: {len(df)} rows, total posts: {total_posts}, avg: {avg_posts:.0f}', 'details': {'rows': len(df), 'total_posts': total_posts, 'avg_posts': avg_posts} } except Exception as e: return {'success': False, 'note': f'Pandas test failed: {str(e)}', 'details': {}} def test_numpy(): """Test numpy functionality""" try: import numpy as np # Test array creation and operations arr = np.array([1.5, 2.3, 3.7, 4.1, 5.9]) # Basic operations mean_val = np.mean(arr) std_val = np.std(arr) max_val = np.max(arr) # Test mathematical functions log_arr = np.log(arr) sqrt_arr = np.sqrt(arr) return { 'success': True, 'note': f'NumPy test passed: array operations successful, mean: {mean_val:.2f}', 'details': {'mean': mean_val, 'std': std_val, 'max': max_val} } except Exception as e: return {'success': False, 'note': f'NumPy test failed: {str(e)}', 'details': {}} def test_requests(): """Test requests functionality with Container Runtime considerations""" try: import requests import json # Test with HTTPBin (reliable testing endpoint) test_url = "https://httpbin.org/json" response = requests.get(test_url, timeout=10) if response.status_code == 200: data = response.json() return { 'success': True, 'note': f'HTTP request successful: status {response.status_code}, response time: {response.elapsed.total_seconds():.2f}s', 'details': {'status_code': response.status_code, 'response_time': response.elapsed.total_seconds()} } else: return { 'success': False, 'note': f'HTTP request failed with status {response.status_code}', 'details': {'status_code': response.status_code} } except requests.exceptions.Timeout: return {'success': False, 'note': 'HTTP request timed out (may indicate network restrictions)', 'details': {}} except requests.exceptions.ConnectionError: return {'success': False, 'note': 'Connection error (network may be blocked in Container Runtime)', 'details': {}} except Exception as e: return {'success': False, 'note': f'Requests test failed: {str(e)}', 'details': {}} def test_snowflake(): """Test Snowflake connector (connection test only)""" try: import snowflake.connector # Test basic imports and class access connect_func = snowflake.connector.connect errors_module = snowflake.connector.errors # Test parameter validation (without actual connection) try: # This should fail gracefully with missing parameters conn = snowflake.connector.connect() except Exception as expected_error: # This is expected - we don't have connection details pass return { 'success': True, 'note': 'Snowflake connector import successful, classes accessible', 'details': {'version': getattr(snowflake.connector, '__version__', 'unknown')} } except Exception as e: return {'success': False, 'note': f'Snowflake connector test failed: {str(e)}', 'details': {}} def test_json(): """Test built-in json module""" try: import json # Test data structure (similar to TikTok API response) test_data = { 'track_info': { 'id': 'track_12345', 'title': 'Sample Track', 'artist': 'Test Artist', 'posts_count': 1500 }, 'analytics': { 'views': [100, 200, 300, 250, 400], 'engagement_rate': 0.045, 'trending': True } } # Test serialization json_str = json.dumps(test_data) # Test deserialization parsed_data = json.loads(json_str) return { 'success': True, 'note': f'JSON operations successful: serialized {len(json_str)} chars, parsed {len(parsed_data)} keys', 'details': {'serialized_length': len(json_str), 'keys': len(parsed_data)} } except Exception as e: return {'success': False, 'note': f'JSON test failed: {str(e)}', 'details': {}} def test_datetime(): """Test datetime module""" try: from datetime import datetime, timedelta import time # Test current time operations now = datetime.now() yesterday = now - timedelta(days=1) # Test formatting (important for API timestamps) iso_format = now.isoformat() str_format = now.strftime('%Y-%m-%d %H:%M:%S') # Test parsing parsed = datetime.fromisoformat(iso_format) return { 'success': True, 'note': f'DateTime operations successful: current time formatted as {str_format}', 'details': {'current_time': str_format, 'iso_format': iso_format} } except Exception as e: return {'success': False, 'note': f'DateTime test failed: {str(e)}', 'details': {}} def test_re(): """Test regex module (important for data cleaning)""" try: import re # Test patterns relevant to TikTok data test_text = "Check out this track: https://www.tiktok.com/music/sample-track-123456789 #trending #music" # Extract TikTok URL url_pattern = r'https://www\.tiktok\.com/music/[\w-]+' urls = re.findall(url_pattern, test_text) # Extract hashtags hashtag_pattern = r'#\w+' hashtags = re.findall(hashtag_pattern, test_text) # Clean/normalize text clean_text = re.sub(r'[^\w\s#]', '', test_text) return { 'success': True, 'note': f'Regex operations successful: found {len(urls)} URLs, {len(hashtags)} hashtags', 'details': {'urls_found': len(urls), 'hashtags_found': len(hashtags)} } except Exception as e: return {'success': False, 'note': f'Regex test failed: {str(e)}', 'details': {}} # Testing interface col1, col2 = st.columns(2) with col1: if st.button("๐Ÿงช Run Functionality Tests", type="primary"): st.info("โณ Testing package functionality...") # Only test packages that are available test_functions = { 'pandas': test_pandas, 'numpy': test_numpy, 'requests': test_requests, 'snowflake-connector-python': test_snowflake, 'json': test_json, 'datetime': test_datetime, 're': test_re } st.session_state.functionality_results = {} for package_name, test_func in test_functions.items(): # Check if package is available before testing package_available = False if package_name in ['json', 'datetime', 're']: # Built-in modules if 'builtin' in st.session_state.package_test_results: package_available = st.session_state.package_test_results['builtin'].get(package_name, {}).get('available', False) else: # External packages if 'required' in st.session_state.package_test_results: package_available = st.session_state.package_test_results['required'].get(package_name, {}).get('available', False) if not package_available and 'optional' in st.session_state.package_test_results: package_available = st.session_state.package_test_results['optional'].get(package_name, {}).get('available', False) if package_available: result = test_func() st.session_state.functionality_results[package_name] = result else: st.session_state.functionality_results[package_name] = { 'success': False, 'note': 'Package not available - skipping test', 'details': {} } st.success("โœ… Functionality tests complete!") with col2: if st.session_state.functionality_results: st.subheader("๐Ÿ“Š Test Summary") total_tests = len(st.session_state.functionality_results) successful_tests = sum(1 for r in st.session_state.functionality_results.values() if r['success']) st.write(f"**Tests Run**: {total_tests}") st.write(f"**Successful**: {successful_tests}") st.write(f"**Failed**: {total_tests - successful_tests}") if successful_tests == total_tests: st.success("๐ŸŽ‰ All tests passed!") elif successful_tests >= total_tests * 0.8: st.warning("โš ๏ธ Most tests passed") else: st.error("โŒ Several tests failed") # Display detailed results if st.session_state.functionality_results: st.subheader("Detailed Test Results") for package_name, result in st.session_state.functionality_results.items(): status_icon = "โœ…" if result['success'] else "โŒ" st.write(f"{status_icon} **{package_name}**: {result['note']}") # Show additional details for successful tests if result['success'] and result.get('details'): with st.expander(f"View {package_name} test details"): for key, value in result['details'].items(): st.write(f"- **{key}**: {value}") # Test 4.3: Python Environment and Container Runtime Analysis st.header("Test 4.3: Python Environment and Container Runtime Analysis") col1, col2 = st.columns(2) with col1: st.subheader("Python Environment Details") st.write(f"**Python Version**: {sys.version.split()[0]}") st.write(f"**Python Build**: {sys.version.split('(')[1].split(')')[0] if '(' in sys.version else 'Unknown'}") st.write(f"**Platform**: {sys.platform}") st.write(f"**Architecture**: {sys.maxsize > 2**32 and '64-bit' or '32-bit'}") # Container Runtime specific checks st.subheader("Container Runtime Analysis") # Check for container indicators container_indicators = [] try: if '/site-packages' in sys.executable: container_indicators.append("Virtual environment detected") if 'streamlit' in sys.executable.lower(): container_indicators.append("Streamlit runtime environment") if len(sys.path) > 10: container_indicators.append(f"Extended Python path ({len(sys.path)} entries)") except: pass if container_indicators: for indicator in container_indicators: st.write(f"โœ“ {indicator}") else: st.write("โšช Standard Python environment") with col2: st.subheader("Python Path Analysis") st.write(f"**Total Path Entries**: {len(sys.path)}") st.write("**Key Paths (first 5):**") for i, path in enumerate(sys.path[:5]): short_path = path[-50:] if len(path) > 50 else path st.write(f"{i+1}. ...{short_path}" if len(path) > 50 else f"{i+1}. {short_path}") if len(sys.path) > 5: st.write(f"... and {len(sys.path) - 5} more paths") # Memory and performance info st.subheader("Runtime Constraints") try: import os if hasattr(os, 'getloadavg'): load_avg = os.getloadavg() st.write(f"**System Load**: {load_avg[0]:.2f}") else: st.write("**System Load**: Not available") except: st.write("**System Load**: Cannot determine") st.write(f"**Max Integer**: {sys.maxsize}") # Test 4.4: Pip Functionality and Container Runtime Constraints st.header("Test 4.4: Pip Functionality and Container Runtime Constraints") def test_pip_constraints(): """Test pip functionality within Container Runtime constraints""" constraints = {} # Test pip availability try: import pip constraints['pip_available'] = True constraints['pip_version'] = getattr(pip, '__version__', 'Unknown') except ImportError: try: # Try alternative pip import import subprocess result = subprocess.run([sys.executable, '-m', 'pip', '--version'], capture_output=True, text=True, timeout=5) constraints['pip_available'] = result.returncode == 0 constraints['pip_version'] = result.stdout.split()[1] if result.returncode == 0 else 'Unknown' except: constraints['pip_available'] = False constraints['pip_version'] = 'Not available' # Test write permissions try: import tempfile with tempfile.NamedTemporaryFile(mode='w', delete=True) as f: f.write('test') constraints['write_permissions'] = True except: constraints['write_permissions'] = False # Test network access capability constraints['network_test'] = 'requests' in st.session_state.functionality_results and \ st.session_state.functionality_results['requests'].get('success', False) return constraints col1, col2 = st.columns(2) with col1: if st.button("๐Ÿ”ง Test Container Constraints"): st.info("โณ Testing Container Runtime constraints...") constraints = test_pip_constraints() st.session_state.container_constraints = constraints st.success("โœ… Constraint analysis complete!") with col2: if 'container_constraints' in st.session_state: st.subheader("Container Runtime Constraints") constraints = st.session_state.container_constraints pip_status = "โœ…" if constraints['pip_available'] else "โŒ" st.write(f"{pip_status} **Pip Available**: {constraints['pip_version']}") write_status = "โœ…" if constraints['write_permissions'] else "โŒ" st.write(f"{write_status} **Write Permissions**: {'Yes' if constraints['write_permissions'] else 'No'}") network_status = "โœ…" if constraints['network_test'] else "โŒ" st.write(f"{network_status} **Network Access**: {'Yes' if constraints['network_test'] else 'Limited'}") # Test 4.5: Requirements Generation and Installation Commands st.header("Test 4.5: Requirements Generation and Installation Strategy") def generate_requirements_advanced(): """Generate comprehensive requirements with version constraints""" if 'required' not in st.session_state.package_test_results: return "# Run package analysis first\n" requirements = ["# TikTok Music Analytics POC - Requirements", "# Generated by Container Runtime Test", ""] # Critical packages requirements.append("# Critical packages for TikTok analytics") for package, info in REQUIRED_PACKAGES.items(): result = st.session_state.package_test_results['required'].get(package, {}) if result.get('available'): version = result.get('version') if version and info.get('min_version'): # Use current version as minimum if it's higher than specified minimum requirements.append(f"{package}>={version} # Found v{version}") elif info.get('min_version'): requirements.append(f"{package}>={info['min_version']} # Minimum required") else: requirements.append(f"{package} # Latest") else: min_version = info.get('min_version', '') if min_version: requirements.append(f"{package}>={min_version} # NOT FOUND - install required") else: requirements.append(f"{package} # NOT FOUND - install required") # Optional packages requirements.append("") requirements.append("# Optional packages for enhanced functionality") for package, info in OPTIONAL_PACKAGES.items(): result = st.session_state.package_test_results['optional'].get(package, {}) if result.get('available'): version = result.get('version') if version: requirements.append(f"{package}>={version} # Optional - found v{version}") else: requirements.append(f"{package} # Optional - available") else: min_version = info.get('min_version', '') if min_version: requirements.append(f"# {package}>={min_version} # Optional - not found") else: requirements.append(f"# {package} # Optional - not found") return "\n".join(requirements) col1, col2 = st.columns(2) with col1: if st.button("๐Ÿ“ Generate Requirements File"): if 'required' in st.session_state.package_test_results: requirements_content = generate_requirements_advanced() st.session_state.requirements_content = requirements_content st.success("โœ… Requirements file generated!") else: st.warning("โš ๏ธ Please run package analysis first") with col2: if 'requirements_content' in st.session_state: st.download_button( label="๐Ÿ“ฅ Download requirements.txt", data=st.session_state.requirements_content, file_name=f"spark_poc_requirements_{datetime.now().strftime('%Y%m%d_%H%M')}.txt", mime="text/plain", help="Download requirements file with version constraints" ) if 'requirements_content' in st.session_state: st.subheader("Generated Requirements File") st.code(st.session_state.requirements_content, language="text") # Installation strategy based on constraints st.subheader("Installation Strategy") if 'required' in st.session_state.package_test_results: missing_critical = [] missing_optional = [] for package, result in st.session_state.package_test_results['required'].items(): if not result['available']: missing_critical.append(package) for package, result in st.session_state.package_test_results['optional'].items(): if not result['available']: missing_optional.append(package) if missing_critical or missing_optional: st.write("**Recommended installation commands:**") if missing_critical: st.write("1. **Install critical packages first:**") critical_cmd = f"pip install {' '.join(missing_critical)}" st.code(critical_cmd, language="bash") if missing_optional: st.write("2. **Install optional packages:**") optional_cmd = f"pip install {' '.join(missing_optional)}" st.code(optional_cmd, language="bash") # Container Runtime specific notes if 'container_constraints' in st.session_state: constraints = st.session_state.container_constraints if not constraints.get('pip_available'): st.error("โš ๏ธ **Warning**: Pip not available in Container Runtime") st.write("Packages may need to be pre-installed in the environment") elif not constraints.get('write_permissions'): st.warning("โš ๏ธ **Warning**: Limited write permissions detected") st.write("Consider using --user flag: `pip install --user package_name`") else: st.success("โœ… All packages are available - no installation needed!") # Test Results Summary and Assessment st.header("๐ŸŽฏ Container Runtime Readiness Assessment") if 'required' in st.session_state.package_test_results: col1, col2, col3 = st.columns(3) # Calculate statistics required_available = sum(1 for r in st.session_state.package_test_results['required'].values() if r['available']) total_required = len(st.session_state.package_test_results['required']) optional_available = sum(1 for r in st.session_state.package_test_results['optional'].values() if r['available']) total_optional = len(st.session_state.package_test_results['optional']) builtin_available = sum(1 for r in st.session_state.package_test_results['builtin'].values() if r['available']) total_builtin = len(st.session_state.package_test_results['builtin']) functionality_success = sum(1 for r in st.session_state.functionality_results.values() if r['success']) if st.session_state.functionality_results else 0 total_functionality = len(st.session_state.functionality_results) if st.session_state.functionality_results else 0 with col1: st.metric("Required Packages", f"{required_available}/{total_required}", f"{(required_available/total_required*100):.0f}%" if total_required > 0 else "0%") st.metric("Built-in Modules", f"{builtin_available}/{total_builtin}", f"{(builtin_available/total_builtin*100):.0f}%" if total_builtin > 0 else "0%") with col2: st.metric("Optional Packages", f"{optional_available}/{total_optional}", f"{(optional_available/total_optional*100):.0f}%" if total_optional > 0 else "0%") if total_functionality > 0: st.metric("Functionality Tests", f"{functionality_success}/{total_functionality}", f"{(functionality_success/total_functionality*100):.0f}%") with col3: # Overall readiness score readiness_score = 0 if total_required > 0: readiness_score += (required_available / total_required) * 0.6 # 60% weight if total_builtin > 0: readiness_score += (builtin_available / total_builtin) * 0.3 # 30% weight if total_optional > 0: readiness_score += (optional_available / total_optional) * 0.1 # 10% weight readiness_percentage = readiness_score * 100 st.metric("Overall Readiness", f"{readiness_percentage:.0f}%") # Readiness assessment if readiness_percentage >= 90: st.success("๐ŸŽ‰ **READY** for development!") elif readiness_percentage >= 70: st.warning("โš ๏ธ **MOSTLY READY** - minor issues") else: st.error("โŒ **NOT READY** - major issues") # Final notes section st.header("๐Ÿ“‹ Package Test Summary and Recommendations") if 'required' in st.session_state.package_test_results: # Create recommendations based on test results recommendations = [] missing_critical = [pkg for pkg, result in st.session_state.package_test_results['required'].items() if not result['available']] if missing_critical: recommendations.append(f"๐Ÿ”ด **Critical**: Install missing packages: {', '.join(missing_critical)}") version_issues = [pkg for pkg, result in st.session_state.package_test_results['required'].items() if result['available'] and result.get('version_compatible') is False] if version_issues: recommendations.append(f"๐ŸŸก **Version**: Update packages with version conflicts: {', '.join(version_issues)}") if 'container_constraints' in st.session_state: constraints = st.session_state.container_constraints if not constraints.get('network_test'): recommendations.append("๐Ÿ”ต **Network**: Limited network access detected - may affect API functionality") if not constraints.get('pip_available'): recommendations.append("๐Ÿ”ต **Environment**: Pip not available - packages must be pre-installed") if st.session_state.functionality_results: failed_tests = [pkg for pkg, result in st.session_state.functionality_results.items() if not result['success'] and 'not available' not in result['note']] if failed_tests: recommendations.append(f"๐ŸŸ  **Functionality**: Package functionality issues: {', '.join(failed_tests)}") if recommendations: st.write("**Key Recommendations:**") for rec in recommendations: st.write(rec) else: st.success("๐ŸŽ‰ **All tests passed!** Container Runtime is ready for TikTok music analytics POC development.") # Notes section st.subheader("๐Ÿ“ Test Notes and Observations") notes_placeholder = """Container Runtime observations: - Package installation capabilities - Network access limitations - Version compatibility issues - Performance considerations - Alternative package suggestions - Workaround strategies""" test_notes = st.text_area( "Record your observations about the Container Runtime environment:", placeholder=notes_placeholder, height=120, key="package_test_notes" ) if test_notes: st.info("๐Ÿ’ก **Tip**: Save these notes for reference when setting up the production environment.")