{"id":55443,"date":"2020-12-18T09:00:59","date_gmt":"2020-12-18T17:00:59","guid":{"rendered":"https:\/\/github.blog\/?p=55443"},"modified":"2021-06-24T16:31:45","modified_gmt":"2021-06-24T23:31:45","slug":"learn-about-ghapi-a-new-third-party-python-client-for-the-github-api","status":"publish","type":"post","link":"https:\/\/github.blog\/developer-skills\/programming-languages-and-frameworks\/learn-about-ghapi-a-new-third-party-python-client-for-the-github-api\/","title":{"rendered":"Learn about ghapi, a new third-party Python client for the GitHub API"},"content":{"rendered":"<p><b>Guest article by <\/b><a href=\"https:\/\/www.fast.ai\/about\/#jeremy\"><b>Jeremy Howard<\/b><\/a><b>, founding researcher at fast.ai and lead developer of ghapi and <\/b><a href=\"https:\/\/hamel.dev\/\"><b>Hamel Husain<\/b><\/a><b>, Staff Machine Learning Engineer at GitHub and contributor to ghapi.<\/b><\/p>\n<p><b><i>Summary<\/i><\/b><i>: Today fast.ai is releasing <\/i><a href=\"https:\/\/ghapi.fast.ai\/\"><i>ghapi<\/i><\/a><i>, the first Python library and CLI to provide complete, idiomatic access to the entire GitHub API, using a consistent interface. It includes tab-completion, integrated documentation, and many little touches to make your life easier, such as automatic pagination of responses, automatic management of all required headers, query strings, route parameters and post data, and much more. hi<\/i><\/p>\n<h2 id=\"the-github-api\"><a class=\"heading-link\" href=\"#the-github-api\">The GitHub API<span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h2>\n<p>Like many developers, I spend a lot of time on GitHub. I maintain dozens of repositories and respond to issues and pull requests every day. I use GitHub Actions to automate testing, build software, triage issues, and even to power whole projects, such as <a href=\"https:\/\/fastpages.fast.ai\/fastpages\/jupyter\/2020\/02\/21\/introducing-fastpages.html\">fastpages<\/a>.<\/p>\n<p>That said, there&#8217;s lots of things I want to automate or customize for my workflows as a maintainer. For instance, I&#8217;d love to be able to see at a glance every issue or PR that someone has replied to or added since I last checked. I want to be able to type a single command to close a bunch of issues with a template response. I want to be able to manage GitHub Actions workflows across all of my repositories with a single command. In general, I prefer using the command line for many things, so just about anything I do through the github.com web interface, I&#8217;d like to be able to do at the terminal.<\/p>\n<p>Thankfully, GitHub provides an extensive <a href=\"https:\/\/docs.github.com\/en\/free-pro-team@latest\/rest\">API<\/a> that provides programming access to nearly anything that you can do through the GitHub web interface or through the Git client. Furthermore, <a href=\"https:\/\/github.com\/features\/actions\">GitHub Actions<\/a> allows code to respond to any GitHub event (such as a new pull request coming in or a software release being published). Thanks to the GitHub API, you can do things like:<\/p>\n<ul>\n<li>Open, list, comment on, or modify <a href=\"https:\/\/guides.github.com\/features\/issues\/\">issues<\/a> or <a href=\"https:\/\/docs.github.com\/en\/free-pro-team@latest\/github\/collaborating-with-issues-and-pull-requests\/about-pull-requests\">pull requests<\/a><\/li>\n<li>Create, list, or modify <a href=\"https:\/\/git-scm.com\/book\/en\/v2\/Git-Basics-Tagging\">Git tags<\/a> or <a href=\"https:\/\/docs.github.com\/en\/free-pro-team@latest\/github\/administering-a-repository\/managing-releases-in-a-repository\">GitHub releases<\/a>, including uploading release assets<\/li>\n<li>Configure and run <a href=\"https:\/\/github.com\/features\/actions\">GitHub Actions<\/a> and <a href=\"https:\/\/docs.github.com\/en\/free-pro-team@latest\/developers\/webhooks-and-events\/about-webhooks\">webhooks<\/a><\/li>\n<li>Set up GitHub <a href=\"https:\/\/docs.github.com\/en\/free-pro-team@latest\/rest\/reference\/users\">users<\/a> and <a href=\"https:\/\/docs.github.com\/en\/free-pro-team@latest\/github\/setting-up-and-managing-organizations-and-teams\/about-organizations\">organizations<\/a><\/li>\n<li>Manage your <a href=\"https:\/\/docs.github.com\/en\/free-pro-team@latest\/rest\/guides\/delivering-deployments\">deployments<\/a><\/li>\n<li>&#8230;and so much more<\/li>\n<\/ul>\n<p>Unfortunately, fully utilizing these features requires familiarity with multiple languages and technologies and raises some challenges:<\/p>\n<ul>\n<li>The GitHub API is accessed through HTTP. Accessing HTTP APIs directly is clunky and requires careful study of every API endpoint. Debugging is difficult, because errors raise obscure HTTP status codes. There are <a href=\"https:\/\/developer.github.com\/v3\/libraries\/\">software libraries<\/a> that make this easier, but each library only handles a subset of the full API, and each one has a whole new interface to learn. Due to the size of the API, libraries generally do not provide full coverage and documentation for all API endpoints.<\/li>\n<li>GitHub provides <a href=\"https:\/\/github.blog\/2020-02-12-supercharge-your-command-line-experience-github-cli-is-now-in-beta\/\">gh<\/a>, a command line tool that integrates with GitHub, including access to some API functionality. However, this API only covers a small subset of the full API&#8217;s functionality.<\/li>\n<li>Local development and building extensions to GitHub Actions requires using TypeScript, which many developers aren&#8217;t familiar with. Furthermore, Actions are run in a special environment, which can slow iteration and debug cycles.<\/li>\n<\/ul>\n<h2 id=\"ghapi\"><a class=\"heading-link\" href=\"#ghapi\">ghapi<span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h2>\n<p>We built <a href=\"https:\/\/ghapi.fast.ai\/\">ghapi<\/a>, a Python library and CLI tool, to resolve these challenges. We spent a lot of time using ghapi for our own projects to ensure that the developer experience is consistent, intuitive, and Pythonic. We even used it to help some other developers with their projects, including using it for GitHub CEO, Nat Friedman&#8217;s, <a href=\"https:\/\/github.com\/nat\/ghtop\/\">ghtop<\/a> project as part of a code overhaul that Nat described as a \u201c<a href=\"https:\/\/github.com\/nat\/ghtop\/pull\/13\">tour de force<\/a>.\u201d The \u201csecret sauce\u201d behind ghapi is GitHub\u2019s new OpenAPI specification, a machine-readable catalog of every part of the GitHub API. We describe this in detail below. But first, let\u2019s see what it looks like to actually use ghapi!<\/p>\n<p>We\u2019ll start by seeing ghapi in action in Python using Jupyter Notebook. You can use any development environment you like. Jupyter is a particularly good choice, because ghapi uses its rich display functionality to make life easier for you.<\/p>\n<p>Let\u2019s say you want to write code to create an issue (for instance, perhaps you are writing something to create an issue whenever continuous integration fails). In order to find the API operation you need, you can search ghapi\u2019s <a href=\"https:\/\/ghapi.fast.ai\/fullapi.html\">full, categorized API reference<\/a>. In the <a href=\"https:\/\/ghapi.fast.ai\/fullapi.html#issues\">issues<\/a> section, we find <a href=\"https:\/\/docs.github.com\/en\/free-pro-team@latest\/rest\/reference\/issues#create-an-issue\">issues.create<\/a>, which shows how to call the method. Alternatively, you can use ghapi\u2019s tab completion to look through the available operations and groups, and even get a link straight to the official GitHub API documentation, as shown in this example:<\/p>\n<div style=\"width: 1400px;\" class=\"wp-video\"><video class=\"wp-video-shortcode\" id=\"video-55443-1\" width=\"1400\" height=\"360\" loop autoplay preload=\"metadata\" controls=\"controls\"><source type=\"video\/mp4\" src=\"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/notebook-comp.mp4#t=0.001?_=1\" \/><a href=\"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/notebook-comp.mp4#t=0.001\">https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/notebook-comp.mp4#t=0.001<\/a><\/video><\/div>\n<p>&nbsp;<\/p>\n<p>You can also type the name of a group, to show all operations in that group, along with parameter details and a link to the documentation:<\/p>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-55448\" src=\"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/1.png?resize=1024%2C554\" alt=\"\" width=\"1024\" height=\"554\" srcset=\"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/1.png?w=1256 1256w, https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/1.png?w=300 300w, https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/1.png?w=768 768w, https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/1.png?w=1024 1024w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/p>\n<p>GitHub\u2019s API generally provides responses as JSON, which isn\u2019t that easy to read at a glance. ghapi formats all JSON responses automatically in a human readable format using bulleted lists. For instance, displaying an issue:<\/p>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-55449\" src=\"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/2.png?resize=1024%2C588\" alt=\"\" width=\"1024\" height=\"588\" srcset=\"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/2.png?w=1264 1264w, https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/2.png?w=300 300w, https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/2.png?w=768 768w, https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/2.png?w=1024 1024w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/p>\n<p>ghapi reduces boilerplate for developers. For instance, arguments are inserted dynamically as needed, if you provide them at instantiation (such as the repository name and owner name), and custom headers (such as for preview endpoints) are handled automatically.<\/p>\n<h3 id=\"integrated-methods\"><a class=\"heading-link\" href=\"#integrated-methods\">Integrated methods<span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h3>\n<p>ghapi doesn\u2019t just provide direct access to the GitHub API, it also integrates a lot of functionality up into Pythonic wrappers.<\/p>\n<p>For instance, many GitHub API calls are paginated, which normally requires that developers manually figure out how many pages to loop through and call a different REST endpoint for each page. In ghapi, pagination is always available as iterators, so you can just use a for loop, list comprehension or whatever approach you like for retrieving each page. ghapi allows you to easily turn any paged result into an iterator with the <a href=\"https:\/\/ghapi.fast.ai\/page.html#paged\">paged<\/a> function. For instance, to get a list of all the repositories in the GitHub organization:<\/p>\n<div align=\"center\"><img data-recalc-dims=\"1\" decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-55450\" src=\"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/3.png?w=420\" alt=\"\"  srcset=\"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/3.png?w=911 911w, https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/3.png?w=300 300w, https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/3.png?w=768 768w\" sizes=\"auto, (max-width: 911px) 100vw, 911px\" \/><\/div>\n<p>Better still, ghapi even lets you grab all available pages at once in parallel and concatenates the results for you. You can read more about this functionality <a href=\"https:\/\/ghapi.fast.ai\/page.html#Getting-pages-in-parallel\">here<\/a>.<\/p>\n<p>This parallel pages functionality is then leveraged in ghapi.event, a module that provides convenient access to the <a href=\"https:\/\/docs.github.com\/en\/free-pro-team@latest\/rest\/reference\/activity\">Events API<\/a>. Normally, using this API requires understanding the special headers that track quota use, using multiple different REST endpoints depending on what events you need, handling multi-page requests, avoiding repeated events, and so forth. ghapi.event handles all that for you, with the fetch_events generator, which provides a continuous stream of deduplicated events, filtered (optionally) to remove bot activity, along with additional filters chosen by the developer.<\/p>\n<p>Many features of the GitHub API are wrapped into convenient integrated methods for you. For instance, editing a file directly in GitHub can be done with a single call:<\/p>\n<div align=\"center\"><img data-recalc-dims=\"1\" decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-55451\" src=\"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/4.png?w=310\" alt=\"\"  srcset=\"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/4.png?w=649 649w, https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/4.png?w=300 300w\" sizes=\"auto, (max-width: 649px) 100vw, 649px\" \/><\/div>\n<h3 id=\"the-cli\"><a class=\"heading-link\" href=\"#the-cli\">The CLI<span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h3>\n<p>ghapi also offers a CLI, which offers the same features as the python interface demonstrated above. Exploration of endpoints through tab completion is available in the CLI as well. Here\u2019s a demonstration of this at work:<\/p>\n<div style=\"width: 1920px;\" class=\"wp-video\"><video class=\"wp-video-shortcode\" id=\"video-55443-2\" width=\"1920\" height=\"360\" loop autoplay preload=\"metadata\" controls=\"controls\"><source type=\"video\/mp4\" src=\"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/terminal-comp.mp4#t=0.001?_=2\" \/><a href=\"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/terminal-comp.mp4#t=0.001\">https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/terminal-comp.mp4#t=0.001<\/a><\/video><\/div>\n<p>&nbsp;<\/p>\n<p>The CLI uses exactly the same operation and parameter names as the Python API, so you can move between the two easily. The full API documentation is available using the &#8211;help flag, for instance:<\/p>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-55453\" src=\"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/5.png?resize=1024%2C105\" alt=\"\" width=\"1024\" height=\"105\" srcset=\"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/5.png?w=1371 1371w, https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/5.png?w=300 300w, https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/5.png?w=768 768w, https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/5.png?w=1024 1024w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/p>\n<p>For more information on how to use and configure the ghapi CLI, see <a href=\"https:\/\/ghapi.fast.ai\/cli.html\">these docs.<\/a><\/p>\n<h2 id=\"github-actions\"><a class=\"heading-link\" href=\"#github-actions\">GitHub Actions<span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h2>\n<p><a href=\"https:\/\/docs.github.com\/en\/free-pro-team@latest\/actions\">GitHub Actions<\/a> help you automate tasks in your software development workflow. As the docs explain:<\/p>\n<p>\u201c<i>GitHub Actions are event driven, meaning that you can run a series of commands after a specified event has occurred. For example, every time someone creates a pull request for a repository, you can automatically run a command that executes a software testing script.<\/i>\u201d<\/p>\n<p>They are a powerful system for automating many software development processes, and open source projects get unlimited compute hours for free! However, workflows can be difficult to create and debug, because:<\/p>\n<ul>\n<li>They run in a custom environment that can be difficult to replicate locally.<\/li>\n<li>Testing workflows often involve creating real events, which can take minutes before your updated workflow is run and you can see the results. This often leads to slow debug and development cycles.<\/li>\n<li>It can be\u00a0 difficult to develop interactively and iteratively.<\/li>\n<li>The canonical way to define a workflow is to write YAML, complimented by special syntax specific to the Actions runtime. However, developers may want to use the full expressiveness of programming languages they are comfortable with instead.<\/li>\n<li>Building full-featured extensions requires using TypeScript, which is not a language that many developers are accustomed to using for scripting, sysadmin, and continuous integration tasks.<\/li>\n<\/ul>\n<p>However, with ghapi you can write your workflows entirely in Python, doing nearly all your development on your local machine. For example, if you want to create a workflow that automatically replies to all pull requests with a comment that says \u201cthank you,\u201d,you would first use the following command to create the new workflow:<\/p>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/6.png?w=600\" alt=\"\"  \/><\/p>\n<p>That will create a Python file for you, which you can then edit to add your script, for instance:<\/p>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-55455\" src=\"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/7.png?resize=1024%2C180\" alt=\"\" width=\"1024\" height=\"180\" srcset=\"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/7.png?w=1210 1210w, https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/7.png?w=300 300w, https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/7.png?w=768 768w, https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/7.png?w=1024 1024w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/p>\n<p>That\u2019s it! You can use the full power of the GitHub API and Python to do whatever you want, in a way that minimizes the use of syntax specific to GitHub Actions. With example payloads available during development for all event types, you can test your scripts on your own machine. You can read more about this functionality <a href=\"https:\/\/ghapi.fast.ai\/tutorial_actions.html\">here<\/a>.<\/p>\n<h2 id=\"openapi\"><a class=\"heading-link\" href=\"#openapi\">OpenAPI<span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h2>\n<p>The key to ghapi\u2019s power and scope is the <a href=\"https:\/\/github.blog\/2020-07-27-introducing-githubs-openapi-description\/\">OpenAPI specification<\/a> of the GitHub API. OpenAPI provides a way to provide a complete machine-readable specification of their APIs, which can then be used to automate the creation of libraries that access those APIs. Creating a GitHub OpenAPI spec, fully and precisely documenting a 12-year-old API covering thousands of features, is a huge task. Having spent a lot of time studying this spec, I can see that a great deal of care and thought has been put into its design. I have not come across a single missing parameter or a single error. The operations are sensibly and consistently named, and the whole API is carefully categorized.<\/p>\n<p>ghapi is one of the first GitHub OpenAPI libraries for any language, and it fully utilizes Python&#8217;s dynamic features to do things that no other REST API library we&#8217;ve seen can do. For instance, most OpenAPI libraries use code generation to create separate methods and data types for each part of a spec. This is the approach used, for instance, by the experimental <a href=\"https:\/\/github.com\/WillAbides\/octo-go\/\">octo-go<\/a> client. Whilst it gets the job done, code generation like this tends to be very verbose. For instance, the octo-go wrapper for the methods from just one group of operations (the repo group), is nearly <a href=\"https:\/\/github.com\/WillAbides\/octo-go\/blob\/main\/requests\/repos\/repos_gen.go\">20,000 lines of code<\/a>! In a static language like Go, there isn&#8217;t much choice, since the compiler has to be told about every data type and every function.<\/p>\n<p>The entire ghapi package on the other hand, weighs in at around 40kB! The trick is that we created a Python module with the key information from the spec and then wrote classes that dynamically create methods by referencing that module. There&#8217;s a lot of neat tricks involved in making this work, which we&#8217;ll explain in detail in a future post.<\/p>\n<h4 id=\"credits\"><a class=\"heading-link\" href=\"#credits\">Credits<span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h4>\n<p>Thanks to <a href=\"https:\/\/www.fast.ai\/about\/#rachel\">Rachel Thomas<\/a> for help in writing this post.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Learn about ghapi, a third-party Python library and CLI client for the GitHub API.  It includes tab-completion, integrated documentation and automatic pagination of responses.  ghapi automatically manages required headers, query strings, route parameters, post data, and much more.<\/p>\n","protected":false},"author":1617,"featured_media":55447,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_gh_post_show_toc":"","_gh_post_is_no_robots":"","_gh_post_is_featured":"","_gh_post_is_excluded":"","_gh_post_is_unlisted":"","_gh_post_related_link_1":"","_gh_post_related_link_2":"","_gh_post_related_link_3":"","_gh_post_sq_img":"","_gh_post_sq_img_id":"","_gh_post_cta_title":"","_gh_post_cta_text":"","_gh_post_cta_link":"","_gh_post_cta_button":"","_gh_post_recirc_hide":"","_gh_post_recirc_col_1":"","_gh_post_recirc_col_2":"","_gh_post_recirc_col_3":"","_gh_post_recirc_col_4":"","_featured_video":"","_gh_post_additional_query_params":"","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"{title}\n\n{excerpt}\n\n{url}","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"_wpas_customize_per_network":false,"jetpack_post_was_ever_published":false,"_links_to":"","_links_to_target":""},"categories":[3298,3304],"tags":[],"coauthors":[],"class_list":["post-55443","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-developer-skills","category-programming-languages-and-frameworks"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v28.4 (Yoast SEO v28.4) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Learn about ghapi, a new third-party Python client for the GitHub API - The GitHub Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/github.blog\/developer-skills\/programming-languages-and-frameworks\/learn-about-ghapi-a-new-third-party-python-client-for-the-github-api\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Learn about ghapi, a new third-party Python client for the GitHub API\" \/>\n<meta property=\"og:description\" content=\"Learn about ghapi, a third-party Python library and CLI client for the GitHub API. It includes tab-completion, integrated documentation and automatic pagination of responses. ghapi automatically manages required headers, query strings, route parameters, post data, and much more.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/github.blog\/developer-skills\/programming-languages-and-frameworks\/learn-about-ghapi-a-new-third-party-python-client-for-the-github-api\/\" \/>\n<meta property=\"og:site_name\" content=\"The GitHub Blog\" \/>\n<meta property=\"article:published_time\" content=\"2020-12-18T17:00:59+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-06-24T23:31:45+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/social-card.png?fit=1200%2C630\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Hamel Husain\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/social-card.png?fit=1200%2C630\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Hamel Husain\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/github.blog\\\/developer-skills\\\/programming-languages-and-frameworks\\\/learn-about-ghapi-a-new-third-party-python-client-for-the-github-api\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/github.blog\\\/developer-skills\\\/programming-languages-and-frameworks\\\/learn-about-ghapi-a-new-third-party-python-client-for-the-github-api\\\/\"},\"author\":{\"name\":\"Hamel Husain\",\"@id\":\"https:\\\/\\\/github.blog\\\/#\\\/schema\\\/person\\\/d76319a9b865a8143ac6c5f20d95c568\"},\"headline\":\"Learn about ghapi, a new third-party Python client for the GitHub API\",\"datePublished\":\"2020-12-18T17:00:59+00:00\",\"dateModified\":\"2021-06-24T23:31:45+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/github.blog\\\/developer-skills\\\/programming-languages-and-frameworks\\\/learn-about-ghapi-a-new-third-party-python-client-for-the-github-api\\\/\"},\"wordCount\":1926,\"image\":{\"@id\":\"https:\\\/\\\/github.blog\\\/developer-skills\\\/programming-languages-and-frameworks\\\/learn-about-ghapi-a-new-third-party-python-client-for-the-github-api\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/github.blog\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/social-card.png?fit=1200%2C630\",\"articleSection\":[\"Developer skills\",\"Programming languages &amp; frameworks\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/github.blog\\\/developer-skills\\\/programming-languages-and-frameworks\\\/learn-about-ghapi-a-new-third-party-python-client-for-the-github-api\\\/\",\"url\":\"https:\\\/\\\/github.blog\\\/developer-skills\\\/programming-languages-and-frameworks\\\/learn-about-ghapi-a-new-third-party-python-client-for-the-github-api\\\/\",\"name\":\"Learn about ghapi, a new third-party Python client for the GitHub API - The GitHub Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/github.blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/github.blog\\\/developer-skills\\\/programming-languages-and-frameworks\\\/learn-about-ghapi-a-new-third-party-python-client-for-the-github-api\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/github.blog\\\/developer-skills\\\/programming-languages-and-frameworks\\\/learn-about-ghapi-a-new-third-party-python-client-for-the-github-api\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/github.blog\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/social-card.png?fit=1200%2C630\",\"datePublished\":\"2020-12-18T17:00:59+00:00\",\"dateModified\":\"2021-06-24T23:31:45+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/github.blog\\\/#\\\/schema\\\/person\\\/d76319a9b865a8143ac6c5f20d95c568\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/github.blog\\\/developer-skills\\\/programming-languages-and-frameworks\\\/learn-about-ghapi-a-new-third-party-python-client-for-the-github-api\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/github.blog\\\/developer-skills\\\/programming-languages-and-frameworks\\\/learn-about-ghapi-a-new-third-party-python-client-for-the-github-api\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/github.blog\\\/developer-skills\\\/programming-languages-and-frameworks\\\/learn-about-ghapi-a-new-third-party-python-client-for-the-github-api\\\/#primaryimage\",\"url\":\"https:\\\/\\\/github.blog\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/social-card.png?fit=1200%2C630\",\"contentUrl\":\"https:\\\/\\\/github.blog\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/social-card.png?fit=1200%2C630\",\"width\":1200,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/github.blog\\\/developer-skills\\\/programming-languages-and-frameworks\\\/learn-about-ghapi-a-new-third-party-python-client-for-the-github-api\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/github.blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Developer skills\",\"item\":\"https:\\\/\\\/github.blog\\\/developer-skills\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Programming languages &amp; frameworks\",\"item\":\"https:\\\/\\\/github.blog\\\/developer-skills\\\/programming-languages-and-frameworks\\\/\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Learn about ghapi, a new third-party Python client for the GitHub API\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/github.blog\\\/#website\",\"url\":\"https:\\\/\\\/github.blog\\\/\",\"name\":\"The GitHub Blog\",\"description\":\"Updates, ideas, and inspiration from GitHub to help developers build and design software.\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/github.blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/github.blog\\\/#\\\/schema\\\/person\\\/d76319a9b865a8143ac6c5f20d95c568\",\"name\":\"Hamel Husain\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/8559ff90c3d3634c9323fe6712034231d4bc474d7c5e8e6b9ccb49482c892459?s=96&d=mm&r=g864feb2bdaca5e9252640651cf5a7686\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/8559ff90c3d3634c9323fe6712034231d4bc474d7c5e8e6b9ccb49482c892459?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/8559ff90c3d3634c9323fe6712034231d4bc474d7c5e8e6b9ccb49482c892459?s=96&d=mm&r=g\",\"caption\":\"Hamel Husain\"},\"sameAs\":[\"http:\\\/\\\/hamel.io\"],\"url\":\"https:\\\/\\\/github.blog\\\/author\\\/hamelsmu\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Learn about ghapi, a new third-party Python client for the GitHub API - The GitHub Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/github.blog\/developer-skills\/programming-languages-and-frameworks\/learn-about-ghapi-a-new-third-party-python-client-for-the-github-api\/","og_locale":"en_US","og_type":"article","og_title":"Learn about ghapi, a new third-party Python client for the GitHub API","og_description":"Learn about ghapi, a third-party Python library and CLI client for the GitHub API. It includes tab-completion, integrated documentation and automatic pagination of responses. ghapi automatically manages required headers, query strings, route parameters, post data, and much more.","og_url":"https:\/\/github.blog\/developer-skills\/programming-languages-and-frameworks\/learn-about-ghapi-a-new-third-party-python-client-for-the-github-api\/","og_site_name":"The GitHub Blog","article_published_time":"2020-12-18T17:00:59+00:00","article_modified_time":"2021-06-24T23:31:45+00:00","og_image":[{"width":1200,"height":630,"url":"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/social-card.png?fit=1200%2C630","type":"image\/png"}],"author":"Hamel Husain","twitter_card":"summary_large_image","twitter_image":"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/social-card.png?fit=1200%2C630","twitter_misc":{"Written by":"Hamel Husain","Est. reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/github.blog\/developer-skills\/programming-languages-and-frameworks\/learn-about-ghapi-a-new-third-party-python-client-for-the-github-api\/#article","isPartOf":{"@id":"https:\/\/github.blog\/developer-skills\/programming-languages-and-frameworks\/learn-about-ghapi-a-new-third-party-python-client-for-the-github-api\/"},"author":{"name":"Hamel Husain","@id":"https:\/\/github.blog\/#\/schema\/person\/d76319a9b865a8143ac6c5f20d95c568"},"headline":"Learn about ghapi, a new third-party Python client for the GitHub API","datePublished":"2020-12-18T17:00:59+00:00","dateModified":"2021-06-24T23:31:45+00:00","mainEntityOfPage":{"@id":"https:\/\/github.blog\/developer-skills\/programming-languages-and-frameworks\/learn-about-ghapi-a-new-third-party-python-client-for-the-github-api\/"},"wordCount":1926,"image":{"@id":"https:\/\/github.blog\/developer-skills\/programming-languages-and-frameworks\/learn-about-ghapi-a-new-third-party-python-client-for-the-github-api\/#primaryimage"},"thumbnailUrl":"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/social-card.png?fit=1200%2C630","articleSection":["Developer skills","Programming languages &amp; frameworks"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/github.blog\/developer-skills\/programming-languages-and-frameworks\/learn-about-ghapi-a-new-third-party-python-client-for-the-github-api\/","url":"https:\/\/github.blog\/developer-skills\/programming-languages-and-frameworks\/learn-about-ghapi-a-new-third-party-python-client-for-the-github-api\/","name":"Learn about ghapi, a new third-party Python client for the GitHub API - The GitHub Blog","isPartOf":{"@id":"https:\/\/github.blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/github.blog\/developer-skills\/programming-languages-and-frameworks\/learn-about-ghapi-a-new-third-party-python-client-for-the-github-api\/#primaryimage"},"image":{"@id":"https:\/\/github.blog\/developer-skills\/programming-languages-and-frameworks\/learn-about-ghapi-a-new-third-party-python-client-for-the-github-api\/#primaryimage"},"thumbnailUrl":"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/social-card.png?fit=1200%2C630","datePublished":"2020-12-18T17:00:59+00:00","dateModified":"2021-06-24T23:31:45+00:00","author":{"@id":"https:\/\/github.blog\/#\/schema\/person\/d76319a9b865a8143ac6c5f20d95c568"},"breadcrumb":{"@id":"https:\/\/github.blog\/developer-skills\/programming-languages-and-frameworks\/learn-about-ghapi-a-new-third-party-python-client-for-the-github-api\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/github.blog\/developer-skills\/programming-languages-and-frameworks\/learn-about-ghapi-a-new-third-party-python-client-for-the-github-api\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/github.blog\/developer-skills\/programming-languages-and-frameworks\/learn-about-ghapi-a-new-third-party-python-client-for-the-github-api\/#primaryimage","url":"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/social-card.png?fit=1200%2C630","contentUrl":"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/social-card.png?fit=1200%2C630","width":1200,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/github.blog\/developer-skills\/programming-languages-and-frameworks\/learn-about-ghapi-a-new-third-party-python-client-for-the-github-api\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/github.blog\/"},{"@type":"ListItem","position":2,"name":"Developer skills","item":"https:\/\/github.blog\/developer-skills\/"},{"@type":"ListItem","position":3,"name":"Programming languages &amp; frameworks","item":"https:\/\/github.blog\/developer-skills\/programming-languages-and-frameworks\/"},{"@type":"ListItem","position":4,"name":"Learn about ghapi, a new third-party Python client for the GitHub API"}]},{"@type":"WebSite","@id":"https:\/\/github.blog\/#website","url":"https:\/\/github.blog\/","name":"The GitHub Blog","description":"Updates, ideas, and inspiration from GitHub to help developers build and design software.","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/github.blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/github.blog\/#\/schema\/person\/d76319a9b865a8143ac6c5f20d95c568","name":"Hamel Husain","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/8559ff90c3d3634c9323fe6712034231d4bc474d7c5e8e6b9ccb49482c892459?s=96&d=mm&r=g864feb2bdaca5e9252640651cf5a7686","url":"https:\/\/secure.gravatar.com\/avatar\/8559ff90c3d3634c9323fe6712034231d4bc474d7c5e8e6b9ccb49482c892459?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/8559ff90c3d3634c9323fe6712034231d4bc474d7c5e8e6b9ccb49482c892459?s=96&d=mm&r=g","caption":"Hamel Husain"},"sameAs":["http:\/\/hamel.io"],"url":"https:\/\/github.blog\/author\/hamelsmu\/"}]}},"jetpack_publicize_connections":[],"jetpack_shortlink":"https:\/\/wp.me\/pamS32-eqf","jetpack_sharing_enabled":true,"jetpack_featured_media_url":"https:\/\/github.blog\/wp-content\/uploads\/2020\/12\/social-card.png?fit=1200%2C630","_links":{"self":[{"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/posts\/55443","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/users\/1617"}],"replies":[{"embeddable":true,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/comments?post=55443"}],"version-history":[{"count":55,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/posts\/55443\/revisions"}],"predecessor-version":[{"id":55537,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/posts\/55443\/revisions\/55537"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/media\/55447"}],"wp:attachment":[{"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/media?parent=55443"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/categories?post=55443"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/tags?post=55443"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/coauthors?post=55443"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}