def GenApiConfig(service_class_names, config_string_generator=None,<EOL>hostname=None, application_path=None, **additional_kwargs):
<EOL>api_service_map = collections.OrderedDict()<EOL>resolved_services = []<EOL>for service_class_name in service_class_names:<EOL><INDENT>module_name, base_service_class_name = service_class_name.rsplit('<STR_LIT:.>', <NUM_LIT:1>)<EOL>module = __import__(module_name, fromlist=base_service_class_name)<EOL>service = getattr(module, base_service_class_name)<EOL>if hasattr(service, '<STR_LIT>'):<EOL><INDENT>resolved_services.extend(service.get_api_classes())<EOL><DEDENT>elif (not isinstance(service, type) or<EOL>not issubclass(service, remote.Service)):<EOL><INDENT>raise TypeError('<STR_LIT>' % service_class_name)<EOL><DEDENT>else:<EOL><INDENT>resolved_services.append(service)<EOL><DEDENT><DEDENT>for resolved_service in resolved_services:<EOL><INDENT>services = api_service_map.setdefault(<EOL>(resolved_service.api_info.name, resolved_service.api_info.api_version), [])<EOL>services.append(resolved_service)<EOL><DEDENT>app_yaml_hostname = _GetAppYamlHostname(application_path)<EOL>service_map = collections.OrderedDict()<EOL>config_string_generator = (<EOL>config_string_generator or api_config.ApiConfigGenerator())<EOL>for api_info, services in api_service_map.items():<EOL><INDENT>assert services, '<STR_LIT>'<EOL>hostname = services[<NUM_LIT:0>].api_info.hostname or hostname or app_yaml_hostname<EOL>service_map['<STR_LIT>' % api_info] = (<EOL>config_string_generator.pretty_print_config_to_json(<EOL>services, hostname=hostname, **additional_kwargs))<EOL><DEDENT>return service_map<EOL>
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.