Hooks ===== This example is an enhanced version of the HelloWorld example that uses service 'hooks' to apply cross-cutting behavior to the service. In this example, the service hooks are used to gather performance information on both the method execution as well as the duration of the entire call, including serialization and deserialization. The available hooks are: * :py:meth:`~soaplib.core.service.DefinitionBase.on_call` This is the first thing called in the service * :py:meth:`soaplib.core.service.DefinitionBase.on_wsdl` Called before the wsdl is requested * :py:meth:`~soaplib.core.service.DefinitionBase.on_wsdl_exception` Called after an exception was thrown when generating the wsdl (shouldn't happen very much) * :py:meth:`~soaplib.core.service.DefinitionBase.on_method_call` Called right before the service method is executed * :py:meth:`~soaplib.core.service.DefinitionBase.on_method_return` Called right after the service method is executed * :py:meth:`~soaplib.core.service.DefinitionBase.on_method_exception_object` Called when an exception occurred in a service method before the exception is serialized. * :py:meth:`~soaplib.core.service.DefinitionBase.on_method_exception_xml` Called after an exception occurred in either the service method or in serialization * :py:meth:`~soaplib.core.service.DefinitionBase.on_return` This is the very last thing called before the wsgi app exits These method can be used to easily apply cross-cutting functionality accross all methods in the service to do things like database transaction management, logging and measuring performance. This example also employs the threadlocal request (soaplib.core.wsgi_soap.request) object to hold the data points for this request. :: from soaplib.core.service import rpc, DefinitionBase from soaplib.core.model.primitive import String, Integer from soaplib.core.model.clazz import Array from time import time class HelloWorldService(DefinitionBase): @soap(String,Integer,_returns=Array(String)) def say_hello(self,name,times): results = [] for i in range(0,times): results.append('Hello, %s'%name) return results def on_call(self,environ): request.additional['call_start'] = time() def on_method_exec(self,environ,body,py_params,soap_params): request.additional['method_start'] = time() def on_results(self,environ,py_results,soap_results,http_headers): request.additional['method_end'] = time() def on_return(self,environ,returnString): call_start = request.additional['call_start'] call_end = time() method_start = request.additional['method_start'] method_end = request.additional['method_end'] print 'Method took [%s] - total execution time[%s]'%(method_end-method_start,call_end-call_start) if __name__=='__main__': from wsgiref.simple_server import make_server server = make_server('localhost', 7789, Application([HelloWorldService])) server.serve_forever() Running this produces:: Method took [0.000195980072021] - total execution time[0.00652194023132] Method took [0.000250101089478] - total execution time[0.00567507743835] Method took [0.000144004821777] - total execution time[0.00521206855774] Method took [0.000141859054565] - total execution time[0.00512409210205] Method took [0.00377607345581] - total execution time[0.00511980056763] Method took [0.00118803977966] - total execution time[0.00673604011536] Method took [0.000146150588989] - total execution time[0.00157499313354] Method took [0.0231170654297] - total execution time[0.0245010852814] Method took [0.000166893005371] - total execution time[0.01802110672] These may be helpful in finding bottlenecks in process, but this technique can also be used to commit/rollback transactions or do setup/teardown operations for all methods in a service.