Spaces:
Running
Running
| #!/usr/bin/env python3 | |
| """AION Search - Galaxy Semantic Search Application. | |
| A Dash web application for semantic search over galaxy images using CLIP embeddings. | |
| """ | |
| import os | |
| import logging | |
| import argparse | |
| # Fix OpenMP conflict - MUST be set before importing torch/numpy | |
| os.environ['KMP_DUPLICATE_LIB_OK'] = 'TRUE' | |
| import dash | |
| import dash_bootstrap_components as dbc | |
| import src.config as config | |
| from src.config import FEATURE_VECTOR_ADDITION | |
| from src.components import get_app_theme, create_layout | |
| from src.services import CLIPModelService, EmbeddingService, ZillizService, SearchService, ImageProcessingService | |
| from src.callbacks import register_callbacks | |
| # Set up logging | |
| logging.basicConfig( | |
| level=logging.INFO, | |
| format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' | |
| ) | |
| logger = logging.getLogger(__name__) | |
| def create_app(checkpoint_path: str) -> dash.Dash: | |
| """Create and configure the Dash application. | |
| Args: | |
| checkpoint_path: Path to the CLIP model checkpoint | |
| Returns: | |
| Configured Dash app instance | |
| """ | |
| # Initialize Dash app | |
| app = dash.Dash( | |
| __name__, | |
| external_stylesheets=[dbc.themes.BOOTSTRAP, dbc.icons.FONT_AWESOME], | |
| suppress_callback_exceptions=True | |
| ) | |
| server = app.server | |
| # Set custom theme | |
| app.index_string = get_app_theme() | |
| # Set app title | |
| app.title = "AION Galaxy Search" | |
| # Initialize services | |
| logger.info("Initializing services...") | |
| # Load CLIP model | |
| clip_service = CLIPModelService() | |
| clip_service.load_model(checkpoint_path) | |
| # Create service instances | |
| embedding_service = EmbeddingService(clip_service) | |
| zilliz_service = ZillizService() | |
| # Initialize image processing service for advanced search | |
| # (now uses pre-existing embeddings from Zilliz, no model loading needed) | |
| image_service = ImageProcessingService() | |
| logger.info("Image processing service initialized successfully") | |
| search_service = SearchService(embedding_service, zilliz_service, image_service) | |
| # Get actual count from Zilliz and update config | |
| actual_count = zilliz_service.get_collection_count() | |
| if actual_count > 0: | |
| config.TOTAL_GALAXIES = actual_count | |
| logger.info(f"Services initialized. Total galaxies: {config.TOTAL_GALAXIES:,}") | |
| else: | |
| logger.warning(f"Failed to get collection count from Zilliz, using default: {config.TOTAL_GALAXIES:,}") | |
| # Create app layout | |
| app.layout = create_layout() | |
| # Register callbacks | |
| register_callbacks(app, search_service) | |
| logger.info("App initialization complete!") | |
| return app | |
| def main(): | |
| """Main entry point for the application.""" | |
| parser = argparse.ArgumentParser(description='AION Galaxy Search App') | |
| parser.add_argument( | |
| '--checkpoint', | |
| type=str, | |
| default='aionsearchmodel.pt', | |
| help='Path to CLIP model checkpoint' | |
| ) | |
| parser.add_argument( | |
| '--port', | |
| type=int, | |
| default=7860, | |
| help='Port to run the app on' | |
| ) | |
| parser.add_argument( | |
| '--debug', | |
| action='store_true', | |
| help='Run in debug mode' | |
| ) | |
| parser.add_argument( | |
| '--host', | |
| type=str, | |
| default='0.0.0.0', | |
| help='Host to run the app on' | |
| ) | |
| args = parser.parse_args() | |
| # Create and run app | |
| logger.info("Starting AION Galaxy Search...") | |
| app = create_app(args.checkpoint) | |
| logger.info(f"Server starting on {args.host}:{args.port}") | |
| app.run_server( | |
| debug=args.debug, | |
| host=args.host, | |
| port=args.port | |
| ) | |
| app = create_app('aionsearchmodel.pt') | |
| server = app.server | |
| if __name__ == "__main__": | |
| main() | |