1313#
1414# You should have received a copy of the GNU Lesser General Public
1515# License along with this library.
16+ import octobot_services .api .service_feeds as service_feeds_api
1617import octobot_services .managers as managers
1718import octobot_services .services as services
1819import octobot_services .interfaces as interfaces
@@ -31,9 +32,57 @@ def _service_async_lock(service_class):
3132 return _SERVICE_ASYNC_LOCKS [service_class .__name__ ]
3233
3334
34- def get_available_services () -> list :
35+ def get_available_services () -> list [ type [ services . AbstractService ]] :
3536 return services .ServiceFactory .get_available_services ()
3637
38+ def get_available_ai_services () -> list [type [services .AbstractAIService ]]:
39+ return services .ServiceFactory .get_available_ai_services ()
40+
41+ def get_available_web_search_services () -> list [type [services .AbstractWebSearchService ]]:
42+ return services .ServiceFactory .get_available_web_search_services ()
43+
44+
45+ def get_available_backtestable_services () -> list :
46+ return [
47+ service_class for service_class in services .ServiceFactory .get_available_services ()
48+ if service_class .BACKTESTING_ENABLED
49+ ]
50+
51+ async def _get_available_service_instance (
52+ get_available_services_func ,
53+ service_type_name : str ,
54+ is_backtesting : bool = False
55+ ):
56+ available_services = get_available_services_func ()
57+ for service_class in available_services :
58+ try :
59+ return await get_service (service_class , is_backtesting , None )
60+ except errors .CreationError :
61+ # Service is not running/initialized, skip it
62+ continue
63+ raise errors .CreationError (f"No { service_type_name } is currently running or available." )
64+
65+ async def get_ai_service (is_backtesting = False ) -> services .AbstractAIService :
66+ return await _get_available_service_instance (
67+ get_available_ai_services ,
68+ "AI service" ,
69+ is_backtesting
70+ )
71+
72+ async def get_web_search_service (is_backtesting = False ) -> services .AbstractWebSearchService :
73+ return await _get_available_service_instance (
74+ get_available_web_search_services ,
75+ "web search service" ,
76+ is_backtesting
77+ )
78+
79+
80+ def is_service_available_in_backtesting (service_class ) -> bool :
81+ return (
82+ service_class .BACKTESTING_ENABLED
83+ or service_feeds_api .is_service_used_by_backtestable_feed (service_class )
84+ )
85+
3786
3887async def get_service (service_class , is_backtesting , config = None ):
3988 # prevent concurrent access when creating a service
@@ -47,7 +96,7 @@ async def get_service(service_class, is_backtesting, config=None):
4796 )
4897 if created :
4998 service = service_class .instance ()
50- if is_backtesting and not service . BACKTESTING_ENABLED :
99+ if is_backtesting and not is_service_available_in_backtesting ( service_class ) :
51100 raise errors .UnavailableInBacktestingError (
52101 f"{ service_class .__name__ } service is not available in backtesting"
53102 )
0 commit comments