Example #1
0
def test_schema_invalid_json():
    ModelValidator.BASE_PATH = './tests/res/'
    try:
        ModelValidator.validate(to_validate={}, field="title", model='bad')
        assert False, f"test_model_validator [test_schema_invalid_json] failed"
    except BaseException:
        assert True
Example #2
0
def test_schema_invalid_json():
    ModelValidator.BASE_PATH = "./integration_tests/res/"
    try:
        ModelValidator.validate(to_validate={}, field="title", model="bad")
        assert False, "test_model_validator [test_schema_invalid_json] failed"
    except BaseException:
        assert True
Example #3
0
def validate_field_helper(field, value, model, field_type):
    # TODO: need to write custom validator for these datetime fields as jsonschema
    # validates datetime in format 2018-11-13T20:20:39+00:00, not a format we use
    # also not totally necessary as these fields are created server side
    if field in ("created_at", "updated_at"):
        return value

    # remove null characters from varchar and text fields
    # Postgres does not support these well and it throws this error if you try to insert
    # `Fatal error in main loop A string literal cannot contain NUL (0x00) characters`
    # the fix is to replace those characters with empty with empty string
    # https://stackoverflow.com/questions/1347646/postgres-error-on-insert-error-invalid-byte-sequence-for-encoding-utf8-0x0
    if type(field_type) in (String, Text) and value:
        value = value.encode("utf-8", "ignore").decode("utf-8", "ignore")
        value = value.replace("\x00", "")

    to_validate = {field: value}
    try:
        ModelValidator.validate(to_validate=to_validate,
                                model=model,
                                field=field)
    except ValidationError as e:
        value = get_default_value(field, value, model, e)
    except BaseException as e:
        logger.error(f"Validation failed: {e}")

    return value
Example #4
0
def test_one_field_schema_pass():
    track = {"title": "ok"}
    try:
        ModelValidator.validate(to_validate=track,
                                field="title",
                                model="Track")
    except ValidationError as e:
        assert False, f"test_model_validator [test_one_field_schema_pass] failed: {e}"
Example #5
0
def test_schema_missing():
    try:
        ModelValidator.validate(to_validate={},
                                field="title",
                                model="non-existant")
        assert False, "test_model_validator [test_one_field_schema_empty_object] failed"
    except BaseException:
        assert True
Example #6
0
def test_one_field_schema_empty_object():
    track = {}
    try:
        ModelValidator.validate(to_validate=track,
                                field="title",
                                model="Track")
        assert False, "test_model_validator [test_one_field_schema_empty_object] failed"
    except BaseException:
        assert True
Example #7
0
def test_one_field_schema_bad_key():
    track = {"wrong": "ok"}
    try:
        ModelValidator.validate(to_validate=track,
                                field="title",
                                model="Track")
        assert False, "test_model_validator [test_one_field_schema_bad_key] failed"
    except BaseException:
        assert True
Example #8
0
def test_one_field_schema_bad_value():
    track = {"title": 1}
    try:
        ModelValidator.validate(to_validate=track,
                                field="title",
                                model="Track")
        assert False, f"test_model_validator [test_one_field_schema_bad_value] failed"
    except BaseException:
        assert True
Example #9
0
def test_one_field_schema_with_additional_properties():
    track = {"title": "ok", "wrong": 1}
    try:
        ModelValidator.validate(to_validate=track,
                                field="title",
                                model="Track")
        assert False, f"test_model_validator [test_one_field_schema_with_additional_properties] failed"
    except BaseException:
        assert True
Example #10
0
def test_schema_missing_model_key():
    ModelValidator.BASE_PATH = './tests/res/'

    try:
        ModelValidator.validate(to_validate={},
                                field="title",
                                model='user_bad')
        assert False, f"test_model_validator [test_schema_missing_model_key] failed"
    except BaseException:
        assert True
Example #11
0
class Playlist(Base):
    __tablename__ = "playlists"
    blockhash = Column(String, ForeignKey("blocks.blockhash"), nullable=True)
    blocknumber = Column(Integer, ForeignKey("blocks.number"), nullable=True)
    slot = Column(Integer, nullable=True)
    txhash = Column(String, default="", nullable=False)
    playlist_id = Column(Integer, nullable=False)
    playlist_owner_id = Column(Integer, nullable=False)
    is_album = Column(Boolean, nullable=False)
    is_private = Column(Boolean, nullable=False)
    playlist_name = Column(String)
    playlist_contents = Column(JSONB, nullable=False)
    playlist_image_multihash = Column(String)
    playlist_image_sizes_multihash = Column(String)
    description = Column(String)
    upc = Column(String)
    is_current = Column(Boolean, nullable=False)
    is_delete = Column(Boolean, nullable=False)
    last_added_to = Column(DateTime, nullable=True)
    updated_at = Column(DateTime, nullable=False)
    created_at = Column(DateTime, nullable=False)

    PrimaryKeyConstraint(is_current, playlist_id, playlist_owner_id, txhash)

    ModelValidator.init_model_schemas("Playlist")
    fields = ["playlist_name", "description"]

    # unpacking args into @validates
    @validates(*fields)
    def validate_field(self, field, value):
        return validate_field_helper(field, value, "Playlist",
                                     getattr(Playlist, field).type)

    def __repr__(self):
        return f"<Playlist(blockhash={self.blockhash},\
Example #12
0
def get_default_value(field, value, model, e):
    field_props = ModelValidator.get_properties_for_field(model, field)

    # type field from the schema. this can either be a string or list
    # required by JSONSchema, cannot be None
    schema_type_field = field_props['type']
    try:
        default_value = field_props['default']
    except KeyError:
        default_value = None

    # If the schema indicates this field is equal to object(if string) or contains object(if list) and
    # the default value isn't set in the schema, set to SQL null, otherwise JSONB columns get
    # set to string 'null'.
    # Other fields can be set to their regular defaults or None.
    if not default_value:
        # if schema_type_field is defined as a list, need to check if 'object' is in list, else check string
        if isinstance(schema_type_field,
                      list) and 'object' in schema_type_field:
            default_value = null()  # sql null
        elif schema_type_field == 'object':
            default_value = null()  # sql null

    logger.warning(f"Validation: Setting the default value {default_value} for field {field} " \
        f"of type {schema_type_field} because of error: {e}")

    return default_value
Example #13
0
class User(Base):
    __tablename__ = "users"

    blockhash = Column(String, ForeignKey("blocks.blockhash"), nullable=True)
    blocknumber = Column(Integer, ForeignKey("blocks.number"), nullable=True)
    slot = Column(Integer, nullable=True)
    user_storage_account = Column(String, nullable=True)
    user_authority_account = Column(String, nullable=True)
    txhash = Column(String, default="", nullable=False)
    user_id = Column(Integer, nullable=False)
    is_current = Column(Boolean, nullable=False)
    handle = Column(String)
    handle_lc = Column(String, index=True)
    wallet = Column(String, index=True)
    is_creator = Column(Boolean, nullable=False, default=False)
    is_verified = Column(Boolean,
                         nullable=False,
                         default=False,
                         server_default="false")
    name = Column(Text)
    profile_picture = Column(String)
    profile_picture_sizes = Column(String)
    cover_photo = Column(String)
    cover_photo_sizes = Column(String)
    bio = Column(String)
    location = Column(String)
    metadata_multihash = Column(String)
    creator_node_endpoint = Column(String)
    updated_at = Column(DateTime, nullable=False)
    created_at = Column(DateTime, nullable=False)
    primary_id = Column(Integer, nullable=True)
    secondary_ids = Column(postgresql.ARRAY(Integer), nullable=True)
    replica_set_update_signer = Column(String, nullable=True)
    has_collectibles = Column(Boolean,
                              nullable=False,
                              default=False,
                              server_default="false")
    playlist_library = Column(JSONB, nullable=True)
    is_deactivated = Column(Boolean,
                            nullable=False,
                            default=False,
                            server_default="false",
                            index=True)

    # NOTE: There is no actualy primary key in the DB
    PrimaryKeyConstraint(is_current, user_id, txhash)

    ModelValidator.init_model_schemas("User")
    fields = get_fields_to_validate("User")

    # unpacking args into @validates
    @validates(*fields)
    def validate_field(self, field, value):
        return validate_field_helper(field, value, "User",
                                     getattr(User, field).type)

    def __repr__(self):
        return f"<User(blockhash={self.blockhash},\
Example #14
0
def validate_field_helper(field, value, model):
    # TODO: need to write custom validator for these datetime fields as jsonschema
    # validates datetime in format 2018-11-13T20:20:39+00:00, not a format we use
    # also not totally necessary as these fields are created server side
    if field in ('created_at', 'updated_at'):
        return value

    to_validate = {field: value}
    try:
        ModelValidator.validate(to_validate=to_validate,
                                model=model,
                                field=field)
    except ValidationError as e:
        value = get_default_value(field, value, model, e)
    except BaseException as e:
        logger.error(f"Validation failed: {e}")

    return value
Example #15
0
class User(Base):
    __tablename__ = "users"

    blockhash = Column(String, ForeignKey("blocks.blockhash"), nullable=False)
    blocknumber = Column(Integer, ForeignKey("blocks.number"), nullable=False)
    txhash = Column(String, default='', nullable=False)
    user_id = Column(Integer, nullable=False)
    is_current = Column(Boolean, nullable=False)
    handle = Column(String)
    handle_lc = Column(String, index=True)
    wallet = Column(String, index=True)
    is_creator = Column(Boolean, nullable=False, default=False)
    is_verified = Column(Boolean,
                         nullable=False,
                         default=False,
                         server_default='false')
    name = Column(Text)
    profile_picture = Column(String)
    profile_picture_sizes = Column(String)
    cover_photo = Column(String)
    cover_photo_sizes = Column(String)
    bio = Column(String)
    location = Column(String)
    metadata_multihash = Column(String)
    creator_node_endpoint = Column(String)
    updated_at = Column(DateTime, nullable=False)
    created_at = Column(DateTime, nullable=False)
    primary_id = Column(Integer, nullable=True)
    secondary_ids = Column(postgresql.ARRAY(Integer), nullable=True)
    replica_set_update_signer = Column(String, nullable=True)
    has_collectibles = Column(Boolean,
                              nullable=False,
                              default=False,
                              server_default='false')

    PrimaryKeyConstraint(is_current, user_id, blockhash, txhash)

    ModelValidator.init_model_schemas('User')
    fields = get_fields_to_validate('User')

    # unpacking args into @validates
    @validates(*fields)
    def validate_field(self, field, value):
        return validate_field_helper(field, value, 'User',
                                     getattr(User, field).type)

    def __repr__(self):
        return f"<User(blockhash={self.blockhash},\
Example #16
0
class Track(Base):
    __tablename__ = "tracks"

    blockhash = Column(String, ForeignKey("blocks.blockhash"), nullable=False)
    blocknumber = Column(Integer, ForeignKey("blocks.number"), nullable=False)
    track_id = Column(Integer, nullable=False)
    is_current = Column(Boolean, nullable=False)
    is_delete = Column(Boolean, nullable=False)
    owner_id = Column(Integer, nullable=False)
    route_id = Column(String, nullable=False)
    title = Column(Text, nullable=True)
    length = Column(Integer, nullable=True)
    cover_art = Column(String, nullable=True)
    cover_art_sizes = Column(String, nullable=True)
    tags = Column(String, nullable=True)
    genre = Column(String, nullable=True)
    mood = Column(String, nullable=True)
    credits_splits = Column(String, nullable=True)
    remix_of = Column(postgresql.JSONB, nullable=True)
    create_date = Column(String, nullable=True)
    release_date = Column(String, nullable=True)
    file_type = Column(String, nullable=True)
    description = Column(String, nullable=True)
    license = Column(String, nullable=True)
    isrc = Column(String, nullable=True)
    iswc = Column(String, nullable=True)
    track_segments = Column(postgresql.JSONB, nullable=False)
    metadata_multihash = Column(String, nullable=True)
    download = Column(postgresql.JSONB, nullable=True)
    updated_at = Column(DateTime, nullable=False)
    created_at = Column(DateTime, nullable=False)
    is_unlisted = Column(Boolean, nullable=False)
    field_visibility = Column(postgresql.JSONB, nullable=True)
    stem_of = Column(postgresql.JSONB, nullable=True)

    # Primary key has to be combo of all 3 is_current/creator_id/blockhash
    PrimaryKeyConstraint(is_current, track_id, blockhash)

    ModelValidator.init_model_schemas('Track')
    fields = get_fields_to_validate('Track')

    # unpacking args into @validates
    @validates(*fields)
    def validate_field(self, field, value):
        return validate_field_helper(field, value, 'Track')

    def __repr__(self):
        return (f"<Track("
                f"blockhash={self.blockhash},"
                f"blocknumber={self.blocknumber},"
                f"track_id={self.track_id},"
                f"is_current={self.is_current},"
                f"is_delete={self.is_delete},"
                f"owner_id={self.owner_id},"
                f"route_id={self.route_id},"
                f"title={self.title},"
                f"length={self.length},"
                f"cover_art={self.cover_art},"
                f"cover_art_sizes={self.cover_art_sizes},"
                f"tags={self.tags},"
                f"genre={self.genre},"
                f"mood={self.mood},"
                f"credits_splits={self.credits_splits},"
                f"remix_of={self.remix_of},"
                f"create_date={self.create_date},"
                f"release_date={self.release_date},"
                f"file_type={self.file_type},"
                f"description={self.description},"
                f"license={self.license},"
                f"isrc={self.isrc},"
                f"iswc={self.iswc},"
                f"track_segments={self.track_segments},"
                f"metadata_multihash={self.metadata_multihash},"
                f"download={self.download},"
                f"updated_at={self.updated_at},"
                f"created_at={self.created_at},"
                f"stem_of={self.stem_of}"
                ")>")
Example #17
0
class Track(Base):
    __tablename__ = "tracks"

    blockhash = Column(String, ForeignKey("blocks.blockhash"), nullable=True)
    blocknumber = Column(Integer, ForeignKey("blocks.number"), nullable=True)
    slot = Column(Integer, nullable=True)
    txhash = Column(String, default="", nullable=False)
    track_id = Column(Integer, nullable=False)
    is_current = Column(Boolean, nullable=False)
    is_delete = Column(Boolean, nullable=False)
    owner_id = Column(Integer, nullable=False)
    route_id = Column(String, nullable=False)
    title = Column(Text, nullable=True)
    length = Column(Integer, nullable=True)
    cover_art = Column(String, nullable=True)
    cover_art_sizes = Column(String, nullable=True)
    tags = Column(String, nullable=True)
    genre = Column(String, nullable=True)
    mood = Column(String, nullable=True)
    credits_splits = Column(String, nullable=True)
    remix_of = Column(postgresql.JSONB, nullable=True)
    create_date = Column(String, nullable=True)
    release_date = Column(String, nullable=True)
    file_type = Column(String, nullable=True)
    description = Column(String, nullable=True)
    license = Column(String, nullable=True)
    isrc = Column(String, nullable=True)
    iswc = Column(String, nullable=True)
    track_segments = Column(postgresql.JSONB, nullable=False)
    metadata_multihash = Column(String, nullable=True)
    download = Column(postgresql.JSONB, nullable=True)
    updated_at = Column(DateTime, nullable=False)
    created_at = Column(DateTime, nullable=False)
    is_unlisted = Column(Boolean, nullable=False)
    field_visibility = Column(postgresql.JSONB, nullable=True)
    stem_of = Column(postgresql.JSONB, nullable=True)
    is_available = Column(Boolean, default=True, nullable=False)

    _routes = relationship(  # type: ignore
        "TrackRoute",
        primaryjoin="and_(\
            remote(Track.track_id) == foreign(TrackRoute.track_id),\
            TrackRoute.is_current)",
        lazy="joined",
        viewonly=True,
    )

    user = relationship(
        "User",
        primaryjoin="and_(\
            remote(Track.owner_id) == foreign(User.user_id),\
            User.is_current)",
        lazy="joined",
        viewonly=True,
    )

    @property
    def _slug(self):
        return self._routes[0].slug if self._routes else ""

    @property
    def permalink(self):
        if self.user and self.user[0].handle and self._slug:
            return f"/{self.user[0].handle}/{self._slug}"
        return ""

    PrimaryKeyConstraint(is_current, track_id, txhash)

    ModelValidator.init_model_schemas("Track")
    fields = get_fields_to_validate("Track")

    # unpacking args into @validates
    @validates(*fields)
    def validate_field(self, field, value):
        return validate_field_helper(field, value, "Track",
                                     getattr(Track, field).type)

    def __repr__(self):
        return (f"<Track("
                f"blockhash={self.blockhash},"
                f"blocknumber={self.blocknumber},"
                f"slot={self.slot},"
                f"txhash={self.txhash},"
                f"track_id={self.track_id},"
                f"is_current={self.is_current},"
                f"is_delete={self.is_delete},"
                f"owner_id={self.owner_id},"
                f"route_id={self.route_id},"
                f"title={self.title},"
                f"length={self.length},"
                f"cover_art={self.cover_art},"
                f"cover_art_sizes={self.cover_art_sizes},"
                f"tags={self.tags},"
                f"genre={self.genre},"
                f"mood={self.mood},"
                f"credits_splits={self.credits_splits},"
                f"remix_of={self.remix_of},"
                f"create_date={self.create_date},"
                f"release_date={self.release_date},"
                f"file_type={self.file_type},"
                f"description={self.description},"
                f"license={self.license},"
                f"isrc={self.isrc},"
                f"iswc={self.iswc},"
                f"track_segments={self.track_segments},"
                f"metadata_multihash={self.metadata_multihash},"
                f"download={self.download},"
                f"updated_at={self.updated_at},"
                f"created_at={self.created_at},"
                f"stem_of={self.stem_of},"
                f"permalink={self.permalink},"
                f"user={self.user}"
                f"is_available={self.is_available}"
                ")>")