# Copyright (c) 2022 Kyle Schouviller (https://github.com/kyle0654) import os from types import ModuleType from invokeai.app.services.database.images.sqlite_images_db_service import ( SqliteImageDb, ) from invokeai.app.services.urls import LocalUrlService import invokeai.backend.util.logging as logger from ..services.default_graphs import create_system_graphs from ..services.latent_storage import DiskLatentsStorage, ForwardCacheLatentsStorage from ..services.model_manager_initializer import get_model_manager from ..services.restoration_services import RestorationServices from ..services.graph import GraphExecutionState, LibraryGraph from ..services.image_storage import DiskImageStorage from ..services.invocation_queue import MemoryInvocationQueue from ..services.invocation_services import InvocationServices from ..services.invoker import Invoker from ..services.processor import DefaultInvocationProcessor from ..services.sqlite import SqliteItemStorage from ..services.metadata import PngMetadataService from ..services.results import SqliteResultsService from .events import FastAPIEventService # TODO: is there a better way to achieve this? def check_internet() -> bool: """ Return true if the internet is reachable. It does this by pinging huggingface.co. """ import urllib.request host = "http://huggingface.co" try: urllib.request.urlopen(host, timeout=1) return True except: return False class ApiDependencies: """Contains and initializes all dependencies for the API""" invoker: Invoker = None def initialize(config, event_handler_id: int, logger: types.ModuleType=logger): logger.info(f"Internet connectivity is {config.internet_available}") events = FastAPIEventService(event_handler_id) output_folder = os.path.abspath( os.path.join(os.path.dirname(__file__), "../../../../outputs") ) latents = ForwardCacheLatentsStorage( DiskLatentsStorage(f"{output_folder}/latents") ) metadata = PngMetadataService() urls = LocalUrlService() images = DiskImageStorage(f"{output_folder}/images", metadata_service=metadata) # TODO: build a file/path manager? db_location = os.path.join(output_folder, "invokeai.db") graph_execution_manager = SqliteItemStorage[GraphExecutionState]( filename=db_location, table_name="graph_executions" ) images_db = SqliteImageDb(filename=db_location) # register event handler to update the `results` table when a graph execution state is inserted or updated # graph_execution_manager.on_changed(results.handle_graph_execution_state_change) services = InvocationServices( model_manager=get_model_manager(config, logger), events=events, latents=latents, images=images, metadata=metadata, images_db=images_db, urls=urls, queue=MemoryInvocationQueue(), graph_library=SqliteItemStorage[LibraryGraph]( filename=db_location, table_name="graphs" ), graph_execution_manager=graph_execution_manager, processor=DefaultInvocationProcessor(), restoration=RestorationServices(config,logger), configuration=config, logger=logger, ) create_system_graphs(services.graph_library) ApiDependencies.invoker = Invoker(services) @staticmethod def shutdown(): if ApiDependencies.invoker: ApiDependencies.invoker.stop()