def ParseAndReturnIncludePaths(appinfo_file, open_fn=open): """Parse an AppYaml file and merge referenced includes and builtins.""" try: appinfo_path = appinfo_file.name if not os.path.isfile(appinfo_path): raise Exception( 'Name defined by appinfo_file does not appear to be a ' 'valid file: %s' % appinfo_path) except AttributeError: raise Exception('File object passed to ParseAndMerge does not define ' 'attribute "name" as as full file path.') appyaml = appinfo.LoadSingleAppInfo(appinfo_file) appyaml, include_paths = _MergeBuiltinsIncludes(appinfo_path, appyaml, open_fn) if not appyaml.handlers: raise appinfo_errors.MissingURLMapping( 'No URLMap entries found in application configuration') if len(appyaml.handlers) > appinfo.MAX_URL_MAPS: raise appinfo_errors.TooManyURLMappings( 'Found more than %d URLMap entries in application configuration' % appinfo.MAX_URL_MAPS) if appyaml.runtime == 'python27' and appyaml.threadsafe: for handler in appyaml.handlers: if (handler.script and (handler.script.endswith('.py') or '/' in handler.script)): raise appinfo_errors.ThreadsafeWithCgiHandler( 'Threadsafe cannot be enabled with CGI handler: %s' % handler.script) return appyaml, include_paths
def CheckInitialized(self): """Ensures that at least one url mapping is provided. Raises: MissingURLMapping when no URLMap objects are present in object. TooManyURLMappings when there are too many URLMap entries. """ super(AppInfoExternal, self).CheckInitialized() if not self.handlers: raise appinfo_errors.MissingURLMapping( 'No URLMap entries found in application configuration') if len(self.handlers) > MAX_URL_MAPS: raise appinfo_errors.TooManyURLMappings( 'Found more than %d URLMap entries in application configuration' % MAX_URL_MAPS)
def ParseAndReturnIncludePaths(appinfo_file, open_fn=open): """Parse an AppYaml file and merge referenced includes and builtins. Args: appinfo_file: an opened file, for example the result of open('app.yaml'). open_fn: a function to open included files. Returns: A tuple where the first element is the parsed appinfo.AppInfoExternal object and the second element is a list of the absolute paths of the included files, in no particular order. """ try: appinfo_path = appinfo_file.name if not os.path.isfile(appinfo_path): raise Exception( 'Name defined by appinfo_file does not appear to be a ' 'valid file: %s' % appinfo_path) except AttributeError: raise Exception('File object passed to ParseAndMerge does not define ' 'attribute "name" as as full file path.') appyaml = appinfo.LoadSingleAppInfo(appinfo_file) appyaml, include_paths = _MergeBuiltinsIncludes(appinfo_path, appyaml, open_fn) if not appyaml.handlers: if appyaml.vm: appyaml.handlers = [appinfo.URLMap(url='.*', script='PLACEHOLDER')] else: raise appinfo_errors.MissingURLMapping( 'No URLMap entries found in application configuration') if len(appyaml.handlers) > appinfo.MAX_URL_MAPS: raise appinfo_errors.TooManyURLMappings( 'Found more than %d URLMap entries in application configuration' % appinfo.MAX_URL_MAPS) if appyaml.runtime == 'python27' and appyaml.threadsafe: for handler in appyaml.handlers: if (handler.script and (handler.script.endswith('.py') or '/' in handler.script)): raise appinfo_errors.ThreadsafeWithCgiHandler( 'Threadsafe cannot be enabled with CGI handler: %s' % handler.script) return appyaml, include_paths
def CheckInitialized(self): """Performs non-regex-based validation. Ensures that at least one url mapping is provided in the URL mappers Also ensures that the major version doesn't contain the string -dot-. Raises: MissingURLMapping when no URLMap objects are present in object. TooManyURLMappings when there are too many URLMap entries. """ super(AppInfoExternal, self).CheckInitialized() if not self.handlers and not self.builtins and not self.includes: raise appinfo_errors.MissingURLMapping( 'No URLMap entries found in application configuration') if self.handlers and len(self.handlers) > MAX_URL_MAPS: raise appinfo_errors.TooManyURLMappings( 'Found more than %d URLMap entries in application configuration' % MAX_URL_MAPS) if self.version.find(ALTERNATE_HOSTNAME_SEPARATOR) != -1: raise validation.ValidationError( 'App version "%s" cannot contain the string "%s"' % (self.version, ALTERNATE_HOSTNAME_SEPARATOR))
def Parse(appinfo_file): """Parse an AppYaml file and merge referenced includes and builtins.""" try: appinfo_path = appinfo_file.name if not os.path.isfile(appinfo_path): raise Exception('Name defined by appinfo_file does not appear to be a ' 'valid file: %s' % appinfo_path) except AttributeError: raise Exception('File object passed to ParseAndMerge does not define ' 'attribute "name" as as full file path.') appyaml = appinfo.LoadSingleAppInfo(appinfo_file) appyaml = _MergeBuiltinsIncludes(appinfo_path, appyaml) if not appyaml.handlers: raise appinfo_errors.MissingURLMapping( 'No URLMap entries found in application configuration') if len(appyaml.handlers) > appinfo.MAX_URL_MAPS: raise appinfo_errors.TooManyURLMappings( 'Found more than %d URLMap entries in application configuration' % appinfo.MAX_URL_MAPS) return appyaml
def CheckInitialized(self): """Performs non-regex-based validation. The following are verified: - At least one url mapping is provided in the URL mappers. - Number of url mappers doesn't exceed MAX_URL_MAPS. - Major version does not contain the string -dot-. - If api_endpoints are defined, an api_config stanza must be defined. - If the runtime is python27 and threadsafe is set, then no CGI handlers can be used. - That the version name doesn't start with BUILTIN_NAME_PREFIX Raises: MissingURLMapping: if no URLMap object is present in the object. TooManyURLMappings: if there are too many URLMap entries. MissingApiConfig: if api_endpoints exist without an api_config. ThreadsafeWithCgiHandler: if the runtime is python27, threadsafe is set and CGI handlers are specified. """ super(AppInfoExternal, self).CheckInitialized() if not self.handlers and not self.builtins and not self.includes: raise appinfo_errors.MissingURLMapping( 'No URLMap entries found in application configuration') if self.handlers and len(self.handlers) > MAX_URL_MAPS: raise appinfo_errors.TooManyURLMappings( 'Found more than %d URLMap entries in application configuration' % MAX_URL_MAPS) if self.libraries: if self.runtime != 'python27': raise appinfo_errors.RuntimeDoesNotSupportLibraries( 'libraries entries are only supported by the "python27" runtime' ) library_names = [library.name for library in self.libraries] for library_name in library_names: if library_names.count(library_name) > 1: raise appinfo_errors.DuplicateLibrary( 'Duplicate library entry for %s' % library_name) if self.version and self.version.find( ALTERNATE_HOSTNAME_SEPARATOR) != -1: raise validation.ValidationError( 'Version "%s" cannot contain the string "%s"' % (self.version, ALTERNATE_HOSTNAME_SEPARATOR)) if self.version and self.version.startswith(BUILTIN_NAME_PREFIX): raise validation.ValidationError( ('Version "%s" cannot start with "%s" because it is a ' 'reserved version name prefix.') % (self.version, BUILTIN_NAME_PREFIX)) if self.handlers: api_endpoints = [ handler.url for handler in self.handlers if handler.GetHandlerType() == HANDLER_API_ENDPOINT ] if api_endpoints and not self.api_config: raise appinfo_errors.MissingApiConfig( 'An api_endpoint handler was specified, but the required ' 'api_config stanza was not configured.') if self.threadsafe and self.runtime == 'python27': for handler in self.handlers: if (handler.script and (handler.script.endswith('.py') or '/' in handler.script)): raise appinfo_errors.ThreadsafeWithCgiHandler( 'Threadsafe cannot be enabled with CGI handler: %s' % handler.script)