def construct(cls, resource, declaration): bases = declaration.__bases__ if isinstance(declaration, (type, ClassType)) and bases: params = cls._pull_request(resource, bases[0]) else: params = {} params.update(pull_class_dict(declaration, cls.ATTRS)) if 'responses' not in params: params['responses'] = {} schema = getattr(declaration, 'schema', None) if schema is not None: if isinstance(schema, dict): schema = Structure(schema) if not schema.name: schema.name = 'request' params['schema'] = schema fields = getattr(declaration, 'fields', None) if fields: if isinstance(params['schema'], Structure): structure = params['schema'].structure for name, field in fields.iteritems(): if isinstance(field, Field): if not field.name: field.name = name structure[name] = field elif field is None and name in structure: del structure[name] else: raise SpecificationError() responses = getattr(declaration, 'responses', {}) for status, response in responses.iteritems(): if not isinstance(response, Response): response = Response(response) response.status = status params['responses'][status] = response description = params.get('description') if not description and declaration.__doc__: params['description'] = dedent(declaration.__doc__) return cls(resource=resource, name=declaration.__name__, **params)
def _pull_request(cls, resource, request): try: get_request = request.get_request except AttributeError: pass else: request = get_request(resource) params = pull_class_dict(request, cls.ATTRS) schema = getattr(request, 'schema', None) if schema: params['schema'] = deepcopy(schema) responses = getattr(request, 'responses', None) if responses: params['responses'] = deepcopy(responses) return params
def _pull_request(cls, resource, request, declaration=None): try: get_request = request.get_request except AttributeError: pass else: request = get_request(resource, declaration) params = pull_class_dict(request, cls.ATTRS) schema = getattr(request, "schema", None) if schema: params["schema"] = deepcopy(schema) responses = getattr(request, "responses", None) if responses: params["responses"] = deepcopy(responses) metadata = getattr(request, "metadata", None) if metadata: params["metadata"] = deepcopy(metadata) return params
def __new__(metatype, name, bases, namespace): asis = namespace.pop('__asis__', False) if asis: resource = type.__new__(metatype, name, bases, namespace) associate_resource_version(resource) return resource base_class = None if namespace.get('abstract', False): base_class = bases[0] if len(bases) > 1 or base_class.name is not None: raise SpecificationError('abstract resource %r may only inherit from a single' ' abstract base resource' % name) else: for candidate in bases: if getattr(candidate, 'abstract', False): continue elif base_class is None: base_class = candidate else: raise SpecificationError('concrete resource %r must inherit from only one' 'concrete resource' % name) if not base_class: raise SpecificationError('resource %r must inherit from exactly one non-abstract ' 'base resource' % name) configuration = getattr(base_class, 'configuration', None) if not configuration: configuration = namespace.get('configuration', None) if not configuration: return type.__new__(metatype, name, (base_class,), namespace) elif not isinstance(configuration, Configuration): raise SpecificationError('invalid configuration') schema = namespace.pop('schema', {}) if isinstance(schema, (type, ClassType)): schema = pull_class_dict(schema) if not isinstance(schema, dict): raise SpecificationError('resource %r has an invalid schema' % name) removed_fields = set() for attr in schema.keys(): if isinstance(schema[attr], Field): schema[attr].name = attr else: if schema[attr] is None: removed_fields.add(attr) del schema[attr] requested_requests = namespace.pop('requests', None) if isinstance(requested_requests, basestring): requested_requests = requested_requests.split(' ') if requested_requests is None: requested_requests = configuration.default_requests declared_requests = {} removed_attrs = set() for attr in namespace.keys(): if attr not in metatype.ATTRS and not attr.startswith('_'): if isinstance(namespace[attr], (type, ClassType)): declared_requests[attr] = namespace.pop(attr) elif namespace[attr] is None: removed_attrs.add(attr) namespace.pop(attr) resource = type.__new__(metatype, name, (base_class,), namespace) if resource.version is not None: if not (isinstance(resource.version, int) and resource.version >= 1): raise SpecificationError('resource %r declares an invalid version' % name) resource.requests = {} resource.schema = {} resource.subresources = {} resource.validators = {} inherited_requests = set() for base in reversed(bases): if hasattr(base, 'schema'): resource.schema.update(base.schema) resource.subresources.update(base.subresources) resource.validators.update(base.validators) for name, request in base.requests.iteritems(): inherited_requests.add(request) resource.requests[name] = request resource.schema.update(schema) for name in removed_fields: if name in resource.schema: del resource.schema[name] if isinstance(resource.composite_key, basestring): resource.composite_key = resource.composite_key.split(' ') id_field = configuration.id_field if id_field.name in resource.schema: resource.schema[id_field.name].is_identifier = True elif id_field.name not in removed_fields: resource.schema[id_field.name] = id_field.clone(is_identifier=True) resource.id_field = resource.schema.get(id_field.name) for name, request in declared_requests.iteritems(): resource.requests[name] = Request.construct(resource, request) for attr, value in namespace.iteritems(): if isinstance(value, Subresource): value.name = attr resource.subresources[attr] = value elif isinstance(value, classmethod): value = getattr(resource, attr) if getattr(value, '__validates__', False): resource.validators[value.__name__] = value delattr(resource, value.__name__) resource.description = dedent(resource.__doc__ or '') if resource.name is None: associate_resource_version(resource) return resource if requested_requests: for name in requested_requests: constructor = configuration.standard_requests.get(name) if constructor: request = resource.requests.get(name) if request and request in inherited_requests and request.auto_constructed: request = None if not request: request = constructor(resource) if request: resource.requests[name] = request else: raise SpecificationError('resource %r requests unknown standard request %r' % (resource.name, name)) for collection in (resource.requests, resource.validators): for name in collection.keys(): if name in removed_attrs: del collection[name] for validator in resource.validators.itervalues(): if validator.requests is None: set_function_attr(validator, 'requests', configuration.validated_requests) for request_name in validator.requests: if request_name in resource.requests: resource.requests[request_name].validators.append(validator) associate_resource_version(resource) return resource
def __new__(metatype, name, bases, namespace): candidates = [getattr(base, 'configuration', None) for base in bases] candidates.append(namespace.get('configuration', None)) configuration = None for candidate in candidates: if isinstance(candidate, Configuration): if not configuration or candidate == configuration: configuration = candidate else: raise SpecificationError('conflicting mesh configurations') if not configuration: return type.__new__(metatype, name, bases, namespace) schema = namespace.pop('schema', {}) if isinstance(schema, (type, ClassType)): schema = pull_class_dict(schema) if not isinstance(schema, dict): raise SpecificationError('resource %r has an invalid schema' % name) removed_fields = set() for attr in schema.keys(): if isinstance(schema[attr], Field): schema[attr].name = attr else: if schema[attr] is None: removed_fields.add(attr) del schema[attr] requested_requests = namespace.pop('requests', None) if isinstance(requested_requests, basestring): requested_requests = requested_requests.split(' ') if requested_requests is None: requested_requests = configuration.standard_requests.keys() declared_requests = {} removed_attrs = set() for attr in namespace.keys(): if attr not in metatype.ATTRS and not attr.startswith('_'): if isinstance(namespace[attr], (type, ClassType)): declared_requests[attr] = namespace.pop(attr) elif namespace[attr] is None: removed_attrs.add(attr) namespace.pop(attr) resource = type.__new__(metatype, name, bases, namespace) if resource.name is not None: if not (isinstance(resource.version, int) and resource.version >= 1): raise SpecificationError('resource %r declares an invalid version' % name) elif resource.version is not None: raise SpecificationError('abstract resource %r must not declare a version' % name) resource.requests = {} resource.schema = {} resource.validators = {} inherited_requests = set() for base in reversed(bases): if hasattr(base, 'schema'): resource.schema.update(base.schema) resource.validators.update(base.validators) for name, request in base.requests.iteritems(): inherited_requests.add(request) resource.requests[name] = request resource.schema.update(schema) for name in removed_fields: if name in resource.schema: del resource.schema[name] id_field = configuration.id_field if id_field.name in resource.schema: resource.schema[id_field.name].is_identifier = True else: resource.schema[id_field.name] = id_field.clone(is_identifier=True) resource.id_field = resource.schema[id_field.name] for name, request in declared_requests.iteritems(): resource.requests[name] = Request.construct(resource, request) for attr, value in namespace.iteritems(): if isinstance(value, classmethod): value = getattr(resource, attr) if getattr(value, '__validates__', False): resource.validators[value.__name__] = value delattr(resource, value.__name__) resource.description = dedent(resource.__doc__ or '') if resource.name is None: return resource if requested_requests: for name in requested_requests: constructor = configuration.standard_requests.get(name) if constructor: request = resource.requests.get(name) if request and request in inherited_requests and request.auto_constructed: request = None if not request: request = constructor(resource) if request: resource.requests[name] = request else: raise SpecificationError('resource %r requests unknown standard request %r' % (resource.name, name)) for collection in (resource.requests, resource.validators): for name in collection.keys(): if name in removed_attrs: del collection[name] for validator in resource.validators.itervalues(): if validator.requests is None: set_function_attr(validator, 'requests', configuration.validated_requests) for request_name in validator.requests: if request_name in resource.requests: resource.requests[request_name].validators.append(validator) versions = getattr(resource, 'versions', None) if versions is None: versions = resource.versions = {} if resource.version in versions: raise SpecificationError('duplicate version') versions[resource.version] = resource return resource
def construct(cls, resource, declaration): bases = declaration.__bases__ if isinstance(declaration, (type, ClassType)) and bases: params = cls._pull_request(resource, bases[0], declaration) else: params = {} params.update(pull_class_dict(declaration, cls.ATTRS)) if "responses" not in params: params["responses"] = {} schema = getattr(declaration, "schema", None) if schema is not None: if isinstance(schema, dict): for name, field in schema.items(): if isinstance(field, basestring): field = resource.schema.get(field) if field: schema[name] = field schema = Structure(schema) if not schema.name: schema.name = "request" params["schema"] = schema fields = getattr(declaration, "fields", None) if fields: if isinstance(params["schema"], Structure): structure = params["schema"].structure for name, field in fields.iteritems(): if isinstance(field, Field): if not field.name: field.name = name structure[name] = field elif isinstance(field, basestring): field = resource.schema.get(field) if field: if field.name != name: field = field.clone(name=name) structure[name] = field else: raise SpecificationError() elif field is None and name in structure: del structure[name] else: raise SpecificationError() responses = getattr(declaration, "responses", {}) for status, response in responses.iteritems(): if not isinstance(response, Response): response = Response(response) response.status = status params["responses"][status] = response description = params.get("description") if not description and declaration.__doc__: params["description"] = dedent(declaration.__doc__) metadata = getattr(declaration, "metadata", None) if metadata: if "metadata" in params: params["metadata"].update(metadata) else: params["metadata"] = metadata return cls(resource=resource, name=declaration.__name__, **params)
def __new__(metatype, name, bases, namespace): candidates = [getattr(base, 'configuration', None) for base in bases] candidates.append(namespace.get('configuration', None)) configuration = None for candidate in candidates: if isinstance(candidate, Configuration): if not configuration or candidate == configuration: configuration = candidate else: raise SpecificationError('conflicting mesh configurations') if not configuration: return type.__new__(metatype, name, bases, namespace) schema = namespace.pop('schema', {}) if isinstance(schema, (type, ClassType)): schema = pull_class_dict(schema) if not isinstance(schema, dict): raise SpecificationError('resource %r has an invalid schema' % name) removed_fields = set() for attr in schema.keys(): if isinstance(schema[attr], Field): schema[attr].name = attr else: if schema[attr] is None: removed_fields.add(attr) del schema[attr] requested_requests = namespace.pop('requests', None) if isinstance(requested_requests, basestring): requested_requests = requested_requests.split(' ') if requested_requests is None: requested_requests = configuration.standard_requests.keys() declared_requests = {} removed_attrs = set() for attr in namespace.keys(): if attr not in metatype.ATTRS and not attr.startswith('_'): if isinstance(namespace[attr], (type, ClassType)): declared_requests[attr] = namespace.pop(attr) elif namespace[attr] is None: removed_attrs.add(attr) namespace.pop(attr) resource = type.__new__(metatype, name, bases, namespace) if resource.name is not None: if not (isinstance(resource.version, int) and resource.version >= 1): raise SpecificationError( 'resource %r declares an invalid version' % name) elif resource.version is not None: raise SpecificationError( 'abstract resource %r must not declare a version' % name) resource.requests = {} resource.schema = {} resource.validators = {} inherited_requests = set() for base in reversed(bases): if hasattr(base, 'schema'): resource.schema.update(base.schema) resource.validators.update(base.validators) for name, request in base.requests.iteritems(): inherited_requests.add(request) resource.requests[name] = request resource.schema.update(schema) for name in removed_fields: if name in resource.schema: del resource.schema[name] id_field = configuration.id_field if id_field.name in resource.schema: resource.schema[id_field.name].is_identifier = True else: resource.schema[id_field.name] = id_field.clone(is_identifier=True) resource.id_field = resource.schema[id_field.name] for name, request in declared_requests.iteritems(): resource.requests[name] = Request.construct(resource, request) for attr, value in namespace.iteritems(): if isinstance(value, classmethod): value = getattr(resource, attr) if getattr(value, '__validates__', False): resource.validators[value.__name__] = value delattr(resource, value.__name__) resource.description = dedent(resource.__doc__ or '') if resource.name is None: return resource if requested_requests: for name in requested_requests: constructor = configuration.standard_requests.get(name) if constructor: request = resource.requests.get(name) if request and request in inherited_requests and request.auto_constructed: request = None if not request: request = constructor(resource) if request: resource.requests[name] = request else: raise SpecificationError( 'resource %r requests unknown standard request %r' % (resource.name, name)) for collection in (resource.requests, resource.validators): for name in collection.keys(): if name in removed_attrs: del collection[name] for validator in resource.validators.itervalues(): if validator.requests is None: set_function_attr(validator, 'requests', configuration.validated_requests) for request_name in validator.requests: if request_name in resource.requests: resource.requests[request_name].validators.append( validator) versions = getattr(resource, 'versions', None) if versions is None: versions = resource.versions = {} if resource.version in versions: raise SpecificationError('duplicate version') versions[resource.version] = resource return resource