Thin GitHub API client for MoonBit built on gaato/http and gaato/sdk-runtime: the whole REST API generated, plus a GraphQL passthrough.
let transport = @http_async.AsyncTransport::new(max_body_bytes=64 * 1024 * 1024)
let gh = @github.GitHub::new(transport, clock, token="ghp_...")
let repo = gh.call(@gen.repos_get_request("gaato", "mbt-sdk"), @gen.repos_get_decode)
let diff = gh.send(
@gen.repos_compare_commits_request("gaato", "mbt-sdk", "main...topic")
.header("accept", "application/vnd.github.diff"),
)let repos = gh
.paginator(@gen.repos_list_for_user_request("gaato", per_page=100), @gen.repos_list_for_user_decode)
.collect(max=250)let data = gh.graphql(
query="query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { stargazerCount } }",
variables={ "owner": "gaato", "name": "mbt-sdk" },
)let gh = @github.GitHub::new(transport, clock, token="ghp_...", gate=() => @http_async.SemaphoreGate::new())test {
let body : @github.ApiErrorBody = {
message: "Not Found",
documentation_url: Some("https://docs.github.com/rest"),
status: Some("404"),
errors: None,
}
assert_eq(body.message, "Not Found")
}pub struct GitHub {
// private fields
} let repo = gh.call(
@gen.repos_get_request("gaato", "mbt-sdk"),
@gen.repos_get_decode,
) let data = gh.graphql(
query=(
#|query($owner: String!, $name: String!) {
#| repository(owner: $owner, name: $name) { stargazerCount }
#|}
),
variables={ "owner": "gaato", "name": "mbt-sdk" },
) let issues = gh
.graphql_paginator(
data => {
guard data is Object(root) else { ... }
...
(nodes, if has_next_page { end_cursor } else { None })
},
query=(
#|query($cursor: String) {
#| repository(owner: "gaato", name: "mbt-sdk") {
#| issues(first: 100, after: $cursor) {
#| nodes { number title }
#| pageInfo { hasNextPage endCursor }
#| }
#| }
#|}
),
cursor_variable="cursor",
)
.collect(max=500)fn GitHub::new(transport : &Transport, clock : &Clock, token? : String, base_url? : String, api_version? : String, user_agent? : String, retry? : RetryPolicy, limiter? : &RateLimiter, graphql_url? : String, gate? : () -> &Gate, timeouts? : Timeouts) -> GitHub let repos = gh
.paginator(
@gen.repos_list_for_user_request("gaato", per_page=100),
@gen.repos_list_for_user_decode,
)
.collect(max=250)impl RetryDecider for GitHubRetrytest {
let retry : @github.GitHubRetry = {
policy: @runtime.RetryPolicy::conservative().with_max_retries(3),
}
let post = @http.Request::post("/repos/o/r/issues")
let limited = @runtime.Status(
status=403,
headers=@http.Headers::new(),
body=b"{\"message\":\"You have exceeded a secondary rate limit.\"}",
)
let waits = [0, 1, 2, 3].map(attempt => {
retry.decide(limited, @runtime.RetryContext::new(post, attempt~))
})
assert_eq(waits, [Wait(60000), Wait(120000), Wait(240000), Stop(Exhausted)])
}test {
let error : @github.GraphqlError = {
message: "Could not resolve to a Repository with the name 'o/r'.",
type_: Some("NOT_FOUND"),
path: Some(["repository"]),
locations: None,
extensions: None,
}
assert_eq(error.type_, Some("NOT_FOUND"))
} if @github.graphql_errors(error) is Some(errors) {
for error in errors {
if error.type_ is Some("RATE_LIMITED") { ... }
}
}Install
Download zipThin GitHub API client for MoonBit built on gaato/http and gaato/sdk-runtime: the whole REST API generated, plus a GraphQL passthrough.