public async Task <ProcessAlbumsResponse> ProcessAlbums([FromForm][Required] string accessToken, [FromForm][Required] string state) { if (!await AuthenticateUser(accessToken, state)) { Response.StatusCode = StatusCodes.Status401Unauthorized; return(new ProcessAlbumsResponse()); } logger.LogInformation($"Started processing {state}"); // Used for timing information DateTime before = DateTime.UtcNow; bool hadToProcessImages = false; int total = 0; int offset = 0; List <SpotifySavedAlbum> albums = new List <SpotifySavedAlbum>(); do { int limit = 50; var savedAlbums = await spotifyClient.GetUserSavedAlbums(limit, offset); offset += limit; albums.AddRange(savedAlbums.Items); total = savedAlbums.Total; }while (albums.Count < total); ProcessAlbumsResponse response = new ProcessAlbumsResponse(); foreach (var album in albums) { SpotifyImage largestImage = album.Album.GetLargestImage(); if (largestImage == null || largestImage.Url == null) { continue; } AlbumInfo?albumInfo = await cosmosAPI.GetAlbumInfo(album.Album.Uri); if (albumInfo == null) { hadToProcessImages = true; ImageAnalysis results; try { results = await computerVisionAPI.AnalyzeImage(largestImage.Url); } catch (Exception ex) { logger.LogError(ex, $"Failed to process image. Spotify URI: {album.Album.Uri}"); continue; } string?artist = null; if (album.Album.Artists.Count > 0) { artist = album.Album.Artists[0].Name; } albumInfo = new AlbumInfo() { AlbumId = album.Album.Uri, AlbumName = album.Album.Name, ArtistName = artist, VisionResults = new VisionResults() { Color = results.Color, Description = results.Description, ImageType = results.ImageType, Tags = results.Tags } }; try { await cosmosAPI.SaveAlbumInfo(albumInfo); } catch (Exception ex) { logger.LogError(ex, $"Failed to save album info. Spotify URI: {album.Album.Uri}"); continue; } AlbumInfoSearchObject searchObject = albumInfo.ToSearchObject(); try { await searchAPI.UploadDocument(searchObject); } catch (Exception ex) { logger.LogError(ex, $"Failed to save search document. Spotify URI: {album.Album.Uri}"); } } response.Albums.Add(album.ToResponseAlbum()); } DateTime after = DateTime.UtcNow; TimeSpan processingTime = after - before; logger.LogInformation($"{{\"processingTime\": {processingTime.TotalSeconds}, \"hadToProcessImages\": {hadToProcessImages}}}"); return(response); }