async def __call__(self): """ data input : { 'interface': 'INTERFACE' }""" registry = await get_registry() if registry is None: return ErrorResponse("BadRequest", _("Not in a container request"), status=412) data = await self.request.json() interface = data.get("interface", None) initial_values = data.get("initial_values", {}) if interface is None: return ErrorResponse("InvalidRequest", "Non existent Interface", status=412) iObject = import_class(interface) registry.register_interface(iObject) config = registry.for_interface(iObject) # Initialize values # If its defined on the guillotina.schema default will not be overwritten # you will need to PATCH for key, field in get_fields(iObject).items(): if key in initial_values and getattr(config, key, _marker) == _marker: # We don't have a value config[key] = initial_values[key] await notify( RegistryEditedEvent(self.context, registry, {interface: initial_values})) return Response(status=201)
async def __call__(self): """ data input : { 'interface': 'INTERFACE' }""" if not hasattr(self.request, 'container_settings'): return ErrorResponse('BadRequest', _("Not in a container request")) data = await self.request.json() interface = data.get('interface', None) initial_values = data.get('initial_values', {}) if interface is None: return ErrorResponse('InvalidRequest', 'Non existent Interface') registry = self.request.container_settings iObject = import_class(interface) registry.register_interface(iObject) config = registry.for_interface(iObject) # Initialize values # If its defined on the guillotina.schema default will not be overwritten # you will need to PATCH for key, field in get_fields(iObject).items(): if key in initial_values and getattr(config, key, _marker) == _marker: # We don't have a value config[key] = initial_values[key] return Response(response={}, status=201)
async def get_schema(self, schema, context, result, behavior): read_permissions = merged_tagged_value_dict(schema, read_permission.key) schema_serial = {} for name, field in get_fields(schema).items(): if not self.check_permission(read_permissions.get(name)): continue if behavior: # omit/include for behaviors need full name dotted_name = schema.__identifier__ + '.' + name else: dotted_name = name if ('*' not in self.include and (dotted_name in self.omit or ( len(self.include) > 0 and ( dotted_name not in self.include and schema.__identifier__ not in self.include)))): # make sure the fields aren't filtered continue value = await self.serialize_field(context, field) if not behavior: result[name] = value else: schema_serial[name] = value if behavior and len(schema_serial) > 0: result[schema.__identifier__] = schema_serial
async def get_schema(self, schema, context, result, behavior): read_permissions = merged_tagged_value_dict(schema, read_permission.key) schema_serial = {} for name, field in get_fields(schema).items(): if not self.check_permission(read_permissions.get(name)): continue if behavior: # omit/include for behaviors need full name dotted_name = schema.__identifier__ + '.' + name else: dotted_name = name if ('*' not in self.include and (dotted_name in self.omit or (len(self.include) > 0 and (dotted_name not in self.include and schema.__identifier__ not in self.include)))): # make sure the fields aren't filtered continue value = await self.serialize_field(context, field) if not behavior: result[name] = value else: schema_serial[name] = value if behavior and len(schema_serial) > 0: result[schema.__identifier__] = schema_serial
async def __call__(self): """ data input : { 'interface': 'INTERFACE' }""" if not hasattr(self.request, 'container_settings'): return ErrorResponse( 'BadRequest', _("Not in a container request"), status=412) data = await self.request.json() interface = data.get('interface', None) initial_values = data.get('initial_values', {}) if interface is None: return ErrorResponse( 'InvalidRequest', 'Non existent Interface', status=412) registry = self.request.container_settings iObject = import_class(interface) registry.register_interface(iObject) config = registry.for_interface(iObject) # Initialize values # If its defined on the guillotina.schema default will not be overwritten # you will need to PATCH for key, field in get_fields(iObject).items(): if key in initial_values and getattr(config, key, _marker) == _marker: # We don't have a value config[key] = initial_values[key] return Response(status=201)
def serialize(self): field = self.get_field() result = {"type": self.field_type} if self.widget is not None: result["widget"] = self.widget # caching the field_attributes here improves performance dramatically if field.__class__ in FIELDS_CACHE: field_attributes = FIELDS_CACHE[field.__class__].copy() else: field_attributes = {} for schema in implementedBy(field.__class__).flattened(): field_attributes.update(get_fields(schema)) FIELDS_CACHE[field.__class__] = field_attributes for attribute_name in sorted(field_attributes.keys()): attribute_field = field_attributes[attribute_name] if attribute_name in self.filtered_attributes: continue element_name = attribute_field.__name__ attribute_field = attribute_field.bind(field) force = element_name in self.forced_fields value = attribute_field.get(field) # For 'default', 'missing_value' etc, we want to validate against # the imported field type itself, not the field type of the # attribute if ( element_name in self.field_type_attributes or element_name in self.non_validated_field_type_attributes ): attribute_field = field text = None if isinstance(value, bytes): text = value.decode("utf-8") elif isinstance(value, str): text = value elif IField.providedBy(value): serializer = get_multi_adapter((value, field, self.request), ISchemaFieldSerializeToJson) text = serializer.serialize() if "properties" in text: text = text["properties"] elif value is not None and (force or value != field.missing_value): text = json_compatible(value) if text: if attribute_name == "value_type": attribute_name = "items" result[attribute_name] = text if result["type"] == "object": if IJSONField.providedBy(field): result.update(field.json_schema) if IDict.providedBy(field): if "properties" not in result: result["properties"] = {} if field.value_type: field_serializer = get_multi_adapter( (field.value_type, self.schema, self.request), ISchemaFieldSerializeToJson ) result["additionalProperties"] = field_serializer.serialize() else: result["additionalProperties"] = True elif IObject.providedBy(field): schema_serializer = get_multi_adapter((field.schema, self.request), ISchemaSerializeToJson) result["properties"] = schema_serializer.serialize() if field.extra_values is not None: result.update(field.extra_values) return result
async def set_schema( self, schema: Type[Interface], obj: IResource, data: Dict[str, Any], errors: List[Dict[str, Any]], validate_all: bool = False, behavior: bool = False, ): write_permissions = merged_tagged_value_dict(schema, write_permission.key) changed = False for name, field in get_fields(schema).items(): if name in RESERVED_ATTRS: continue if field.readonly: continue if behavior: found = False if data.get(schema.__identifier__): sdata = data[schema.__identifier__] data_value = sdata[name] if name in sdata else None found = True if name in sdata else False else: data_value = data[name] if name in data else None found = True if name in data else False if found: if not self.check_permission(write_permissions.get(name)): raise Unauthorized("Write permission not allowed") try: field = field.bind(obj) value = await self.get_value(field, obj, data_value) except ValueError as e: errors.append({ "message": "Value error", "field": name, "error": e }) except ValidationError as e: errors.append(e.json()) except ValueDeserializationError as e: errors.append({ "message": e.message, "field": name, "error": e }) except Invalid as e: errors.append({ "message": e.args[0], "field": name, "error": e }) else: # record object changes for potential future conflict resolution try: await apply_coroutine(field.set, obj, value) changed = True except ValidationError as e: errors.append(e.json()) except ValueDeserializationError as e: errors.append({ "message": e.message, "field": name, "error": e }) except AttributeError: logger.warning( f"AttributeError setting data on field {name}", exc_info=True) except Exception: logger.warning( f"Unhandled error setting data on field, {schema} {name}", exc_info=True) errors.append({ "message": "Unhandled exception", "field": name, "error": ValueDeserializationError(field, value, "Unhandled error"), }) else: if validate_all and field.required and getattr( obj, name, None) is None: errors.append({ "message": "Required parameter", "field": name, "error": ValueError("Required parameter"), }) for error in await validate_invariants(schema, obj): if isinstance(error, ValidationError): errors.append({ "message": error.doc(), "value": error.value, "field": error.field_name, "error": error.errors, }) else: if len(getattr(error, "args", [])) > 0 and isinstance( error.args[0], str): message = error.args[0] else: message = error.__doc__ errors.append({"message": message, "error": error}) if changed: obj.register()
async def set_schema(self, schema, obj, data, errors, validate_all=False, behavior=False): write_permissions = merged_tagged_value_dict(schema, write_permission.key) for name, field in get_fields(schema).items(): if name in RESERVED_ATTRS: continue if field.readonly: continue if behavior: found = False if schema.__identifier__ in data: sdata = data[schema.__identifier__] data_value = sdata[name] if name in sdata else None found = True if name in sdata else False else: data_value = data[name] if name in data else None found = True if name in data else False if found: if not self.check_permission(write_permissions.get(name)): raise Unauthorized('Write permission not allowed') try: field = field.bind(obj) value = await self.get_value(field, obj, data_value) except ValueError as e: errors.append({ 'message': 'Value error', 'field': name, 'error': e }) except ValidationError as e: errors.append({ 'message': e.doc(), 'field': name, 'error': e }) except ValueDeserializationError as e: errors.append({ 'message': e.message, 'field': name, 'error': e }) except Invalid as e: errors.append({ 'message': e.args[0], 'field': name, 'error': e }) else: # record object changes for potential future conflict resolution try: await notify(BeforeFieldModifiedEvent(field, value)) await apply_coroutine(field.set, obj, value) except ValidationError as e: errors.append({ 'message': e.doc(), 'field': name, 'error': e }) except ValueDeserializationError as e: errors.append({ 'message': e.message, 'field': name, 'error': e }) except AttributeError: logger.warning( f'AttributeError setting data on field {name}', exc_info=True) except Exception: if not isinstance(getattr(type(obj), name, None), property): # we can not set data on properties logger.warning( 'Error setting data on field, falling back to setattr', exc_info=True) setattr(obj, name, value) else: logger.warning('Error setting data on field', exc_info=True) else: if validate_all and field.required and getattr( obj, name, None) is None: errors.append({ 'message': 'Required parameter', 'field': name, 'error': ValueError('Required parameter') }) if validate_all: invariant_errors = [] try: schema.validateInvariants(object, invariant_errors) except Invalid: # Just collect errors pass validation = [(None, e) for e in invariant_errors] if len(validation): for error in validation: errors.append({ 'message': error[1].doc(), 'field': error[0], 'error': error })
def _callFUT(self, schema): from guillotina.schema import get_fields return get_fields(schema)
def _callFUT(self, schema): from guillotina.schema import get_fields return get_fields(schema)
def serialize(self): field = self.get_field() result = {'type': self.field_type} # caching the field_attributes here improves performance dramatically if field.__class__ in FIELDS_CACHE: field_attributes = FIELDS_CACHE[field.__class__].copy() else: field_attributes = {} for schema in implementedBy(field.__class__).flattened(): field_attributes.update(get_fields(schema)) FIELDS_CACHE[field.__class__] = field_attributes for attribute_name in sorted(field_attributes.keys()): attribute_field = field_attributes[attribute_name] if attribute_name in self.filtered_attributes: continue element_name = attribute_field.__name__ attribute_field = attribute_field.bind(field) force = (element_name in self.forced_fields) value = attribute_field.get(field) # For 'default', 'missing_value' etc, we want to validate against # the imported field type itself, not the field type of the # attribute if element_name in self.field_type_attributes or \ element_name in self.non_validated_field_type_attributes: attribute_field = field text = None if isinstance(value, bytes): text = value.decode('utf-8') elif isinstance(value, str): text = value elif IField.providedBy(value): serializer = get_multi_adapter( (value, field, self.request), ISchemaFieldSerializeToJson) text = serializer.serialize() if 'properties' in text: text = text['properties'] elif value is not None and (force or value != field.missing_value): text = json_compatible(value) if text: if attribute_name == 'value_type': attribute_name = 'items' result[attribute_name] = text if result['type'] == 'object': if IJSONField.providedBy(field): result.update(field.json_schema) if IDict.providedBy(field): if field.value_type: field_serializer = get_multi_adapter( (field.value_type, self.schema, self.request), ISchemaFieldSerializeToJson) result['additionalProperties'] = field_serializer.serialize() else: result['additionalProperties'] = True elif IObject.providedBy(field): schema_serializer = get_multi_adapter((field.schema, self.request), ISchemaSerializeToJson) result['properties'] = schema_serializer.serialize() if field.extra_values is not None: result.update(field.extra_values) return result
def _init( self, resource_class, resource_interface, resource_type, fhir_release, **kw ): """ """ if "default" in kw: if ( isinstance(kw["default"], (str, dict)) or kw["default"] is None ) is False: msg = ( "Only dict or string or None is accepted as " "default value but got {0}".format(type(kw["default"])) ) raise Invalid(msg) field_attributes = get_fields(IFhirField) attribute = field_attributes["resource_class"].bind(self) if resource_class is None: attribute.validate(resource_class) attribute_val = None else: attribute_val = attribute.from_unicode(resource_class) attribute.set(self, attribute_val) attribute = field_attributes["resource_interface"].bind(self) if resource_interface is None: attribute.validate(resource_interface) attribute_val = None else: attribute_val = attribute.from_unicode(resource_interface) attribute.set(self, attribute_val) attribute = field_attributes["resource_type"].bind(self) if resource_type is None: attribute.validate(resource_type) attribute_val = None else: attribute_val = attribute.from_unicode(resource_type) attribute.set(self, attribute_val) attribute = field_attributes["fhir_release"].bind(self) if fhir_release is None: attribute.validate(fhir_release) attribute_val = None else: attribute_val = attribute.from_unicode(fhir_release) # just for ensure correct value FHIR_VERSION[attribute_val] attribute.set(self, attribute_val) if self.resource_type and self.resource_class is not None: raise Invalid( "Either `resource_class` or `resource_type` value is acceptable! " "you cannot provide both!" ) if self.resource_class: try: klass = import_string(self.resource_class) self.ensure_fhir_abstract(klass) except ImportError: msg = ( "Invalid FHIR Resource class `{0}`! " "Please check the module or class name." ).format(self.resource_class) return reraise(Invalid, msg) if not IFhirResource.implementedBy(klass): raise Invalid( "{0!r} must be valid resource class from fhir.resources".format( klass ) ) self._resource_class = klass if self.resource_type: try: self._resource_class = implementer(IFhirResource)( lookup_fhir_class(self.resource_type) ) except ImportError: msg = "{0} is not valid fhir resource type!".format(self.resource_type) return reraise(Invalid, msg) if self.resource_interface: try: klass = implementer(IFhirResource)( import_string(self.resource_interface) ) except ImportError: msg = ( "Invalid FHIR Resource Interface`{0}`! " "Please check the module or class name." ).format(self.resource_interface) return reraise(Invalid, msg) if not IInterface.providedBy(klass): raise WrongType("An interface is required", klass, self.__name__) if klass is not IFhirResource and not issubclass(klass, IFhirResource): msg = "`{0!r}` must be derived from {1}".format( klass, IFhirResource.__module__ + "." + IFhirResource.__class__.__name__, ) raise Invalid(msg) self._resource_interface_class = klass
def _init(self, resource_class, resource_interface, resource_type, **kw): """ """ if "default" in kw: if (isinstance(kw["default"], (str, dict)) or kw["default"] is None) is False: msg = ("Only dict or string or None is accepted as " "default value but got {0}".format(type(kw["default"]))) raise Invalid(msg) field_attributes = get_fields(IFhirField) attribute = field_attributes['resource_class'].bind(self) if resource_class is None: attribute.validate(resource_class) attribute_val = None else: attribute_val = attribute.from_unicode(resource_class) attribute.set(self, attribute_val) attribute = field_attributes['resource_interface'].bind(self) if resource_interface is None: attribute.validate(resource_interface) attribute_val = None else: attribute_val = attribute.from_unicode(resource_interface) attribute.set(self, attribute_val) attribute = field_attributes['resource_type'].bind(self) if resource_type is None: attribute.validate(resource_type) attribute_val = None else: attribute_val = attribute.from_unicode(resource_type) attribute.set(self, attribute_val) if self.resource_type and self.resource_class is not None: raise Invalid( "Either `resource_class` or `resource_type` value is acceptable! you cannot provide both!" ) if self.resource_class: try: klass = import_string(self.resource_class) except ImportError: msg = "Invalid FHIR Resource class `{0}`! Please check the module or class name.".format( self.resource_class) t, v, tb = sys.exc_info() try: reraise(Invalid(msg), None, tb) finally: del t, v, tb if not IFhirResource.implementedBy(klass): raise Invalid( "{0!r} must be valid resource class from fhir.resources". format(klass)) self._resource_class = klass if self.resource_type: try: self._resource_class = resource_type_to_resource_cls( self.resource_type) except ImportError: msg = "{0} is not valid fhir resource type!".format( self.resource_type) t, v, tb = sys.exc_info() try: reraise(Invalid(msg), None, tb) finally: del t, v, tb raise Invalid(msg) if self.resource_interface: try: klass = import_string(self.resource_interface) except ImportError: msg = "Invalid FHIR Resource Interface`{0}`! Please check the module or class name.".format( self.resource_interface) t, v, tb = sys.exc_info() try: reraise(Invalid(msg), None, tb) finally: del t, v, tb if not IInterface.providedBy(klass): raise WrongType("An interface is required", klass, self.__name__) if klass is not IFhirResource and not issubclass( klass, IFhirResource): msg = "`{0!r}` must be derived from {1}".format( klass, IFhirResource.__module__ + "." + IFhirResource.__class__.__name__, ) raise Invalid(msg) self._resource_interface_class = klass
async def __call__(self): field = self.get_field() result = {'type': self.field_type} # caching the field_attributes here improves performance dramatically if field.__class__ in FIELDS_CACHE: field_attributes = FIELDS_CACHE[field.__class__].copy() else: field_attributes = {} for schema in implementedBy(field.__class__).flattened(): field_attributes.update(get_fields(schema)) FIELDS_CACHE[field.__class__] = field_attributes for attribute_name in sorted(field_attributes.keys()): attribute_field = field_attributes[attribute_name] if attribute_name in self.filtered_attributes: continue element_name = attribute_field.__name__ attribute_field = attribute_field.bind(field) force = (element_name in self.forced_fields) value = attribute_field.get(field) # For 'default', 'missing_value' etc, we want to validate against # the imported field type itself, not the field type of the # attribute if element_name in self.field_type_attributes or \ element_name in self.non_validated_field_type_attributes: attribute_field = field text = None if isinstance(value, bytes): text = value.decode('utf-8') elif isinstance(value, str): text = value elif IField.providedBy(value): serializer = get_multi_adapter((value, field, self.request), ISchemaFieldSerializeToJson) text = await serializer() if 'properties' in text: text = text['properties'] elif value is not None and (force or value != field.missing_value): text = json_compatible(value) if text: if attribute_name == 'value_type': attribute_name = 'items' result[attribute_name] = text if result['type'] == 'object': if IJSONField.providedBy(field): result['properties'] = field.json_schema if IDict.providedBy(field): if field.value_type: field_serializer = get_multi_adapter( (field.value_type, self.schema, self.request), ISchemaFieldSerializeToJson) result['additionalProperties'] = await field_serializer() else: result['additionalProperties'] = True elif IObject.providedBy(field): schema_serializer = get_multi_adapter( (field.schema, self.request), ISchemaSerializeToJson) result['properties'] = await schema_serializer() if field.extra_values is not None: result.update(field.extra_values) return result
async def __call__(self): result = {'type': self.field_type} # caching the field_attributes here improves performance dramatically if self.field.__class__ in FIELDS_CACHE: field_attributes = FIELDS_CACHE[self.field.__class__].copy() else: field_attributes = {} for schema in implementedBy(self.field.__class__).flattened(): field_attributes.update(get_fields(schema)) FIELDS_CACHE[self.field.__class__] = field_attributes for attribute_name in sorted(field_attributes.keys()): attribute_field = field_attributes[attribute_name] if attribute_name in self.filtered_attributes: continue element_name = attribute_field.__name__ attribute_field = attribute_field.bind(self.field) force = (element_name in self.forced_fields) value = attribute_field.get(self.field) # For 'default', 'missing_value' etc, we want to validate against # the imported field type itself, not the field type of the # attribute if element_name in self.field_type_attributes or \ element_name in self.non_validated_field_type_attributes: attribute_field = self.field text = None if isinstance(value, bytes): text = value.decode('utf-8') elif isinstance(value, str): text = value elif IField.providedBy(value): serializer = get_multi_adapter( (value, self.field, self.request), ISchemaFieldSerializeToJson) text = await serializer() elif value is not None and (force or value != self.field.missing_value): text = json_compatible(value) # handle i18n # if isinstance(value, Message): # child.set(ns('domain', I18N_NAMESPACE), value.domain) # if not value.default: # child.set(ns('translate', I18N_NAMESPACE), '') # else: # child.set(ns('translate', I18N_NAMESPACE), child.text) # child.text = converter.toUnicode(value.default) if text: if attribute_name == 'value_type': attribute_name = 'items' result[attribute_name] = text if result['type'] == 'object': if IJSONField.providedBy(self.field): result['properties'] = self.field.json_schema else: schema_serializer = get_multi_adapter( (self.field.schema, self.request), ISchemaSerializeToJson) result['properties'] = await schema_serializer() return result
async def set_schema( self, schema, obj, data, errors, validate_all=False, behavior=False): write_permissions = merged_tagged_value_dict(schema, write_permission.key) for name, field in get_fields(schema).items(): if field.readonly: continue if behavior: found = False if schema.__identifier__ in data: sdata = data[schema.__identifier__] data_value = sdata[name] if name in sdata else None found = True if name in sdata else False else: data_value = data[name] if name in data else None found = True if name in data else False f = schema.get(name) if found: if not self.check_permission(write_permissions.get(name)): continue try: value = await self.get_value(f, obj, data_value) except ValueError as e: errors.append({ 'message': e.message, 'field': name, 'error': e}) except ValidationError as e: errors.append({ 'message': e.doc(), 'field': name, 'error': e}) except ValueDeserializationError as e: errors.append({ 'message': e.message, 'field': name, 'error': e}) except Invalid as e: errors.append({ 'message': e.args[0], 'field': name, 'error': e}) else: # record object changes for potential future conflict resolution try: await apply_coroutine(field.set, obj, value) except Exception: logger.warning( 'Error setting data on field, falling back to setattr', exc_info=True) setattr(obj, name, value) else: if f.required and not hasattr(obj, name): errors.append({ 'message': 'Required parameter', 'field': name, 'error': ValueError('Required parameter')}) if validate_all: invariant_errors = [] try: schema.validateInvariants(object, invariant_errors) except Invalid: # Just collect errors pass validation = [(None, e) for e in invariant_errors] if len(validation): for e in validation: errors.append({ 'message': e[1].doc(), 'field': e[0], 'error': e })
async def set_schema( self, schema, obj, data, errors, validate_all=False, behavior=False): write_permissions = merged_tagged_value_dict(schema, write_permission.key) for name, field in get_fields(schema).items(): if name in RESERVED_ATTRS: continue if field.readonly: continue if behavior: found = False if schema.__identifier__ in data: sdata = data[schema.__identifier__] data_value = sdata[name] if name in sdata else None found = True if name in sdata else False else: data_value = data[name] if name in data else None found = True if name in data else False if found: if not self.check_permission(write_permissions.get(name)): raise Unauthorized('Write permission not allowed') try: field = field.bind(obj) value = await self.get_value(field, obj, data_value) except ValueError as e: errors.append({ 'message': 'Value error', 'field': name, 'error': e}) except ValidationError as e: errors.append({ 'message': e.doc(), 'field': name, 'error': e}) except ValueDeserializationError as e: errors.append({ 'message': e.message, 'field': name, 'error': e}) except Invalid as e: errors.append({ 'message': e.args[0], 'field': name, 'error': e}) else: # record object changes for potential future conflict resolution try: await apply_coroutine(field.set, obj, value) except ValidationError as e: errors.append({ 'message': e.doc(), 'field': name, 'error': e}) except ValueDeserializationError as e: errors.append({ 'message': e.message, 'field': name, 'error': e}) except AttributeError: logger.warning( f'AttributeError setting data on field {name}', exc_info=True) except Exception: if not isinstance(getattr(type(obj), name, None), property): # we can not set data on properties logger.warning( 'Error setting data on field, falling back to setattr', exc_info=True) setattr(obj, name, value) else: logger.warning( 'Error setting data on field', exc_info=True) else: if validate_all and field.required and getattr(obj, name, None) is None: errors.append({ 'message': 'Required parameter', 'field': name, 'error': ValueError('Required parameter')}) if validate_all: invariant_errors = [] try: schema.validateInvariants(object, invariant_errors) except Invalid: # Just collect errors pass validation = [(None, e) for e in invariant_errors] if len(validation): for error in validation: errors.append({ 'message': error[1].doc(), 'field': error[0], 'error': error })