To access the API you need an instance of a GithubAPI client.
var token = get_github_oauth
assert not token.is_empty
# Init the client.
var api = new GithubAPI(token)The API client allows you to get Github API entities.
var repo = api.get_repo("nitlang/nit")
assert repo != null
assert repo.name == "nit"
var user = api.get_user("Morriar")
assert user != null
assert user.login == "Morriar"github :: GithubAPI :: defaultinit
github :: GithubAPI :: deserialize
Deserialize an objectgithub :: GithubAPI :: enable_cache=
Enable caching for this client.github :: GithubAPI :: get_auth_user
Get the Github logged user fromauth token.
			github :: GithubAPI :: get_branch
Get the Github branch withname.
			github :: GithubAPI :: get_commit
Get the Github commit withsha.
			github :: GithubAPI :: get_commit_comment
Get the Github commit comment withid.
			github :: GithubAPI :: get_commit_status
Get the status of a commitgithub :: GithubAPI :: get_issue_comment
Get the Github issue comment withid.
			github :: GithubAPI :: get_issue_comments
List of event on this issue.github :: GithubAPI :: get_issue_event
Get the Github issue event withid.
			github :: GithubAPI :: get_issue_events
List of events on this issue.github :: GithubAPI :: get_milestone
Get the Github milestone withid.
			github :: GithubAPI :: get_pull_comment
Get a specific pull request commentgithub :: GithubAPI :: get_pull_comments
List of comments on a pull requestgithub :: GithubAPI :: get_repo_branches
List of repo branches.github :: GithubAPI :: get_repo_contrib_stats
List of contributor related statistics.github :: GithubAPI :: get_repo_issues
List of issues associated with their ids.github :: GithubAPI :: get_repo_labels
List of labels associated with their names.github :: GithubAPI :: get_repo_milestones
List of milestones associated with their ids.github :: GithubAPI :: get_repo_pulls
List of pull-requests associated with their ids.github :: GithubAPI :: last_error
Last error occured during Github API communications.github :: GithubAPI :: last_error=
Last error occured during Github API communications.github :: GithubAPI :: search_repo_issues
Search issues in this repo form an advanced query.github :: GithubAPI :: user_agent=
User agent used for HTTP requests.github :: GithubAPI :: valid_tokens=
Tokens mocked as validgithub :: GithubAPI :: was_error=
Does the last request provoqued an error?github :: test_wallet $ GithubAPI :: get_auth_user
Mock so it returns the response from a filecore :: Object :: class_factory
Implementation used byget_class to create the specific class.
			core :: Object :: defaultinit
github :: GithubAPI :: defaultinit
github :: GithubAPI :: deserialize
Deserialize an objectgithub :: GithubAPI :: enable_cache=
Enable caching for this client.github :: GithubAPI :: get_auth_user
Get the Github logged user fromauth token.
			github :: GithubAPI :: get_branch
Get the Github branch withname.
			github :: GithubAPI :: get_commit
Get the Github commit withsha.
			github :: GithubAPI :: get_commit_comment
Get the Github commit comment withid.
			github :: GithubAPI :: get_commit_status
Get the status of a commitgithub :: GithubAPI :: get_issue_comment
Get the Github issue comment withid.
			github :: GithubAPI :: get_issue_comments
List of event on this issue.github :: GithubAPI :: get_issue_event
Get the Github issue event withid.
			github :: GithubAPI :: get_issue_events
List of events on this issue.github :: GithubAPI :: get_milestone
Get the Github milestone withid.
			github :: GithubAPI :: get_pull_comment
Get a specific pull request commentgithub :: GithubAPI :: get_pull_comments
List of comments on a pull requestgithub :: GithubAPI :: get_repo_branches
List of repo branches.github :: GithubAPI :: get_repo_contrib_stats
List of contributor related statistics.github :: GithubAPI :: get_repo_issues
List of issues associated with their ids.github :: GithubAPI :: get_repo_labels
List of labels associated with their names.github :: GithubAPI :: get_repo_milestones
List of milestones associated with their ids.github :: GithubAPI :: get_repo_pulls
List of pull-requests associated with their ids.core :: Object :: is_same_instance
Return true ifself and other are the same instance (i.e. same identity).
			core :: Object :: is_same_serialized
Isself the same as other in a serialization context?
			core :: Object :: is_same_type
Return true ifself and other have the same dynamic type.
			github :: GithubAPI :: last_error
Last error occured during Github API communications.github :: GithubAPI :: last_error=
Last error occured during Github API communications.core :: Object :: output_class_name
Display class name on stdout (debug only).github :: GithubAPI :: search_repo_issues
Search issues in this repo form an advanced query.github :: GithubAPI :: user_agent=
User agent used for HTTP requests.github :: GithubAPI :: valid_tokens=
Tokens mocked as validgithub :: GithubAPI :: was_error=
Does the last request provoqued an error?
# Client to Github API
#
# To access the API you need an instance of a `GithubAPI` client.
#
# ~~~nitish
# # Get Github authentification token.
# var token = get_github_oauth
# assert not token.is_empty
#
# # Init the client.
# var api = new GithubAPI(token)
# ~~~
#
# The API client allows you to get Github API entities.
#
# ~~~nitish
# var repo = api.get_repo("nitlang/nit")
# assert repo != null
# assert repo.name == "nit"
#
# var user = api.get_user("Morriar")
# assert user != null
# assert user.login == "Morriar"
# ~~~
class GithubAPI
	# Github API OAuth token
	#
	# To access your private ressources, you must
	# [authenticate](https://developer.github.com/guides/basics-of-authentication/).
	#
	# For client applications, Github recommands to use the
	# [OAuth tokens](https://developer.github.com/v3/oauth/) authentification method.
	#
	#
	#
	# Be aware that there is [rate limits](https://developer.github.com/v3/rate_limit/)
	# associated to the key.
	var auth: nullable String = null is optional
	# User agent used for HTTP requests.
	#
	# Default is `nit_github_api`.
	#
	# See <https://developer.github.com/v3/#user-agent-required>
	var user_agent: String = "nit_github_api" is optional
	# Headers to use on all requests
	fun new_headers: HeaderMap do
		var map = new HeaderMap
		var auth = self.auth
		if auth != null then
			map["Authorization"] = "token {auth}"
		end
		map["User-Agent"] = user_agent
		# FIXME remove when projects and team are no more in beta
		map["Accept"] = "application/vnd.github.inertia-preview+json"
		map["Accept"] = "application/vnd.github.hellcat-preview+json"
		return map
	end
	# Github API base url.
	#
	# Default is `https://api.github.com` and should not be changed.
	var api_url = "https://api.github.com"
	# Send a HTTPRequest to the Github API
	fun send(method, path: String, headers: nullable HeaderMap, body: nullable String): nullable String do
		last_error = null
		path = sanitize_uri(path)
		var uri = "{api_url}{path}"
		var request = new CurlHTTPRequest(uri)
		request.method = method
		request.user_agent = user_agent
		request.headers = headers or else self.new_headers
		request.body = body
		return check_response(uri, request.execute)
	end
	private fun check_response(uri: String, response: CurlResponse): nullable String do
		if response isa CurlResponseSuccess then
			was_error = false
			return response.body_str
		else if response isa CurlResponseFailed then
			last_error = new GithubAPIError(
				response.error_msg,
				response.error_code,
				uri
			)
			was_error = true
			return null
		else abort
	end
	# Deserialize an object
	fun deserialize(string: nullable Serializable): nullable Object do
		if string == null then return null
		var deserializer = new GithubDeserializer(string.to_s)
		var res = deserializer.deserialize
		if deserializer.errors.not_empty then
			was_error = true
			last_error = new GithubDeserializerErrors("Deserialization failed", deserializer.errors)
			return null
		else if res isa GithubError then
			was_error = true
			last_error = res
			return null
		end
		was_error = false
		return res
	end
	# Escape `uri` in an acceptable format for Github.
	private fun sanitize_uri(uri: String): String do
		# TODO better URI escape.
		return uri.replace(" ", "%20")
	end
	# Last error occured during Github API communications.
	var last_error: nullable Error = null is public writable
	# Does the last request provoqued an error?
	var was_error = false is protected writable
	# Execute a GET request on Github API.
	#
	# This method returns a deserialized result.
	#
	# For raw data see `send`.
	#
	# ~~~nitish
	# var api = new GithubAPI(get_github_oauth)
	# var obj = api.get("/repos/nitlang/nit")
	# assert obj isa Repo
	# assert obj.name == "nit"
	# ~~~
	#
	# Returns `null` in case of `error`.
	#
	# ~~~nitish
	# obj = api.get("/foo/bar/baz")
	# assert obj == null
	# assert api.was_error
	# assert api.last_error isa GithubError
	# ~~~
	fun get(path: String, headers: nullable HeaderMap, data: nullable String): nullable Object do
		return deserialize(send("GET", path, headers, data))
	end
	# Get the Github logged user from `auth` token.
	#
	# Loads the `User` from the API or returns `null` if the user cannot be found.
	#
	# ~~~nitish
	# var api = new GithubAPI(get_github_oauth)
	# var user = api.get_auth_user
	# assert user.login == "Morriar"
	# ~~~
	fun get_auth_user: nullable User do
		return get("/user").as(nullable User)
	end
	# Get the Github user with `login`
	#
	# Loads the `User` from the API or returns `null` if the user cannot be found.
	#
	# ~~~nitish
	# var api = new GithubAPI(get_github_oauth)
	# var user = api.get_user("Morriar")
	# print user or else "null"
	# assert user.login == "Morriar"
	# ~~~
	fun get_user(login: String): nullable User do
		return get("/users/{login}").as(nullable User)
	end
	# Get the Github repo with `full_name`.
	#
	# Loads the `Repo` from the API or returns `null` if the repo cannot be found.
	#
	# ~~~nitish
	# var api = new GithubAPI(get_github_oauth)
	# var repo = api.get_repo("nitlang/nit")
	# assert repo.name == "nit"
	# assert repo.owner.login == "nitlang"
	# assert repo.default_branch == "master"
	# ~~~
	fun get_repo(repo_slug: String): nullable Repo do
		return get("/repos/{repo_slug}").as(nullable Repo)
	end
	# List of repo branches.
	#
	# Pagination:
	#	* `page`: page to fetch (default: 1)
	#	* `per_page`: number of branches by page (default: 30)
	fun get_repo_branches(repo_slug: String, page, per_page: nullable Int): Array[Branch] do
		return new GithubArray[Branch].from(get(
			"/repos/{repo_slug}/branches?{pagination(page, per_page)}"))
	end
	# List of issues associated with their ids.
	fun get_repo_issues(repo_slug: String, page, per_page: nullable Int): Array[Issue] do
		return new GithubArray[Issue].from(get(
			"/repos/{repo_slug}/issues?{pagination(page, per_page)}"))
	end
	# Search issues in this repo form an advanced query.
	#
	# Example:
	#
	# ~~~nitish
	# var issues = repo.search_issues("is:open label:need_review")
	# ~~~
	#
	# See <https://developer.github.com/v3/search/#search-issues>.
	fun search_repo_issues(repo_slug: String, query: String, page, per_page: nullable Int): nullable SearchResults do
		return get("/search/issues?q={query} repo:{repo_slug}&{pagination(page, per_page)}").as(nullable SearchResults)
	end
	# List of labels associated with their names.
	fun get_repo_labels(repo_slug: String, page, per_page: nullable Int): Array[Label] do
		return new GithubArray[Label].from(get(
			"/repos/{repo_slug}/labels?{pagination(page, per_page)}"))
	end
	# List of milestones associated with their ids.
	fun get_repo_milestones(repo_slug: String, page, per_page: nullable Int): Array[Milestone] do
		return new GithubArray[Milestone].from(get(
			"/repos/{repo_slug}/milestones?{pagination(page, per_page)}"))
	end
	# List of pull-requests associated with their ids.
	#
	# Implementation notes: because PR numbers are not consecutive,
	# PR are loaded from pages.
	# See: https://developer.github.com/v3/pulls/#list-pull-requests
	fun get_repo_pulls(repo_slug: String, page, per_page: nullable Int): Array[PullRequest] do
		return new GithubArray[PullRequest].from(get(
			"/repos/{repo_slug}/pulls?{pagination(page, per_page)}"))
	end
	# List of contributor related statistics.
	fun get_repo_contrib_stats(repo_slug: String): Array[ContributorStats] do
		return new GithubArray[ContributorStats].from(get("/repos/{repo_slug}/stats/contributors"))
	end
	# Get the Github branch with `name`.
	#
	# Returns `null` if the branch cannot be found.
	#
	# ~~~nitish
	# var api = new GithubAPI(get_github_oauth)
	# var repo = api.get_repo("nitlang/nit")
	# assert repo != null
	# var branch = api.get_branch(repo, "master")
	# assert branch.name == "master"
	# assert branch.commit isa Commit
	# ~~~
	fun get_branch(repo_slug: String, name: String): nullable Branch do
		return get("/repos/{repo_slug}/branches/{name}").as(nullable Branch)
	end
	# Get the Github commit with `sha`.
	#
	# Returns `null` if the commit cannot be found.
	#
	# ~~~nitish
	# var api = new GithubAPI(get_github_oauth)
	# var repo = api.get_repo("nitlang/nit")
	# assert repo != null
	# var commit = api.get_commit(repo, "64ce1f")
	# assert commit isa Commit
	# ~~~
	fun get_commit(repo_slug: String, sha: String): nullable Commit do
		return get("/repos/{repo_slug}/commits/{sha}").as(nullable Commit)
	end
	# Get the status of a commit
	#
	# The status holds the result of each check ran on a commit like CI, reviews etc.
	fun get_commit_status(repo_slug: String, sha: String): nullable CommitStatus do
		return get("/repos/{repo_slug}/commits/{sha}/status").as(nullable CommitStatus)
	end
	# Get the Github issue #`number`.
	#
	# Returns `null` if the issue cannot be found.
	#
	# ~~~nitish
	# var api = new GithubAPI(get_github_oauth)
	# var repo = api.get_repo("nitlang/nit")
	# assert repo != null
	# var issue = api.get_issue(repo, 1)
	# assert issue.title == "Doc"
	# ~~~
	fun get_issue(repo_slug: String, number: Int): nullable Issue do
		return get("/repos/{repo_slug}/issues/{number}").as(nullable Issue)
	end
	# List of event on this issue.
	fun get_issue_comments(repo_slug: String, issue_number: Int, page, per_page: nullable Int): Array[IssueComment] do
		return new GithubArray[IssueComment].from(get(
			"/repos/{repo_slug}/issues/{issue_number}/comments?{pagination(page, per_page)}"))
	end
	# List of events on this issue.
	fun get_issue_events(repo_slug: String, issue_number: Int, page, per_page: nullable Int): Array[IssueEvent] do
		return new GithubArray[IssueEvent].from(get(
			"/repos/{repo_slug}/issues/{issue_number}/events?{pagination(page, per_page)}"))
	end
	# Get the Github pull request #`number`.
	#
	# Returns `null` if the pull request cannot be found.
	#
	# ~~~nitish
	# var api = new GithubAPI(get_github_oauth)
	# var repo = api.get_repo("nitlang/nit")
	# assert repo != null
	# var pull = api.get_pull(repo, 1)
	# assert pull.title == "Doc"
	# assert pull.user.login == "Morriar"
	# ~~~
	fun get_pull(repo_slug: String, number: Int): nullable PullRequest do
		return get("/repos/{repo_slug}/pulls/{number}").as(nullable PullRequest)
	end
	# List of comments on a pull request
	fun get_pull_comments(repo_slug: String, pull_number: Int, page, per_page: nullable Int): Array[PullComment] do
		return new GithubArray[PullComment].from(get(
			"/repos/{repo_slug}/pulls/{pull_number}/comments?{pagination(page, per_page)}"))
	end
	# Get a specific pull request comment
	fun get_pull_comment(repo_slug: String, id: Int): nullable PullComment do
		return get("/repos/{repo_slug}/pulls/comments/{id}").as(nullable PullComment)
	end
	# Get the Github label with `name`.
	#
	# Returns `null` if the label cannot be found.
	#
	# ~~~nitish
	# var api = new GithubAPI(get_github_oauth)
	# var repo = api.get_repo("nitlang/nit")
	# assert repo != null
	# var labl = api.get_label(repo, "ok_will_merge")
	# assert labl != null
	# ~~~
	fun get_label(repo_slug: String, name: String): nullable Label do
		return get("/repos/{repo_slug}/labels/{name}").as(nullable Label)
	end
	# Get the Github milestone with `id`.
	#
	# Returns `null` if the milestone cannot be found.
	#
	# ~~~nitish
	# var api = new GithubAPI(get_github_oauth)
	# var repo = api.get_repo("nitlang/nit")
	# assert repo != null
	# var stone = api.get_milestone(repo, 4)
	# assert stone.title == "v1.0prealpha"
	# ~~~
	fun get_milestone(repo_slug: String, id: Int): nullable Milestone do
		return get("/repos/{repo_slug}/milestones/{id}").as(nullable Milestone)
	end
	# Get the Github issue event with `id`.
	#
	# Returns `null` if the event cannot be found.
	#
	# ~~~nitish
	# var api = new GithubAPI(get_github_oauth)
	# var repo = api.get_repo("nitlang/nit")
	# assert repo isa Repo
	# var event = api.get_issue_event(repo, 199674194)
	# assert event isa IssueEvent
	# assert event.actor.login == "privat"
	# assert event.event == "labeled"
	# assert event.labl isa Label
	# assert event.labl.name == "need_review"
	# ~~~
	fun get_issue_event(repo_slug: String, id: Int): nullable IssueEvent do
		return get("/repos/{repo_slug}/issues/events/{id}").as(nullable IssueEvent)
	end
	# Get the Github commit comment with `id`.
	#
	# Returns `null` if the comment cannot be found.
	#
	# ~~~nitish
	# var api = new GithubAPI(get_github_oauth)
	# var repo = api.get_repo("nitlang/nit")
	# assert repo != null
	# var comment = api.get_commit_comment(repo, 8982707)
	# assert comment.user.login == "Morriar"
	# assert comment.body == "For testing purposes...\n"
	# assert comment.commit_id == "7eacb86d1e24b7e72bc9ac869bf7182c0300ceca"
	# ~~~
	fun get_commit_comment(repo_slug: String, id: Int): nullable CommitComment do
		return get("/repos/{repo_slug}/comments/{id}").as(nullable CommitComment)
	end
	# Get the Github issue comment with `id`.
	#
	# Returns `null` if the comment cannot be found.
	#
	# ~~~nitish
	# var api = new GithubAPI(get_github_oauth)
	# var repo = api.get_repo("nitlang/nit")
	# assert repo != null
	# var comment = api.get_issue_comment(repo, 6020149)
	# assert comment.user.login == "privat"
	# assert comment.created_at.to_s == "2012-05-30T20:16:54Z"
	# assert comment.issue_number == 10
	# ~~~
	fun get_issue_comment(repo_slug: String, id: Int): nullable IssueComment do
		return get("/repos/{repo_slug}/issues/comments/{id}").as(nullable IssueComment)
	end
	private fun pagination(page, per_page: nullable Int): String do
		return "page={page or else 1}&per_page={per_page or else 30}"
	end
end
					lib/github/api.nit:28,1--453,3
				
redef class GithubAPI
	# Enable caching for this client.
	# Default is `false`.
	var enable_cache = false is writable
	# JsonStore used to cache data.
	#
	# Default directory is `".github_data/"`.
	var store = new JsonStore(".github_data/") is writable, lazy
	# Delete the cache directory.
	fun clear_cache do store.clear
	# If no cache data is found for `key` then json is loaded from Github API.
	redef fun get(key, headers, data) do
		if not enable_cache then return super
		if store.has_key(key) then
			# print "Get {key} (cache)" # debug
			was_error = false
			return deserialize(store.load_object(key).to_json)
		end
		var obj = super
		if not was_error and obj isa Serializable then
			cache(key, obj)
		end
		return obj
	end
	# Save `json` data in cache under `key`.
	private fun cache(key: String, obj: Serializable) do
		# print "Cache key {key}" # debug
		store.store_object(key, obj.to_json.parse_json.as(JsonObject))
	end
	# Check if a cache file exists for `key`.
	fun has_cache(key: String): Bool do
		return store.has_key(key)
	end
end
					lib/github/cache.nit:43,1--82,3
				
redef class GithubAPI
	# Tokens mocked as valid
	#
	# All other tokens will be considered as bad credentials.
	var valid_tokens = ["t1", "t2"]
	# Mock so it returns the response from a file
	#
	# See `update_responses_cache`.
	redef fun get_auth_user do
		if not valid_tokens.has(auth) then
			was_error = true
			last_error = new GithubAPIError("""{
				"message":"Bad credentials",
				"documentation_url":"https://developer.github.com/v3"
			}""", 401, "/user")
			return null
		end
		was_error = false
		last_error = null
		return new User("test")
	end
end
					lib/github/tests/test_wallet.nit:19,1--43,3