Git Product home page Git Product logo

ghapi's Introduction

ghapi

ghapi provides 100% always-updated coverage of the entire GitHub API. Because we automatically convert the OpenAPI spec to a Pythonic API, ghapi is always up to date with the latest changes to GitHub APIs. Furthermore, because this is all done dynamically, the entire package is only 35kB in size!

Using ghapi, you can automate nearly anything that you can do through the GitHub web interface or through the git client, such as:

There are two ways to use ghapi: either through Python, or from the command line. An overview of each is provided below.

Installation

To install, run either pip install ghapi or conda install -c fastai ghapi.

How to use - Python

Throughout this documentation, you will see code inputs and outputs shown in this format:

1+1
2

We recommend reading the documentation on the official site, rather than on GitHub, since not all the functionality described on this page is available through the GitHub viewer.

All of the documentation is available directly as Jupyter Notebooks, for instance the current page you’re reading is available as a notebook here. To open any page as an interactive notebook in Google Colab, click the Colab badge at the top of the page.

To access the GitHub API, first create a GhApi object:

from ghapi.all import GhApi
api = GhApi()

Every part of the API includes documentation directly in the api object itself. For instance, here’s how to explore the groups of functionality provided by the API by displaying the object:

api

Then we can explore the endpoints provided by the API in each group, e.g. for the git group:

api.git

Here’s how to learn about an endpoint you want to use, e.g.:

api.git.get_ref

git.get_ref(owner, repo, ref): Get a reference

In Jupyter Notebook full tab completion, parameter lists, etc are provided for all endpoints. Endpoints are called as standard Python methods:

api.git.get_ref(owner='fastai', repo='fastcore', ref='heads/master')

To use ghapi to access authenticated operations (other than when running through GitHub Actions), you will need a GitHub personal access token, which is a secret code used to access your account. If you don’t have one, click here to create one. You’ll be asked to enter a name – choose anything you like, for instance “ghapi”. You’ll also be asked to choose “scopes”; this limits what you’ll be able to do with the API using this token. If you’re not sure, click “repo” “gist”, “notifications”, and “workflow”. Then click “Generate Token” at the bottom of the screen, and copy the token (the long string of letters and numbers shown). You can easily do that by clicking the little clipboard icon next to the token.

Rather than pasting that token into every script, it’s easiest to save it as an environment variable. If you save it as $GITHUB_TOKEN then it will be most convenient, so add this to the end of your .bashrc or .zshrc file:

export GITHUB_TOKEN=xxx

…replacing the xxx with the token you just copied. (Don’t forget to source that file after you change it.), pass a [GitHub token].

As well as your token, you can also pass any parameters you want auto-inserted into relevant methods, such as owner and repo:

api = GhApi(owner='fastai', repo='fastcore', token=github_token)

We can now repeat the previous method, but only need to pass ref:

api.git.get_ref('heads/master')

Now that we’ve provided our token, we can use authenticated endpoints such as creating an issue:

issue = api.issues.create("Remember to check out GhApi!")

Since we’ve now checked out GhApi, let’s close this issue. 😎

api.issues.update(issue.number, state='closed')

How to use - command line

You can use GhApi via the command line, and can access nearly everything in the GitHub API. We provide an overview here of one of the command line programs, ghapi – see the full CLI docs page for details on all the programs available.

We strongly recommend enabling tab completion for ghapi, which you can do by placing the following command at the end of your ~/.bashrc or ~/.zshrc file:

eval "$(completion-ghapi --install)"

To get started with the ghapi command, first find the name of the operation you wish to perform, for instance by searching the full API reference.

To use ghapi, pass the method name (exactly the same as you’d use in the Python API) as the first parameter, followed by any positional parameters required, and then keyword arguments with “--” before each parameter name.

For instance, git.get_ref takes three parameters: owner, repo, and ref. If we wish to pass the first two as positional parameters, and the last as a named argument, then we’d call:

ghapi git.get_ref fastai ghapi-test --ref heads/master

If you have enabled tab completion, then after you’ve typed ghapi g try pressing Tab, and you’ll see all the operation groups available in the GitHub API that start with g. If you keep typing, e.g. ghapi git., and hit Tab again, you’ll now see all the operations available in the git group, i.e:

git.create_blob git.create_commit git.create_ref git.create_tag git.create_tree git.delete_ref git.get_blob git.get_commit git.get_ref git.get_tag git.get_tree git.list_matching_refs git.name git.update_ref git.verbs

If you pass just --help after the operation name, you’ll see a full list of all parameters accepted, and a link to the official GitHub documentation.

ghapi git.get_ref --help
>>> git.get_ref(owner, repo, ref)
>>> https://docs.github.com/rest/reference/git#get-a-reference

In addition to --help and the GitHub operation parameters, you can also pass the following:

  • --headers: A list of extra headers to pass, JSON-encoded
  • --token: A GitHub authentation token
  • --debug: Print requests before sending them

ghapi's People

Contributors

danpalmer avatar dependabot[bot] avatar ffalor avatar hamelsmu avatar hwine avatar jean avatar jph00 avatar jrieke avatar lfdebrux avatar mszhanyi avatar muellerzr avatar nedbat avatar rshk avatar seem avatar shreve avatar sou-786 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ghapi's Issues

Timeout after lots of API calls

Summary

If I do lots (~hundreds) of requests within a few minutes, the API call sometimes times out without raising an error (i.e. it just runs indefinitely).

Details

I'm using the api.activity.list_stargazers_for_repo endpoint (didn't check if the problem persists with other endpoints). I'm not sure why this happens but I double-checked that I'm not rate-limited (using limit_cb callback + printing api.rate_limit.get() regularly). If I stop the process and start it again right after, it also works fine, so I assume it's just a temporary timeout.

Possible fix

A great workaround would already be to be able to set a manual timeout when initializing the API or calling an endpoint.

fastcore.basics.HTTP403ForbiddenError: HTTP Error 403: Forbidden

I have using 'search.issues_and_pull_requests' to look some titles of issues in my repo. Using a for loop, I am getting the titles from a csv file which has around 100 issues. I am getting the following error -- sometime I get the error after the 30th item in the list, sometime when I invoke my script. Any ideas?

File "/usr/local/lib/python3.9/site-packages/ghapi/core.py", line 61, in __call__
    return self.client(self.path, self.verb, headers=headers, route=route_p, query=query_p, data=data_p)
  File "/usr/local/lib/python3.9/site-packages/ghapi/core.py", line 104, in __call__
    res,self.recv_hdrs = urlsend(path, verb, headers=headers or None, debug=self.debug, return_headers=True,
  File "/usr/local/lib/python3.9/site-packages/fastcore/net.py", line 175, in urlsend
    return urlread(req, return_json=return_json, return_headers=return_headers)
  File "/usr/local/lib/python3.9/site-packages/fastcore/net.py", line 112, in urlread
    if 400 <= e.code < 500: raise ExceptionsHTTP[e.code](e.url, e.hdrs, e.fp) from None
fastcore.basics.HTTP403ForbiddenError: HTTP Error 403: Forbidden

UnicodeDecodeError on actions.download_artifact

I might obviously be missing something, but I'm getting a UnicodeDecodeError, when trying to download an artifact:

>>> api.actions.download_artifact("YannickJadoul", "Parselmouth", 28315202, "zip")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/yannick/.local/lib/python3.6/site-packages/ghapi/core.py", line 60, in __call__
    return self.client(self.path, self.verb, headers=headers, route=route_p, query=query_p, data=data_p)
  File "/home/yannick/.local/lib/python3.6/site-packages/ghapi/core.py", line 104, in __call__
    route=route or None, query=query or None, data=data or None)
  File "/home/yannick/.local/lib/python3.6/site-packages/fastcore/net.py", line 175, in urlsend
    return urlread(req, return_json=return_json, return_headers=return_headers)
  File "/home/yannick/.local/lib/python3.6/site-packages/fastcore/net.py", line 115, in urlread
    if decode: res = res.decode()
UnicodeDecodeError: 'utf-8' codec can't decode bytes in position 68-69: invalid continuation byte

It seems like the download bytes are attempted to be decoded to a unicode string? I hope I didn't miss any advice in the docs on how to disable this.

The issue doesn't seem to be happening for e.g. git.get_blob, because the response there is base64-encoded, while GhApi.get_content does return some bytes (though it's not possible to download artifacts this way, as far as I know).

Add links to documentations for paylods

It would be cool if the repr for payloads would somehow let you see the link to the associated GitHub documentation, similar to what is currently done for endpoints.

Docs don't make location of GhApi clear

I could not figure out where GhApi came from just by reading the docs, I tried ghapi.GhApi, I tried dir(ghapi), and no sign of it. I clicked through a bit and didn't see it either. Finally found it by entering colab and seeing the ghapi.core import at the top that gets hidden. Two recommendations:

  • Somewhere in the docs mention that ghapi.core is the home for GhApi.
  • Use qualified references in the docs. import * makes docs really hard to follow (especially when it's then hidden! But even not hidden it is bad in docs). Since most operations are on the ghapi.core.GhApi object, it won't make the docs that much more verbose, and would be much easier to follow.

PS: It's also missing from the readme.

Example for pagination doesn't seem to work

The docs don't mention where to get paged. I'm guessing it's from ghapi.page import paged.
Anyway, when trying to follow the example I get:

In [82]: repos = api.repos.list_for_org('<...>')                                                                                                                                             
In [83]: len(repos)                                                                                                                                                                                
Out[83]: 30                                                                                                                                                                                        

In [84]: repos_paged = paged(api.repos.list_for_org('<...>'))                                                                                                                                
In [85]: for page in repos_paged: print(len(page), page[0].name)                                                                                                                                   
---------------------------------------------------------------------------                                                                                                                        
TypeError                                 Traceback (most recent call last)                                                                                                                        
<ipython-input-85-f32e698c6d18> in <module>                                                                                                                                                        
----> 1 for page in repos_paged: print(len(page), page[0].name)                                                                                                                                    
                                                                                                                                                                                                   
~/git/github-analysis/lib/python3.8/site-packages/ghapi/page.py in paged(oper, per_page, max_pages, *args, **kwargs)                                                                               
     14 def paged(oper, *args, per_page=30, max_pages=9999, **kwargs):                                                                                                                             
     15     "Convert operation `oper(*args,**kwargs)` into an iterator"                                                                                                                            
---> 16     yield from itertools.takewhile(noop, (oper(*args, per_page=per_page, page=i, **kwargs) for i in range(1,max_pages+1)))                                                                 
     17                                                                                                                                                                                            
     18 # Cell                                                                                                                                                                                     
                                                                                                                                                                                                   
~/git/github-analysis/lib/python3.8/site-packages/ghapi/page.py in <genexpr>(.0)                                                                                                                   
     14 def paged(oper, *args, per_page=30, max_pages=9999, **kwargs):                                                                                                                             
     15     "Convert operation `oper(*args,**kwargs)` into an iterator"                                                                                                                            
---> 16     yield from itertools.takewhile(noop, (oper(*args, per_page=per_page, page=i, **kwargs) for i in range(1,max_pages+1)))                                                                 
     17                                                                                                                                                                                            
     18 # Cell                                                                                                                                                                                     
                                                                                                                                                                                                   
TypeError: 'L' object is not callable                  

recv_hdrs issue with parallel headers

When following the documentation on parallel pages

gh_repos = pages(api.repos.list_for_org, api.last_page(), 'github').concat()
len(gh_repos)

I get the following error:

File "/workspaces/test/github.py", line 25, in <module>
    gh_repos = pages(api.repos.list_for_org, api.last_page(), 'github').concat()
  File "/home/vscode/.local/lib/python3.9/site-packages/ghapi/page.py", line 57, in last_page
    header = self.recv_hdrs.get('Link', '')
  File "/home/vscode/.local/lib/python3.9/site-packages/ghapi/core.py", line 116, in __getattr__
    def __getattr__(self,k): return self.groups[k] if 'groups' in vars(self) and k in self.groups else stop(AttributeError(k))
  File "/home/vscode/.local/lib/python3.9/site-packages/fastcore/basics.py", line 202, in stop
    raise e
AttributeError: recv_hdrs

Should I have extra parameters in my api initialization? I currently am just doing

api = GhApi(token="abunchofrandomchars")

typo in docs

there's a typo in fullapi.html.

rate-limit.get is wrong. it should be replaced to rate_limit.get.

<li><a href="https://docs.github.com/v3/rate_limit/#get-rate-limit-status-for-the-authenticated-user">rate-limit.get</a>(): <em>Get rate limit status for the authenticated user</em></li>

Unable to create gist using `GhApi().gists.create()`

Hello,

I am trying to use ghapi to create gists. I am consistently getting HTTP404NotFoundError: HTTP Error 404: Not Found every time I try to create a gist using GhApi().gists.create(...). I am authenticated and I can perform other operations such as fetching user data or fetching my own gists. This is the error I get and the code I am running:
pic-selected-210207-2017-39

This is the stack trace:

---------------------------------------------------------------------------
HTTP404NotFoundError                      Traceback (most recent call last)
<ipython-input-155-f9c2313cdf94> in <module>
----> 1 ghapi.gists.create(description='ghapi test', files= 'CONTRIBUTING.md')

~/.config/miniconda3/envs/nb2medium/lib/python3.9/site-packages/ghapi/core.py in __call__(self, headers, *args, **kwargs)
     59         route_p,query_p,data_p = [{p:kwargs[p] for p in o if p in kwargs}
     60                                  for o in (self.route_ps,self.params,d)]
---> 61         return self.client(self.path, self.verb, headers=headers, route=route_p, query=query_p, data=data_p)
     62 
     63     def __str__(self): return f'{self.tag}.{self.name}{signature(self)}\n{self.doc_url}'

~/.config/miniconda3/envs/nb2medium/lib/python3.9/site-packages/ghapi/core.py in __call__(self, path, verb, headers, route, query, data)
    102         headers = {**self.headers,**(headers or {})}
    103         if path[:7] not in ('http://','https:/'): path = GH_HOST+path
--> 104         res,self.recv_hdrs = urlsend(path, verb, headers=headers or None, debug=self.debug, return_headers=True,
    105                                      route=route or None, query=query or None, data=data or None)
    106         if 'X-RateLimit-Remaining' in self.recv_hdrs:

~/.config/miniconda3/envs/nb2medium/lib/python3.9/site-packages/fastcore/net.py in urlsend(url, verb, headers, route, query, data, json_data, return_json, return_headers, debug)
    173     req = urlrequest(url, verb, headers, route=route, query=query, data=data, json_data=json_data)
    174     if debug: debug(req)
--> 175     return urlread(req, return_json=return_json, return_headers=return_headers)
    176 
    177 # Cell

~/.config/miniconda3/envs/nb2medium/lib/python3.9/site-packages/fastcore/net.py in urlread(url, data, headers, decode, return_json, return_headers, **kwargs)
    110         with urlopen(url, data=data, headers=headers, **kwargs) as u: res,hdrs = u.read(),u.headers
    111     except HTTPError as e:
--> 112         if 400 <= e.code < 500: raise ExceptionsHTTP[e.code](e.url, e.hdrs, e.fp) from None
    113         else: raise
    114 

HTTP404NotFoundError: HTTP Error 404: Not Found

I am using python 3.9.1 and ghapi 0.1.16

Bug: `paged` does not pass `kwargs` to operation

On this line, the kwargs that paged receives are not passed on to the operation (as is described in the docs here and the docstring in the line above).

This produces an error for me when using paged with a custom header, e.g.:

paged(api.activity.list_stargazers_for_repo, "fastai", "ghapi", headers={"Accept": "application/vnd.github.v3.star+json"})

Proxy settings

I have an environment that has proxy settings and can't find any way to get ghapi to use the proxy. Is this possible or can it be added?

Error in documentation regarding Rate Limit

Thanks for this great library .

Looking at: https://ghapi.fast.ai/fullapi.html#rate_limit

It does refer the as being rate-limit.get() but it is rate_limit.get()

>>> api.rate_limit.get()
- resources: 
  - core: 
    - limit: 60
    - remaining: 59
    - reset: 1609793829
    - used: 1
  - graphql: 
    - limit: 0
    - remaining: 0
    - reset: 1609795315
    - used: 0
  - integration_manifest: 
    - limit: 5000
    - remaining: 5000
    - reset: 1609795315
    - used: 0
  - search: 
    - limit: 10
    - remaining: 10
    - reset: 1609791775
    - used: 0
- rate: 
  - limit: 60
  - remaining: 59
  - reset: 1609793829
  - used: 1
>>> api.rate-limit.get()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/x/.local/lib/python3.8/site-packages/ghapi/core.py", line 115, in __getattr__
    def __getattr__(self,k): return self.groups[k] if 'groups' in vars(self) and k in self.groups else stop(AttributeError(k))
  File "/home/x/.local/lib/python3.8/site-packages/fastcore/basics.py", line 202, in stop
    raise e
AttributeError: rate

Moving a Project card results in HTTP422UnprocessableEntityError

What I'm trying to do

I'm trying to use this library to move a GitHub Project card to the top of its list. The context here is that some cards point to issues with a 🔥 priority label, and I'd like to write a short script that:

  • Loops through each card in a column
  • If that card points to an issue (via content_url), grab the issue's list of labels
  • If priority is in one of the labels, then bump the card to the top of the column.

What's not working

Whenever I try to move a card using ghapi, e.g. via:

api.projects.move_card(59656056, 0)

I get this message:

HTTP422UnprocessableEntityError: HTTP Error 422: Unprocessable Entity

If I debug and look at the URL of the Request object, it doesn't seem quite right

req.full_url
> 'https://api.github.com/projects/columns/cards/59656056/moves'

I'm not sure if I'm doing something wrong, or if this is a bug. So, opening it in case others have a suggestion :-)

How do I get a public gist?

How do I get a public gist?

I was interested in retrieving a public gist in Github.

Example:
Given the following gist:

- url: https://api.github.com/gists/abcc6208af09ddaff6725b87b05be034
- forks_url: https://api.github.com/gists/abcc6208af09ddaff6725b87b05be034/forks
- commits_url: https://api.github.com/gists/abcc6208af09ddaff6725b87b05be034/commits
- id: abcc6208af09ddaff6725b87b05be034
- node_id: MDQ6R2lzdGFiY2M2MjA4YWYwOWRkYWZmNjcyNWI4N2IwNWJlMDM0
- git_pull_url: https://gist.github.com/abcc6208af09ddaff6725b87b05be034.git
- git_push_url: https://gist.github.com/abcc6208af09ddaff6725b87b05be034.git
- html_url: https://gist.github.com/abcc6208af09ddaff6725b87b05be034
- files: 
  - main.py: 
    - filename: main.py
    - type: application/x-python
    - language: Python
    - raw_url: https://gist.githubusercontent.com/daanklijn/abcc6208af09ddaff6725b87b05be034/raw/e69e00be58406d956e2cd22f6c4c83569172db23/main.py
    - size: 680
- public: True
- created_at: 2021-01-11T14:45:30Z
- updated_at: 2021-01-11T14:45:31Z
- description: main
- comments: 0
- user: None
- comments_url: https://api.github.com/gists/abcc6208af09ddaff6725b87b05be034/comments
- owner: 
  - login: daanklijn
  - id: 27863547
  - node_id: MDQ6VXNlcjI3ODYzNTQ3
  - avatar_url: https://avatars0.githubusercontent.com/u/27863547?v=4
  - gravatar_id: 
  - url: https://api.github.com/users/daanklijn
  - html_url: https://github.com/daanklijn
  - followers_url: https://api.github.com/users/daanklijn/followers
  - following_url: https://api.github.com/users/daanklijn/following{/other_user}
  - gists_url: https://api.github.com/users/daanklijn/gists{/gist_id}
  - starred_url: https://api.github.com/users/daanklijn/starred{/owner}{/repo}
  - subscriptions_url: https://api.github.com/users/daanklijn/subscriptions
  - organizations_url: https://api.github.com/users/daanklijn/orgs
  - repos_url: https://api.github.com/users/daanklijn/repos
  - events_url: https://api.github.com/users/daanklijn/events{/privacy}
  - received_events_url: https://api.github.com/users/daanklijn/received_events
  - type: User
  - site_admin: False
- truncated: False

I then tried to run the code:

gh_client.gists.get('10199742')

However, this returned:

*** fastcore.basics.HTTP404NotFoundError: HTTP Error 404: Not Found

Is there any way to retrieve a public gist like the one above?

Note: This may not be the right place to make this issue. After reading contributing guidelines, I couldn't find where to point my questions so let me know if there is a better place.

Builtin documentation not working

The README says:

Every part of the API includes documentation directly in the api object itself. For instance, here's how to explore the groups of functionality provided by the API by displaying the object:

api

But this doesn't work for me:

>python
Python 3.8.7 (default, Feb  3 2021, 06:31:03) 
[Clang 12.0.0 (clang-1200.0.32.29)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from ghapi.all import GhApi
>>> api = GhApi()
>>> api
<ghapi.core.GhApi object at 0x107574460>
>>> 

What am I doing wrong?

urllib.error.URLError: <urlopen error [Errno 54] Connection reset by peer>

hello thanks for your work
I meet this error in macos,but it is normal in colab
how can i fix it

File "main.py", line 20, in

issuessss=api.issues.list_for_repo(owner='AllenZYJ', repo='test_bbs',labels='bug')

File "/Users/zhangyiji/opt/miniconda3/envs/bbs_base_github/lib/python3.6/site-packages/ghapi/core.py", line 61, in call
return self.client(self.path, self.verb, headers=headers, route=route_p, query=query_p, data=data_p)
File "/Users/zhangyiji/opt/miniconda3/envs/bbs_base_github/lib/python3.6/site-packages/ghapi/core.py", line 105, in call
route=route or None, query=query or None, data=data or None)
File "/Users/zhangyiji/opt/miniconda3/envs/bbs_base_github/lib/python3.6/site-packages/fastcore/net.py", line 179, in urlsend
return urlread(req, return_json=return_json, return_headers=return_headers)
File "/Users/zhangyiji/opt/miniconda3/envs/bbs_base_github/lib/python3.6/site-packages/fastcore/net.py", line 110, in urlread
with urlopen(url, data=data, headers=headers, **kwargs) as u: res,hdrs = u.read(),u.headers
File "/Users/zhangyiji/opt/miniconda3/envs/bbs_base_github/lib/python3.6/site-packages/fastcore/net.py", line 104, in urlopen
return _opener.open(urlwrap(url, data=data, headers=headers))
File "/Users/zhangyiji/opt/miniconda3/envs/bbs_base_github/lib/python3.6/urllib/request.py", line 526, in open
response = self._open(req, data)
File "/Users/zhangyiji/opt/miniconda3/envs/bbs_base_github/lib/python3.6/urllib/request.py", line 544, in _open
'_open', req)
File "/Users/zhangyiji/opt/miniconda3/envs/bbs_base_github/lib/python3.6/urllib/request.py", line 504, in _call_chain
result = func(*args)
File "/Users/zhangyiji/opt/miniconda3/envs/bbs_base_github/lib/python3.6/urllib/request.py", line 1392, in https_open
context=self._context, check_hostname=self._check_hostname)
File "/Users/zhangyiji/opt/miniconda3/envs/bbs_base_github/lib/python3.6/urllib/request.py", line 1351, in do_open
raise URLError(err)
urllib.error.URLError: <urlopen error [Errno 54] Connection reset by peer>

Cannot serialise GitHub issues to JSON

Description of the problem

Hello Jeremy and Hamel,

I'm trying to use ghapi to fetch issues from a GitHub repo and then dump them to disk as a jsonl file, where each line is an issue.

The problem I'm running into is that the result from GhAPI.issues.list_for_repo contains fastcore's special L type which appears to not be JSON serialisable. As a result I'm getting the following error: TypeError: Object of type L is not JSON serializable

Is there a way to make L play nice with JSON?

Steps to reproduce

import json
from ghapi.all import GhApi

api = GhApi()
issues = api.issues.list_for_repo("huggingface", "transformers", page=1, per_page=5, state="all")

# try to write the first issue
with open("issues.jsonl", "w") as f:
    json.dump(issues[0], f)

Expected result

I can write GitHub issues to disk in JSON format.

Actual result

Here's the stack trace

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-48-04139a7641e4> in <module>
      6 
      7 with open("issues.json", "w") as f:
----> 8     json.dump(issues[0], f)

~/miniconda3/envs/transformersbook/lib/python3.8/json/__init__.py in dump(obj, fp, skipkeys, ensure_ascii, check_circular, allow_nan, cls, indent, separators, default, sort_keys, **kw)
    177     # could accelerate with writelines in some versions of Python, at
    178     # a debuggability cost
--> 179     for chunk in iterable:
    180         fp.write(chunk)
    181 

~/miniconda3/envs/transformersbook/lib/python3.8/json/encoder.py in _iterencode(o, _current_indent_level)
    429             yield from _iterencode_list(o, _current_indent_level)
    430         elif isinstance(o, dict):
--> 431             yield from _iterencode_dict(o, _current_indent_level)
    432         else:
    433             if markers is not None:

~/miniconda3/envs/transformersbook/lib/python3.8/json/encoder.py in _iterencode_dict(dct, _current_indent_level)
    403                 else:
    404                     chunks = _iterencode(value, _current_indent_level)
--> 405                 yield from chunks
    406         if newline_indent is not None:
    407             _current_indent_level -= 1

~/miniconda3/envs/transformersbook/lib/python3.8/json/encoder.py in _iterencode(o, _current_indent_level)
    436                     raise ValueError("Circular reference detected")
    437                 markers[markerid] = o
--> 438             o = _default(o)
    439             yield from _iterencode(o, _current_indent_level)
    440             if markers is not None:

~/miniconda3/envs/transformersbook/lib/python3.8/json/encoder.py in default(self, o)
    177 
    178         """
--> 179         raise TypeError(f'Object of type {o.__class__.__name__} '
    180                         f'is not JSON serializable')
    181 

TypeError: Object of type L is not JSON serializable

Versions

  • ghapi: v0.1.16

Create examples

Here's some examples we could create for ghapi without gh actions - show both Python and CLI (where appropriate) how-tos:

  • Basic tutorial on finding operations, key concepts, etc
  • Equivalent of some gh commands
    • Create an issue
    • Create a gist
    • View a gist
    • Download a release asset
    • Fork and clone a repo
  • Ping a webhook
  • Run a workflow
  • View an issue and reply/close with template response
    • Search for an issue
    • Discuss pagination
    • Show issues/PRs you are assigned to; show those that aren't assigned
  • Add text to a file in a repo
  • Show all added or updated issues and PRs in last hours, except updates from user
    • For a repo; for a user; for an org
    • Show those without a reply for days
  • Plot # forks and clones by day for last month
  • Render markdown
  • fastrelease

Here's some examples we could create for ghapi with gh actions (just show Python how-tos):

  • Check PRs are in an acceptable format, and it not, add a PR reply explaining how to fix, and create a CI fail
  • Multi-OS go build and release (copy over from hugo-mathjax)
  • Use pip cache
  • Lock stale issues/PRs
  • More examples

Remove need to URL-quote some parameters

I just found a gotcha where I was trying to update a github label that had a space in it. Trying to do so was raising a 400 error. I fixed it by doing:

from urllib.parse import quote
quote(label["name"])

It would be helpful to either automate this under-the-hood, or to raise a more helpful error that suggests this might be the issue.

broken links in index.html page

Conflict between `ghapi` GITHUB_TOKEN and local git credentials

Hello,

I started using ghapi in a project last weekened and stored the token in my rc file as the GITHUB_TOKEN variable. This seems to be clashing with my git and gh credentials when working from the CLI. I've found myself havibng to unset the GITHUB_TOKEN variable in order to be able to interact with github like I usually do (pull, push, clone...).

FYI, I set up my git credentials via gh, this is what I get when I run gh auth status:

github.com
  ✓ Logged in to github.com as lc5415 (GITHUB_TOKEN)
  ✓ Git operations for github.com configured to use https protocol.
  ✓ Token: *******************

And this is my .gitconfig:

[credential "https://github.com"]
	helper = !gh auth git-credential
[user]
	email = [email protected]
	name = Luis Chaves

Am I missing something? Thanks for all your work!

Consider using direct imports in the GitHub actions demo

First of all, this tool is amazing, thanks 🚀

I am trying to figure out how to use ghapi inside of a GitHub Action. In reading through this nice example, I found it hard to track down where some functions were because of the * at the top.

As one example, I was looking for the github_token function referenced in the docs. The imports in there only list from ghapi import * whereas that function is actually at ghapi.actions import github_token, so I had to look at the github repository codebase to find it.

It would be helpful for newcomers if direct imports were used over the * syntax so they don't have to go hunting for the location of stuff! (at least, for stodgy old newcomers like me who don't like doing import * 😅)

`HTTP Error 422: Unprocessable Entity` returned for `issues.add_labels` in version `0.1.17`

I'm having issues with the ghapi 0.1.17 version released on May, 24th.

I have a private project where I use ghapi to automatically label PRs and issues based on the path of the files mentioned or modified, and the title of the PR/issue. I am using the following public project to test the workflows and scripts:
https://github.com/jhlegarreta/labelertest

The labeler on the PR/issue title was working fine with ghapi 0.1.16, but it is systematically returning an HTTP Error 422: Unprocessable Entity error for the following call:

api.issues.add_labels(
            accept="application/vnd.github.v3+json",
            issue_number=pull_request.number, labels=title_labels_to_add)

where the issue_number and labels have the appropriate values.

Here is an example of a successful call using 0.1.16:
https://github.com/jhlegarreta/labelertest/runs/2750092407?check_suite_focus=true#step:5:495

And here is an example of a successful call using 0.1.17:
https://github.com/jhlegarreta/labelertest/runs/2750038846?check_suite_focus=true#step:5:505

for the same contents from the viewpoint of the files added in the PRs and their titles.

I have not found any release notes notifying about changes, or an older version of the documentation. According to the latest documentation:
https://docs.github.com/en/rest/reference/issues#add-labels-to-an-issue

I would be providing the expected parameters to the call.

For what is worth, the 0.1.16 was also working when I only had:

api.issues.add_labels(pull_request.number, title_labels_to_add)

but 0.1.17 failed as described, so the parameters seem not to be the problem.

The relevant GitHub workflow file is https://github.com/jhlegarreta/labelertest/blob/main/.github/workflows/pr_title_labeler.yml, and the Python script containing the calls to the ghapi is https://github.com/jhlegarreta/labelertest/blob/main/.github/scripts/pr_title_regex_labeler.py

Would you please be able to tell what I am doing wrong.

Thanks for providing us with this valuable tool and thanks for the support.

Authorization error when running from GitHub Actions (and reading from a diff repository)

I'm trying to set up a GitHub Action that will create a weekly "team sync" issue for our team, and populate that issue with a few open issues that need attention.

I'm using ghapi to read lists of issues from a few other repositories, and then create an issue in the present repository.

When I run this script locally, it works just fine. However, when run in GitHub Actions, I get an Unauthorized error. To try and get around this I've tried to create a Personal Access Token and use it in the script (it is just ACCESS_TOKEN in my action above). But this doesn't seem to fix the problem.

I'm curious if anyone has thoughts as to how this could be fixed! Here's a PR where I am trying t odebug.

cc @hamelsmu in case he has experienced this issue with GHA!

Support GHE

This looks awesome!

My team has lots of code that dumps data from an internal GHE instance, and I'd love to experiment with replacing much of that code with usage of this library instead. However, looking at the source code it seems like this library is currently hard-coded to work only with github.com.

Are there any plans to extend this with support for GHE instances on custom URLs?

Events api doesn't use constructor values

When calling the events api, none of the values passed into the constructor are included

EG given two api objects:

owned_api = GhApi(username='gone', token=github_token)
global_api = GHApi(token=github_token)

I would expect these two calls to be equivalent:

owned_api.list_events()
global_api.list_events(username='gone')

But get them to be the same, I need to pass the username into both list_events calls.

user/ org population for `.search`?

Example

print(
    GhApi(owner="theislab", repo="scanpy")
    .search
    .issues_and_pull_requests('label:"backport needed" type:pr')
    ["total_count"]
)
# 3678

print(
    GhApi(owner="theislab", repo="scanpy")
    .search
    .issues_and_pull_requests('repo:theislab/scanpy label:"backport needed" type:pr')
    ["total_count"]
)
# 20

Description

I was confused by the behaviour of GhApi(owner=..., repo=...).search.issues_and_pull_requests until I realized it did not auto populate the owner and repo fields. This seems unintuitive to me. There are a few alternatives that I think would be a more clear:

  • Populate these fields in search
  • Don't make the search methods available if they aren't going to use the already provided fields.
  • Add some mention of this to the docstring for search

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.