Why Session-Aware?

So far, your recommendation engine has done a solid job at capturing long-term user preferences. But musical taste isn’t static — what you liked last month might not match your current vibe. That’s where session-aware recommendations come in. In this lesson, you’ll learn how your Smart Music Player now recommends tracks based on real-time listening context — recent moods, tempos, and energy levels — to better reflect what the user is currently into.

You’ll walk through how the backend:

  • Scores recent session traits (mood, tempo, energy)
  • Filters and re-sorts similarity-based recommendations
  • Serves personalized session-aware results through a dedicated API route

You’ll also see how your recommend_tracks_session_aware function intelligently selects music that matches what the user has recently been vibing with.

Core Logic: recommend_tracks_session_aware

Located in src/recommend.py, this function upgrades standard similarity-based recommendations by injecting session context.

def recommend_tracks_session_aware(user_id: str, top_n: int = 5):
    base_recs = recommend_tracks_by_similarity(user_id, top_n=20)
    trends = get_recent_session_trends(user_id)
    if not trends:
        return base_recs[:top_n]

    scored = []
    for tid in base_recs:
        track = get_track_by_id(tid)
        score = 0
        if track.get("mood") == trends["common_mood"]:
            score += 1
        if abs(track.get("tempo", 0) - trends["avg_tempo"]) < 15:
            score += 1
        if abs(track.get("energy", 0) - trends["avg_energy"]) < 0.2:
            score += 1
        scored.append((tid, score))

    sorted_recs = sorted(scored, key=lambda x: x[1], reverse=True)
    return [tid for tid, _ in sorted_recs[:top_n]]

How It Works (Step-by-Step)

  • Step 1: Pull 20 base recommendations from recommend_tracks_by_similarity. This gives tracks the user is likely to enjoy based on embedding similarity.
  • Step 2: Call get_recent_session_trends(user_id) to extract session-level stats:
    • common_mood — most frequent mood in recent listens
    • avg_tempo — average tempo
    • avg_energy — average energy
  • Step 3: Iterate over the base recommendations and compare each track’s attributes to the trends:
    • +1 if the mood matches
    • +1 if tempo is within 15 BPM
    • +1 if energy is within ±0.2
  • Step 4: Sort the tracks by score and return the top N best matches

🧠 The more a track matches the session profile, the higher it ranks.

API Integration: /api/recommendations/session_aware/<user_id>

To make this functionality accessible to the dashboard, you expose it through a dedicated route in app.py:

@app.route('/api/recommendations/session_aware/<user_id>', methods=['GET'])
def get_session_aware_recommendations_endpoint(user_id: str):
    try:
        top_n_str = request.args.get('top_n', default='5')
        top_n = int(top_n_str)
        if top_n <= 0:
            return jsonify({"error": "top_n must be a positive integer"}), 400
    except ValueError:
        return jsonify({"error": "top_n must be a valid integer"}), 400

    recommended_track_ids = recommend_tracks_session_aware(user_id, top_n=top_n)
    if not recommended_track_ids:
        return jsonify({
            "user_id": user_id,
            "recommendations": [],
            "message": "No session-aware recommendations found."
        }), 200

    recommended_tracks_details = [
        get_track_by_id(tid)
        for tid in recommended_track_ids
        if get_track_by_id(tid)
    ]
    return jsonify({
        "user_id": user_id,
        "recommendations": recommended_tracks_details
    })

Key Behavior:

  • Accepts a user_id and optional top_n query parameter
  • Fetches session-aware recs using the logic you just saw
  • Retrieves track metadata and returns it as a structured JSON object

Sample Response:

{
  "user_id": "user123",
  "recommendations": [
    {
      "id": "track42",
      "title": "High-Energy Anthem",
      "mood": "energetic",
      "tempo": 128,
      "energy": 0.82
    },
    {
      "id": "track9",
      "title": "Fast Lane",
      "mood": "energetic",
      "tempo": 125,
      "energy": 0.78
    }
  ]
}

These tracks were selected not just because the user liked similar music in the past — but because they align with their current listening behavior.

Try It Yourself Head back to the dashboard and click the "Session-Aware" button. Watch how the recommendations change as you simulate new sessions using different moods and energies.

Want energetic recs? Simulate listening to some high-tempo, high-energy tracks. Want chill ones? Log listens for ambient or slow tracks.

You’re no longer just building a recommender — you’re building a context-aware companion.

Summary And What’s Next

In this lesson, you learned how to

  • You learned how recommend_tracks_session_aware adds real-time session awareness to your recs
  • You saw how the backend scores each track based on recent mood, tempo, and energy
  • You exposed the logic via a dedicated API route and observed its response structure
  • You tested the feature live in the dashboard

Next up: let’s take a closer look at how the session trend analysis works behind the scenes. Stay tuned — the intelligence layer is just getting started.

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal