feat: list operations now support AsyncPageable if next_page_token is returned (#196)
* feat: jobs/list and jobs/runs/list now returns AsyncPageable * More AsyncPageable support * fixing style issue
This commit is contained in:
Родитель
d5c1b2039c
Коммит
5be4182381
|
@ -10,6 +10,7 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="Azure.Identity" Version="1.12.0" />
|
||||
<PackageReference Include="Polly" Version="8.4.0" />
|
||||
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -598,10 +598,11 @@ public class JobApiClientTest : ApiClientTest
|
|||
}
|
||||
|
||||
[TestMethod]
|
||||
[Obsolete]
|
||||
public async Task TestList()
|
||||
{
|
||||
var apiUri = new Uri(JobsApiUri, "list");
|
||||
var requestUri = new Uri(apiUri, "?limit=20&offset=0&expand_tasks=false");
|
||||
var requestUri = new Uri(apiUri, "?limit=20&expand_tasks=false&offset=0");
|
||||
|
||||
var expectedResponse = new JobList
|
||||
{
|
||||
|
@ -644,6 +645,78 @@ public class JobApiClientTest : ApiClientTest
|
|||
);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task TestListPageable()
|
||||
{
|
||||
var apiUri = new Uri(JobsApiUri, "list");
|
||||
var expectedRequestUrl1 = new Uri(apiUri, "?limit=2&expand_tasks=false");
|
||||
var expectedRequestUrl2 = new Uri(apiUri, "?limit=2&expand_tasks=false&page_token=second");
|
||||
var expectedRequestUrl3 = new Uri(apiUri, "?limit=2&expand_tasks=false&page_token=third");
|
||||
|
||||
const string response1 = @"
|
||||
{
|
||||
""jobs"":[{""job_id"": 1}, {""job_id"": 2}],
|
||||
""has_more"": true,
|
||||
""next_page_token"": ""second"",
|
||||
""prev_page_token"": """"
|
||||
}
|
||||
";
|
||||
const string response2 = @"
|
||||
{
|
||||
""jobs"":[{""job_id"": 3}, {""job_id"": 4}],
|
||||
""has_more"": true,
|
||||
""next_page_token"": ""third"",
|
||||
""prev_page_token"": ""first""
|
||||
}
|
||||
";
|
||||
const string response3 = @"
|
||||
{
|
||||
""jobs"":[{""job_id"": 5}, {""job_id"": 6}],
|
||||
""has_more"": false,
|
||||
""next_page_token"": """",
|
||||
""prev_page_token"": ""second""
|
||||
}
|
||||
";
|
||||
|
||||
var handler = CreateMockHandler();
|
||||
handler
|
||||
.SetupRequest(HttpMethod.Get, expectedRequestUrl1)
|
||||
.ReturnsResponse(HttpStatusCode.OK, response1, "application/json")
|
||||
.Verifiable();
|
||||
handler.SetupRequest(HttpMethod.Get, expectedRequestUrl2)
|
||||
.ReturnsResponse(HttpStatusCode.OK, response2, "application/json")
|
||||
.Verifiable();
|
||||
handler.SetupRequest(HttpMethod.Get, expectedRequestUrl3)
|
||||
.ReturnsResponse(HttpStatusCode.OK, response3, "application/json")
|
||||
.Verifiable();
|
||||
|
||||
var hc = handler.CreateClient();
|
||||
hc.BaseAddress = BaseApiUri;
|
||||
|
||||
using var client = new JobsApiClient(hc);
|
||||
var jobs = client.ListPageable(pageSize: 2);
|
||||
|
||||
Assert.AreEqual(6, await jobs.CountAsync());
|
||||
|
||||
handler.VerifyRequest(
|
||||
HttpMethod.Get,
|
||||
expectedRequestUrl1,
|
||||
Times.Once()
|
||||
);
|
||||
|
||||
handler.VerifyRequest(
|
||||
HttpMethod.Get,
|
||||
expectedRequestUrl2,
|
||||
Times.Once()
|
||||
);
|
||||
|
||||
handler.VerifyRequest(
|
||||
HttpMethod.Get,
|
||||
expectedRequestUrl3,
|
||||
Times.Once()
|
||||
);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task TestRunNow()
|
||||
{
|
||||
|
@ -1073,6 +1146,79 @@ public class JobApiClientTest : ApiClientTest
|
|||
);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task TestRunsListPageable()
|
||||
{
|
||||
var apiUri = new Uri(JobsApiUri, "runs/list");
|
||||
|
||||
var expectedRequestUrl1 = new Uri(apiUri, "?limit=2&job_id=11223344");
|
||||
var expectedRequestUrl2 = new Uri(apiUri, "?limit=2&job_id=11223344&page_token=second");
|
||||
var expectedRequestUrl3 = new Uri(apiUri, "?limit=2&job_id=11223344&page_token=third");
|
||||
|
||||
const string response1 = @"
|
||||
{
|
||||
""runs"":[{""job_id"": 11223344,""run_id"": 1}, {""job_id"": 11223344,""run_id"": 2}],
|
||||
""has_more"": true,
|
||||
""next_page_token"": ""second"",
|
||||
""prev_page_token"": """"
|
||||
}
|
||||
";
|
||||
const string response2 = @"
|
||||
{
|
||||
""runs"":[{""job_id"": 11223344,""run_id"": 3}, {""job_id"": 11223344,""run_id"": 4}],
|
||||
""has_more"": true,
|
||||
""next_page_token"": ""third"",
|
||||
""prev_page_token"": ""first""
|
||||
}
|
||||
";
|
||||
const string response3 = @"
|
||||
{
|
||||
""runs"":[{""job_id"": 11223344,""run_id"": 5}, {""job_id"": 11223344,""run_id"": 6}],
|
||||
""has_more"": false,
|
||||
""next_page_token"": """",
|
||||
""prev_page_token"": ""second""
|
||||
}
|
||||
";
|
||||
|
||||
var handler = CreateMockHandler();
|
||||
handler
|
||||
.SetupRequest(HttpMethod.Get, expectedRequestUrl1)
|
||||
.ReturnsResponse(HttpStatusCode.OK, response1, "application/json")
|
||||
.Verifiable();
|
||||
handler.SetupRequest(HttpMethod.Get, expectedRequestUrl2)
|
||||
.ReturnsResponse(HttpStatusCode.OK, response2, "application/json")
|
||||
.Verifiable();
|
||||
handler.SetupRequest(HttpMethod.Get, expectedRequestUrl3)
|
||||
.ReturnsResponse(HttpStatusCode.OK, response3, "application/json")
|
||||
.Verifiable();
|
||||
|
||||
var hc = handler.CreateClient();
|
||||
hc.BaseAddress = BaseApiUri;
|
||||
|
||||
using var client = new JobsApiClient(hc);
|
||||
var runs = client.RunsListPageable(jobId: 11223344, pageSize: 2);
|
||||
|
||||
Assert.AreEqual(6, await runs.CountAsync());
|
||||
|
||||
handler.VerifyRequest(
|
||||
HttpMethod.Get,
|
||||
expectedRequestUrl1,
|
||||
Times.Once()
|
||||
);
|
||||
|
||||
handler.VerifyRequest(
|
||||
HttpMethod.Get,
|
||||
expectedRequestUrl2,
|
||||
Times.Once()
|
||||
);
|
||||
|
||||
handler.VerifyRequest(
|
||||
HttpMethod.Get,
|
||||
expectedRequestUrl3,
|
||||
Times.Once()
|
||||
);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task TestRunsExport()
|
||||
{
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Polly" Version="8.4.0" />
|
||||
<PackageReference Include="Polly" Version="8.4.0" />
|
||||
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the MIT License.
|
||||
|
||||
using Microsoft.Azure.Databricks.Client.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
|
@ -96,11 +97,7 @@ public class ClusterPoliciesApiClient : ApiClient, IClusterPoliciesApi
|
|||
public async Task<(IEnumerable<PolicyFamily>, string)> ListPolicyFamily(int maxResults = 20, string pageToken = default, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var requestUri = $"{ApiVersion}/policy-families?max_results={maxResults}";
|
||||
|
||||
if (!string.IsNullOrEmpty(pageToken))
|
||||
{
|
||||
requestUri += $"&page_token={pageToken}";
|
||||
}
|
||||
requestUri += string.IsNullOrEmpty(pageToken) ? string.Empty : $"&page_token={pageToken}";
|
||||
|
||||
var response = await HttpGet<JsonObject>(this.HttpClient, requestUri, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
|
@ -112,4 +109,13 @@ public class ClusterPoliciesApiClient : ApiClient, IClusterPoliciesApi
|
|||
|
||||
return (families, nextPageToken);
|
||||
}
|
||||
|
||||
public global::Azure.AsyncPageable<PolicyFamily> ListPolicyFamilyPageable(int pageSize, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return new AsyncPageable<PolicyFamily>(async (pageToken) =>
|
||||
{
|
||||
var (policyFamilyList, nextPageToken) = await ListPolicyFamily(pageSize, pageToken, cancellationToken).ConfigureAwait(false);
|
||||
return (policyFamilyList.ToList(), !string.IsNullOrEmpty(nextPageToken), nextPageToken);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -53,4 +53,6 @@ public interface IClusterPoliciesApi : IDisposable
|
|||
Task<PolicyFamily> GetPolicyFamily(string id, CancellationToken cancellationToken = default);
|
||||
|
||||
Task<(IEnumerable<PolicyFamily>, string)> ListPolicyFamily(int maxResults, string pageToken = default, CancellationToken cancellationToken = default);
|
||||
|
||||
global::Azure.AsyncPageable<PolicyFamily> ListPolicyFamilyPageable(int pageSize, CancellationToken cancellationToken = default);
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using Azure;
|
||||
using Microsoft.Azure.Databricks.Client.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@ -24,9 +25,16 @@ public interface IJobsApi : IDisposable
|
|||
/// <param name="offset">The offset of the first job to return, relative to the most recently created job.</param>
|
||||
/// <param name="name">A filter on the list based on the exact (case insensitive) job name.</param>
|
||||
/// <param name="expandTasks">Whether to include task and cluster details in the response.</param>
|
||||
[Obsolete("The offset parameter is deprecated. Use method with pageToken to iterate through the pages.")]
|
||||
Task<JobList> List(int limit = 20, int offset = 0, string name = default, bool expandTasks = false,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// List all jobs.
|
||||
/// </summary>
|
||||
global::Azure.AsyncPageable<Job> ListPageable(int pageSize = 20, string name = default, bool expandTasks = false,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the job and sends an email to the addresses specified in JobSettings.email_notifications. No action will occur if the job has already been removed. After the job is removed, neither its details or its run history will be visible via the Jobs UI or API. The job is guaranteed to be removed upon completion of this request. However, runs that were active before the receipt of this request may still be active. They will be terminated asynchronously.
|
||||
/// </summary>
|
||||
|
@ -133,6 +141,11 @@ public interface IJobsApi : IDisposable
|
|||
bool expandTasks = default, DateTimeOffset? startTimeFrom = default,
|
||||
DateTimeOffset? startTimeTo = default, CancellationToken cancellationToken = default);
|
||||
|
||||
global::Azure.AsyncPageable<Run> RunsListPageable(long? jobId = default, int pageSize = 25,
|
||||
bool activeOnly = default, bool completedOnly = default, RunType? runType = default,
|
||||
bool expandTasks = default, DateTimeOffset? startTimeFrom = default,
|
||||
DateTimeOffset? startTimeTo = default, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the metadata of a run.
|
||||
/// </summary>
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
using Microsoft.Azure.Databricks.Client.Models;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -14,6 +13,8 @@ public interface IPipelinesApi : IDisposable
|
|||
/// </summary>
|
||||
Task<PipelinesList> List(int maxResults = 25, string pageToken = default, CancellationToken cancellationToken = default);
|
||||
|
||||
global::Azure.AsyncPageable<Pipeline> ListPageable(int pageSize = 25, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new data processing pipeline based on the requested configuration.
|
||||
/// If successful, this method returns the ID of the new pipeline.
|
||||
|
@ -70,6 +71,12 @@ public interface IPipelinesApi : IDisposable
|
|||
string untilUpdateId = null,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
global::Azure.AsyncPageable<PipelineUpdate> ListUpdatesPageable(
|
||||
string pipelineId,
|
||||
int pageSize = 25,
|
||||
string untilUpdateId = null,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Starts or queues a pipeline update.
|
||||
/// </summary>
|
||||
|
@ -87,8 +94,18 @@ public interface IPipelinesApi : IDisposable
|
|||
Task<PipelineEventsList> ListEvents(
|
||||
string pipelineId,
|
||||
int maxResults = 25,
|
||||
string orderBy = null,
|
||||
string filter = null,
|
||||
string pageToken = null,
|
||||
string orderBy = default,
|
||||
string filter = default,
|
||||
string pageToken = default,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves events for a pipeline.
|
||||
/// </summary>
|
||||
global::Azure.AsyncPageable<PipelineEvent> ListEventsPageable(
|
||||
string pipelineId,
|
||||
int pageSize = 25,
|
||||
string orderBy = default,
|
||||
string filter = default,
|
||||
CancellationToken cancellationToken = default);
|
||||
}
|
||||
|
|
|
@ -18,6 +18,11 @@ public interface IReposApi : IDisposable
|
|||
/// <param name="pageToken">Token used to get the next page of results. If not specified, returns the first page of results as well as a next page token if there are more results.</param>
|
||||
Task<(IEnumerable<Repo>, string)> List(string pathPrefix = default, string pageToken = default, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Returns repos that the calling user has Manage permissions on. Results are paginated with each page containing twenty repos.
|
||||
/// </summary>
|
||||
/// <param name="pathPrefix">Filters repos that have paths starting with the given path prefix.</param>
|
||||
global::Azure.AsyncPageable<Repo> ListPageable(string pathPrefix = default, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a repo in the workspace and links it to the remote Git repo specified. Note that repos created programmatically must be linked to a remote Git repo, unlike repos created in the browser.
|
||||
|
|
|
@ -13,6 +13,7 @@ using System.Threading;
|
|||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.Azure.Databricks.Client;
|
||||
|
||||
public class JobsApiClient : ApiClient, IJobsApi
|
||||
{
|
||||
protected override string ApiVersion => "2.1";
|
||||
|
@ -39,6 +40,20 @@ public class JobsApiClient : ApiClient, IJobsApi
|
|||
return jobIdentifier["job_id"]!.GetValue<long>();
|
||||
}
|
||||
|
||||
private string BuildJobsListUrl(int limit, string name, bool expandTasks)
|
||||
{
|
||||
StringBuilder url = new($"{ApiVersion}/jobs/list?limit={limit}");
|
||||
|
||||
if (name is not null)
|
||||
{
|
||||
url.Append($"&name={name}");
|
||||
}
|
||||
|
||||
url.Append($"&expand_tasks={expandTasks.ToString().ToLowerInvariant()}");
|
||||
return url.ToString();
|
||||
}
|
||||
|
||||
[Obsolete("The offset parameter is deprecated. Use method with pageToken to iterate through the pages.")]
|
||||
public async Task<JobList> List(int limit = 20, int offset = 0, string name = default, bool expandTasks = false,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
|
@ -52,14 +67,10 @@ public class JobsApiClient : ApiClient, IJobsApi
|
|||
throw new ArgumentOutOfRangeException(nameof(offset), "offset must be greater than or equal to 0");
|
||||
}
|
||||
|
||||
var requestUri = $"{ApiVersion}/jobs/list?limit={limit}&offset={offset}&expand_tasks={expandTasks.ToString().ToLowerInvariant()}";
|
||||
var url = BuildJobsListUrl(limit, name, expandTasks);
|
||||
url += $"&offset={offset}";
|
||||
|
||||
if (name is not null)
|
||||
{
|
||||
requestUri += $"&name={name}";
|
||||
}
|
||||
|
||||
var response = await HttpGet<JsonObject>(this.HttpClient, requestUri, cancellationToken)
|
||||
var response = await HttpGet<JsonObject>(this.HttpClient, url, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
response.TryGetPropertyValue("jobs", out var jobsNode);
|
||||
|
@ -68,6 +79,23 @@ public class JobsApiClient : ApiClient, IJobsApi
|
|||
return new JobList { Jobs = jobs, HasMore = hasMore };
|
||||
}
|
||||
|
||||
public global::Azure.AsyncPageable<Job> ListPageable(int pageSize = 20, string name = null, bool expandTasks = false, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (pageSize < 1 || pageSize > 25)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(pageSize), "pageSize must be between 1 and 25");
|
||||
}
|
||||
|
||||
return new AsyncPageable<Job>(async (nextPageToken) =>
|
||||
{
|
||||
var url = BuildJobsListUrl(pageSize, name, expandTasks);
|
||||
url += string.IsNullOrEmpty(nextPageToken) ? string.Empty : $"&page_token={nextPageToken}";
|
||||
|
||||
var jobList = await HttpGet<JobList>(this.HttpClient, url, cancellationToken).ConfigureAwait(false);
|
||||
return (jobList.Jobs.ToList(), jobList.HasMore, jobList.NextPageToken);
|
||||
});
|
||||
}
|
||||
|
||||
public async Task Delete(long jobId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
await HttpPost(this.HttpClient, $"{ApiVersion}/jobs/delete", new { job_id = jobId }, cancellationToken).ConfigureAwait(false);
|
||||
|
@ -193,9 +221,26 @@ public class JobsApiClient : ApiClient, IJobsApi
|
|||
{
|
||||
string url = BuildRunsListUrl(jobId, limit, activeOnly, completedOnly, runType, expandTasks, startTimeFrom, startTimeTo);
|
||||
url += string.IsNullOrEmpty(pageToken) ? string.Empty : $"&page_token={pageToken}";
|
||||
|
||||
|
||||
await Console.Out.WriteLineAsync("Request: " + url);
|
||||
|
||||
|
||||
return await HttpGet<RunList>(this.HttpClient, url, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public global::Azure.AsyncPageable<Run> RunsListPageable(long? jobId = null, int pageSize = 25,
|
||||
bool activeOnly = false, bool completedOnly = false, RunType? runType = null, bool expandTasks = false,
|
||||
DateTimeOffset? startTimeFrom = null, DateTimeOffset? startTimeTo = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return new AsyncPageable<Run>(async (nextPageToken) =>
|
||||
{
|
||||
var response = await RunsList(nextPageToken, jobId, pageSize, activeOnly, completedOnly, runType, expandTasks,
|
||||
startTimeFrom, startTimeTo, cancellationToken).ConfigureAwait(false);
|
||||
return (response.Runs.ToList(), response.HasMore, response.NextPageToken);
|
||||
});
|
||||
}
|
||||
|
||||
public async Task<(Run, RepairHistory)> RunsGet(long runId, bool includeHistory = default,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
|
|
|
@ -8,6 +8,11 @@ namespace Microsoft.Azure.Databricks.Client.Models;
|
|||
|
||||
public record JobList
|
||||
{
|
||||
public JobList()
|
||||
{
|
||||
this.Jobs = new List<Job>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The list of jobs.
|
||||
/// </summary>
|
||||
|
@ -20,4 +25,16 @@ public record JobList
|
|||
[JsonPropertyName("has_more")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||
public bool HasMore { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A token that can be used to list the next page of runs.
|
||||
/// </summary>
|
||||
[JsonPropertyName("next_page_token")]
|
||||
public string NextPageToken { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A token that can be used to list the previous page of runs.
|
||||
/// </summary>
|
||||
[JsonPropertyName("prev_page_token")]
|
||||
public string PrevPageToken { get; set; }
|
||||
}
|
|
@ -11,6 +11,9 @@ public record PipelineEventsList
|
|||
[JsonPropertyName("next_page_token")]
|
||||
public string NextPageToken { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public bool HasMore => !string.IsNullOrEmpty(NextPageToken);
|
||||
|
||||
/// <summary>
|
||||
/// If present, a token to fetch the previous page of events.
|
||||
/// </summary>
|
||||
|
|
|
@ -17,6 +17,9 @@ public record PipelineUpdatesList
|
|||
[JsonPropertyName("next_page_token")]
|
||||
public string NextPageToken { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public bool HasMore => !string.IsNullOrEmpty(this.NextPageToken);
|
||||
|
||||
/// <summary>
|
||||
/// If present, then this token can be used in a subsequent request to fetch the previous page.
|
||||
/// </summary>
|
||||
|
|
|
@ -16,4 +16,7 @@ public class PipelinesList
|
|||
/// </summary>
|
||||
[JsonPropertyName("next_page_token")]
|
||||
public string NextPageToken { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public bool HasMore => !string.IsNullOrEmpty(this.NextPageToken);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,11 @@ namespace Microsoft.Azure.Databricks.Client.Models;
|
|||
|
||||
public record RunList
|
||||
{
|
||||
public RunList()
|
||||
{
|
||||
this.Runs = new List<Run>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A list of runs, from most recently started to least.
|
||||
/// </summary>
|
||||
|
@ -31,4 +36,4 @@ public record RunList
|
|||
/// </summary>
|
||||
[JsonPropertyName("prev_page_token")]
|
||||
public string PrevPageToken { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
using Azure;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.Azure.Databricks.Client
|
||||
{
|
||||
internal class AsyncPageable<T> : global::Azure.AsyncPageable<T>
|
||||
{
|
||||
private readonly Func<string, Task<(List<T>, bool, string)>> _getNextPage;
|
||||
|
||||
public AsyncPageable(Func<string, Task<(List<T>, bool, string)>> getNextPage)
|
||||
{
|
||||
this._getNextPage = getNextPage;
|
||||
}
|
||||
|
||||
public override async IAsyncEnumerable<Page<T>> AsPages(string continuationToken = null, int? pageSizeHint = null)
|
||||
{
|
||||
var nextPageToken = continuationToken;
|
||||
var hasNextPage = true;
|
||||
|
||||
do
|
||||
{
|
||||
var response = await _getNextPage(nextPageToken);
|
||||
hasNextPage = response.Item2;
|
||||
nextPageToken = response.Item3;
|
||||
yield return Page<T>.FromValues(response.Item1, nextPageToken, null);
|
||||
} while (hasNextPage);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -35,6 +35,17 @@ public class PipelinesApiClient : ApiClient, IPipelinesApi
|
|||
return await HttpGet<PipelinesList>(this.HttpClient, requestUri, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public global::Azure.AsyncPageable<Pipeline> ListPageable(int pageSize = 25, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return new AsyncPageable<Pipeline>(
|
||||
async (string pageToken) =>
|
||||
{
|
||||
var response = await List(pageSize, pageToken, cancellationToken).ConfigureAwait(false);
|
||||
return (response.Pipelines.ToList(), response.HasMore, response.NextPageToken);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public async Task<(string, PipelineSpecification)> Create(
|
||||
PipelineSpecification pipelineSpecification,
|
||||
bool dryRun = true,
|
||||
|
@ -129,6 +140,21 @@ public class PipelinesApiClient : ApiClient, IPipelinesApi
|
|||
return await HttpGet<PipelineUpdatesList>(this.HttpClient, requestUri, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public global::Azure.AsyncPageable<PipelineUpdate> ListUpdatesPageable(
|
||||
string pipelineId,
|
||||
int pageSize = 25,
|
||||
string untilUpdateId = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
return new AsyncPageable<PipelineUpdate>(
|
||||
async (string pageToken) =>
|
||||
{
|
||||
var response = await ListUpdates(pipelineId, pageSize, pageToken, untilUpdateId, cancellationToken).ConfigureAwait(false);
|
||||
return (response.Updates.ToList(), response.HasMore, response.NextPageToken);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public async Task<string> Start(
|
||||
string pipelineId,
|
||||
bool fullRefresh = false,
|
||||
|
@ -166,9 +192,9 @@ public class PipelinesApiClient : ApiClient, IPipelinesApi
|
|||
public async Task<PipelineEventsList> ListEvents(
|
||||
string pipelineId,
|
||||
int maxResults = 25,
|
||||
string orderBy = null,
|
||||
string filter = null,
|
||||
string pageToken = null,
|
||||
string orderBy = default,
|
||||
string filter = default,
|
||||
string pageToken = default,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var requestUriSb = new StringBuilder($"{ApiVersion}/pipelines/{pipelineId}/events?max_results={maxResults}");
|
||||
|
@ -192,4 +218,20 @@ public class PipelinesApiClient : ApiClient, IPipelinesApi
|
|||
|
||||
return await HttpGet<PipelineEventsList>(this.HttpClient, requestUri, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public global::Azure.AsyncPageable<PipelineEvent> ListEventsPageable(
|
||||
string pipelineId,
|
||||
int pageSize = 25,
|
||||
string orderBy = default,
|
||||
string filter = default,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
return new AsyncPageable<PipelineEvent>(
|
||||
async (string pageToken) =>
|
||||
{
|
||||
var response = await ListEvents(pipelineId, pageSize, orderBy, filter, pageToken, cancellationToken).ConfigureAwait(false);
|
||||
return (response.Events.ToList(), response.HasMore, response.NextPageToken);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,6 +64,15 @@ public class ReposApiClient : ApiClient, IReposApi
|
|||
return (repos, nextPageToken);
|
||||
}
|
||||
|
||||
public global::Azure.AsyncPageable<Repo> ListPageable(string pathPrefix = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return new AsyncPageable<Repo>(async (pageToken) =>
|
||||
{
|
||||
var (repos, nextPageToken) = await List(pathPrefix, pageToken, cancellationToken).ConfigureAwait(false);
|
||||
return (repos.ToList(), !string.IsNullOrEmpty(nextPageToken), nextPageToken);
|
||||
});
|
||||
}
|
||||
|
||||
public async Task Update(long repoId, string branch = null, string tag = null, RepoSparseCheckout sparseCheckout = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var requestUri = $"{_apiBaseUrl}/{repoId}";
|
||||
|
|
|
@ -11,12 +11,19 @@ public interface ITablesApi : IDisposable
|
|||
|
||||
Task<(IEnumerable<TableSummary>, string)> ListSummaries(
|
||||
string catalogName,
|
||||
int maxResults = 10000,
|
||||
int? maxResults = 10000,
|
||||
string schemaNamePattern = default,
|
||||
string tableNamePattern = default,
|
||||
string pageToken = default,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
global::Azure.AsyncPageable<TableSummary> ListSummariesPageable(
|
||||
string catalogName,
|
||||
int? pageSize = default,
|
||||
string schemaNamePattern = default,
|
||||
string tableNamePattern = default,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Gets an array of all tables for the current metastore under the parent catalog and schema.
|
||||
/// </summary>
|
||||
|
@ -28,6 +35,12 @@ public interface ITablesApi : IDisposable
|
|||
bool? includeDeltaMetadata = default,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
global::Azure.AsyncPageable<Table> ListPageable(
|
||||
string catalogName,
|
||||
string schemaName,
|
||||
int? pageSize = default,
|
||||
bool? includeDeltaMetadata = default);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a table from the metastore for a specific catalog and schema.
|
||||
/// </summary>
|
||||
|
|
|
@ -18,7 +18,7 @@ public class TablesApiClient : ApiClient, ITablesApi
|
|||
|
||||
public async Task<(IEnumerable<TableSummary>, string)> ListSummaries(
|
||||
string catalogName,
|
||||
int maxResults = 10000,
|
||||
int? maxResults = 10000,
|
||||
string schemaNamePattern = default,
|
||||
string tableNamePattern = default,
|
||||
string pageToken = default,
|
||||
|
@ -55,6 +55,27 @@ public class TablesApiClient : ApiClient, ITablesApi
|
|||
return (tables, nextPageToken);
|
||||
}
|
||||
|
||||
public global::Azure.AsyncPageable<TableSummary> ListSummariesPageable(
|
||||
string catalogName,
|
||||
int? pageSize = default,
|
||||
string schemaNamePattern = default,
|
||||
string tableNamePattern = default,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
return new AsyncPageable<TableSummary>(async (pageToken) =>
|
||||
{
|
||||
var (tableSummaries, nextPageToken) = await ListSummaries(
|
||||
catalogName,
|
||||
pageSize,
|
||||
schemaNamePattern,
|
||||
tableNamePattern,
|
||||
pageToken,
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return (tableSummaries.ToList(), !string.IsNullOrEmpty(nextPageToken), nextPageToken);
|
||||
});
|
||||
}
|
||||
|
||||
public async Task<(IEnumerable<Table>, string)> List(
|
||||
string catalogName,
|
||||
string schemaName,
|
||||
|
@ -94,6 +115,26 @@ public class TablesApiClient : ApiClient, ITablesApi
|
|||
return (tables, nextPageToken);
|
||||
}
|
||||
|
||||
public global::Azure.AsyncPageable<Table> ListPageable(
|
||||
string catalogName,
|
||||
string schemaName,
|
||||
int? pageSize = default,
|
||||
bool? includeDeltaMetadata = default)
|
||||
{
|
||||
return new AsyncPageable<Table>(async (pageToken) =>
|
||||
{
|
||||
var (tables, nextPageToken) = await List(
|
||||
catalogName,
|
||||
schemaName,
|
||||
pageSize,
|
||||
pageToken,
|
||||
includeDeltaMetadata,
|
||||
CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
return (tables.ToList(), !string.IsNullOrEmpty(nextPageToken), nextPageToken);
|
||||
});
|
||||
}
|
||||
|
||||
public async Task<Table> Get(
|
||||
string fullTableName,
|
||||
bool? includeDeltaMetadata = default,
|
||||
|
|
Загрузка…
Ссылка в новой задаче