Notice: For those who learn this submit and seize some examples from it, be sure you learn to the underside. I wrote my capabilities utilizing a GitHub-depreciated JSON object up till the ultimate operate. You’ve gotten been warned.
I’m working with the GitHub REST API at present and I discovered one thing new. Why not share it and create a useful resource for myself for the second in time once I want a refresh.
Unauthenticated API requests to GitHub are restricted to 60 per hour. I did a few of my very own checks, however there may be documentation round this. At dwelling, which is the place I work as of late, the non-public/NAT’ed IPs on two totally different computer systems, behind my public IP tackle, have been two totally different gadgets to GitHub. This was not an enormous shock, however good to know, nonetheless.
Let’s take the GitHub charge restrict API for a spin. This API is not rate-limited, which implies you’ll be able to name it as many occasions as you desire to in an hour in an unauthenticated method. GitHub writes, “Accessing this endpoint doesn’t rely towards your REST API charge restrict.” Within the under instance, we assign a $Uri
and $Header
variable and use these as part of our Invoke-RestMethod
command, which shops the ends in the $Json
variable.
$Uri = 'https://api.github.com/rate_limit' $Headers = @{Headers="software/vnd.github.v3+json"} $Json = Invoke-RestMethod -Uri $Uri -Headers $Headers | ConvertTo-Json $Json
As soon as that’s achieved, we output the contents saved within the $Json
variable. Let’s chat about among the knowledge returned on this JSON object. Beneath assets
after which core
, we’ve got restrict
, remaining
, and used
. Restrict
is what number of unauthenticated requests we’ve got (per hour), remaining
is what number of of 60 we’ve got left within the hour, and used
, is what number of API calls we’ve got already used this hour. Subsequently if we had 59 remaining, we might have 1 used. Towards the underside, we’ve got charge
. The content material saved on this object is equivalent to what’s saved in assets.core
.
{ "assets": { "core": { "restrict": 60, "remaining": 60, "reset": 1646979987, "used": 0, "useful resource": "core" }, "graphql": { "restrict": 0, "remaining": 0, "reset": 1646979987, "used": 0, "useful resource": "graphql" }, "integration_manifest": { "restrict": 5000, "remaining": 5000, "reset": 1646979987, "used": 0, "useful resource": "integration_manifest" }, "search": { "restrict": 10, "remaining": 10, "reset": 1646976447, "used": 0, "useful resource": "search" } }, "charge": { "restrict": 60, "remaining": 60, "reset": 1646979987, "used": 0, "useful resource": "core" } }
Within the above, Invoke-RestMethod
command, we piped the output to ConvertTo-Json
with the intention to see the JSON object. Beneath, we is not going to try this, so that we will see the PowerShell object and work with its properties. Bear in mind, this command is kind of highly effective attributable to its built-in potential to deserialize returned content material into one thing extra useable by people working with PowerShell.
With out viewing the nested properties we’re offered the assets
and charge
properties. This could appear acquainted from the above JSON. We are able to return the charge
property or the assets.core
property and get to restrict
, remaining
, and the used
property, as effectively.
$NotJson = Invoke-RestMethod -Uri $Uri -Technique Get -Headers $Headers $NotJson assets charge --------- ---- @{core=; graphql=; integration_manifest=; search=} @{restrict=60; remaining=60; reset=1646692433; used=0; useful resource=core} $NotJson.charge restrict : 60 remaining : 60 reset : 1646980018 used : 0 useful resource : core
There’s one other property that we’ve got but to debate, and that’s the reset
property. This worth is ready on the primary API name. It’s set 60 minutes into the long run, so we all know when our remaining
worth will return to 60, and our used
worth will return to 0.
This property is recorded and saved as Epoch time (or Unix time, or Unix epoch). It’s the variety of seconds since January 1, 1970. The under PowerShell will covert the Epoch time to a human-readable type. We are going to use this additional under inside a operate we are going to use to see all of this working collectively.
((Get-Date 01.01.1970)+([System.TimeSpan]::fromseconds(1646980018))).ToLocalTime()
Thursday, March 10, 2022 11:26:58 PM
Like I usually do, I created a operate, which I’ll embrace under. I cannot do a line-by-line clarification. I’ll talk about it, nonetheless. It accepts three parameters. One is the GitHub charge restrict URI, one is the Headers we ship in with every API name, and the ultimate parameter is a URI of one among my tasks on GitHub. Following the parameters, when the operate is invoked, it can execute a charge restrict GitHub API name and return some knowledge, execute a GitHub API name towards my undertaking (with Out-Null
[so no output]), after which execute a charge restrict GitHub API name and return some knowledge once more. This enables us to see the earlier than charge restrict data and the after charge restrict data. Check out the instance beneath the operate, after you could have seemed it over.
operate Watch-GitHubRateLimit { [CmdletBinding()] Param ( [Parameter()] $GHRateLimitUri = 'https://api.github.com/rate_limit', [Parameter()] $Headers = @{Headers="software/vnd.github.v3+json"}, [Parameter()] $GHGeneralUri = 'https://api.github.com/repos/tommymaynard/TMOutput' ) $Json = Invoke-RestMethod -Uri $GHRateLimitUri -Headers $Headers [PSCustomObject]@{ Invocation = 'Earlier than' Restrict = $Json.Price.Restrict Remaining = $Json.Price.Remaining ResetEpoch = $Json.Price.Reset ResetReadable = ((Get-Date -Date 01-01-1970)+ ([System.TimeSpan]::fromseconds($Json.charge.reset ))).ToLocalTime() Used = $Json.Price.Used } Invoke-RestMethod -Uri $GHGeneralUri -Headers $Headers | Out-Null $Json = Invoke-RestMethod -Uri $GHRateLimitUri -Headers $Headers [PSCustomObject]@{ Invocation = 'After' Restrict = $Json.Price.Restrict Remaining = $Json.Price.Remaining ResetEpoch = $Json.Price.Reset ResetReadable = ((Get-Date -Date 01-01-1970)+ ([System.TimeSpan]::fromseconds($Json.Price.Reset ))).ToLocalTime() Used = $Json.Price.Used } } Watch-GitHubRateLimit
Invocation : Earlier than Restrict : 60 Remaining : 60 ResetEpoch : 1646980115 ResetReadable : 3/10/2022 11:28:35 PM Used : 0 Invocation : After Restrict : 60 Remaining : 59 ResetEpoch : 1646980115 ResetReadable : 3/10/2022 11:28:35 PM Used : 1
Now cease and return and have a look at the above operate. What’s fallacious with that? Overlook GitHub and API calls (sort of). How might that operate be improved?
Determine it out? Do you see all that duplicated code? Yuck. Taking a look at one thing like this could set off a sense that one thing is fallacious. What we’d like, as an alternative of all that duplicated code, is a nested operate. I’ve a rewrite under. Have a look after which view the following two examples.
operate Watch-GitHubRateLimit { [CmdletBinding()] Param ( [Parameter()] $GHRateLimitUri = 'https://api.github.com/rate_limit', [Parameter()] $Headers = @{Headers="software/vnd.github.v3+json"}, [Parameter()] $GHGeneralUri = 'https://api.github.com/repos/tommymaynard/TMOutput' ) operate Get-GitHubRateLimitStats { param ($Invocation) $Json = Invoke-RestMethod -Uri $GHRateLimitUri -Headers $Headers [PSCustomObject]@{ Invocation = $Invocation Restrict = $Json.Price.Restrict Remaining = $Json.Price.Remaining ResetEpoch = $Json.Price.Reset ResetReadable = ((Get-Date -Date 01-01-1970)+ ([System.TimeSpan]::fromseconds($Json.Price.Reset ))).ToLocalTime() Used = $Json.Price.Used } } Get-GitHubRateLimitStats -Invocation 'Earlier than' Invoke-RestMethod -Uri $GHGeneralUri -Headers $Headers | Out-Null Get-GitHubRateLimitStats -Invocation 'After' } Watch-GitHubRateLimit
Invocation : Earlier than Restrict : 60 Remaining : 59 ResetEpoch : 1646980116 ResetReadable : 3/10/2022 11:28:36 PM Used : 1 Invocation : After Restrict : 60 Remaining : 58 ResetEpoch : 1646980116 ResetReadable : 3/10/2022 11:28:36 PM Used : 2
Significantly better, however then I learn this: “Notice: The charge
object is deprecated. For those who’re writing new API shopper code or updating current code, you must use the core
object as an alternative of the charge
object. The core
object accommodates the identical data that’s current within the charge
object.” That is taken from this Git Hub Price restrict web page. Now that we all know this, let’s replace the ultimate operate so it makes use of the proper object.
operate Watch-GitHubRateLimit { [CmdletBinding()] Param ( [Parameter()] $GHRateLimitUri = 'https://api.github.com/rate_limit', [Parameter()] $Headers = @{Headers="software/vnd.github.v3+json"}, [Parameter()] $GHGeneralUri = 'https://api.github.com/repos/tommymaynard/TMOutput' ) operate Get-GitHubRateLimitStats { param ($Invocation) $Json = Invoke-RestMethod -Uri $GHRateLimitUri -Headers $Headers [PSCustomObject]@{ Invocation = $Invocation Restrict = $Json.Assets.Core.Restrict Remaining = $Json.Assets.Core.Remaining ResetEpoch = $Json.Assets.Core.Reset ResetReadable = ((Get-Date -Date 01-01-1970)+ ([System.TimeSpan]::fromseconds($Json.Assets.Core.Reset ))).ToLocalTime() Used = $Json.Assets.Core.Used } } Get-GitHubRateLimitStats -Invocation 'Earlier than' Invoke-RestMethod -Uri $GHGeneralUri -Headers $Headers | Out-Null Get-GitHubRateLimitStats -Invocation 'After' } Watch-GitHubRateLimit
Invocation : Earlier than Restrict : 60 Remaining : 58 ResetEpoch : 1646980116 ResetReadable : 3/10/2022 11:28:36 PM Used : 2 Invocation : After Restrict : 60 Remaining : 57 ResetEpoch : 1646980116 ResetReadable : 3/10/2022 11:28:36 PM Used : 3
I understand how I really feel a few submit as I’m writing it and people emotions keep constant till the top. I like what I’ve written right here. There’s a nice alternative to study working with APIs and even some operate writing. I hope is it useful for others, clearly (as it’s sort of what I do). The takeaway although is that if there may be an API for one thing, work with it. It’s fascinating to collect data from web sites and net providers by way of PowerShell. In the future you may be requested to do it, so that you may as effectively get some expertise now.