Skip to content

Commit

Permalink
[AUD-741] Add query and endpoint for remixable tracks and update libs…
Browse files Browse the repository at this point in the history
… to expose the new endpoint (#1633)

* Add query and endpoint for remixable tracks and update libs to expose the new endpoint

* Update params and remove libs code

* Remove null import

* Add remixable endpoint to full namespace

* Update decayed_score helper function
  • Loading branch information
Kyle-Shanks committed Jul 12, 2021
1 parent 852e682 commit e329ed9
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 4 deletions.
32 changes: 32 additions & 0 deletions discovery-provider/src/api/v1/tracks.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
from src.queries.get_savers_for_track import get_savers_for_track
from src.queries.get_tracks_including_unlisted import get_tracks_including_unlisted
from src.queries.get_stems_of import get_stems_of
from src.queries.get_remixable_tracks import get_remixable_tracks
from src.queries.get_remixes_of import get_remixes_of
from src.queries.get_remix_track_parents import get_remix_track_parents
from src.queries.get_trending_ids import get_trending_ids
Expand Down Expand Up @@ -602,6 +603,37 @@ def get(self, track_id):
stems = list(map(stem_from_track, stems))
return success_response(stems)

track_remixables_route_parser = reqparse.RequestParser()
track_remixables_route_parser.add_argument("user_id", required=False)
track_remixables_route_parser.add_argument("limit", required=False, type=int)
track_remixables_route_parser.add_argument("with_users", required=False, type=bool)
@full_ns.route("/remixables")
class RemixableTracks(Resource):
@record_metrics
@full_ns.doc(
id="""Remixable Tracks""",
params={
"user_id": "User ID",
"limit": "Number of remixable tracks to fetch",
"with_users": "Boolean to include user info with tracks"
},
responses={
200: "Success",
400: "Bad request",
500: "Server error"
}
)
@full_ns.marshal_with(tracks_response)
@cache(ttl_sec=5)
def get(self):
args = track_remixables_route_parser.parse_args()
args = {
"current_user_id": get_current_user_id(args),
"limit": get_default_max(args.get("limit"), 25, 100),
"with_users": args.get("with_users", False),
}
tracks = get_remixable_tracks(args)
return success_response(tracks)

remixes_response = make_full_response(
"remixes_response_full", full_ns, fields.Nested(remixes_response_model)
Expand Down
59 changes: 59 additions & 0 deletions discovery-provider/src/queries/get_remixable_tracks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from sqlalchemy import desc
from src.models import Track, Stem
from src.queries.query_helpers import create_save_repost_count_subquery, \
populate_track_metadata, add_users_to_tracks, decayed_score
from src.utils.db_session import get_db_read_replica
from src.utils import helpers

def get_remixable_tracks(args):
"""Gets a list of remixable tracks"""
db = get_db_read_replica()
limit = args.get("limit", 25)
current_user_id = args.get("current_user_id", None)

with db.scoped_session() as session:
# Subquery to get current tracks that have stems
remixable_tracks_subquery = (
session.query(Track)
.join(Stem, Stem.parent_track_id == Track.track_id)
.filter(
Track.is_current == True,
Track.is_unlisted == False,
Track.is_delete == False
)
.subquery()
)

count_subquery = create_save_repost_count_subquery(session, "track")

query = (
session.query(
remixable_tracks_subquery,
count_subquery.c["count"],
decayed_score(
count_subquery.c["count"],
remixable_tracks_subquery.c.created_at
).label("score")
)
.select_from(remixable_tracks_subquery)
.join(
count_subquery,
count_subquery.c["id"] == remixable_tracks_subquery.c.track_id
)
.order_by(
desc("score"),
desc(remixable_tracks_subquery.c.track_id)
)
.limit(limit)
)

tracks = helpers.query_result_to_list(query.all())
track_ids = list(map(lambda track: track["track_id"], tracks))

# Get user specific data for tracks
tracks = populate_track_metadata(session, track_ids, tracks, current_user_id)

if args.get("with_users", False):
add_users_to_tracks(session, tracks, current_user_id)

return tracks
8 changes: 4 additions & 4 deletions discovery-provider/src/queries/query_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1191,11 +1191,11 @@ def decayed_score(score, created_at, peak=5, nominal_timestamp=14 * 24 * 60 * 60
Returns:
A SQLAlchemy expression representing decayed score (score * multipler)
where multipler is represented by:
max(0.2, 5 ^ 1 - min(time_ago / nominal_timestamp, 1))
peak ^ 1 - min(time_ago / nominal_timestamp, 1)
"""
return score * func.greatest(
func.pow(5, 1 - func.least(seconds_ago(created_at) / nominal_timestamp, 1)), 0.2
)
decay_exponent = 1 - func.least(seconds_ago(created_at) / nominal_timestamp, 1) # goes from 1 -> 0
decay_value = func.pow(peak, decay_exponent) / peak # decay slope value
return score * decay_value


def filter_to_playlist_mood(session, mood, query, correlation):
Expand Down

0 comments on commit e329ed9

Please sign in to comment.