def define_service(service_descriptor, module): """Define a new service proxy. Args: service_descriptor: ServiceDescriptor class that describes the service. module: Module to add service to. Request and response types are found relative to this module. Returns: Service class proxy capable of communicating with a remote server. """ class_dict = {'__module__': module.__name__} class_name = service_descriptor.name.encode('utf-8') for method_descriptor in service_descriptor.methods or []: request_definition = messages.find_definition( method_descriptor.request_type, module) response_definition = messages.find_definition( method_descriptor.response_type, module) method_name = method_descriptor.name.encode('utf-8') def remote_method(self, request): """Actual service method.""" raise NotImplementedError('Method is not implemented') remote_method.__name__ = method_name remote_method_decorator = remote.method(request_definition, response_definition) class_dict[method_name] = remote_method_decorator(remote_method) service_class = type(class_name, (remote.Service,), class_dict) return service_class
def define_service(service_descriptor, module): """Define a new service proxy. Args: service_descriptor: ServiceDescriptor class that describes the service. module: Module to add service to. Request and response types are found relative to this module. Returns: Service class proxy capable of communicating with a remote server. """ class_dict = {'__module__': module.__name__} class_name = service_descriptor.name.encode('utf-8') for method_descriptor in service_descriptor.methods or []: request_definition = messages.find_definition( method_descriptor.request_type, module) response_definition = messages.find_definition( method_descriptor.response_type, module) method_name = method_descriptor.name.encode('utf-8') def remote_method(self, request): """Actual service method.""" raise NotImplementedError('Method is not implemented') remote_method.__name__ = method_name remote_method_decorator = remote.method(request_definition, response_definition) class_dict[method_name] = remote_method_decorator(remote_method) service_class = type(class_name, (remote.Service, ), class_dict) return service_class
def response_type(self): """Expected response type for remote method.""" if isinstance(self.__response_type, basestring): self.__response_type = messages.find_definition( self.__response_type, relative_to=sys.modules[self.__method.__module__]) return self.__response_type
def import_descriptor_loader(definition_name, importer=__import__): """Find objects by importing modules as needed. A definition loader is a function that resolves a definition name to a descriptor. The import finder resolves definitions to their names by importing modules when necessary. Args: definition_name: Name of definition to find. importer: Import function used for importing new modules. Returns: Appropriate descriptor for any describable type located by name. Raises: DefinitionNotFoundError when a name does not refer to either a definition or a module. """ # Attempt to import descriptor as a module. if definition_name.startswith('.'): definition_name = definition_name[1:] if not definition_name.startswith('.'): leaf = definition_name.split('.')[-1] if definition_name: try: module = importer(definition_name, '', '', [leaf]) except ImportError: pass else: return describe(module) try: # Attempt to use messages.find_definition to find item. return describe(messages.find_definition(definition_name, importer=__import__)) except messages.DefinitionNotFoundError, err: # There are things that find_definition will not find, but if the parent # is loaded, its children can be searched for a match. split_name = definition_name.rsplit('.', 1) if len(split_name) > 1: parent, child = split_name try: parent_definition = import_descriptor_loader(parent, importer=importer) except messages.DefinitionNotFoundError: # Fall through to original error. pass else: # Check the parent definition for a matching descriptor. if isinstance(parent_definition, FileDescriptor): search_list = parent_definition.service_types or [] elif isinstance(parent_definition, ServiceDescriptor): search_list = parent_definition.methods or [] elif isinstance(parent_definition, EnumDescriptor): search_list = parent_definition.values or [] elif isinstance(parent_definition, MessageDescriptor): search_list = parent_definition.fields or [] else: search_list = [] for definition in search_list: if definition.name == child: return definition # Still didn't find. Reraise original exception. raise err
def import_descriptor_loader(definition_name, importer=__import__): """Find objects by importing modules as needed. A definition loader is a function that resolves a definition name to a descriptor. The import finder resolves definitions to their names by importing modules when necessary. Args: definition_name: Name of definition to find. importer: Import function used for importing new modules. Returns: Appropriate descriptor for any describable type located by name. Raises: DefinitionNotFoundError when a name does not refer to either a definition or a module. """ # Attempt to import descriptor as a module. if definition_name.startswith('.'): definition_name = definition_name[1:] if not definition_name.startswith('.'): leaf = definition_name.split('.')[-1] if definition_name: try: module = importer(definition_name, '', '', [leaf]) except ImportError: pass else: return describe(module) try: # Attempt to use messages.find_definition to find item. return describe( messages.find_definition(definition_name, importer=__import__)) except messages.DefinitionNotFoundError, err: # There are things that find_definition will not find, but if the parent # is loaded, its children can be searched for a match. split_name = definition_name.rsplit('.', 1) if len(split_name) > 1: parent, child = split_name try: parent_definition = import_descriptor_loader(parent, importer=importer) except messages.DefinitionNotFoundError: # Fall through to original error. pass else: # Check the parent definition for a matching descriptor. if isinstance(parent_definition, FileDescriptor): search_list = parent_definition.service_types or [] elif isinstance(parent_definition, ServiceDescriptor): search_list = parent_definition.methods or [] elif isinstance(parent_definition, EnumDescriptor): search_list = parent_definition.values or [] elif isinstance(parent_definition, MessageDescriptor): search_list = parent_definition.fields or [] else: search_list = [] for definition in search_list: if definition.name == child: return definition # Still didn't find. Reraise original exception. raise err