@@ -85,10 +85,12 @@ def register_service(self, namespace: str, domain: str, service: str, callback:
8585 name = kwargs .get ("__name" )
8686 # first we confirm if the namespace exists
8787 if name and namespace not in self .AD .state .state :
88- raise NamespaceException (f"Namespace { namespace } , doesn't exist" )
88+ raise NamespaceException (
89+ f"Namespace { namespace } , doesn't exist" )
8990
9091 elif not callable (callback ):
91- raise ValueError (f"The given callback { callback } is not a callable function" )
92+ raise ValueError (f"The given callback {
93+ callback } is not a callable function" )
9294
9395 if namespace not in self .services :
9496 self .services [namespace ] = {}
@@ -99,27 +101,32 @@ def register_service(self, namespace: str, domain: str, service: str, callback:
99101 if service in self .services [namespace ][domain ]:
100102 # there was a service already registered before
101103 # so if a different app, we ask to deregister first
102- service_app = self .services [namespace ][domain ][service ].get ("__name" )
104+ service_app = self .services [namespace ][domain ][service ].get (
105+ "__name" )
103106 if service_app and service_app != name :
104107 self .logger .warning (
105- f"This service '{ domain } /{ service } ' already registered to a different app '{ service_app } ', and so cannot be registered to { name } . Do deregister from app first"
108+ f"This service '{ domain } /{ service } ' already registered to a different app '{
109+ service_app } ', and so cannot be registered to { name } . Do deregister from app first"
106110 )
107111 return
108112
109- self .services [namespace ][domain ][service ] = {"callback" : callback , "__name" : name , ** kwargs }
113+ self .services [namespace ][domain ][service ] = {
114+ "callback" : callback , "__name" : name , ** kwargs }
110115
111116 if __silent is False :
112117 data = {
113118 "event_type" : "service_registered" ,
114119 "data" : {"namespace" : namespace , "domain" : domain , "service" : service },
115120 }
116- self .AD .loop .create_task (self .AD .events .process_event (namespace , data ))
121+ self .AD .loop .create_task (
122+ self .AD .events .process_event (namespace , data ))
117123
118124 if name :
119125 if name not in self .app_registered_services :
120126 self .app_registered_services [name ] = set ()
121127
122- self .app_registered_services [name ].add (f"{ namespace } :{ domain } :{ service } " )
128+ self .app_registered_services [name ].add (
129+ f"{ namespace } :{ domain } :{ service } " )
123130
124131 def deregister_service (self , namespace : str , domain : str , service : str , __name : str ) -> bool :
125132 """Used to unregister a service"""
@@ -133,12 +140,14 @@ def deregister_service(self, namespace: str, domain: str, service: str, __name:
133140 )
134141
135142 if __name not in self .app_registered_services :
136- raise ValueError (f"The given App { __name } has no services registered" )
143+ raise ValueError (f"The given App {
144+ __name } has no services registered" )
137145
138146 app_service = f"{ namespace } :{ domain } :{ service } "
139147
140148 if app_service not in self .app_registered_services [__name ]:
141- raise ValueError (f"The given App { __name } doesn't have the given service registered it" )
149+ raise ValueError (f"The given App {
150+ __name } doesn't have the given service registered it" )
142151
143152 # if it gets here, then time to deregister
144153 with self .services_lock :
@@ -149,7 +158,8 @@ def deregister_service(self, namespace: str, domain: str, service: str, __name:
149158 "event_type" : "service_deregistered" ,
150159 "data" : {"namespace" : namespace , "domain" : domain , "service" : service , "app" : __name },
151160 }
152- self .AD .loop .create_task (self .AD .events .process_event (namespace , data ))
161+ self .AD .loop .create_task (
162+ self .AD .events .process_event (namespace , data ))
153163
154164 # now check if that domain is empty
155165 # if it is, remove it also
@@ -192,29 +202,37 @@ def list_services(self, ns: str = "global") -> list[dict[str, str]]:
192202 ]
193203
194204 async def call_service (
195- self ,
196- namespace : str ,
197- domain : str ,
198- service : str ,
199- name : str | None = None ,
200- data : dict [str , Any ] | None = None , # Don't expand with **data
201- ) -> Any :
205+ self ,
206+ namespace : str ,
207+ domain : str ,
208+ service : str ,
209+ name : str | None = None ,
210+ data : dict [str , Any ] | None = None , # Don't expand with **data
211+ ) -> Any :
202212 self .logger .debug (
203213 "call_service: namespace=%s domain=%s service=%s data=%s" ,
204214 namespace ,
205215 domain ,
206216 service ,
207217 data ,
208218 )
219+
220+ # data can be None, later on we assume it is not!
221+ if data is None :
222+ data = {}
223+
209224 with self .services_lock :
210225 if namespace not in self .services :
211- raise NamespaceException (f"Unknown namespace { namespace } in call_service from { name } " )
226+ raise NamespaceException (f"Unknown namespace {
227+ namespace } in call_service from { name } " )
212228
213229 if domain not in self .services [namespace ]:
214- raise DomainException (f"Unknown domain ({ namespace } /{ domain } ) in call_service from { name } " )
230+ raise DomainException (
231+ f"Unknown domain ({ namespace } /{ domain } ) in call_service from { name } " )
215232
216233 if service not in self .services [namespace ][domain ]:
217- raise ServiceException (f"Unknown service ({ namespace } /{ domain } /{ service } ) in call_service from { name } " )
234+ raise ServiceException (
235+ f"Unknown service ({ namespace } /{ domain } /{ service } ) in call_service from { name } " )
218236
219237 # If we have namespace in data it's an override for the domain of the eventual service call, as distinct
220238 # from the namespace the call itself is executed from. e.g. set_state() is in the AppDaemon namespace but
@@ -230,9 +248,10 @@ async def call_service(
230248 match isasync := service_def .pop ("__async" , 'auto' ):
231249 case 'auto' :
232250 # Remove any wrappers from the funcref before determining if it's async or not
233- isasync = asyncio .iscoroutinefunction (utils .unwrapped (funcref ))
251+ isasync = asyncio .iscoroutinefunction (
252+ utils .unwrapped (funcref ))
234253 case bool ():
235- pass # isasync already set as a bool from above
254+ pass # isasync already set as a bool from above
236255 case _:
237256 raise TypeError (f'Invalid __async type: { isasync } ' )
238257
@@ -247,9 +266,11 @@ async def call_service(
247266 else :
248267 # It's not a coroutine, run it in an executor
249268 if use_dictionary_unpacking :
250- coro = utils .run_in_executor (self , funcref , ns , domain , service , ** data )
269+ coro = utils .run_in_executor (
270+ self , funcref , ns , domain , service , ** data )
251271 else :
252- coro = utils .run_in_executor (self , funcref , ns , domain , service , data )
272+ coro = utils .run_in_executor (
273+ self , funcref , ns , domain , service , data )
253274
254275 @utils .warning_decorator (error_text = f"Unexpected error calling service { ns } /{ domain } /{ service } " )
255276 async def safe_service (self : 'Services' ):
0 commit comments