Esempio n. 1
0
def get_by_user(
    ls: dependencies.LoginSession = f.Depends(
        dependencies.dependency_login_session),
    user_id: int = f.Path(
        ..., description="The id of the user to get audit logs about."),
    limit: int = f.Query(
        500, description="The number of objects that will be returned.", ge=0),
    offset: int = f.Query(
        0,
        description=
        "The starting object from which the others will be returned.",
        ge=0),
    order: models.enums.TimestampOrdering = f.Query(
        models.enums.TimestampOrdering.ANY,
        description="The order you want the objects to be returned in."),
):
    """
    Get an array of the audit logs in which the specified user is involved, in pages of `limit` elements and
    starting at the element number `offset`.

    To avoid denial of service attacks, `limit` cannot be greater than 500.
    """
    user = ls.get(tables.User, user_id)
    return (ordered(ls.session.query(tables.AuditLog).filter_by(user=user),
                    tables.AuditLog.timestamp,
                    order=order).limit(limit).offset(offset).all())
Esempio n. 2
0
def edit_multiple_uninvolve(
    ls: dependencies.LoginSession = f.Depends(
        dependencies.dependency_login_session),
    album_ids: List[int] = f.Query(
        ...,
        description="The ids of the albums to uninvolve the person from."),
    person_id: int = f.Query(
        ..., description="The ids of the person to uninvolve."),
    role_id: int = f.Query(
        ..., description="The id of the role of the involvement."),
):
    """
    The opposite of _involve_: delete the connection between the specified person and the specified albums that has
    the specified role.

    Non-existing `album_ids` passed to the method will be silently skipped, while a 404 error will be raised for
    non-existing people or roles.

    Involvements that don't exist will be silently ignored.
    """
    role = ls.get(tables.Role, role_id)
    person = ls.get(tables.Person, person_id)
    for song in ls.group(tables.Album, album_ids):
        tables.AlbumInvolvement.unmake(session=ls.session,
                                       role=role,
                                       song=song,
                                       person=person)
        ls.log("album.edit.multiple.uninvolve", obj=song.id)
    ls.session.commit()
    return f.Response(status_code=204)
Esempio n. 3
0
def lfg_get(
        *,
        ls: LoginSession = f.Depends(dep_loginsession),

        limit: int = f.Query(
            50, description="The number of LFGs that will be returned.", ge=0, le=500
        ),
        offset: int = f.Query(
            0, description="Start returning LFGs from this offset.", ge=0
        ),
        filter_state: t.Optional[database.AnnouncementState] = f.Query(
            None, description="Get only LFGs in the specified state."
        ),
):
    """
    Return all LFGs sorted starting by the earliest autostart time.

    Requires the `read:lfg` scope.
    """
    if "read:lfg" not in ls.cu.permissions:
        raise f.HTTPException(403, "Missing `read:lfg` scope.")

    query = ss.select(database.Announcement)
    query = query.where(database.Announcement.state == filter_state) if filter_state is not None else query
    query = query.offset(offset)
    query = query.limit(limit)
    query = query.order_by(database.Announcement.autostart_time)
    results = ls.session.execute(query)
    return list(results.scalars())
Esempio n. 4
0
def delete_runtime_resources(
    project: str,
    label_selector: typing.Optional[str] = fastapi.Query(
        None, alias="label-selector"),
    kind: typing.Optional[str] = None,
    object_id: typing.Optional[str] = fastapi.Query(None, alias="object-id"),
    force: bool = False,
    grace_period: int = fastapi.Query(
        mlrun.mlconf.runtime_resources_deletion_grace_period,
        alias="grace-period"),
    auth_info: mlrun.api.schemas.AuthInfo = fastapi.Depends(
        mlrun.api.api.deps.authenticate_request),
    db_session: sqlalchemy.orm.Session = fastapi.Depends(
        mlrun.api.api.deps.get_db_session),
):
    return _delete_runtime_resources(
        db_session,
        auth_info,
        project,
        label_selector,
        kind,
        object_id,
        force,
        grace_period,
    )
Esempio n. 5
0
def edit_multiple_involve(
    ls: dependencies.LoginSession = f.Depends(
        dependencies.dependency_login_session),
    album_ids: List[int] = f.Query(
        ..., description="The ids of the albums to involve the person with."),
    person_id: int = f.Query(...,
                             description="The ids of the person to involve."),
    role_id: int = f.Query(
        ..., description="The id of the role of the involvement."),
):
    """
    Connect the specified person to the specified albums detailing a role as the role of their involvement.

    For example, "[Luis Fonsi](https://en.wikipedia.org/wiki/Luis_Fonsi)" should be involved with the album
    "[Vida](https://en.wikipedia.org/wiki/Vida_(Luis_Fonsi_album))" with the role "Artist".

    Non-existing `album_ids` passed to the method will be silently skipped, while a 404 error will be raised for
    non-existing people or roles.

    Trying to create an involvement that already exists will result in that involvement being skipped.
    """
    role = ls.get(tables.Role, role_id)
    person = ls.get(tables.Person, person_id)
    for album in ls.group(tables.Album, album_ids):
        tables.AlbumInvolvement.make(session=ls.session,
                                     role=role,
                                     album=album,
                                     person=person)
        ls.log("album.edit.multiple.involve", obj=album.id)
    ls.session.commit()
    return f.Response(status_code=204)
Esempio n. 6
0
def get_all(
    ls: dependencies.LoginSession = f.Depends(
        dependencies.dependency_login_session),
    limit: int = f.Query(
        500,
        description="The number of objects that will be returned.",
        ge=0,
        le=500),
    offset: int = f.Query(
        0,
        description=
        "The starting object from which the others will be returned.",
        ge=0),
):
    """
    Get an array of all the genres currently in the database, in pages of `limit` elements and starting at the
    element number `offset`.

    To avoid denial of service attacks, `limit` cannot be greater than 500.

    Note that this method doesn't return any information about parents and children of the genres; to access them,
    you'll have to use the method that GETs the genres one by one.
    """
    return ls.session.query(tables.Genre).order_by(
        tables.Genre.id).limit(limit).offset(offset).all()
Esempio n. 7
0
def get(
    ls: dependencies.LoginSession = f.Depends(
        dependencies.dependency_login_session),
    limit: int = f.Query(
        500,
        description="The number of objects that will be returned.",
        ge=0,
        le=500),
    offset: int = f.Query(
        0,
        description=
        "The starting object from which the others will be returned.",
        ge=0),
    order: models.enums.TimestampOrdering = f.Query(
        models.enums.TimestampOrdering.ANY,
        description="The order you want the objects to be returned in."),
):
    """
    Get an array of all audit logs currently in the database, in pages of `limit` elements and starting at the 
    element number `offset`.

    To avoid denial of service attacks, `limit` cannot be greater than 500.
    """
    return ordered(ls.session.query(tables.AuditLog),
                   tables.AuditLog.timestamp,
                   order=order).limit(limit).offset(offset).all()
Esempio n. 8
0
def get_by_action(
    ls: dependencies.LoginSession = f.Depends(
        dependencies.dependency_login_session),
    action: str = f.Path(
        ...,
        description=
        "The action to get audit logs about. Uses SQL 'like' syntax. Case "
        "insensitive."),
    limit: int = f.Query(
        500, description="The number of objects that will be returned.", ge=0),
    offset: int = f.Query(
        0,
        description=
        "The starting object from which the others will be returned.",
        ge=0),
    order: models.enums.TimestampOrdering = f.Query(
        models.enums.TimestampOrdering.ANY,
        description="The order you want the objects to be returned in."),
):
    """
    Get an array of the audit logs that match the passed `action` pattern, in pages of `limit` elements and
    starting at the element number `offset`.

    To avoid denial of service attacks, `limit` cannot be greater than 500.
    """
    return (ordered(ls.session.query(tables.AuditLog).filter(
        tables.AuditLog.action.ilike(action)),
                    tables.AuditLog.timestamp,
                    order=order).limit(limit).offset(offset).all())
Esempio n. 9
0
def list_projects(
        format_: schemas.Format = fastapi.Query(schemas.Format.full,
                                                alias="format"),
        owner: str = None,
        labels: typing.List[str] = fastapi.Query(None, alias="label"),
        state: schemas.ProjectState = None,
        db_session: Session = fastapi.Depends(deps.get_db_session),
):
    return get_project_member().list_projects(db_session, owner, format_,
                                              labels, state)
Esempio n. 10
0
def get_all(
    ls: dependencies.LoginSession = f.Depends(dependencies.dependency_login_session),
    limit: int = f.Query(500, description="The number of objects that will be returned.", ge=0, le=500),
    offset: int = f.Query(0, description="The starting object from which the others will be returned.", ge=0),
):
    """
    Get an array of all the songs currently in the database, in pages of `limit` elements and starting at the
    element number `offset`.

    To avoid denial of service attacks, `limit` cannot be greater than 500.
    """
    return ls.session.query(tables.Song).order_by(tables.Song.id).limit(limit).offset(offset).all()
Esempio n. 11
0
def edit_multiple_calendarize(
    ls: dependencies.LoginSession = f.Depends(dependencies.dependency_login_session),
    song_ids: List[int] = f.Query(..., description="The ids of the songs to calendarize."),
    year: Optional[int] = f.Query(None, description="The year to set the songs to, or None to clear the year."),
):
    """
    Change the release year of all the specified songs.
    """
    for song in ls.group(tables.Song, song_ids):
        song.year = year
        ls.log("song.edit.multiple.calendarize", obj=song.id)
    ls.session.commit()
    return f.Response(status_code=204)
Esempio n. 12
0
 def __call__(
     self,
     limit: int = fastapi.Query(
         default=bases_settings.PAGINATION_DEFAULT_LIMIT,
         ge=bases_settings.PAGINATION_MIN_LIMIT,
         le=bases_settings.PAGINATION_MAX_LIMIT,
     ),
     offset: int = fastapi.Query(
         default=bases_settings.PAGINATION_DEFAULT_OFFSET,
         ge=bases_settings.PAGINATION_MIN_OFFSET,
     ),
 ) -> Paginator:
     """Enable to use inside FastAPI Depends"""
     return Paginator(skip=offset, limit=limit)
Esempio n. 13
0
def list_runtime_resources(
    project: str,
    label_selector: typing.Optional[str] = fastapi.Query(
        None, alias="label-selector"),
    kind: typing.Optional[str] = None,
    object_id: typing.Optional[str] = fastapi.Query(None, alias="object-id"),
    group_by: typing.Optional[
        mlrun.api.schemas.ListRuntimeResourcesGroupByField] = fastapi.Query(
            None, alias="group-by"),
    auth_info: mlrun.api.schemas.AuthInfo = fastapi.Depends(
        mlrun.api.api.deps.authenticate_request),
):
    return _list_runtime_resources(project, auth_info, label_selector,
                                   group_by, kind, object_id)
Esempio n. 14
0
def edit_multiple_group(
    ls: dependencies.LoginSession = f.Depends(dependencies.dependency_login_session),
    song_ids: List[int] = f.Query(..., description="The ids of the songs to group."),
    disc_number: Optional[int] = f.Query(None, description="The number of the disc to group the songs in, "
                                                           "or None to clear the disc number.", ge=1),
):
    """
    Change the disc number of all the specified songs.
    """
    for song in ls.group(tables.Song, song_ids):
        song.disc = disc_number
        ls.log("song.edit.multiple.group", obj=song.id)
    ls.session.commit()
    return f.Response(status_code=204)
Esempio n. 15
0
async def get_comp_ranking(
        boss_slug: str,

        # Query Params
        limit: int = 20,
        role: typing.List[str] = fastapi.Query([""]),
        spec: typing.List[str] = fastapi.Query([""]),
        killtime_min: int=0,
        killtime_max: int=0,
):
    """Fetch comp rankings for a given boss encounter.

    Args:
        boss_slug (str): name of the boss (full_name_slug)

    Query Params:
        limit (int): max number of fights to fetch (default: 20)
        role (list[str]): role filters
        spec (list[str]): spec filters

    Returns:
        dict:
            fights (list[dict]):
            updated

    """
    # get search inputs
    search = {}
    search["fights.0.composition.roles"] = role or []
    search["fights.0.composition.specs"] = spec or []
    search["fights.0.composition.classes"] = []  # implement this, if needed

    search["fights.0"] = []
    if killtime_min:
        search["fights.0"] += [f"duration.gt.{killtime_min * 1000}"]
    if killtime_max:
        search["fights.0"] += [f"duration.lt.{killtime_max * 1000}"]

    # lookup DB
    comp_ranking = warcraftlogs_comp_ranking.CompRanking(boss_slug=boss_slug)
    if not comp_ranking.valid:
        return "Invalid Boss.", 404

    reports = comp_ranking.get_reports(limit=limit, search=search)

    # return
    return {
        "fights": [report.fight.as_dict() for report in reports if report.fight],
        "updated": comp_ranking.updated,
    }
Esempio n. 16
0
async def roll_a_dice(roll: str = fastapi.Query("1d20")):
    tray = Dicetray(roll)
    tray.roll()
    return {
        "result": tray.result,
        "dice": [dice.__dict__() for dice in tray.dice]
    }
Esempio n. 17
0
async def cpfs(c: typing.Optional[str] = fastapi.Query(
    None,
    title='cnjs',
    description='cnjs numbers',
    alias='item-query',
    deprecated=True), ):
    return {'c': c}
Esempio n. 18
0
async def read_items(q: typing.Optional[str] = fastapi.Query(None,
                                                             min_length=3,
                                                             max_length=10)):
    results = {'items': [{'item_id': 'Foo'}, {'item_id': 'Bar'}]}
    if q:
        results.update({'q': q})
    return results
Esempio n. 19
0
def delete_project(
        name: str,
        deletion_strategy: schemas.DeletionStrategy = fastapi.Header(
            schemas.DeletionStrategy.default(),
            alias=schemas.HeaderNames.deletion_strategy),
        projects_role: typing.Optional[schemas.ProjectsRole] = fastapi.Header(
            None, alias=schemas.HeaderNames.projects_role),
        # TODO: we're in a http request context here, therefore it doesn't make sense that by default it will hold the
        #  request until the process will be completed - after UI supports waiting - change default to False
        wait_for_completion: bool = fastapi.Query(True,
                                                  alias="wait-for-completion"),
        auth_verifier: deps.AuthVerifier = fastapi.Depends(deps.AuthVerifier),
        db_session: Session = fastapi.Depends(deps.get_db_session),
):
    is_running_in_background = get_project_member().delete_project(
        db_session,
        name,
        deletion_strategy,
        projects_role,
        auth_verifier.auth_info.session,
        wait_for_completion=wait_for_completion,
    )
    if is_running_in_background:
        return fastapi.Response(status_code=HTTPStatus.ACCEPTED.value)
    return fastapi.Response(status_code=HTTPStatus.NO_CONTENT.value)
Esempio n. 20
0
def patch_project(
        project: dict,
        name: str,
        patch_mode: schemas.PatchMode = fastapi.Header(
            schemas.PatchMode.replace, alias=schemas.HeaderNames.patch_mode),
        projects_role: typing.Optional[schemas.ProjectsRole] = fastapi.Header(
            None, alias=schemas.HeaderNames.projects_role),
        # TODO: we're in a http request context here, therefore it doesn't make sense that by default it will hold the
        #  request until the process will be completed - after UI supports waiting - change default to False
        wait_for_completion: bool = fastapi.Query(True,
                                                  alias="wait-for-completion"),
        iguazio_session: typing.Optional[str] = fastapi.Cookie(
            None, alias="session"),
        db_session: Session = fastapi.Depends(deps.get_db_session),
):
    project, is_running_in_background = get_project_member().patch_project(
        db_session,
        name,
        project,
        patch_mode,
        projects_role,
        iguazio_session,
        wait_for_completion=wait_for_completion,
    )
    if is_running_in_background:
        return fastapi.Response(status_code=HTTPStatus.ACCEPTED.value)
    return project
Esempio n. 21
0
async def memcached_demo_post(
    key: str = fastapi.Query(..., title='the job id'),
    cache: MemcachedClient = fastapi.Depends(depends_memcached),
) -> typing.Dict:
    await cache.set(key.encode(), str(key + '_value').encode())
    value = await cache.get(key.encode())
    return dict(ping=(await cache.ping()).decode(), key=key, value=value)
Esempio n. 22
0
def patch_project(
    project: dict,
    name: str,
    patch_mode: mlrun.api.schemas.PatchMode = fastapi.Header(
        mlrun.api.schemas.PatchMode.replace,
        alias=mlrun.api.schemas.HeaderNames.patch_mode,
    ),
    # TODO: we're in a http request context here, therefore it doesn't make sense that by default it will hold the
    #  request until the process will be completed - after UI supports waiting - change default to False
    wait_for_completion: bool = fastapi.Query(True,
                                              alias="wait-for-completion"),
    auth_verifier: mlrun.api.api.deps.AuthVerifierDep = fastapi.Depends(
        mlrun.api.api.deps.AuthVerifierDep),
    db_session: sqlalchemy.orm.Session = fastapi.Depends(
        mlrun.api.api.deps.get_db_session),
):
    project, is_running_in_background = get_project_member().patch_project(
        db_session,
        name,
        project,
        patch_mode,
        auth_verifier.auth_info.projects_role,
        auth_verifier.auth_info.session,
        wait_for_completion=wait_for_completion,
    )
    if is_running_in_background:
        return fastapi.Response(status_code=http.HTTPStatus.ACCEPTED.value)
    return project
Esempio n. 23
0
def merge(
    ls: dependencies.LoginSession = f.Depends(dependencies.dependency_login_session),
    ss: sqlalchemy.orm.Session = f.Depends(dependencies.dependency_db_session_serializable),
    song_ids: List[int] = f.Query(..., description="The ids of the genres to merge."),
):
    """
    Move the layers of all the specified songs into a single one, which will have the metadata of the first song
    specified.
    """

    if len(song_ids) < 2:
        raise f.HTTPException(400, "Not enough songs specified")

    # Get the first genre
    main_song = ss.query(tables.Song).get(song_ids[0])
    ls.log("song.merge.to", obj=main_song.id)

    # Get the other genres
    other_songs = ss.query(tables.Song).filter(tables.Song.id.in_(song_ids[1:])).all()

    # Replace and delete the other genres
    for merged_song in other_songs:
        for layer in merged_song.layers:
            layer.song = main_song

        ls.log("song.merge.from", obj=merged_song.id)
        ss.delete(merged_song)

    ss.commit()
    ss.close()

    ls.session.commit()
    return f.Response(status_code=204)
Esempio n. 24
0
def lfg_post(
        *,
        ls: LoginSession = f.Depends(dep_loginsession),
        session: so.Session = f.Depends(database.DatabaseSession),
        user: t.Optional[str] = f.Query(None, description="The user on behalf of which you are acting."),
        data: models.AnnouncementEditable = f.Body(..., description="The data of the LFG you are creating."),
):
    """
    Create a new LFG with the passed data.

    Requires the `create:lfg` scope, or the `create:lfg_sudo` scope if you're creating a LFG on behalf of another user.
    """
    if "create:lfg" not in ls.cu.permissions:
        raise f.HTTPException(403, "Missing `create:lfg` scope.")

    if user is None:
        user = ls.cu.sub

    if "create:lfg_sudo" not in ls.cu.permissions and user != ls.cu.sub:
        raise f.HTTPException(403, "Missing `create:lfg_sudo` scope.")

    # noinspection PyArgumentList
    lfg = database.Announcement(**data.dict(), creator_id=user)
    session.add(lfg)
    session.commit()

    planned_event.set()

    send_message(session, models.EventAnnouncement(
        type="create",
        announcement=models.AnnouncementFull.from_orm(lfg),
    ).json())

    return lfg
Esempio n. 25
0
def delete_project(
    name: str,
    deletion_strategy: mlrun.api.schemas.DeletionStrategy = fastapi.Header(
        mlrun.api.schemas.DeletionStrategy.default(),
        alias=mlrun.api.schemas.HeaderNames.deletion_strategy,
    ),
    # TODO: we're in a http request context here, therefore it doesn't make sense that by default it will hold the
    #  request until the process will be completed - after UI supports waiting - change default to False
    wait_for_completion: bool = fastapi.Query(True,
                                              alias="wait-for-completion"),
    auth_info: mlrun.api.schemas.AuthInfo = fastapi.Depends(
        mlrun.api.api.deps.authenticate_request),
    db_session: sqlalchemy.orm.Session = fastapi.Depends(
        mlrun.api.api.deps.get_db_session),
):
    is_running_in_background = get_project_member().delete_project(
        db_session,
        name,
        deletion_strategy,
        auth_info.projects_role,
        auth_info,
        wait_for_completion=wait_for_completion,
    )
    if is_running_in_background:
        return fastapi.Response(status_code=http.HTTPStatus.ACCEPTED.value)
    return fastapi.Response(status_code=http.HTTPStatus.NO_CONTENT.value)
Esempio n. 26
0
def edit_multiple_rename(
    ls: dependencies.LoginSession = f.Depends(
        dependencies.dependency_login_session),
    layer_ids: List[int] = f.Query(
        ..., description="The ids of the layers that should be renamed."),
    name: str = f.Query(
        ..., description="The location the layers should be renamed to."),
):
    """
    Bulk change the location of all the specified layers.
    """
    for layer in ls.group(tables.Layer, layer_ids):
        layer.name = name
        ls.log("layer.edit.multiple.rename", obj=layer.id)

    ls.session.commit()
    return f.Response(status_code=204)
Esempio n. 27
0
def edit_multiple_move(
    ls: dependencies.LoginSession = f.Depends(
        dependencies.dependency_login_session),
    layer_ids: List[int] = f.Query(
        ..., description="The ids of the layers that should be moved."),
    song_id: int = f.Query(
        ..., description="The id of the song the layers should be moved to."),
):
    """
    Change the song the specified layers are associated with.
    """
    song = ls.get(tables.Song, song_id)
    for layer in ls.group(tables.Layer, layer_ids):
        layer.song = song
        ls.log("layer.edit.multiple.move", obj=layer.id)
    ls.session.commit()
    return f.Response(status_code=204)
Esempio n. 28
0
async def get_games_list(
    q: str = fastapi.Query(..., title="Query string"),
    limit: pydantic.conint(ge=1,
                           le=1000) = fastapi.Query(10, title="Result limit"),
):
    """Handle listing games"""
    games = await search_utils.search(search.GameSummary,
                                      _get_games_search_query(q),
                                      limit=limit)
    games_attrs = []
    for game in games:
        game = game.to_dict()
        players = game.get("players", {})
        for position in list(players.keys()):
            players[position] = models.Player.parse_obj(players[position])
        games_attrs.append(game)
    return games_attrs
Esempio n. 29
0
def edit_multiple_declassify(
    ls: dependencies.LoginSession = f.Depends(dependencies.dependency_login_session),
    song_ids: List[int] = f.Query(..., description="The ids of the songs to remove a genre from."),
    genre_id: int = f.Query(..., description="The id of the genre to remove."),
):
    """
    Remove the specified genre from all the specified songs.

    Non-existing `song_ids` passed to the method will be silently skipped, while a 404 error will be raised for a
    non-existing genre.
    """
    genre = ls.get(tables.Genre, genre_id)
    for song in ls.group(tables.Song, song_ids):
        song.genres.remove(genre)
        ls.log("song.edit.multiple.declassify", obj=song.id)
    ls.session.commit()
    return f.Response(status_code=204)
Esempio n. 30
0
 def __call__(
     self,
     fields_show: str = fastapi.Query(
         default=None,
         alias="fieldsShow",
         description="Comma separated values with field names. (You can't exclude '_id' field)",
     ),
     fields_hide: str = fastapi.Query(
         default=None,
         alias="fieldsHide",
         description="Comma separated values with field names. (You can't exclude '_id' field)",
     ),
 ):
     if fields_show is not None and fields_hide is not None:
         raise HandlerException("You can't add 'fieldsShow' and 'fieldsHide' together to Projector")
     self.fields_show = fields_show
     self.fields_hide = fields_hide
     return self