diff --git a/SpotifyAPI.Web.Examples/Example.CLI.PersistentConfig/Program.cs b/SpotifyAPI.Web.Examples/Example.CLI.PersistentConfig/Program.cs
index 76861994..67942070 100644
--- a/SpotifyAPI.Web.Examples/Example.CLI.PersistentConfig/Program.cs
+++ b/SpotifyAPI.Web.Examples/Example.CLI.PersistentConfig/Program.cs
@@ -59,7 +59,7 @@ namespace Example.CLI.PersistentConfig
var me = await spotify.UserProfile.Current();
Console.WriteLine($"Welcome {me.DisplayName} ({me.Id}), your authenticated!");
- var playlists = await spotify.PaginateAll(() => spotify.Playlists.CurrentUsers());
+ var playlists = await spotify.PaginateAll(spotify.Playlists.CurrentUsers());
Console.WriteLine($"Total Playlists in your Account: {playlists.Count}");
_server.Dispose();
diff --git a/SpotifyAPI.Web/Clients/Interfaces/IShowsClient.cs b/SpotifyAPI.Web/Clients/Interfaces/IShowsClient.cs
index ddb5e57c..a14ab7ae 100644
--- a/SpotifyAPI.Web/Clients/Interfaces/IShowsClient.cs
+++ b/SpotifyAPI.Web/Clients/Interfaces/IShowsClient.cs
@@ -4,14 +4,60 @@ namespace SpotifyAPI.Web
{
public interface IShowsClient
{
+ ///
+ /// Get Spotify catalog information for a single show identified by its unique Spotify ID.
+ ///
+ /// The Spotify ID for the show.
+ ///
+ /// https://developer.spotify.com/documentation/web-api/reference-beta/#endpoint-get-a-show
+ ///
+ ///
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716")]
Task Get(string showId);
+
+ ///
+ /// Get Spotify catalog information for a single show identified by its unique Spotify ID.
+ ///
+ /// The Spotify ID for the show.
+ /// The request-model which contains required and optional parameters.
+ ///
+ /// https://developer.spotify.com/documentation/web-api/reference-beta/#endpoint-get-a-show
+ ///
+ ///
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716")]
Task Get(string showId, ShowRequest request);
+ ///
+ /// Get Spotify catalog information for several shows based on their Spotify IDs.
+ ///
+ /// The request-model which contains required and optional parameters.
+ ///
+ /// https://developer.spotify.com/documentation/web-api/reference-beta/#endpoint-get-multiple-shows
+ ///
+ ///
Task GetSeveral(ShowsRequest request);
+ ///
+ /// Get Spotify catalog information about an show’s episodes.
+ /// Optional parameters can be used to limit the number of episodes returned.
+ ///
+ /// The Spotify ID for the show.
+ ///
+ /// https://developer.spotify.com/documentation/web-api/reference-beta/#endpoint-get-a-shows-episodes
+ ///
+ ///
Task> GetEpisodes(string showId);
+
+ ///
+ /// Get Spotify catalog information about an show’s episodes.
+ /// Optional parameters can be used to limit the number of episodes returned.
+ ///
+ /// The Spotify ID for the show.
+ /// The request-model which contains required and optional parameters.
+ ///
+ /// https://developer.spotify.com/documentation/web-api/reference-beta/#endpoint-get-a-shows-episodes
+ ///
+ ///
Task> GetEpisodes(string showId, ShowEpisodesRequest request);
}
}
diff --git a/SpotifyAPI.Web/Clients/Interfaces/ISpotifyClient.cs b/SpotifyAPI.Web/Clients/Interfaces/ISpotifyClient.cs
index abff6dde..40907235 100644
--- a/SpotifyAPI.Web/Clients/Interfaces/ISpotifyClient.cs
+++ b/SpotifyAPI.Web/Clients/Interfaces/ISpotifyClient.cs
@@ -1,3 +1,4 @@
+using System.Threading;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
@@ -7,56 +8,296 @@ namespace SpotifyAPI.Web
{
public interface ISpotifyClient
{
+ ///
+ /// The default paginator used by the Paginator methods
+ ///
+ ///
IPaginator DefaultPaginator { get; }
+ ///
+ /// Operations related to Spotify User Profiles
+ ///
+ ///
IUserProfileClient UserProfile { get; }
+ ///
+ /// Operations related to Spotify Browse Endpoints
+ ///
+ ///
IBrowseClient Browse { get; }
+ ///
+ /// Operations related to Spotify Shows
+ ///
+ ///
IShowsClient Shows { get; }
+ ///
+ /// Operations related to Spotify Playlists
+ ///
+ ///
IPlaylistsClient Playlists { get; }
+ ///
+ /// Operations related to Spotify Search
+ ///
+ ///
ISearchClient Search { get; }
+ ///
+ /// Operations related to Spotify Follows
+ ///
+ ///
IFollowClient Follow { get; }
+ ///
+ /// Operations related to Spotify Tracks
+ ///
+ ///
ITracksClient Tracks { get; }
+ ///
+ /// Operations related to Spotify Player Endpoints
+ ///
+ ///
IPlayerClient Player { get; }
+ ///
+ /// Operations related to Spotify Albums
+ ///
+ ///
IAlbumsClient Albums { get; }
+ ///
+ /// Operations related to Spotify Artists
+ ///
+ ///
IArtistsClient Artists { get; }
+ ///
+ /// Operations related to Spotify Personalization Endpoints
+ ///
+ ///
IPersonalizationClient Personalization { get; }
+ ///
+ /// Operations related to Spotify Podcast Episodes
+ ///
+ ///
IEpisodesClient Episodes { get; }
+ ///
+ /// Operations related to Spotify User Library
+ ///
+ ///
ILibraryClient Library { get; }
+ ///
+ /// Returns the last response received by an API call.
+ ///
+ ///
IResponse? LastResponse { get; }
- Task> PaginateAll(Paging firstPage);
- Task> PaginateAll(Paging firstPage, IPaginator paginator);
- Task> PaginateAll(Func>> getFirstPage);
- Task> PaginateAll(Func>> getFirstPage, IPaginator paginator);
+ ///
+ /// Fetches all pages and returns them grouped in a list.
+ /// The default paginator will fetch all available resources without a delay between requests.
+ /// This can drain your request limit quite fast, so consider using a custom paginator with delays.
+ ///
+ /// The first page, will be included in the output list!
+ /// Optional. If not supplied, DefaultPaginator will be used
+ /// The Paging-Type
+ /// A list containing all fetched pages
+ Task> PaginateAll(Paging firstPage, IPaginator? paginator = default!);
- Task> PaginateAll(Paging firstPage, Func> mapper);
- Task> PaginateAll(Paging firstPage, Func> mapper, IPaginator paginator);
- Task> PaginateAll(Func>> getFirstPage, Func> mapper);
- Task> PaginateAll(Func>> getFirstPage, Func> mapper, IPaginator paginator);
+ ///
+ /// Fetches all pages and returns them grouped in a list.
+ /// The default paginator will fetch all available resources without a delay between requests.
+ /// This can drain your request limit quite fast, so consider using a custom paginator with delays.
+ ///
+ /// A function to retrive the first page, will be included in the output list!
+ /// Optional. If not supplied, DefaultPaginator will be used
+ /// The Paging-Type
+ /// A list containing all fetched pages
+ Task> PaginateAll(Func>> getFirstPage, IPaginator? paginator = default!);
+
+ ///
+ /// Fetches all pages and returns them grouped in a list.
+ /// The default paginator will fetch all available resources without a delay between requests.
+ /// This can drain your request limit quite fast, so consider using a custom paginator with delays.
+ ///
+ /// A task to retrive the first page, will be included in the output list!
+ /// Optional. If not supplied, DefaultPaginator will be used
+ /// The Paging-Type
+ /// A list containing all fetched pages
+ Task> PaginateAll(Task> firstPageTask, IPaginator? paginator = default!);
+
+ ///
+ /// Fetches all pages and returns them grouped in a list.
+ /// Some responses (e.g search response) have the pagination nested in a JSON Property.
+ /// To workaround this limitation, the mapper is required and needs to point to the correct next pagination.
+ /// The default paginator will fetch all available resources without a delay between requests.
+ /// This can drain your request limit quite fast, so consider using a custom paginator with delays.
+ ///
+ /// A first page, will be included in the output list!
+ /// A function which maps response objects to the next paging object
+ /// Optional. If not supplied, DefaultPaginator will be used
+ /// The Paging-Type
+ /// A list containing all fetched pages
+ Task> PaginateAll(
+ Paging firstPage,
+ Func> mapper,
+ IPaginator? paginator = default!
+ );
+
+ ///
+ /// Fetches all pages and returns them grouped in a list.
+ /// Some responses (e.g search response) have the pagination nested in a JSON Property.
+ /// To workaround this limitation, the mapper is required and needs to point to the correct next pagination.
+ /// The default paginator will fetch all available resources without a delay between requests.
+ /// This can drain your request limit quite fast, so consider using a custom paginator with delays.
+ ///
+ /// A function to retrive the first page, will be included in the output list!
+ /// A function which maps response objects to the next paging object
+ /// Optional. If not supplied, DefaultPaginator will be used
+ /// The Paging-Type
+ /// The Response-Type
+ ///
+ Task> PaginateAll(
+ Func>> getFirstPage,
+ Func> mapper,
+ IPaginator? paginator = default!
+ );
+
+ ///
+ /// Fetches all pages and returns them grouped in a list.
+ /// Some responses (e.g search response) have the pagination nested in a JSON Property.
+ /// To workaround this limitation, the mapper is required and needs to point to the correct next pagination.
+ /// The default paginator will fetch all available resources without a delay between requests.
+ /// This can drain your request limit quite fast, so consider using a custom paginator with delays.
+ ///
+ /// A Task to retrive the first page, will be included in the output list!
+ /// A function which maps response objects to the next paging object
+ /// Optional. If not supplied, DefaultPaginator will be used
+ /// The Paging-Type
+ /// The Response-Type
+ ///
+ Task> PaginateAll(
+ Task> firstPageTask,
+ Func> mapper,
+ IPaginator? paginator = default!
+ );
#if NETSTANDARD2_1
- IAsyncEnumerable Paginate(Paging firstPage);
- IAsyncEnumerable Paginate(Paging firstPage, IPaginator paginator);
- IAsyncEnumerable Paginate(Func>> getFirstPage);
- IAsyncEnumerable Paginate(Func>> getFirstPage, IPaginator paginator);
+ ///
+ /// Paginate through pages by using IAsyncEnumerable, introduced in C# 8
+ /// The default paginator will fetch all available resources without a delay between requests.
+ /// This can drain your request limit quite fast, so consider using a custom paginator with delays.
+ ///
+ /// A first page, will be included in the output list!
+ /// Optional. If not supplied, DefaultPaginator will be used
+ /// An optional Cancellation Token
+ /// The Paging-Type
+ /// An iterable IAsyncEnumerable
+ IAsyncEnumerable Paginate(
+ Paging firstPage,
+ IPaginator? paginator = default!,
+ CancellationToken cancellationToken = default!
+ );
- IAsyncEnumerable Paginate(Paging firstPage, Func> mapper);
- IAsyncEnumerable Paginate(Paging firstPage, Func> mapper, IPaginator paginator);
- IAsyncEnumerable Paginate(Func>> getFirstPage, Func> mapper);
- IAsyncEnumerable Paginate(Func>> getFirstPage, Func> mapper, IPaginator paginator);
+ ///
+ /// Paginate through pages by using IAsyncEnumerable, introduced in C# 8
+ /// The default paginator will fetch all available resources without a delay between requests.
+ /// This can drain your request limit quite fast, so consider using a custom paginator with delays.
+ ///
+ /// A Function to retrive the first page, will be included in the output list!
+ /// Optional. If not supplied, DefaultPaginator will be used
+ /// An optional Cancellation Token
+ /// The Paging-Type
+ /// An iterable IAsyncEnumerable
+ IAsyncEnumerable Paginate(
+ Func>> getFirstPage,
+ IPaginator? paginator = default!,
+ CancellationToken cancellationToken = default!
+ );
+
+ ///
+ /// Paginate through pages by using IAsyncEnumerable, introduced in C# 8
+ /// The default paginator will fetch all available resources without a delay between requests.
+ /// This can drain your request limit quite fast, so consider using a custom paginator with delays.
+ ///
+ /// A Task to retrive the first page, will be included in the output list!
+ /// Optional. If not supplied, DefaultPaginator will be used
+ /// An optional Cancellation Token
+ /// The Paging-Type
+ /// An iterable IAsyncEnumerable
+ IAsyncEnumerable Paginate(
+ Task> firstPageTask,
+ IPaginator? paginator = default!,
+ CancellationToken cancellationToken = default!
+ );
+
+ ///
+ /// Paginate through pages by using IAsyncEnumerable, introduced in C# 8
+ /// Some responses (e.g search response) have the pagination nested in a JSON Property.
+ /// To workaround this limitation, the mapper is required and needs to point to the correct next pagination.
+ /// The default paginator will fetch all available resources without a delay between requests.
+ /// This can drain your request limit quite fast, so consider using a custom paginator with delays.
+ ///
+ /// A first page, will be included in the output list!
+ /// A function which maps response objects to the next paging object
+ /// Optional. If not supplied, DefaultPaginator will be used
+ /// An optional Cancellation Token
+ /// The Paging-Type
+ /// The Response-Type
+ ///
+ IAsyncEnumerable Paginate(
+ Paging firstPage,
+ Func> mapper,
+ IPaginator? paginator = default!,
+ CancellationToken cancellationToken = default!
+ );
+
+ ///
+ /// Paginate through pages by using IAsyncEnumerable, introduced in C# 8
+ /// Some responses (e.g search response) have the pagination nested in a JSON Property.
+ /// To workaround this limitation, the mapper is required and needs to point to the correct next pagination.
+ /// The default paginator will fetch all available resources without a delay between requests.
+ /// This can drain your request limit quite fast, so consider using a custom paginator with delays.
+ ///
+ /// A Function to retrive the first page, will be included in the output list!
+ /// A function which maps response objects to the next paging object
+ /// Optional. If not supplied, DefaultPaginator will be used
+ /// An optional Cancellation Token
+ /// The Paging-Type
+ /// The Response-Type
+ ///
+ IAsyncEnumerable Paginate(
+ Func>> getFirstPage,
+ Func> mapper,
+ IPaginator? paginator = default!,
+ CancellationToken cancellationToken = default!
+ );
+
+ ///
+ /// Paginate through pages by using IAsyncEnumerable, introduced in C# 8
+ /// Some responses (e.g search response) have the pagination nested in a JSON Property.
+ /// To workaround this limitation, the mapper is required and needs to point to the correct next pagination.
+ /// The default paginator will fetch all available resources without a delay between requests.
+ /// This can drain your request limit quite fast, so consider using a custom paginator with delays.
+ ///
+ /// A Task to retrive the first page, will be included in the output list!
+ /// A function which maps response objects to the next paging object
+ /// Optional. If not supplied, DefaultPaginator will be used
+ /// An optional Cancellation Token
+ /// The Paging-Type
+ /// The Response-Type
+ ///
+ IAsyncEnumerable Paginate(
+ Task> firstPageTask,
+ Func> mapper,
+ IPaginator? paginator = default!,
+ CancellationToken cancellationToken = default!
+ );
#endif
}
}
diff --git a/SpotifyAPI.Web/Clients/SpotifyClient.cs b/SpotifyAPI.Web/Clients/SpotifyClient.cs
index a30982a7..e5c958b3 100644
--- a/SpotifyAPI.Web/Clients/SpotifyClient.cs
+++ b/SpotifyAPI.Web/Clients/SpotifyClient.cs
@@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
+using System.Threading;
using System.Threading.Tasks;
using SpotifyAPI.Web.Http;
+using System.Runtime.CompilerServices;
namespace SpotifyAPI.Web
{
@@ -80,157 +82,287 @@ namespace SpotifyAPI.Web
public IResponse? LastResponse { get; private set; }
- public Task> PaginateAll(Paging firstPage)
+ ///
+ /// Fetches all pages and returns them grouped in a list.
+ /// The default paginator will fetch all available resources without a delay between requests.
+ /// This can drain your request limit quite fast, so consider using a custom paginator with delays.
+ ///
+ /// The first page, will be included in the output list!
+ /// Optional. If not supplied, DefaultPaginator will be used
+ /// The Paging-Type
+ /// A list containing all fetched pages
+ public Task> PaginateAll(Paging firstPage, IPaginator? paginator = null)
{
- return DefaultPaginator.PaginateAll(firstPage, _apiConnector);
+ return (paginator ?? DefaultPaginator).PaginateAll(firstPage, _apiConnector);
}
- public Task> PaginateAll(Paging firstPage, IPaginator paginator)
- {
- Ensure.ArgumentNotNull(paginator, nameof(paginator));
-
- return paginator.PaginateAll(firstPage, _apiConnector);
- }
-
- public async Task> PaginateAll(Func>> getFirstPage)
+ ///
+ /// Fetches all pages and returns them grouped in a list.
+ /// The default paginator will fetch all available resources without a delay between requests.
+ /// This can drain your request limit quite fast, so consider using a custom paginator with delays.
+ ///
+ /// A function to retrive the first page, will be included in the output list!
+ /// Optional. If not supplied, DefaultPaginator will be used
+ /// The Paging-Type
+ /// A list containing all fetched pages
+ public async Task> PaginateAll(Func>> getFirstPage, IPaginator? paginator = null)
{
Ensure.ArgumentNotNull(getFirstPage, nameof(getFirstPage));
- return await DefaultPaginator.PaginateAll(
- await getFirstPage().ConfigureAwait(false), _apiConnector
- ).ConfigureAwait(false);
+ var firstPage = await getFirstPage().ConfigureAwait(false);
+ return await (paginator ?? DefaultPaginator).PaginateAll(firstPage, _apiConnector).ConfigureAwait(false);
}
- public async Task> PaginateAll(Func>> getFirstPage, IPaginator paginator)
+ ///
+ /// Fetches all pages and returns them grouped in a list.
+ /// The default paginator will fetch all available resources without a delay between requests.
+ /// This can drain your request limit quite fast, so consider using a custom paginator with delays.
+ ///
+ /// A task to retrive the first page, will be included in the output list!
+ /// Optional. If not supplied, DefaultPaginator will be used
+ /// The Paging-Type
+ /// A list containing all fetched pages
+ public async Task> PaginateAll(Task> firstPageTask, IPaginator? paginator = null)
{
- Ensure.ArgumentNotNull(getFirstPage, nameof(getFirstPage));
- Ensure.ArgumentNotNull(paginator, nameof(paginator));
+ Ensure.ArgumentNotNull(firstPageTask, nameof(firstPageTask));
- return await paginator.PaginateAll(
- await getFirstPage().ConfigureAwait(false), _apiConnector
- ).ConfigureAwait(false);
+ var firstPage = await firstPageTask.ConfigureAwait(false);
+ return await (paginator ?? DefaultPaginator).PaginateAll(firstPage, _apiConnector).ConfigureAwait(false);
}
- public Task> PaginateAll(
- Paging firstPage,
- Func> mapper
- )
- {
- return DefaultPaginator.PaginateAll(firstPage, mapper, _apiConnector);
- }
-
- public async Task> PaginateAll(
- Func>> getFirstPage,
- Func> mapper
- )
- {
- Ensure.ArgumentNotNull(getFirstPage, nameof(getFirstPage));
-
- return await DefaultPaginator.PaginateAll(await getFirstPage().ConfigureAwait(false), mapper, _apiConnector).ConfigureAwait(false);
- }
+ ///
+ /// Fetches all pages and returns them grouped in a list.
+ /// Some responses (e.g search response) have the pagination nested in a JSON Property.
+ /// To workaround this limitation, the mapper is required and needs to point to the correct next pagination.
+ /// The default paginator will fetch all available resources without a delay between requests.
+ /// This can drain your request limit quite fast, so consider using a custom paginator with delays.
+ ///
+ /// A first page, will be included in the output list!
+ /// A function which maps response objects to the next paging object
+ /// Optional. If not supplied, DefaultPaginator will be used
+ /// The Paging-Type
+ /// A list containing all fetched pages
public Task> PaginateAll(
Paging firstPage,
Func> mapper,
- IPaginator paginator)
+ IPaginator? paginator = null
+ )
{
- Ensure.ArgumentNotNull(paginator, nameof(paginator));
-
- return paginator.PaginateAll(firstPage, mapper, _apiConnector);
+ return (paginator ?? DefaultPaginator).PaginateAll(firstPage, mapper, _apiConnector);
}
+
+ ///
+ /// Fetches all pages and returns them grouped in a list.
+ /// Some responses (e.g search response) have the pagination nested in a JSON Property.
+ /// To workaround this limitation, the mapper is required and needs to point to the correct next pagination.
+ /// The default paginator will fetch all available resources without a delay between requests.
+ /// This can drain your request limit quite fast, so consider using a custom paginator with delays.
+ ///
+ /// A function to retrive the first page, will be included in the output list!
+ /// A function which maps response objects to the next paging object
+ /// Optional. If not supplied, DefaultPaginator will be used
+ /// The Paging-Type
+ /// The Response-Type
+ ///
public async Task> PaginateAll(
Func>> getFirstPage,
Func> mapper,
- IPaginator paginator
+ IPaginator? paginator = null
)
{
Ensure.ArgumentNotNull(getFirstPage, nameof(getFirstPage));
- Ensure.ArgumentNotNull(paginator, nameof(paginator));
- return await paginator.PaginateAll(
- await getFirstPage().ConfigureAwait(false), mapper, _apiConnector
- ).ConfigureAwait(false);
+ var firstPage = await getFirstPage().ConfigureAwait(false);
+ return await (paginator ?? DefaultPaginator).PaginateAll(firstPage, mapper, _apiConnector).ConfigureAwait(false);
}
+ ///
+ /// Fetches all pages and returns them grouped in a list.
+ /// Some responses (e.g search response) have the pagination nested in a JSON Property.
+ /// To workaround this limitation, the mapper is required and needs to point to the correct next pagination.
+ /// The default paginator will fetch all available resources without a delay between requests.
+ /// This can drain your request limit quite fast, so consider using a custom paginator with delays.
+ ///
+ /// A Task to retrive the first page, will be included in the output list!
+ /// A function which maps response objects to the next paging object
+ /// Optional. If not supplied, DefaultPaginator will be used
+ /// The Paging-Type
+ /// The Response-Type
+ ///
+ public async Task> PaginateAll(
+ Task> firstPageTask,
+ Func> mapper,
+ IPaginator? paginator = null
+ )
+ {
+ Ensure.ArgumentNotNull(firstPageTask, nameof(firstPageTask));
+
+ var firstPage = await firstPageTask.ConfigureAwait(false);
+ return await (paginator ?? DefaultPaginator).PaginateAll(firstPage, mapper, _apiConnector).ConfigureAwait(false);
+ }
#if NETSTANDARD2_1
- public IAsyncEnumerable Paginate(Paging firstPage)
+
+ ///
+ /// Paginate through pages by using IAsyncEnumerable, introduced in C# 8
+ /// The default paginator will fetch all available resources without a delay between requests.
+ /// This can drain your request limit quite fast, so consider using a custom paginator with delays.
+ ///
+ /// A first page, will be included in the output list!
+ /// Optional. If not supplied, DefaultPaginator will be used
+ /// An optional Cancellation Token
+ /// The Paging-Type
+ /// An iterable IAsyncEnumerable
+ public IAsyncEnumerable Paginate(
+ Paging firstPage,
+ IPaginator? paginator = null,
+ CancellationToken cancellationToken = default
+ )
{
- return DefaultPaginator.Paginate(firstPage, _apiConnector);
+ return (paginator ?? DefaultPaginator).Paginate(firstPage, _apiConnector, cancellationToken);
}
- public IAsyncEnumerable Paginate(Paging firstPage, IPaginator paginator)
+ ///
+ /// Paginate through pages by using IAsyncEnumerable, introduced in C# 8
+ /// The default paginator will fetch all available resources without a delay between requests.
+ /// This can drain your request limit quite fast, so consider using a custom paginator with delays.
+ ///
+ /// A Function to retrive the first page, will be included in the output list!
+ /// Optional. If not supplied, DefaultPaginator will be used
+ /// An optional Cancellation Token
+ /// The Paging-Type
+ /// An iterable IAsyncEnumerable
+ public async IAsyncEnumerable Paginate(
+ Func>> getFirstPage,
+ IPaginator? paginator = null,
+ [EnumeratorCancellation] CancellationToken cancellationToken = default
+ )
{
- Ensure.ArgumentNotNull(paginator, nameof(paginator));
- return paginator.Paginate(firstPage, _apiConnector);
- }
-
- public async IAsyncEnumerable Paginate(Func>> getFirstPage)
- {
Ensure.ArgumentNotNull(getFirstPage, nameof(getFirstPage));
var firstPage = await getFirstPage().ConfigureAwait(false);
- await foreach (var item in DefaultPaginator.Paginate(firstPage, _apiConnector))
+ await foreach (var item in (paginator ?? DefaultPaginator)
+ .Paginate(firstPage, _apiConnector)
+ .WithCancellation(cancellationToken)
+ )
{
yield return item;
}
}
- public async IAsyncEnumerable Paginate(Func>> getFirstPage, IPaginator paginator)
+ ///
+ /// Paginate through pages by using IAsyncEnumerable, introduced in C# 8
+ /// The default paginator will fetch all available resources without a delay between requests.
+ /// This can drain your request limit quite fast, so consider using a custom paginator with delays.
+ ///
+ /// A Task to retrive the first page, will be included in the output list!
+ /// Optional. If not supplied, DefaultPaginator will be used
+ /// An optional Cancellation Token
+ /// The Paging-Type
+ /// An iterable IAsyncEnumerable
+ public async IAsyncEnumerable Paginate(
+ Task> firstPageTask,
+ IPaginator? paginator = null,
+ [EnumeratorCancellation] CancellationToken cancellationToken = default)
{
- Ensure.ArgumentNotNull(getFirstPage, nameof(getFirstPage));
- Ensure.ArgumentNotNull(paginator, nameof(paginator));
+ Ensure.ArgumentNotNull(firstPageTask, nameof(firstPageTask));
- var firstPage = await getFirstPage().ConfigureAwait(false);
- await foreach (var item in DefaultPaginator.Paginate(firstPage, _apiConnector))
+ var firstPage = await firstPageTask.ConfigureAwait(false);
+ await foreach (var item in (paginator ?? DefaultPaginator)
+ .Paginate(firstPage, _apiConnector)
+ .WithCancellation(cancellationToken)
+ )
{
yield return item;
}
}
- public IAsyncEnumerable Paginate(Paging firstPage, Func> mapper)
- {
- return DefaultPaginator.Paginate(firstPage, mapper, _apiConnector);
- }
-
+ ///
+ /// Paginate through pages by using IAsyncEnumerable, introduced in C# 8
+ /// Some responses (e.g search response) have the pagination nested in a JSON Property.
+ /// To workaround this limitation, the mapper is required and needs to point to the correct next pagination.
+ /// The default paginator will fetch all available resources without a delay between requests.
+ /// This can drain your request limit quite fast, so consider using a custom paginator with delays.
+ ///
+ /// A first page, will be included in the output list!
+ /// A function which maps response objects to the next paging object
+ /// Optional. If not supplied, DefaultPaginator will be used
+ /// An optional Cancellation Token
+ /// The Paging-Type
+ /// The Response-Type
+ ///
public IAsyncEnumerable Paginate(
Paging firstPage,
Func> mapper,
- IPaginator paginator
+ IPaginator? paginator = null,
+ CancellationToken cancellationToken = default
)
{
- Ensure.ArgumentNotNull(paginator, nameof(paginator));
-
- return paginator.Paginate(firstPage, mapper, _apiConnector);
+ return (paginator ?? DefaultPaginator).Paginate(firstPage, mapper, _apiConnector, cancellationToken);
}
+ ///
+ /// Paginate through pages by using IAsyncEnumerable, introduced in C# 8
+ /// Some responses (e.g search response) have the pagination nested in a JSON Property.
+ /// To workaround this limitation, the mapper is required and needs to point to the correct next pagination.
+ /// The default paginator will fetch all available resources without a delay between requests.
+ /// This can drain your request limit quite fast, so consider using a custom paginator with delays.
+ ///
+ /// A Function to retrive the first page, will be included in the output list!
+ /// A function which maps response objects to the next paging object
+ /// Optional. If not supplied, DefaultPaginator will be used
+ /// An optional Cancellation Token
+ /// The Paging-Type
+ /// The Response-Type
+ ///
public async IAsyncEnumerable Paginate(
Func>> getFirstPage,
- Func> mapper
- )
+ Func> mapper,
+ IPaginator? paginator = null,
+ [EnumeratorCancellation] CancellationToken cancellationToken = default)
{
Ensure.ArgumentNotNull(getFirstPage, nameof(getFirstPage));
var firstPage = await getFirstPage().ConfigureAwait(false);
- await foreach (var item in DefaultPaginator.Paginate(firstPage, mapper, _apiConnector))
+ await foreach (var item in (paginator ?? DefaultPaginator)
+ .Paginate(firstPage, mapper, _apiConnector)
+ .WithCancellation(cancellationToken)
+ )
{
yield return item;
}
}
+ ///
+ /// Paginate through pages by using IAsyncEnumerable, introduced in C# 8
+ /// Some responses (e.g search response) have the pagination nested in a JSON Property.
+ /// To workaround this limitation, the mapper is required and needs to point to the correct next pagination.
+ /// The default paginator will fetch all available resources without a delay between requests.
+ /// This can drain your request limit quite fast, so consider using a custom paginator with delays.
+ ///
+ /// A Task to retrive the first page, will be included in the output list!
+ /// A function which maps response objects to the next paging object
+ /// Optional. If not supplied, DefaultPaginator will be used
+ /// An optional Cancellation Token
+ /// The Paging-Type
+ /// The Response-Type
+ ///
public async IAsyncEnumerable Paginate(
- Func>> getFirstPage,
+ Task> firstPageTask,
Func> mapper,
- IPaginator paginator
- )
+ IPaginator? paginator = null,
+ [EnumeratorCancellation] CancellationToken cancellationToken = default)
{
- Ensure.ArgumentNotNull(getFirstPage, nameof(getFirstPage));
- Ensure.ArgumentNotNull(paginator, nameof(paginator));
+ Ensure.ArgumentNotNull(firstPageTask, nameof(firstPageTask));
- var firstPage = await getFirstPage().ConfigureAwait(false);
- await foreach (var item in paginator.Paginate(firstPage, mapper, _apiConnector))
+ var firstPage = await firstPageTask.ConfigureAwait(false);
+ await foreach (var item in (paginator ?? DefaultPaginator)
+ .Paginate(firstPage, mapper, _apiConnector)
+ .WithCancellation(cancellationToken)
+ )
{
yield return item;
}
diff --git a/SpotifyAPI.Web/Models/Request/ShowEpisodesRequest.cs b/SpotifyAPI.Web/Models/Request/ShowEpisodesRequest.cs
index 71c08cef..8f355ebe 100644
--- a/SpotifyAPI.Web/Models/Request/ShowEpisodesRequest.cs
+++ b/SpotifyAPI.Web/Models/Request/ShowEpisodesRequest.cs
@@ -2,12 +2,30 @@ namespace SpotifyAPI.Web
{
public class ShowEpisodesRequest : RequestParams
{
+ ///
+ /// The maximum number of episodes to return. Default: 20. Minimum: 1. Maximum: 50.
+ ///
+ ///
[QueryParam("limit")]
public int? Limit { get; set; }
+ ///
+ /// The index of the first episode to return.
+ /// Default: 0 (the first object). Use with limit to get the next set of episodes.
+ ///
+ ///
[QueryParam("offset")]
public int? Offset { get; set; }
+ ///
+ /// An ISO 3166-1 alpha-2 country code. If a country code is specified, only shows and episodes
+ /// that are available in that market will be returned.
+ /// If a valid user access token is specified in the request header,
+ /// the country associated with the user account will take priority over this parameter.
+ /// Note: If neither market or user country are provided, the content is considered unavailable for the client.
+ /// Users can view the country that is associated with their account in the account settings.
+ ///
+ ///
[QueryParam("market")]
public string? Market { get; set; }
}
diff --git a/SpotifyAPI.Web/Models/Request/ShowRequest.cs b/SpotifyAPI.Web/Models/Request/ShowRequest.cs
index be0726fa..e2cd1fba 100644
--- a/SpotifyAPI.Web/Models/Request/ShowRequest.cs
+++ b/SpotifyAPI.Web/Models/Request/ShowRequest.cs
@@ -2,6 +2,16 @@ namespace SpotifyAPI.Web
{
public class ShowRequest : RequestParams
{
+ ///
+ /// An ISO 3166-1 alpha-2 country code. If a country code is specified,
+ /// only shows and episodes that are available in that market will be returned.
+ /// If a valid user access token is specified in the request header,
+ /// the country associated with the user account will take priority over this parameter.
+ /// Note: If neither market or user country are provided, the content
+ /// is considered unavailable for the client.
+ /// Users can view the country that is associated with their account in the account settings.
+ ///
+ ///
[QueryParam("market")]
public string? Market { get; set; }
}
diff --git a/SpotifyAPI.Web/Models/Request/ShowsRequest.cs b/SpotifyAPI.Web/Models/Request/ShowsRequest.cs
index eccf38fc..edccc421 100644
--- a/SpotifyAPI.Web/Models/Request/ShowsRequest.cs
+++ b/SpotifyAPI.Web/Models/Request/ShowsRequest.cs
@@ -4,6 +4,12 @@ namespace SpotifyAPI.Web
{
public class ShowsRequest : RequestParams
{
+ ///
+ /// Get Spotify catalog information for several shows based on their Spotify IDs.
+ ///
+ ///
+ /// A comma-separated list of the Spotify IDs for the shows. Maximum: 50 IDs.
+ ///
public ShowsRequest(IList ids)
{
Ensure.ArgumentNotNullOrEmptyList(ids, nameof(ids));
@@ -11,9 +17,23 @@ namespace SpotifyAPI.Web
Ids = ids;
}
+ ///
+ /// A comma-separated list of the Spotify IDs for the shows. Maximum: 50 IDs.
+ ///
+ ///
[QueryParam("ids")]
public IList Ids { get; }
+ ///
+ /// An ISO 3166-1 alpha-2 country code. If a country code is specified, only shows and episodes
+ /// that are available in that market will be returned.
+ /// If a valid user access token is specified in the request header,
+ /// the country associated with the user account will take priority over this parameter.
+ /// Note: If neither market or user country are provided,
+ /// the content is considered unavailable for the client.
+ /// Users can view the country that is associated with their account in the account settings.
+ ///
+ ///
[QueryParam("market")]
public string? Market { get; set; }
}
diff --git a/SpotifyAPI.Web/Models/Response/CategoriesResponse.cs b/SpotifyAPI.Web/Models/Response/CategoriesResponse.cs
index 92b2d6f4..ca63e5b1 100644
--- a/SpotifyAPI.Web/Models/Response/CategoriesResponse.cs
+++ b/SpotifyAPI.Web/Models/Response/CategoriesResponse.cs
@@ -2,7 +2,7 @@ namespace SpotifyAPI.Web
{
public class CategoriesResponse
{
- public Paging Categories { get; set; } = default!;
+ public Paging Categories { get; set; } = default!;
}
}
diff --git a/SpotifyAPI.Web/Models/Response/CategoryPlaylistsResponse.cs b/SpotifyAPI.Web/Models/Response/CategoryPlaylistsResponse.cs
index 1f895bc0..e65fa8ad 100644
--- a/SpotifyAPI.Web/Models/Response/CategoryPlaylistsResponse.cs
+++ b/SpotifyAPI.Web/Models/Response/CategoryPlaylistsResponse.cs
@@ -2,7 +2,7 @@ namespace SpotifyAPI.Web
{
public class CategoryPlaylistsResponse
{
- public Paging Playlists { get; set; } = default!;
+ public Paging Playlists { get; set; } = default!;
}
}
diff --git a/SpotifyAPI.Web/Models/Response/FeaturedPlaylistsResponse.cs b/SpotifyAPI.Web/Models/Response/FeaturedPlaylistsResponse.cs
index 7a97d741..f38b7346 100644
--- a/SpotifyAPI.Web/Models/Response/FeaturedPlaylistsResponse.cs
+++ b/SpotifyAPI.Web/Models/Response/FeaturedPlaylistsResponse.cs
@@ -3,7 +3,7 @@ namespace SpotifyAPI.Web
public class FeaturedPlaylistsResponse
{
public string Message { get; set; } = default!;
- public Paging Playlists { get; set; } = default!;
+ public Paging Playlists { get; set; } = default!;
}
}
diff --git a/SpotifyAPI.Web/Models/Response/NewReleasesResponse.cs b/SpotifyAPI.Web/Models/Response/NewReleasesResponse.cs
index 4d683c51..d9ec7aa6 100644
--- a/SpotifyAPI.Web/Models/Response/NewReleasesResponse.cs
+++ b/SpotifyAPI.Web/Models/Response/NewReleasesResponse.cs
@@ -3,7 +3,7 @@ namespace SpotifyAPI.Web
public class NewReleasesResponse
{
public string Message { get; set; } = default!;
- public Paging Albums { get; set; } = default!;
+ public Paging Albums { get; set; } = default!;
}
}