class GroupWithMembers(Schema): uuid = fields.UUID() fullname = fields.Str() shortname = fields.Str() members = fields.Nested(UserWithUUID(many=True)) coordinators = fields.Nested(UserWithUUID(many=True))
def user_registration_input(request: FlaskRequest) -> Type[Schema]: attributes: MarshmallowSchema = {} attributes["name"] = fields.Str(required=True) attributes["surname"] = fields.Str(required=True) # This is because Email is not typed on marshmallow attributes["email"] = fields.Email( # type: ignore required=True, metadata={"label": "Username (email address)"}, validate=validate.Length(max=100), ) attributes["password"] = fields.Str( required=True, validate=validate.Length(min=auth.MIN_PASSWORD_LENGTH), metadata={"password": True}, ) attributes["password_confirm"] = fields.Str( required=True, validate=validate.Length(min=auth.MIN_PASSWORD_LENGTH), metadata={ "label": "Password confirmation", "password": True }, ) if custom_fields := mem.customizer.get_custom_input_fields( request=None, scope=mem.customizer.REGISTRATION): attributes.update(custom_fields)
class Pagination(PartialSchema): get_total = fields.Boolean( required=False, description="Request the total number of elements" ) page = fields.Int( required=False, description="Current page number", validate=validate.Range(min=1), ) size = fields.Int( required=False, description="Number of elements to retrieve", validate=validate.Range(min=1, max=100), ) sort_order = fields.Str( validate=validate.OneOf(["asc", "desc"]), required=False, missing="asc" ) sort_by = fields.Str(required=False, missing=None) input_filter = fields.Str(required=False, missing=None) @post_load def verify_parameters(self, data, **kwargs): if "get_total" in data: data["page"] = None data["size"] = None else: data.setdefault("get_total", False) data.setdefault("page", 1) data.setdefault("size", 20) return data
def getProfileData(): # as defined in Marshmallow.schema.from_dict attributes: Dict[str, Union[fields.Field, type]] = {} attributes["uuid"] = fields.UUID(required=True) attributes["email"] = fields.Email(required=True) attributes["name"] = fields.Str(required=True) attributes["surname"] = fields.Str(required=True) attributes["isAdmin"] = fields.Boolean(required=True) attributes["isStaff"] = fields.Boolean(required=True) attributes["isCoordinator"] = fields.Boolean(required=True) attributes["privacy_accepted"] = fields.Boolean(required=True) attributes["is_active"] = fields.Boolean(required=True) attributes["expiration"] = fields.DateTime(allow_none=True, format=ISO8601UTC) attributes["roles"] = fields.Dict(required=True) attributes["last_password_change"] = fields.DateTime( required=True, format=ISO8601UTC ) attributes["first_login"] = fields.DateTime(required=True, format=ISO8601UTC) attributes["last_login"] = fields.DateTime(required=True, format=ISO8601UTC) attributes["group"] = fields.Nested(Group) attributes["two_factor_enabled"] = fields.Boolean(required=True) if custom_fields := mem.customizer.get_custom_output_fields(None): attributes.update(custom_fields)
def admin_user_output(many: bool = True) -> Schema: attributes: MarshmallowSchema = {} attributes["uuid"] = fields.UUID() # This is because Email is not typed on marshmallow attributes["email"] = fields.Email() # type: ignore attributes["name"] = fields.Str() attributes["surname"] = fields.Str() attributes["first_login"] = fields.DateTime(allow_none=True, format=ISO8601UTC) attributes["last_login"] = fields.DateTime(allow_none=True, format=ISO8601UTC) attributes["last_password_change"] = fields.DateTime(allow_none=True, format=ISO8601UTC) attributes["is_active"] = fields.Boolean() attributes["privacy_accepted"] = fields.Boolean() attributes["roles"] = fields.List(fields.Nested(Role)) attributes["expiration"] = fields.DateTime(allow_none=True, format=ISO8601UTC) if Connector.authentication_service == "neo4j": attributes["belongs_to"] = fields.Neo4jRelationshipToSingle( Group, data_key="group") else: attributes["belongs_to"] = fields.Nested(Group, data_key="group") if custom_fields := mem.customizer.get_custom_output_fields(None): attributes.update(custom_fields)
def profile_output() -> Schema: attributes: MarshmallowSchema = {} attributes["uuid"] = fields.UUID(required=True) # This is because Email is not typed on marshmallow attributes["email"] = fields.Email(required=True) # type: ignore attributes["name"] = fields.Str(required=True) attributes["surname"] = fields.Str(required=True) attributes["isAdmin"] = fields.Boolean(required=True) attributes["isStaff"] = fields.Boolean(required=True) attributes["isCoordinator"] = fields.Boolean(required=True) attributes["privacy_accepted"] = fields.Boolean(required=True) attributes["is_active"] = fields.Boolean(required=True) attributes["expiration"] = fields.DateTime(allow_none=True, format=ISO8601UTC) attributes["roles"] = fields.Dict(required=True) attributes["last_password_change"] = fields.DateTime(required=True, format=ISO8601UTC) attributes["first_login"] = fields.DateTime(required=True, format=ISO8601UTC) attributes["last_login"] = fields.DateTime(required=True, format=ISO8601UTC) if Connector.authentication_service == "neo4j": attributes["belongs_to"] = fields.Neo4jRelationshipToSingle( Group, data_key="group") else: attributes["belongs_to"] = fields.Nested(Group, data_key="group") attributes["two_factor_enabled"] = fields.Boolean(required=True) if custom_fields := mem.customizer.get_custom_output_fields(None): attributes.update(custom_fields)
class TokenSchema(Schema): id = fields.Str() IP = fields.Str() location = fields.Str() token = fields.Str() emitted = fields.DateTime(format=ISO8601UTC) expiration = fields.DateTime(format=ISO8601UTC) last_access = fields.DateTime(format=ISO8601UTC)
class Input1(Schema): unique_delimited_list = UniqueDelimitedList(fields.Str(), delimiter=",", required=True) advanced_list = AdvancedList(fields.Str(), unique=True, min_items=2, required=True)
class LoginsSchema(Schema): # This is because Email is not typed on marshmallow username = fields.Email() # type: ignore date = fields.DateTime(format=ISO8601UTC) IP = fields.Str() location = fields.Str() failed = fields.Boolean() flushed = fields.Boolean()
class MailOutput(Schema): html_body = fields.Str() plain_body = fields.Str() subject = fields.Str() # # This is because Email is not typed on marshmallow to = fields.Email() # type: ignore cc = fields.List(fields.Email()) # type: ignore bcc = fields.List(fields.Email()) # type: ignore
class DatasetOutput(Schema): uuid = fields.Str(required=True) name = fields.Str(required=True) description = fields.Str(required=False) status = fields.Str(required=False) technical = fields.Neo4jRelationshipToSingle(TechnicalMetadata) phenotype = fields.Neo4jRelationshipToSingle(Phenotype) files = fields.Neo4jRelationshipToCount() readonly = fields.Bool(dump_default=True)
def build_schema(self, model: Type[Any]) -> None: # Get the full list of parent classes from model to object classes = inspect.getmro(model) starting_point = False # Iterate in reversed order to start from object for c in reversed(classes): # Skip all parentes up to StructuredNode and StructuredRel (included) if not starting_point: # Found the starting point, next class will be descended up to model if c == StructuredNode or c == StructuredRel: starting_point = True # skip all parent up to StructuredNode and StructuredRel INCLUDED continue # Iterate all class attributes to find neomodel properties for attribute in c.__dict__: prop = getattr(c, attribute) if not isinstance(prop, properties.Property): continue # self.fields can be None when the special value * is given in input if self.fields and attribute not in self.fields: continue # log.info("Including property {}.{}", model.__name__, attribute) if isinstance(prop, properties.StringProperty): if prop.choices is None: self.declared_fields[attribute] = fields.Str() else: self.declared_fields[attribute] = fields.Neo4jChoice( prop.choices) elif isinstance(prop, properties.BooleanProperty): self.declared_fields[attribute] = fields.Boolean() elif isinstance(prop, properties.IntegerProperty): self.declared_fields[attribute] = fields.Integer() elif isinstance(prop, properties.FloatProperty): self.declared_fields[attribute] = fields.Float() elif isinstance(prop, properties.EmailProperty): # This is because Nested is not typed on marshmallow self.declared_fields[attribute] = fields.Email( ) # type: ignore elif isinstance(prop, properties.DateTimeProperty): self.declared_fields[attribute] = fields.AwareDateTime() elif isinstance(prop, properties.DateProperty): self.declared_fields[attribute] = fields.Date() elif isinstance(prop, properties.UniqueIdProperty): self.declared_fields[attribute] = fields.Str() else: # pragma: no cover log.error( "Unsupport neomodel property: {}, fallback to StringProperty", prop.__class__.__name__, ) self.declared_fields[attribute] = fields.Str()
class StudyOutput(Schema): uuid = fields.Str(required=True) name = fields.Str(required=True) description = fields.Str(required=True) # Number of related datasets datasets = fields.Neo4jRelationshipToCount() phenotypes = fields.Neo4jRelationshipToCount() technicals = fields.Neo4jRelationshipToCount() readonly = fields.Bool(dump_default=True) owning_group_name = fields.Str()
def profile_patch_input() -> Schema: attributes: MarshmallowSchema = {} attributes["name"] = fields.Str(metadata={"label": "First Name"}) attributes["surname"] = fields.Str(metadata={"label": "Last Name"}) attributes["privacy_accepted"] = fields.Boolean() if custom_fields := mem.customizer.get_custom_input_fields( request=None, scope=mem.customizer.PROFILE): attributes.update(custom_fields)
def admin_group_input(request: FlaskRequest) -> Type[Schema]: attributes: MarshmallowSchema = {} attributes["shortname"] = fields.Str( required=True, metadata={"description": "Short name"}) attributes["fullname"] = fields.Str(required=True, metadata={"description": "Full name"}) return Schema.from_dict(attributes, name="GroupDefinition")
def group_users_output() -> Schema: attributes: MarshmallowSchema = {} # This is because Email is not typed on marshmallow attributes["email"] = fields.Email() # type: ignore attributes["name"] = fields.Str() attributes["surname"] = fields.Str() attributes["roles"] = fields.List(fields.Nested(Role)) if custom_fields := mem.customizer.get_custom_output_fields(None): attributes.update(custom_fields)
class TechmetaPutSchema(Schema): name = fields.Str(required=False) sequencing_date = fields.Date(format=DATE_FORMAT) platform = fields.Str(allow_none=True, validate=validate.OneOf(PLATFORMS)) enrichment_kit = fields.Str() @pre_load def null_platform(self, data: Dict[str, Any], **kwargs: Any) -> Dict[str, Any]: if "platform" in data and data["platform"] == "": data["platform"] = None return data
class PhenotypeOutputSchema(Schema): uuid = fields.Str(required=True) name = fields.Str(required=True) age = fields.Integer() sex = fields.Str(required=True, validate=validate.OneOf(SEX)) hpo = fields.List(fields.Nested(Hpo), required=False) birth_place = fields.Nested(GeoData, required=False) relationships = fields.Nested( Relationships, metadata={"description": "family relationships between phenotypes"}, )
class Input1(Schema): # Note: This is a replacement of the normal DelimitedList defined by rapydo unique_delimited_list = fields.DelimitedList( fields.Str(), delimiter=",", required=True, unique=True ) # Note: This is a replacement of the normal List list defined by rapydo advanced_list = fields.List( fields.Str(), required=True, unique=True, min_items=2, )
def patchUserProfile(): # as defined in Marshmallow.schema.from_dict attributes: Dict[str, Union[fields.Field, type]] = {} attributes["name"] = fields.Str() attributes["surname"] = fields.Str() attributes["privacy_accepted"] = fields.Boolean() if custom_fields := mem.customizer.get_custom_input_fields( request=None, scope=mem.customizer.PROFILE ): attributes.update(custom_fields)
class PrivateStatsOutput(Schema): num_users = fields.Integer(required=False) num_studies = fields.Integer(required=False) num_datasets = fields.Integer(required=False) num_datasets_per_group = fields.Dict(required=False, keys=fields.Str(), values=fields.Integer()) num_datasets_with_vcf = fields.Integer(required=False) num_datasets_with_vcf_per_group = fields.Dict(required=False, keys=fields.Str(), values=fields.Integer()) num_datasets_with_gvcf = fields.Integer(required=False) num_datasets_with_gvcf_per_group = fields.Dict(required=False, keys=fields.Str(), values=fields.Integer()) num_files = fields.Integer(required=False)
def getInputSchema(request: FlaskRequest, is_post: bool) -> Type[Schema]: graph = neo4j.get_instance() # as defined in Marshmallow.schema.from_dict attributes: Dict[str, Union[fields.Field, type]] = {} attributes["name"] = fields.Str(required=True) attributes["age"] = fields.Integer(allow_none=True, validate=validate.Range(min=0)) attributes["sex"] = fields.Str( required=True, validate=validate.OneOf(SEX), metadata={"description": ""} ) attributes["hpo"] = fields.List( fields.Str(), metadata={ "label": "HPO", "autocomplete_endpoint": "/api/hpo", "autocomplete_show_id": True, "autocomplete_id_bind": "hpo_id", "autocomplete_label_bind": "label", }, ) geodata_keys = [] geodata_labels = [] for g in graph.GeoData.nodes.all(): geodata_keys.append(g.uuid) geodata_labels.append(g.province) if len(geodata_keys) == 1: default_geodata = geodata_keys[0] else: default_geodata = None attributes["birth_place"] = fields.Str( required=False, allow_none=True, metadata={ "label": "Birth Place", "description": "", }, dump_default=default_geodata, validate=validate.OneOf(choices=geodata_keys, labels=geodata_labels), ) return Schema.from_dict(attributes, name="PhenotypeDefinition")
class NewPassword(Schema): password = fields.Str( required=True, metadata={"password": True}, # Not needed to check the length of the current password... if set... # validate=validate.Length(min=auth.MIN_PASSWORD_LENGTH), ) new_password = fields.Str( required=True, validate=validate.Length(min=auth.MIN_PASSWORD_LENGTH), metadata={"password": True}, ) password_confirm = fields.Str( required=True, validate=validate.Length(min=auth.MIN_PASSWORD_LENGTH), metadata={"password": True}, ) totp_code = fields.TOTP(required=False)
class Credentials(Schema): username = fields.Email(required=True) password = fields.Str( required=True, password=True, # Otherwise default testing password, like test, will fail # validate=validate.Length(min=auth.MIN_PASSWORD_LENGTH) ) new_password = fields.Str( required=False, password=True, validate=validate.Length(min=auth.MIN_PASSWORD_LENGTH), ) password_confirm = fields.Str( required=False, password=True, validate=validate.Length(min=auth.MIN_PASSWORD_LENGTH), ) totp_code = TOTP(required=False)
class SingleInput(Schema): element = fields.Str( required=True, metadata={ "autocomplete_endpoint": "/api/tests/autocomplete", "autocomplete_id_bind": "my_id", "autocomplete_label_bind": "my_label", "autocomplete_show_id": False, }, )
class ListInput(Schema): elements = fields.List( fields.Str(), required=True, metadata={ "autocomplete_endpoint": "/api/tests/autocomplete", "autocomplete_id_bind": "my_id", "autocomplete_label_bind": "my_label", "autocomplete_show_id": True, }, )
class Credentials(Schema): # This is because Email is not typed on marshmallow username = fields.Email( # type: ignore required=True, validate=validate.Length(max=100)) password = fields.Str( required=True, metadata={"password": True}, # Otherwise default testing password, like test, will fail # validate=validate.Length(min=auth.MIN_PASSWORD_LENGTH) ) new_password = fields.Str( required=False, validate=validate.Length(min=auth.MIN_PASSWORD_LENGTH), metadata={"password": True}, ) password_confirm = fields.Str( required=False, validate=validate.Length(min=auth.MIN_PASSWORD_LENGTH), metadata={"password": True}, ) totp_code = fields.TOTP(required=False)
class MailInput(Schema): subject = fields.Str(required=True, metadata={"description": "Subject of your email"}) body = fields.Str( required=True, validate=validate.Length(max=9999), metadata={ "description": "Body of your email. You can use html code here." }, ) # This is because Email is not typed on marshmallow to = fields.Email( # type: ignore required=True, metadata={"label": "Destination email address"}) cc = fields.DelimitedList( # This is because Email is not typed on marshmallow fields.Email(), # type: ignore metadata={ "label": "CC - Carbon Copy", "description": "CC email addresses (comma-delimited list)", }, ) bcc = fields.DelimitedList( # This is because Email is not typed on marshmallow fields.Email(), # type: ignore metadata={ "label": "BCC - Blind Carbon Copy", "description": "BCC email addresses (comma-delimited list)", }, ) dry_run = fields.Boolean( required=True, metadata={ "label": "Dry run execution", "description": "Only simulate the email, do not send it", }, )
def getInputSchema(request): # as defined in Marshmallow.schema.from_dict attributes: Dict[str, Union[fields.Field, type]] = {} attributes["name"] = fields.Str(required=True) attributes["surname"] = fields.Str(required=True) attributes["email"] = fields.Email(required=True, label="Username (email address)") attributes["password"] = fields.Str( required=True, password=True, validate=validate.Length(min=auth.MIN_PASSWORD_LENGTH), ) attributes["password_confirm"] = fields.Str( required=True, password=True, label="Password confirmation", validate=validate.Length(min=auth.MIN_PASSWORD_LENGTH), ) if custom_fields := mem.customizer.get_custom_input_fields( request=None, scope=mem.customizer.REGISTRATION): attributes.update(custom_fields)
def get_output_schema(): # as defined in Marshmallow.schema.from_dict attributes: Dict[str, Union[fields.Field, type]] = {} attributes["uuid"] = fields.UUID() attributes["email"] = fields.Email() attributes["name"] = fields.Str() attributes["surname"] = fields.Str() attributes["first_login"] = fields.DateTime(allow_none=True, format=ISO8601UTC) attributes["last_login"] = fields.DateTime(allow_none=True, format=ISO8601UTC) attributes["last_password_change"] = fields.DateTime(allow_none=True, format=ISO8601UTC) attributes["is_active"] = fields.Boolean() attributes["privacy_accepted"] = fields.Boolean() attributes["roles"] = fields.List(fields.Nested(Roles)) attributes["expiration"] = fields.DateTime(allow_none=True, format=ISO8601UTC) attributes["belongs_to"] = fields.Nested(Group, data_key="group") if custom_fields := mem.customizer.get_custom_output_fields(None): attributes.update(custom_fields)