Spaces:
Running
Running
| import importlib | |
| import inspect | |
| from typing import TYPE_CHECKING, get_type_hints | |
| from cachetools import LRUCache, cached | |
| from loguru import logger | |
| from langflow.services.schema import ServiceType | |
| if TYPE_CHECKING: | |
| from langflow.services.base import Service | |
| class ServiceFactory: | |
| def __init__( | |
| self, | |
| service_class, | |
| ) -> None: | |
| self.service_class = service_class | |
| self.dependencies = infer_service_types(self, import_all_services_into_a_dict()) | |
| def create(self, *args, **kwargs) -> "Service": | |
| raise self.service_class(*args, **kwargs) | |
| def hash_factory(factory: ServiceFactory) -> str: | |
| return factory.service_class.__name__ | |
| def hash_dict(d: dict) -> str: | |
| return str(d) | |
| def hash_infer_service_types_args(factory: ServiceFactory, available_services=None) -> str: | |
| factory_hash = hash_factory(factory) | |
| services_hash = hash_dict(available_services) | |
| return f"{factory_hash}_{services_hash}" | |
| def infer_service_types(factory: ServiceFactory, available_services=None) -> list["ServiceType"]: | |
| create_method = factory.create | |
| type_hints = get_type_hints(create_method, globalns=available_services) | |
| service_types = [] | |
| for param_name, param_type in type_hints.items(): | |
| # Skip the return type if it's included in type hints | |
| if param_name == "return": | |
| continue | |
| # Convert the type to the expected enum format directly without appending "_SERVICE" | |
| type_name = param_type.__name__.upper().replace("SERVICE", "_SERVICE") | |
| try: | |
| # Attempt to find a matching enum value | |
| service_type = ServiceType[type_name] | |
| service_types.append(service_type) | |
| except KeyError as e: | |
| msg = f"No matching ServiceType for parameter type: {param_type.__name__}" | |
| raise ValueError(msg) from e | |
| return service_types | |
| def import_all_services_into_a_dict(): | |
| # Services are all in langflow.services.{service_name}.service | |
| # and are subclass of Service | |
| # We want to import all of them and put them in a dict | |
| # to use as globals | |
| from langflow.services.base import Service | |
| services = {} | |
| for service_type in ServiceType: | |
| try: | |
| service_name = ServiceType(service_type).value.replace("_service", "") | |
| module_name = f"langflow.services.{service_name}.service" | |
| module = importlib.import_module(module_name) | |
| services.update( | |
| { | |
| name: obj | |
| for name, obj in inspect.getmembers(module, inspect.isclass) | |
| if issubclass(obj, Service) and obj is not Service | |
| } | |
| ) | |
| except Exception as exc: | |
| logger.exception(exc) | |
| msg = "Could not initialize services. Please check your settings." | |
| raise RuntimeError(msg) from exc | |
| return services | |