GitHubApiStatus
                                
                                 GitHubApiStatus copied to clipboard
                                
                                    GitHubApiStatus copied to clipboard
                            
                            
                            
                        A .NET library to easily parse GitHub's API Rate Limit
GitHubApiStatus
| 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

GitHub API Rate Limits
REST API
(From the GitHub REST API Docs)
GraphQL API
(From the GitHub GraphQL API Docs)
Rate Limit Headers

Setup
GitHubApiStatus
- Available on NuGet: https://www.nuget.org/packages/GitHubApiStatus/
- Add to any project supporting .NET Standard 1.3
GitHubApiStatus.Extensions
- Available on NuGet: https://www.nuget.org/packages/GitHubApiStatus.Extensions/
- Add to any project supporting .NET Standard 2.0
- Leverages Microsoft.Extensions.Http
GitHubApiStatus API
GetApiRateLimits
public Task<GitHubApiRateLimits> GetApiRateLimits(AuthenticationHeaderValue authenticationHeaderValue)
- Get the current GitHub API Rate Limit status
- Returns RateLimitDatafor 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
GetRateLimit
public int GetRateLimit(HttpResponseHeaders httpResponseHeaders)
- Get the total number of GitHub API Requests available
- Parses the X-RateLimit-Limitheader and return itsintvalue
GetRemainingRequestCount
public int GetRemainingRequestCount(HttpResponseHeaders httpResponseHeaders)
- Get the number of GitHub API Requests remaining
- Parses the X-RateLimit-Remainingheader and return itsintvalue
HasReachedMaximimApiCallLimit
public bool HasReachedMaximimApiCallLimit(HttpResponseHeaders httpResponseHeaders)
- Determines whether the maximum number of requests
- Parses the X-RateLimit-Remainingheader and returns wether or not it is greater than 0
GetRateLimitTimeRemaining
public TimeSpan GetRateLimitTimeRemaining(HttpResponseHeaders httpResponseHeaders)
- Get the time remaining until GitHub API rate limit resets
- Parses the X-RateLimit-Resetheader and returns theTimeSpanvalue from the current time
IsResponseFromAuthenticatedRequest
public bool IsResponseFromAuthenticatedRequest(HttpResponseHeaders httpResponseHeaders)
- Determine whether the request was made using an authenticated bearer token
- Determines whether or not the Authorizationkey exists in theVaryheader
GetRateLimitResetDateTime
public DateTimeOffset GetRateLimitResetDateTime(HttpResponseHeaders httpResponseHeaders)
- Get the Date Time when the GitHub API rate limit resets
- Parses the X-RateLimit-Resetheader and returns itsDateTimeOffsetvalue
GetRateLimitResetDateTime_UnixEpochSeconds
public long GetRateLimitResetDateTime_UnixEpochSeconds(HttpResponseHeaders httpResponseHeaders)
- Get the Date Time when the GitHub API rate limit resets
- Parses the X-RateLimit-Resetheader and returns itslongvalue in Unix Epoch Seconds
DoesContainGitHubRateLimitHeader
public static bool DoesContainGitHubRateLimitHeader(this HttpResponseHeaders headers)
- Returns whether HttpResponseHeaders Contain X-RateLimit-Limit
DoesContainGitHubRateLimitResetHeader
public static bool DoesContainGitHubRateLimitResetHeader(this HttpResponseHeaders headers)
- Returns whether HttpResponseHeaders Contain X-RateLimit-Reset
DoesContainGitHubRateLimitRemainingHeader
public static bool DoesContainGitHubRateLimitRemainingHeader(this HttpResponseHeaders headers)
- Returns whether HttpResponseHeaders Contain X-RateLimit-Remaining
GitHubApiStatus.Extensions API
AddGitHubApiStatusService
public static IHttpClientBuilder AddGitHubApiStatusService(this IServiceCollection services, AuthenticationHeaderValue authenticationHeaderValue, ProductHeaderValue productHeaderValue)
- Adds GitHubApiStatus.GitHubApiStatusService to Microsoft.Extensions.DependencyInjection.IServiceCollection
AddGitHubApiStatusService<TGitHubApiStatusService>
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
Examples
- Jump to Get Current GitHub API Status
- Jump to Parse API Status from HttpResponseHeaders
- Jump to Dependency Injection
Get Current GitHub API Status
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
}
Parse API status from HttpResponseHeaders
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.HasReachedMaximimApiCallLimit(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
}
Dependency Injection
- Jump to Blazor Example
- Jump to ASP.NET Core Example
- Jump to Azure Functions Example
Blazor Example
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();
    }
}
ASP.NET Core Example
- 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;
    }
    // ...
}
Azure Functions Example
- 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);
    }
}

