Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/brminnick/githubapistatus
A .NET library to easily parse GitHub's API Rate Limit
https://github.com/brminnick/githubapistatus
github github-api github-api-ratelimit github-api-v3 github-api-v4
Last synced: about 2 months ago
JSON representation
A .NET library to easily parse GitHub's API Rate Limit
- Host: GitHub
- URL: https://github.com/brminnick/githubapistatus
- Owner: brminnick
- License: mit
- Created: 2020-05-11T01:15:05.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2024-02-12T03:18:16.000Z (11 months ago)
- Last Synced: 2024-05-15T21:45:33.417Z (7 months ago)
- Topics: github, github-api, github-api-ratelimit, github-api-v3, github-api-v4
- Language: C#
- Homepage:
- Size: 1.5 MB
- Stars: 16
- Watchers: 3
- Forks: 1
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
[![Build Projects](https://github.com/brminnick/GitHubApiStatus/actions/workflows/build.yml/badge.svg)](https://github.com/brminnick/GitHubApiStatus/actions/workflows/build.yml) [![Run Unit Tests](https://github.com/brminnick/GitHubApiStatus/actions/workflows/unittests.yml/badge.svg)](https://github.com/brminnick/GitHubApiStatus/actions/workflows/unittests.yml)
# GitHubApiStatus
| GitHubApiStatus | GitHubApiStatus.Extensions |
| --------------- | -------------------------- |
| [![NuGet Version](https://img.shields.io/nuget/vpre/GitHubApiStatus)](https://www.nuget.org/packages/GitHubApiStatus/) [![NuGet Downloads](https://img.shields.io/nuget/dt/GitHubApiStatus)](https://www.nuget.org/packages/GitHubApiStatus/) | [![NuGet](https://img.shields.io/nuget/vpre/GitHubApiStatus.Extensions)](https://www.nuget.org/packages/GitHubApiStatus.Extensions/) [![NuGet](https://img.shields.io/nuget/dt/GitHubApiStatus.Extensions)](https://www.nuget.org/packages/GitHubApiStatus.Extensions/) |GitHubApiStatus makes it easy to understand GitHub's API Rate Limit!
- [Jump to the Setup](#Setup)
- [Jump to the GitHubApiStatus API](#GitHubApiStatus-API)
- [Jump to the GitHubApiStatus.Extensions API](#GitHubApiStatusExtensions-API)
- [Jump to Examples](#Examples)For more information, check out this blog post, [Introducing GitHubApiStatus](https://codetraveler.io/2021/01/12/introducing-githubapistatus/)
## GitHub API Rate Limits
### REST API
(From the [GitHub REST API Docs](https://docs.github.com/en/free-pro-team@latest/rest/overview/resources-in-the-rest-api#rate-limiting))
[![GitHub RST API Limits](https://user-images.githubusercontent.com/13558917/97235854-066e5680-17a1-11eb-98f9-01fae7c02ac0.png)](https://docs.github.com/en/free-pro-team@latest/rest/overview/resources-in-the-rest-api#rate-limiting)
### GraphQL API
(From the [GitHub GraphQL API Docs](https://docs.github.com/en/free-pro-team@latest/graphql/overview/resource-limitations#rate-limit))
[![GitHub GraphQL API Limits](https://user-images.githubusercontent.com/13558917/97235806-ec347880-17a0-11eb-9637-fc1eb7f8dbc8.png)](https://docs.github.com/en/free-pro-team@latest/graphql/overview/resource-limitations#rate-limit)
### Rate Limit Headers
![Rate Limit Headers](https://user-images.githubusercontent.com/13558917/97235863-0e2dfb00-17a1-11eb-98f8-23c1065eb043.png)
## Setup
### GitHubApiStatus
[![NuGet](https://buildstats.info/nuget/GitHubApiStatus?includePreReleases=true)](https://www.nuget.org/packages/GitHubApiStatus/)
- Available on NuGet: https://www.nuget.org/packages/GitHubApiStatus/
- Add to any project supporting .NET Standard 1.3### GitHubApiStatus.Extensions
[![NuGet](https://buildstats.info/nuget/GitHubApiStatus.Extensions?includePreReleases=true)](https://www.nuget.org/packages/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](https://www.nuget.org/packages/Microsoft.Extensions.Http/)## GitHubApiStatus API
#### GetApiRateLimits
```csharp
public Task 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](https://docs.github.com/en/free-pro-team@latest/rest/reference/rate-limit) which does not count against your rate limit totals#### GetRateLimit
```csharp
public int GetRateLimit(HttpResponseHeaders httpResponseHeaders)
```
- Get the total number of GitHub API Requests available
- Parses the `X-RateLimit-Limit` header and return its `int` value
#### GetRemainingRequestCount
```csharp
public int GetRemainingRequestCount(HttpResponseHeaders httpResponseHeaders)
```
- Get the number of GitHub API Requests remaining
- Parses the `X-RateLimit-Remaining` header and return its `int` value
#### HasReachedMaximumApiCallLimit
```csharp
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
#### GetRateLimitTimeRemaining
```csharp
public TimeSpan GetRateLimitTimeRemaining(HttpResponseHeaders httpResponseHeaders)
```
- Get the time remaining until GitHub API rate limit resets
- Parses the `X-RateLimit-Reset` header and returns the `TimeSpan` value from the current time
#### IsResponseFromAuthenticatedRequest
```csharp
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 the `Vary` header#### GetRateLimitResetDateTime
```csharp
public DateTimeOffset GetRateLimitResetDateTime(HttpResponseHeaders httpResponseHeaders)
```
- Get the Date Time when the GitHub API rate limit resets
- Parses the `X-RateLimit-Reset` header and returns its `DateTimeOffset` value
#### GetRateLimitResetDateTime_UnixEpochSeconds
```csharp
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 its `long` value in [Unix Epoch Seconds](https://www.epochconverter.com)### DoesContainGitHubRateLimitHeader
```csharp
public static bool DoesContainGitHubRateLimitHeader(this HttpResponseHeaders headers)
```
- Returns whether HttpResponseHeaders Contain X-RateLimit-Limit### DoesContainGitHubRateLimitResetHeader
```csharp
public static bool DoesContainGitHubRateLimitResetHeader(this HttpResponseHeaders headers)
```
- Returns whether HttpResponseHeaders Contain X-RateLimit-Reset### DoesContainGitHubRateLimitRemainingHeader
```csharp
public static bool DoesContainGitHubRateLimitRemainingHeader(this HttpResponseHeaders headers)
```
- Returns whether HttpResponseHeaders Contain X-RateLimit-Remaining## GitHubApiStatus.Extensions API
#### AddGitHubApiStatusService
```csharp
public static IHttpClientBuilder AddGitHubApiStatusService(this IServiceCollection services, AuthenticationHeaderValue authenticationHeaderValue, ProductHeaderValue productHeaderValue)
```
- Adds GitHubApiStatus.GitHubApiStatusService to `Microsoft.Extensions.DependencyInjection.IServiceCollection`#### AddGitHubApiStatusService<TGitHubApiStatusService>
```csharp
public static IHttpClientBuilder AddGitHubApiStatusService(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](#Get-Current-GitHub-API-Status)
- [Jump to Parse API Status from HttpResponseHeaders](#parse-api-status-from-httpresponseheaders)
- [Jump to Dependency Injection](#Dependency-Injection)### Get Current GitHub API Status
```csharp
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:00Console.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:00Console.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:00Console.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:00Console.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`
```csharp
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? 56Console.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](#blazor-example)
- [Jump to ASP.NET Core Example](#aspnet-core-example)
- [Jump to Azure Functions Example](#azure-functions-example)#### Blazor Example
```csharp
public class Program
{
public static Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add("#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();
}
}
``````csharp
@page "/graphql"
@using GitHubApiStatus
@inject IGitHubApiStatusService GitHubApiStatusServiceGitHub REST Api Status
@_graphQLApiStatus
Get Status
@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](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-5.0&WT.mc_id=mobile-11370-bramin)
```csharp
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();
}/// ...
}
``````csharp
class MyPageModel : PageModel
{
readonly ILogger _logger;
readonly IGitHubApiStatusService _gitHubApiStatusService;public MyPageModel(IGitHubApiStatusService gitHubApiStatusService, ILogger logger)
{
_logger = logger;
_gitHubApiStatusService = gitHubApiStatusService;
}// ...
}
```#### Azure Functions Example
- Requires [Microsoft.Azure.Functions.Extensions NuGet Package](https://www.nuget.org/packages/Microsoft.Azure.Functions.Extensions/)
- Learn More about [Azure Functions Dependency Injection](https://docs.microsoft.com/azure/azure-functions/functions-dotnet-dependency-injection?WT.mc_id=mobile-11370-bramin)```csharp
[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 });
}
}
}
``````csharp
class GitHubApiStatusFunction
{
readonly IGitHubApiStatusService _gitHubApiStatusService;public MyHttpTriggerFunction(IGitHubApiStatusService gitHubApiStatusService) => _gitHubApiStatusService = gitHubApiStatusService
[FunctionName("GitHubApiStatus")]
public async Task 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);
}
}
```