Пример #1
0
def GenApiConfig(service_class_names,
                 config_string_generator=None,
                 hostname=None,
                 application_path=None):
    """Write an API configuration for endpoints annotated ProtoRPC services.

  Args:
    service_class_names: A list of fully qualified ProtoRPC service classes.
    config_string_generator: A generator object that produces API config strings
      using its pretty_print_config_to_json method.
    hostname: A string hostname which will be used as the default version
      hostname. If no hostname is specificied in the @endpoints.api decorator,
      this value is the fallback.
    application_path: A string with the path to the AppEngine application.

  Raises:
    TypeError: If any service classes don't inherit from remote.Service.
    messages.DefinitionNotFoundError: If a service can't be found.

  Returns:
    A map from service names to a string containing the API configuration of the
      service in JSON format.
  """

    api_service_map = collections.OrderedDict()
    for service_class_name in service_class_names:
        module_name, base_service_class_name = service_class_name.rsplit(
            '.', 1)
        module = __import__(module_name, fromlist=base_service_class_name)
        service = getattr(module, base_service_class_name)
        if not isinstance(service, type) or not issubclass(
                service, remote.Service):
            raise TypeError('%s is not a ProtoRPC service' %
                            service_class_name)

        services = api_service_map.setdefault(
            (service.api_info.name, service.api_info.version), [])
        services.append(service)

    app_yaml_hostname = _GetAppYamlHostname(application_path)

    service_map = collections.OrderedDict()
    config_string_generator = (config_string_generator
                               or api_config.ApiConfigGenerator())
    for api_info, services in six.iteritems(api_service_map):
        assert len(
            services) > 0, 'An API must have at least one ProtoRPC service'

        hostname = services[
            0].api_info.hostname or hostname or app_yaml_hostname

        service_map['%s-%s' % api_info] = (
            config_string_generator.pretty_print_config_to_json(
                services, hostname=hostname))

    return service_map
Пример #2
0
    def __register_services(api_name_version_map, api_config_registry):
        """Register & return a list of each SPI URL and class that handles that URL.

    This finds every service class in api_name_version_map, registers it with
    the given ApiConfigRegistry, builds the SPI url for that class, and adds
    the URL and its factory to a list that's returned.

    Args:
      api_name_version_map: A mapping from (api name, api version) to a list of
        service factories, as returned by __create_name_version_map.
      api_config_registry: The ApiConfigRegistry where service classes will
        be registered.

    Returns:
      A list of (SPI URL, service_factory) for each service class in
      api_name_version_map.

    Raises:
      ApiConfigurationError: If a Service class appears more than once
        in api_name_version_map.  This could happen if one class is used to
        implement multiple APIs.
    """
        generator = api_config.ApiConfigGenerator()
        protorpc_services = []
        for service_factories in api_name_version_map.itervalues():
            service_classes = [
                service_factory.service_class
                for service_factory in service_factories
            ]
            config_file = generator.pretty_print_config_to_json(
                service_classes)
            api_config_registry.register_spi(config_file)

            for service_factory in service_factories:
                protorpc_class_name = service_factory.service_class.__name__
                root = _ApiServer.__SPI_PREFIX + protorpc_class_name
                if any(service_map[0] == root
                       or service_map[1] == service_factory
                       for service_map in protorpc_services):
                    raise api_config.ApiConfigurationError(
                        'Can\'t reuse the same class in multiple APIs: %s' %
                        protorpc_class_name)
                protorpc_services.append((root, service_factory))
        return protorpc_services