GitHubApiStatus | GitHubApiStatus.Extensions |
---|---|
GitHubApiStatus makes it easy to understand GitHub's API Rate Limit!
- Jump to the Setup
- Jump to the GitHubApiStatus API
- Jump to the GitHubApiStatus.Extensions API
- Jump to Examples
For more information, check out this blog post, Introducing GitHubApiStatus
(From the GitHub REST API Docs)
(From the GitHub GraphQL API Docs)
- Available on NuGet: https://www.nuget.org/packages/GitHubApiStatus/
- Add to any project supporting .NET Standard 1.3
- Available on NuGet: https://www.nuget.org/packages/GitHubApiStatus.Extensions/
- Add to any project supporting .NET Standard 2.0
- Leverages Microsoft.Extensions.Http
public Task<GitHubApiRateLimits> GetApiRateLimits(AuthenticationHeaderValue authenticationHeaderValue)
- Get the current GitHub API Rate Limit status
- Returns
RateLimitData
for the following GitHub APIs:- REST API
- Search API
- GraphQL API
- Source Import API
- App Manifest Configuration API
- Leverage's GitHub Rate Limit API which does not count against your rate limit totals
public int GetRateLimit(HttpResponseHeaders httpResponseHeaders)
- Get the total number of GitHub API Requests available
- Parses the
X-RateLimit-Limit
header and return itsint
value
public int GetRemainingRequestCount(HttpResponseHeaders httpResponseHeaders)
- Get the number of GitHub API Requests remaining
- Parses the
X-RateLimit-Remaining
header and return itsint
value
public bool HasReachedMaximumApiCallLimit(HttpResponseHeaders httpResponseHeaders)
- Determines whether the maximum number of requests
- Parses the
X-RateLimit-Remaining
header and returns wether or not it is greater than 0
public TimeSpan GetRateLimitTimeRemaining(HttpResponseHeaders httpResponseHeaders)
- Get the time remaining until GitHub API rate limit resets
- Parses the
X-RateLimit-Reset
header and returns theTimeSpan
value from the current time
public bool IsResponseFromAuthenticatedRequest(HttpResponseHeaders httpResponseHeaders)
- Determine whether the request was made using an authenticated bearer token
- Determines whether or not the
Authorization
key exists in theVary
header
public DateTimeOffset GetRateLimitResetDateTime(HttpResponseHeaders httpResponseHeaders)
- Get the Date Time when the GitHub API rate limit resets
- Parses the
X-RateLimit-Reset
header and returns itsDateTimeOffset
value
public long GetRateLimitResetDateTime_UnixEpochSeconds(HttpResponseHeaders httpResponseHeaders)
- Get the Date Time when the GitHub API rate limit resets
- Parses the
X-RateLimit-Reset
header and returns itslong
value in Unix Epoch Seconds
public static bool DoesContainGitHubRateLimitHeader(this HttpResponseHeaders headers)
- Returns whether HttpResponseHeaders Contain X-RateLimit-Limit
public static bool DoesContainGitHubRateLimitResetHeader(this HttpResponseHeaders headers)
- Returns whether HttpResponseHeaders Contain X-RateLimit-Reset
public static bool DoesContainGitHubRateLimitRemainingHeader(this HttpResponseHeaders headers)
- Returns whether HttpResponseHeaders Contain X-RateLimit-Remaining
public static IHttpClientBuilder AddGitHubApiStatusService(this IServiceCollection services, AuthenticationHeaderValue authenticationHeaderValue, ProductHeaderValue productHeaderValue)
- Adds GitHubApiStatus.GitHubApiStatusService to
Microsoft.Extensions.DependencyInjection.IServiceCollection
public static IHttpClientBuilder AddGitHubApiStatusService<TGitHubApiStatusService>(this IServiceCollection services, AuthenticationHeaderValue authenticationHeaderValue, ProductHeaderValue productHeaderValue) where TGitHubApiStatusService : IGitHubApiStatusService
- Adds a custom implementation of IGitHubApiStatusService to
Microsoft.Extensions.DependencyInjection.IServiceCollection
- Jump to Get Current GitHub API Status
- Jump to Parse API Status from HttpResponseHeaders
- Jump to Dependency Injection
static async Task Main(string[] args)
{
var gitHubApiStatusService = new GitHubApiStatusService(new AuthenticationHeaderValue("bearer", "Your GitHub Personal Access Token, e.g. 123456789012345"));
//Generate Personal Access Token https://github.com/settings/tokens
var apiRateLimits = await gitHubApiStatusService.GetApiRateLimits();
// REST API Results
Console.WriteLine($"What is the GitHub REST API Rate Limit? {apiRateLimits.RestApi.RateLimit}"); // What is the GitHub REST API Rate Limit? 5000
Console.WriteLine($"How many REST API requests do I have remaining? {apiRateLimits.RestApi.RemainingRequestCount}"); // How many REST API requests do I have remaining? 4983
Console.WriteLine($"How long until the GitHub REST API Rate Limit resets? {apiRateLimits.RestApi.RateLimitReset_TimeRemaining}"); // How long until the GitHub REST API Rate Limit resets? 00:40:13.8035515
Console.WriteLine($"When does the GitHub REST API Rate Limit reset? {apiRateLimits.RestApi.RateLimitReset_DateTime}"); // When does the GitHub REST API Rate Limit reset? 10/29/2020 3:28:58 AM +00:00
Console.WriteLine();
// GraphQL API Results
Console.WriteLine($"What is the GitHub GraphQL API Rate Limit? {apiRateLimits.GraphQLApi.RateLimit}"); // What is the GitHub GraphQL API Rate Limit? 5000
Console.WriteLine($"How many GraphQL API requests do I have remaining? {apiRateLimits.GraphQLApi.RemainingRequestCount}"); // How many GraphQL API requests do I have remaining? 5000
Console.WriteLine($"How long until the GitHub GraphQL API Rate Limit resets? {apiRateLimits.GraphQLApi.RateLimitReset_TimeRemaining}"); // How long until the GitHub GraphQL API Rate Limit resets? 00:59:59.8034526
Console.WriteLine($"When does the GitHub GraphQL API Rate Limit reset? {apiRateLimits.GraphQLApi.RateLimitReset_DateTime}"); // When does the GitHub GraphQL API Rate Limit reset? 10/29/2020 3:48:44 AM +00:00
Console.WriteLine();
// Search API Results
Console.WriteLine($"What is the GitHub Search API Rate Limit? {apiRateLimits.SearchApi.RateLimit}"); // What is the GitHub Search API Rate Limit? 30
Console.WriteLine($"How many Search API requests do I have remaining? {apiRateLimits.SearchApi.RemainingRequestCount}"); // How many Search API requests do I have remaining? 30
Console.WriteLine($"How long until the GitHub Search API Rate Limit resets? {apiRateLimits.SearchApi.RateLimitReset_TimeRemaining}"); // How long until the GitHub Search API Rate Limit resets? 00:00:59.8034988
Console.WriteLine($"When does the GitHub Search API Rate Limit reset? {apiRateLimits.SearchApi.RateLimitReset_DateTime}"); // When does the GitHub Search API Rate Limit reset? 10/29/2020 2:49:44 AM +00:00
Console.WriteLine();
// Source Import API Results
Console.WriteLine($"What is the GitHub Source Import API Rate Limit? {apiRateLimits.SourceImport.RateLimit}"); // What is the GitHub Source Import API Rate Limit? 100
Console.WriteLine($"How many Source Import API requests do I have remaining? {apiRateLimits.SourceImport.RemainingRequestCount}"); // How many Source Import API requests do I have remaining? 100
Console.WriteLine($"How long until the GitHub Source Import API Rate Limit resets? {apiRateLimits.SourceImport.RateLimitReset_TimeRemaining}"); // How long until the GitHub Source Import API Rate Limit resets? 00:00:59.8034154
Console.WriteLine($"When does the GitHub Source Import API Rate Limit reset? {apiRateLimits.SourceImport.RateLimitReset_DateTime}"); // When does the GitHub Source Import API Rate Limit reset? 10/29/2020 2:49:44 AM +00:00
Console.WriteLine();
// App Manifest Configuration API Results
Console.WriteLine($"What is the GitHub App Manifest Configuration API Rate Limit? {apiRateLimits.AppManifestConfiguration.RateLimit}"); // What is the GitHub App Manifest Configuration API Rate Limit? 5000
Console.WriteLine($"How many App Manifest Configuration API requests do I have remaining? {apiRateLimits.AppManifestConfiguration.RemainingRequestCount}"); // How many App Manifest Configuration API requests do I have remaining? 5000
Console.WriteLine($"How long until the GitHub App Manifest Configuration API Rate Limit resets? {apiRateLimits.AppManifestConfiguration.RateLimitReset_TimeRemaining}"); // How long until the GitHub App Manifest Configuration API Rate Limit resets? 00:59:59.8033802
Console.WriteLine($"When does the GitHub App Manifest Configuration API Rate Limit reset? {apiRateLimits.AppManifestConfiguration.RateLimitReset_DateTime}"); // When does the GitHub App Manifest Configuration API Rate Limit reset? 10/29/2020 3:48:44 AM +00:00
Console.WriteLine();
// Code Scanning Upload API Results
Console.WriteLine($"What is the GitHub Code Scanning Upload API Rate Limit? {apiRateLimits.CodeScanningUpload.RateLimit}"); // What is the GitHub Code Scanning Upload API Rate Limit? 500
Console.WriteLine($"How many Code Scanning Upload API requests do I have remaining? {apiRateLimits.CodeScanningUpload.RemainingRequestCount}"); // How many Code Scanning Upload API requests do I have remaining? 500
Console.WriteLine($"How long until the GitHub Code Scanning Upload API Rate Limit resets? {apiRateLimits.CodeScanningUpload.RateLimitReset_TimeRemaining}"); // How long until the GitHub Code Scanning Upload API Rate Limit resets? 00:59:59.8033455
Console.WriteLine($"When does the GitHub Code Scanning Upload API Rate Limit reset? {apiRateLimits.CodeScanningUpload.RateLimitReset_DateTime}"); // When does the GitHub Code Scanning Upload API Rate Limit reset? 10/29/2020 3:48:44 AM +00:00
}
const string _gitHubRestApiUrl = "https://api.github.com";
static readonly HttpClient _client = new HttpClient
{
DefaultRequestHeaders =
{
{ "Authorization", "bearer [Your GitHub Personal Access Token, e.g. 123456789012345]" }
{ "User-Agent", "GitHubApiStatus" }
}
};
static async Task Main(string[] args)
{
var gitHubApiStatusService = new GitHubApiStatusService(_client);
HttpResponseMessage restApiResponse = await _client.GetAsync($"{ _gitHubRestApiUrl}/repos/brminnick/GitHubApiStatus");
restApiResponse.EnsureSuccessStatusCode();
TimeSpan rateLimitTimeRemaining = gitHubApiStatusService.GetRateLimitTimeRemaining(restApiResponse.Headers);
int rateLimit = gitHubApiStatusService.GetRateLimit(restApiResponse.Headers);
int remainingRequestCount = gitHubApiStatusService.GetRemainingRequestCount(restApiResponse.Headers);
bool isAuthenticated = gitHubApiStatusService.IsResponseFromAuthenticatedRequest(restApiResponse.Headers);
bool hasReachedMaximumApiLimit = gitHubApiStatusService.HasReachedMaximumApiCallLimit(restApiResponse.Headers);
Console.WriteLine($"What is the GitHub REST API Rate Limit? {rateLimit}"); // What is the GitHub REST API Rate Limit? 60
Console.WriteLine($"Have I reached the Maximum REST API Limit? {hasReachedMaximumApiLimit}"); // Have I reached the Maximum REST API Limit? False
Console.WriteLine($"How many REST API requests do I have remaining? {remainingRequestCount}"); // How many REST API requests do I have remaining? 56
Console.WriteLine($"How long until the GitHub REST API Rate Limit resets? {rateLimitTimeRemaining}"); // How long until the GitHub REST API Rate Limit resets? 00:29:12.4134330
Console.WriteLine($"Did the GitHub REST API Request include a Bearer Token? {isAuthenticated}"); // Did GitHub REST API Request include a Bearer Token? False
}
public class Program
{
public static Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
// AddGitHubApiStatusService
builder.Services.AddGitHubApiStatusService(new AuthenticationHeaderValue("bearer", "[Your GitHub Personal Access Token, e.g. 123456789012345]"), new ProductHeaderValue("MyApp"))
.ConfigurePrimaryHttpMessageHandler(config => new HttpClientHandler { AutomaticDecompression = System.Net.DecompressionMethods.GZip | System.Net.DecompressionMethods.Deflate });
return builder.Build().RunAsync();
}
}
@page "/graphql"
@using GitHubApiStatus
@inject IGitHubApiStatusService GitHubApiStatusService
<h1>GitHub REST Api Status</h1>
<p>@_graphQLApiStatus</p>
<button class="btn btn-primary" @onclick="GetGraphQLApiStatus">Get Status</button>
@code {
string _graphQLApiStatus = string.Empty;
async Task GetGraphQLApiStatus()
{
var apiRateLimitStatuses = await GitHubApiStatusService.GetApiRateLimits(System.Threading.CancellationToken.None).ConfigureAwait(false);
_graphQLApiStatus = apiRateLimitStatuses.GraphQLApi.ToString();
}
}
- Learn more about Dependency Injection in ASP.NET Core
public class Startup
{
// ...
public void ConfigureServices(IServiceCollection services)
{
services.AddGitHubApiStatusService(new AuthenticationHeaderValue("bearer", "[Your GitHub Personal Access Token, e.g. 123456789012345]"), new ProductHeaderValue("MyApp"))
.ConfigurePrimaryHttpMessageHandler(config => new HttpClientHandler { AutomaticDecompression = System.Net.DecompressionMethods.GZip | System.Net.DecompressionMethods.Deflate });
services.AddRazorPages();
}
/// ...
}
class MyPageModel : PageModel
{
readonly ILogger<IndexModel> _logger;
readonly IGitHubApiStatusService _gitHubApiStatusService;
public MyPageModel(IGitHubApiStatusService gitHubApiStatusService, ILogger<MyPageModel> logger)
{
_logger = logger;
_gitHubApiStatusService = gitHubApiStatusService;
}
// ...
}
- Requires Microsoft.Azure.Functions.Extensions NuGet Package
- Learn More about Azure Functions Dependency Injection
[assembly: FunctionsStartup(typeof(MyApp.Functions.Startup))]
namespace MyApp.Functions
{
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddGitHubApiStatusService(new AuthenticationHeaderValue("bearer", "[Your GitHub Personal Access Token, e.g. 123456789012345]"), new ProductHeaderValue("MyApp"))
.ConfigurePrimaryHttpMessageHandler(config => new HttpClientHandler { AutomaticDecompression = System.Net.DecompressionMethods.GZip | System.Net.DecompressionMethods.Deflate });
}
}
}
class GitHubApiStatusFunction
{
readonly IGitHubApiStatusService _gitHubApiStatusService;
public MyHttpTriggerFunction(IGitHubApiStatusService gitHubApiStatusService) => _gitHubApiStatusService = gitHubApiStatusService
[FunctionName("GitHubApiStatus")]
public async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequest req, ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(2));
var apiStatus = await _gitHubApiStatusService.GetApiRateLimits(cancellationTokenSource.Token).ConfigureAwait(false);
return new OkObjectResult(apiStatus);
}
}