def validate_required_primitive_elements_2851( cls, values: typing.Dict[str, typing.Any]) -> typing.Dict[str, typing.Any]: """https://www.hl7.org/fhir/extensibility.html#Special-Case In some cases, implementers might find that they do not have appropriate data for an element with minimum cardinality = 1. In this case, the element must be present, but unless the resource or a profile on it has made the actual value of the primitive data type mandatory, it is possible to provide an extension that explains why the primitive value is not present. """ required_fields = [("uid", "uid__ext")] _missing = object() def _fallback(): return "" errors: typing.List["ErrorWrapper"] = [] for name, ext in required_fields: field = cls.__fields__[name] ext_field = cls.__fields__[ext] value = values.get(field.alias, _missing) if value not in (_missing, None): continue ext_value = values.get(ext_field.alias, _missing) missing_ext = True if ext_value not in (_missing, None): if isinstance(ext_value, dict): missing_ext = len(ext_value.get("extension", [])) == 0 elif (getattr(ext_value.__class__, "get_resource_type", _fallback)() == "FHIRPrimitiveExtension"): if ext_value.extension and len(ext_value.extension) > 0: missing_ext = False else: validate_pass = True for validator in ext_field.type_.__get_validators__(): try: ext_value = validator(v=ext_value) except ValidationError as exc: errors.append( ErrorWrapper(exc, loc=ext_field.alias)) validate_pass = False if not validate_pass: continue if ext_value.extension and len(ext_value.extension) > 0: missing_ext = False if missing_ext: if value is _missing: errors.append(ErrorWrapper(MissingError(), loc=field.alias)) else: errors.append( ErrorWrapper(NoneIsNotAllowedError(), loc=field.alias)) if len(errors) > 0: raise ValidationError(errors, cls) # type: ignore return values
def validate_model_attributes_tel(cls, values): """ Validates that model attributes contain correct TEL expressions without cyclic dependencies """ if 'attributes' in values: attributes: List[FdqModelAttribute] = values['attributes'] # get set of available taxon slugs available_taxon_slugs = set( cls._get_available_attrs_taxon_slugs(attributes)) # our TEL visitor only verifies here that all available TEL transformations are valid # we dont care about the SQL output here invalid_taxons_attr = {} for attribute in attributes: try: # we dont really care from which taxon we start # if there is cyclic reference somewhere, we will run into it eventually taxon_slug = next(filter(None, attribute.field_map)) except StopIteration: # we dont care, if we dont find the taxon - this check is performed somewhere else continue try: # initialize options for the visitor visitor_parameters = AttributeValidationTelVisitorParams( taxon_slug, attributes) tree = ModelTelDialect.parse(attribute.data_reference) visitor = AttributeValidationTelVisitor(visitor_parameters) visitor.visit(tree) # check whether this TEL transformation uses any taxons which arent available in this model additional_taxons = visitor.result.used_taxon_slugs - available_taxon_slugs if len(additional_taxons) > 0: invalid_taxons_attr[ attribute.data_reference] = additional_taxons except ModelTelCyclicReferenceException: # there's no point in checking other attributes when we run into cyclic reference raise ValueError( f'Data reference "{attribute.data_reference}" contains TEL transformation with cyclic reference' ) # if we found any attribute with missing taxons, output them all in one error message if invalid_taxons_attr: attribute_msgs = [ f'Data reference "{attr_key}": {", ".join(taxon_slugs)} not available in this model' for attr_key, taxon_slugs in invalid_taxons_attr.items() ] raise ValidationError([ ErrorWrapper(ValueError(msg), 'attributes') for msg in attribute_msgs ], cls) return values
async def app(request: Request) -> Response: try: body = None if body_field: if is_body_form: raw_body = await request.form() form_fields = {} for field, value in raw_body.items(): if isinstance(value, UploadFile): form_fields[field] = await value.read() else: form_fields[field] = value if form_fields: body = form_fields else: body_bytes = await request.body() if body_bytes: body = await request.json() except Exception as e: logging.error("Error getting request body", e) raise HTTPException( status_code=400, detail="There was an error parsing the body" ) values, errors = await solve_dependencies( request=request, dependant=dependant, body=body ) if errors: errors_out = ValidationError(errors) raise HTTPException( status_code=HTTP_422_UNPROCESSABLE_ENTITY, detail=errors_out.errors() ) else: assert dependant.call is not None, "dependant.call must me a function" if is_coroutine: raw_response = await dependant.call(**values) else: raw_response = await run_in_threadpool(dependant.call, **values) if isinstance(raw_response, Response): return raw_response response_data = serialize_response( field=response_field, response=raw_response ) return content_type(content=response_data, status_code=status_code)
async def app(request: Request) -> Response: try: body = None if body_field: if is_body_form: body = await request.form() else: body_bytes = await request.body() if body_bytes: body = await request.json() except Exception as e: logging.error(f"Error getting request body: {e}") raise HTTPException( status_code=400, detail="There was an error parsing the body" ) values, errors, background_tasks = await solve_dependencies( request=request, dependant=dependant, body=body ) if errors: errors_out = ValidationError(errors) raise HTTPException( status_code=HTTP_422_UNPROCESSABLE_ENTITY, detail=errors_out.errors() ) else: assert dependant.call is not None, "dependant.call must me a function" if is_coroutine: raw_response = await dependant.call(**values) else: raw_response = await run_in_threadpool(dependant.call, **values) if isinstance(raw_response, Response): if raw_response.background is None: raw_response.background = background_tasks return raw_response response_data = serialize_response( field=response_field, response=raw_response ) return response_class( content=response_data, status_code=status_code, background=background_tasks, )
def level2_validation_handler(request: Request, exc: ValidationError): """ Most validation errors are caught immediately, but we do some secondary validation when populating our xxx_answers tables this catches those and returns a 422 """ rslogger.error(exc) return JSONResponse( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, content=jsonable_encoder({"detail": exc.errors()}), )
async def serialize_response( *, field: ModelField = None, response_content: Any, include: Union[SetIntStr, DictIntStrAny] = None, exclude: Union[SetIntStr, DictIntStrAny] = set(), by_alias: bool = True, exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, is_coroutine: bool = True, ) -> Any: if field: errors = [] response_content = _prepare_response_content( response_content, by_alias=by_alias, exclude_unset=exclude_unset, exclude_defaults=exclude_defaults, exclude_none=exclude_none, ) if is_coroutine: value, errors_ = field.validate(response_content, {}, loc=("response",)) else: value, errors_ = await run_in_threadpool( field.validate, response_content, {}, loc=("response",) ) if isinstance(errors_, ErrorWrapper): errors.append(errors_) elif isinstance(errors_, list): errors.extend(errors_) if errors: raise ValidationError(errors, field.type_) return jsonable_encoder( value, include=include, exclude=exclude, by_alias=by_alias, exclude_unset=exclude_unset, exclude_defaults=exclude_defaults, exclude_none=exclude_none, ) else: return jsonable_encoder( response_content, include=include, exclude=exclude, by_alias=by_alias, exclude_unset=exclude_unset, exclude_defaults=exclude_defaults, exclude_none=exclude_none, )
def create_workflow(*, db_session: Session = Depends(get_db), workflow_in: WorkflowCreate): """Create a new workflow.""" plugin_instance = plugin_service.get_instance( db_session=db_session, plugin_instance_id=workflow_in.plugin_instance.id ) if not plugin_instance: raise ValidationError( [ErrorWrapper(NotFoundError(msg="No plugin instance found."), loc="plugin_instance")], model=WorkflowCreate, ) workflow = create(db_session=db_session, workflow_in=workflow_in) return workflow
def serialize_response(*, field: Field = None, response: Response) -> Any: if field: errors = [] value, errors_ = field.validate(response, {}, loc=("response", )) if isinstance(errors_, ErrorWrapper): errors.append(errors_) elif isinstance(errors_, list): errors.extend(errors_) if errors: raise ValidationError(errors) return jsonable_encoder(value) else: return jsonable_encoder(response)
def create_term(*, db_session: Session = Depends(get_db), term_in: TermCreate): """Create a new term.""" term = get_by_text(db_session=db_session, text=term_in.text) if term: raise ValidationError( [ ErrorWrapper( ExistsError(msg="A term with this name already exists."), loc="name") ], model=TermCreate, ) term = create(db_session=db_session, term_in=term_in) return term
def validate_extension_or_fhir_comment_required( cls, values: typing.Dict[str, typing.Any]) -> typing.Dict[str, typing.Any]: """Conditional Required Validation""" errors = list() extension = values.get("extension", None) fhir_comments = values.get("fhir_comments", None) if extension is None and fhir_comments is None: errors.append(ErrorWrapper(MissingError(), loc="extension")) raise ValidationError(errors, cls) # type: ignore return values
def create_search_filter(*, db_session: Session = Depends(get_db), search_filter_in: SearchFilterCreate): """Create a new filter.""" try: return create(db_session=db_session, search_filter_in=search_filter_in) except IntegrityError: raise ValidationError( [ ErrorWrapper(ExistsError( msg="A search filter with this name already exists."), loc="name") ], model=SearchFilterRead, )
def get_default_or_raise(*, db_session) -> Organization: """Returns the default organization or raise a ValidationError if one doesn't exist.""" organization = get_default(db_session=db_session) if not organization: raise ValidationError( [ ErrorWrapper( NotFoundError(msg="No default organization defined."), loc="organization", ) ], model=OrganizationRead, ) return organization
def get_default_or_raise(*, db_session, project_id: int) -> IncidentType: """Returns the default incident_type or raise a ValidationError if one doesn't exist.""" incident_type = get_default(db_session=db_session, project_id=project_id) if not incident_type: raise ValidationError( [ ErrorWrapper( NotFoundError(msg="No default incident_type defined."), loc="incident_type", ) ], model=IncidentTypeRead, ) return incident_type
def create_project(*, db_session: Session = Depends(get_db), project_in: ProjectCreate): """Create a new project.""" project = get_by_name(db_session=db_session, name=project_in.name) if project: raise ValidationError( [ ErrorWrapper(ExistsError( msg="A project with this name already exists."), loc="name") ], model=ProjectCreate, ) project = create(db_session=db_session, project_in=project_in) return project
def update_instance( *, db_session, plugin_instance: PluginInstance, plugin_instance_in: PluginInstanceUpdate) -> PluginInstance: """Updates a plugin instance.""" plugin_instance_data = plugin_instance.dict() update_data = plugin_instance_in.dict(skip_defaults=True) if plugin_instance_in.enabled: # user wants to enable the plugin if not plugin_instance.plugin.multiple: # we can't have multiple plugins of this type disable the currently enabled one enabled_plugin_instances = get_enabled_instances_by_type( db_session=db_session, project_id=plugin_instance.project_id, plugin_type=plugin_instance.plugin.type, ) if enabled_plugin_instances: enabled_plugin_instances[0].enabled = False if not plugin_instance_in.enabled: # user wants to disable the plugin if plugin_instance.plugin.type == OncallPlugin.type: oncall_services = service_service.get_all_by_type_and_status( db_session=db_session, service_type=plugin_instance.plugin.slug, is_active=True) if oncall_services: raise ValidationError( [ ErrorWrapper( InvalidConfigurationError( msg= f"Cannot disable plugin instance: {plugin_instance.plugin.title}. One or more oncall services depend on it. " ), loc="plugin_instance", ) ], model=PluginInstanceUpdate, ) for field in plugin_instance_data: if field in update_data: setattr(plugin_instance, field, update_data[field]) plugin_instance.configuration = plugin_instance_in.configuration db_session.commit() return plugin_instance
def create_definition(*, db_session: Session = Depends(get_db), definition_in: DefinitionCreate): """Create a new definition.""" definition = get_by_text(db_session=db_session, text=definition_in.text) if definition: raise ValidationError( [ ErrorWrapper(ExistsError( msg="A description with this text already exists."), loc="text") ], model=DefinitionRead, ) definition = create(db_session=db_session, definition_in=definition_in) return definition
def create_tag_type(*, db_session: Session = Depends(get_db), tag_type_in: TagTypeCreate): """Create a new tag type.""" try: tag_type = create(db_session=db_session, tag_type_in=tag_type_in) except IntegrityError: raise ValidationError( [ ErrorWrapper(ExistsError( msg="A tag type with this name already exists."), loc="name") ], model=TagTypeCreate, ) return tag_type
async def validate_hook_url(url: str) -> t.Optional[ValidationError]: """Validator for discord webhook urls.""" async def validate() -> t.Optional[str]: if not isinstance(url, str): raise ValueError("Webhook URL must be a string.") if "discord.com/api/webhooks/" not in url: raise ValueError("URL must be a discord webhook.") try: async with httpx.AsyncClient() as client: response = await client.get(url) response.raise_for_status() except httpx.RequestError as error: # Catch exceptions in request format raise ValueError( f"Encountered error while trying to connect to url: `{error}`") except httpx.HTTPStatusError as error: # Catch exceptions in response status = error.response.status_code if status == 401: raise ValueError( "Could not authenticate with target. Please check the webhook url." ) elif status == 404: raise ValueError( "Target could not find webhook url. Please check the webhook url." ) else: raise ValueError( f"Unknown error ({status}) while connecting to target: {error}" ) return url # Validate, and return errors, if any try: await validate() except Exception as e: loc = (WebHook.__name__.lower(), WebHook.URL.value) return ValidationError([ErrorWrapper(e, loc=loc)], _WebHook)
def create_team(*, db_session: Session = Depends(get_db), team_contact_in: TeamContactCreate): """Create a new team contact.""" team = get_by_email(db_session=db_session, email=team_contact_in.email, project_id=team_contact_in.project.id) if team: raise ValidationError( [ ErrorWrapper( ExistsError(msg="A team with this name already exists."), loc="name") ], model=TeamContactCreate, ) team = create(db_session=db_session, team_contact_in=team_contact_in) return team
def get_by_name_or_raise(*, db_session, project_id: int, incident_in: IncidentRead) -> Incident: """Returns an incident based on a given name or raises ValidationError""" incident = get_by_name(db_session=db_session, project_id=project_id, name=incident_in.name) if not incident: raise ValidationError( [ ErrorWrapper( NotFoundError( msg="Incident not found.", query=incident_in.name, ), loc="incident", ) ], model=IncidentRead, ) return incident
def get_by_name_or_raise(*, db_session, alert_in=AlertRead) -> AlertRead: """Returns the alert specified or raises ValidationError.""" alert = get_by_name(db_session=db_session, name=alert_in.name) if not alert: raise ValidationError( [ ErrorWrapper( NotFoundError( msg="Alert not found.", alert=alert_in.name, ), loc="alert", ) ], model=AlertRead, ) return alert
def parse_raw( cls: Type["Model"], b: StrBytes, *, content_type: str = "application/yaml", # This is a reasonable default, right? encoding: str = "utf-8", proto: ExtendedProto = None, allow_pickle: bool = False, ) -> "Model": # NOTE: Type checking this function is a PITA, because we're overriding # BaseModel.parse_raw, but not inheriting it due to the MRO problem! # Check whether we're specifically asked to parse YAML is_yaml = is_yaml_requested(content_type=content_type, proto=proto) # Note that JSON is a subset of the YAML 1.2 spec, so we should be OK # even if JSON is passed. It will be slower, however. if is_yaml: try: cfg = cast(YamlModelMixinConfig, cls.__config__) obj = cfg.yaml_loads(b) except RecursionError as e: raise ValueError( "YAML files with recursive references are unsupported." ) from e except ValidationError: raise except Exception as e: raise ValidationError([ErrorWrapper(e, loc=ROOT_KEY)], cls) from e else: obj = load_str_bytes( b, proto=proto, content_type=content_type, encoding=encoding, allow_pickle=allow_pickle, json_loads=cls.__config__.json_loads, ) res = cls.parse_obj(obj) # type: ignore return cast("Model", res)
def get_by_slug_or_raise(*, db_session, organization_in=OrganizationRead) -> Organization: """Returns the organization specified or raises ValidationError.""" organization = get_by_name(db_session=db_session, name=organization_in.name) if not organization: raise ValidationError( [ ErrorWrapper( NotFoundError(msg="Organization not found.", organization=organization_in.name), loc="organization", ) ], model=OrganizationRead, ) return organization
async def validation_exception_response(request: Request, exc: ValidationError): # logger.debug(traceback.format_exc()) print(traceback.format_exc()) error = exc.errors()[0] try: field = error['loc'][1] except IndexError: field = '' err_type = error['type'] if err_type == 'type_error.enum': msg = error['msg'].replace('value', field, 1) else: msg = f"{error['msg']}: {field}" return UJSONResponse( status_code=400, content={ 'status': 'error', 'message': msg }, )
async def serialize_response( *, field: ModelField = None, response: Response, include: Union[SetIntStr, DictIntStrAny] = None, exclude=None, by_alias: bool = True, exclude_unset: bool = False, is_coroutine: bool = True, ) -> Any: if exclude is None: exclude = set() if field: errors = [] if exclude_unset and isinstance(response, BaseModel): if PYDANTIC_1: response = response.dict(exclude_unset=exclude_unset) else: response = response.dict( skip_defaults=exclude_unset) # pragma: nocover if is_coroutine: value, errors_ = field.validate(response, {}, loc=("response", )) else: value, errors_ = await run_in_threadpool(field.validate, response, {}, loc=("response", )) if isinstance(errors_, ErrorWrapper): errors.append(errors_) elif isinstance(errors_, list): errors.extend(errors_) if errors: raise ValidationError(errors, field.type_) return jsonable_encoder( value, include=include, exclude=exclude, by_alias=by_alias, exclude_unset=exclude_unset, ) else: return jsonable_encoder(response)
def get_window_sizes_from_args(window_sizes: List[str]) -> List[WindowSize]: result = [] errors = [] for window_size in window_sizes: try: width, height = window_size.split(",") result.append(WindowSize(width=int(width), height=int(height))) except ValueError: errors.append( ErrorWrapper( BadParameter( message= f"🔥 `{window_size}` is not a valid window size. Must be of type `1920,1080`" ), loc="window_size", )) if errors: raise ValidationError(errors=errors, model=WindowSize) return result
def get_by_name_or_raise(*, db_session, project_id: int, incident_type_in=IncidentTypeRead) -> IncidentType: """Returns the incident_type specified or raises ValidationError.""" incident_type = get_by_name(db_session=db_session, project_id=project_id, name=incident_type_in.name) if not incident_type: raise ValidationError( [ ErrorWrapper( NotFoundError(msg="IncidentType not found.", incident_type=incident_type_in.name), loc="incident_type", ) ], model=IncidentTypeRead, ) return incident_type
def login_user( user_in: UserLogin, organization: OrganizationSlug, db_session: Session = Depends(get_db), ): user = get_by_email(db_session=db_session, email=user_in.email) if user and user.check_password(user_in.password): return {"token": user.token} raise ValidationError( [ ErrorWrapper( InvalidUsernameError(msg="Invalid username."), loc="username", ), ErrorWrapper( InvalidPasswordError(msg="Invalid password."), loc="password", ), ], model=UserLogin, )
def get_by_name_or_raise(*, db_session, project_id: int, tag_type_in=TagTypeRead) -> TagType: """Returns the tag_type specified or raises ValidationError.""" tag_type = get_by_name(db_session=db_session, project_id=project_id, name=tag_type_in.name) if not tag_type: raise ValidationError( [ ErrorWrapper( NotFoundError(msg="TagType not found.", tag_type=tag_type_in.name), loc="tag_type", ) ], model=TagTypeRead, ) return tag_type
def register_user( user_in: UserRegister, organization: OrganizationSlug, db_session: Session = Depends(get_db), ): user = get_by_email(db_session=db_session, email=user_in.email) if user: raise ValidationError( [ ErrorWrapper( InvalidConfigurationError( msg="A user with this email already exists."), loc="email", ) ], model=UserRegister, ) user = create(db_session=db_session, organization=organization, user_in=user_in) return user