class PagespeedEntry(validation.Validated): """Describes the format of a pagespeed configuration from a yaml file. URL blacklist entries are patterns (with '?' and '*' as wildcards). Any URLs that match a pattern on the blacklist will not be optimized by PageSpeed. Rewriter names are strings (like 'CombineCss' or 'RemoveComments') describing individual PageSpeed rewriters. A full list of valid rewriter names can be found in the PageSpeed documentation. The domains-to-rewrite list is a whitelist of domain name patterns with '*' as a wildcard, optionally starting with 'http://' or 'https://'. If no protocol is given, 'http://' is assumed. A resource will only be rewritten if it is on the same domain as the HTML that references it, or if its domain is on the domains-to-rewrite list. """ ATTRIBUTES = { URL_BLACKLIST: validation.Optional( validation.Repeated(validation.Regex(_URL_BLACKLIST_REGEX))), ENABLED_REWRITERS: validation.Optional( validation.Repeated(validation.Regex(_REWRITER_NAME_REGEX))), DISABLED_REWRITERS: validation.Optional( validation.Repeated(validation.Regex(_REWRITER_NAME_REGEX))), DOMAINS_TO_REWRITE: validation.Optional( validation.Repeated(validation.Regex(_DOMAINS_TO_REWRITE_REGEX))), }
class ApiConfigHandler(HandlerBase): """Class representing api_config handler directives in application info.""" ATTRIBUTES = HandlerBase.ATTRIBUTES ATTRIBUTES.update({ URL: validation.Regex(_URL_REGEX), HANDLER_SCRIPT: validation.Regex(_FILES_REGEX) })
class Regexes(validation.Validated): ATTRIBUTES = { 'number': validation.Regex(r'-?[0-9]+(\.[0-9]+)?', str), 'identifier': validation.Regex(r'[a-zA-Z0-9_]+', six.text_type), 'choice': validation.Regex(r'dog|cat|pony', str), }
class PagespeedInfoExternal(validation.Validated): """Describes the format of a pagespeed.yaml file. URL blacklist entries are patterns (with '?' and '*' as wildcards). Any URLs that match a pattern on the blacklist will not be optimized by PageSpeed. Rewriter names are strings (like 'CombineCss' or 'RemoveComments') describing individual PageSpeed rewriters. A full list of valid rewriter names can be found in the PageSpeed documentation. """ ATTRIBUTES = { URL_BLACKLIST: validation.Optional( validation.Repeated(validation.Regex(_URL_BLACKLIST_REGEX))), ENABLED_REWRITERS: validation.Optional( validation.Repeated(validation.Regex(_REWRITER_NAME_REGEX))), DISABLED_REWRITERS: validation.Optional( validation.Repeated(validation.Regex(_REWRITER_NAME_REGEX))), }
class DispatchEntry(validation.Validated): """A Dispatch entry describes a mapping from a URL pattern to a server.""" ATTRIBUTES = { URL: DispatchEntryURLValidator(), SERVER: validation.Regex(appinfo.SERVER_ID_RE_STRING), }
class AppInfoExternal(validation.Validated): """Class representing users application info. This class is passed to a yaml_object builder to provide the validation for the application information file format parser. Attributes: application: Unique identifier for application. version: Application's major version number. runtime: Runtime used by application. api_version: Which version of APIs to use. handlers: List of URL handlers. default_expiration: Default time delta to use for cache expiration for all static files, unless they have their own specific 'expiration' set. See the URLMap.expiration field's documentation for more information. skip_files: An re object. Files that match this regular expression will not be uploaded by appcfg.py. For example: skip_files: | .svn.*| #.*# """ ATTRIBUTES = { APPLICATION: APPLICATION_RE_STRING, VERSION: VERSION_RE_STRING, RUNTIME: RUNTIME_RE_STRING, API_VERSION: API_VERSION_RE_STRING, BUILTINS: validation.Optional(validation.Repeated(BuiltinHandler)), INCLUDES: validation.Optional(validation.Type(list)), HANDLERS: validation.Optional(validation.Repeated(URLMap)), SERVICES: validation.Optional( validation.Repeated(validation.Regex(_SERVICE_RE_STRING))), DEFAULT_EXPIRATION: validation.Optional(_EXPIRATION_REGEX), SKIP_FILES: validation.RegexStr(default=DEFAULT_SKIP_FILES), DERIVED_FILE_TYPE: validation.Optional( validation.Repeated( validation.Options(JAVA_PRECOMPILED, PYTHON_PRECOMPILED))), ADMIN_CONSOLE: validation.Optional(AdminConsole), ERROR_HANDLERS: validation.Optional(validation.Repeated(ErrorHandlers)), } 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))
class AppInfoExternal(validation.Validated): """Class representing users application info. This class is passed to a yaml_object builder to provide the validation for the application information file format parser. Attributes: application: Unique identifier for application. version: Application's major version. runtime: Runtime used by application. api_version: Which version of APIs to use. handlers: List of URL handlers. default_expiration: Default time delta to use for cache expiration for all static files, unless they have their own specific 'expiration' set. See the URLMap.expiration field's documentation for more information. skip_files: An re object. Files that match this regular expression will not be uploaded by appcfg.py. For example: skip_files: | .svn.*| #.*# nobuild_files: An re object. Files that match this regular expression will not be built into the app. Go only. api_config: URL root and script/servlet path for enhanced api serving """ ATTRIBUTES = { APPLICATION: APPLICATION_RE_STRING, VERSION: validation.Optional(VERSION_RE_STRING), RUNTIME: RUNTIME_RE_STRING, API_VERSION: API_VERSION_RE_STRING, BUILTINS: validation.Optional(validation.Repeated(BuiltinHandler)), INCLUDES: validation.Optional(validation.Type(list)), HANDLERS: validation.Optional(validation.Repeated(URLMap)), LIBRARIES: validation.Optional(validation.Repeated(Library)), SERVICES: validation.Optional( validation.Repeated(validation.Regex(_SERVICE_RE_STRING))), DEFAULT_EXPIRATION: validation.Optional(_EXPIRATION_REGEX), SKIP_FILES: validation.RegexStr(default=DEFAULT_SKIP_FILES), NOBUILD_FILES: validation.RegexStr(default=DEFAULT_NOBUILD_FILES), DERIVED_FILE_TYPE: validation.Optional( validation.Repeated( validation.Options(JAVA_PRECOMPILED, PYTHON_PRECOMPILED))), ADMIN_CONSOLE: validation.Optional(AdminConsole), ERROR_HANDLERS: validation.Optional(validation.Repeated(ErrorHandlers)), BACKENDS: validation.Optional(validation.Repeated(backendinfo.BackendEntry)), THREADSAFE: validation.Optional(bool), API_CONFIG: validation.Optional(ApiConfigHandler), } 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) def ApplyBackendSettings(self, backend_name): """Applies settings from the indicated backend to the AppInfoExternal. Backend entries may contain directives that modify other parts of the app.yaml, such as the 'start' directive, which adds a handler for the start request. This method performs those modifications. Args: backend_name: The name of a backend defined in 'backends'. Raises: BackendNotFound: If the indicated backend was not listed in 'backends'. """ if backend_name is None: return if self.backends is None: raise appinfo_errors.BackendNotFound self.version = backend_name match = None for backend in self.backends: if backend.name != backend_name: continue if match: raise appinfo_errors.DuplicateBackend else: match = backend if match is None: raise appinfo_errors.BackendNotFound if match.start is None: return start_handler = URLMap(url=_START_PATH, script=match.start) self.handlers.insert(0, start_handler)
class CapitalizedKeysStringValues(validation.ValidatedDict): """A dictionary that maps capitalized strings to strings.""" KEY_VALIDATOR = validation.Regex('[A-Z].*') VALUE_VALIDATOR = six.string_types
class Stuff(validation.Validated): ATTRIBUTES = { 'services': validation.Repeated(validation.Regex('mail|xmpp')), }
class HasRegex(validation.Validated): ATTRIBUTES = { 'prop1': validation.RegexStr(default='.*'), 'prop2': validation.RegexStr(), 'prop3': validation.Regex('foo.*'), }
class DispatchEntry(validation.Validated): """A Dispatch entry describes a mapping from a URL pattern to a module.""" ATTRIBUTES = { URL: DispatchEntryURLValidator(), MODULE: validation.Regex(appinfo.MODULE_ID_RE_STRING), }
class AppInfoExternal(validation.Validated): """Class representing users application info. This class is passed to a yaml_object builder to provide the validation for the application information file format parser. Attributes: application: Unique identifier for application. version: Application's major version number. runtime: Runtime used by application. api_version: Which version of APIs to use. handlers: List of URL handlers. default_expiration: Default time delta to use for cache expiration for all static files, unless they have their own specific 'expiration' set. See the URLMap.expiration field's documentation for more information. skip_files: An re object. Files that match this regular expression will not be uploaded by appcfg.py. For example: skip_files: | .svn.*| #.*# """ ATTRIBUTES = { APPLICATION: APPLICATION_RE_STRING, VERSION: VERSION_RE_STRING, RUNTIME: RUNTIME_RE_STRING, API_VERSION: API_VERSION_RE_STRING, HANDLERS: validation.Optional(validation.Repeated(URLMap)), SERVICES: validation.Optional( validation.Repeated(validation.Regex(_SERVICE_RE_STRING))), DEFAULT_EXPIRATION: validation.Optional(_EXPIRATION_REGEX), SKIP_FILES: validation.RegexStr(default=DEFAULT_SKIP_FILES), DERIVED_FILE_TYPE: validation.Optional( validation.Repeated( validation.Options(JAVA_PRECOMPILED, PYTHON_PRECOMPILED))), ADMIN_CONSOLE: validation.Optional(AdminConsole), ERROR_HANDLERS: validation.Optional(validation.Repeated(ErrorHandlers)), } 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 FixSecureDefaults(self): """Force omitted 'secure: ...' handler fields to 'secure: optional'. The effect is that handler.secure is never equal to the (nominal) default. See http://b/issue?id=2073962. """ if self.handlers: for handler in self.handlers: if handler.secure == SECURE_DEFAULT: handler.secure = SECURE_HTTP_OR_HTTPS def WarnReservedURLs(self): """Generates a warning for reserved URLs. See: http://code.google.com/appengine/docs/python/config/appconfig.html#Reserved_URLs """ if self.handlers: for handler in self.handlers: if handler.url == '/form': logging.warning( 'The URL path "/form" is reserved and will not be matched.' )
def __init__(self): self.regex = validation.Regex(PARAMETER_NAME_REGEX)
class PhoneNumberDict(v.ValidatedDict): """Maps nonempty strings to strings, used to test ValidatedDict fields.""" KEY_VALIDATOR = v.Regex('.+') VALUE_VALIDATOR = str
class HasRegex(v.Validated): ATTRIBUTES = {'regex': v.Regex(r'ab+a')}