{"id":13442537,"url":"https://github.com/ccqpein/Github-API-CL","last_synced_at":"2025-03-20T14:31:20.193Z","repository":{"id":41538061,"uuid":"280457428","full_name":"ccqpein/Github-API-CL","owner":"ccqpein","description":"Common Lisp Github REST API Client ","archived":false,"fork":false,"pushed_at":"2024-04-28T18:10:22.000Z","size":50,"stargazers_count":15,"open_issues_count":0,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-16T18:03:38.150Z","etag":null,"topics":["common-lisp","github-api","rest-api"],"latest_commit_sha":null,"homepage":"","language":"Common Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ccqpein.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-07-17T15:16:24.000Z","updated_at":"2024-04-28T18:10:26.000Z","dependencies_parsed_at":"2024-10-28T04:00:09.646Z","dependency_job_id":"459e7ad4-f167-4b0e-97a5-6e9c91c798bd","html_url":"https://github.com/ccqpein/Github-API-CL","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ccqpein%2FGithub-API-CL","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ccqpein%2FGithub-API-CL/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ccqpein%2FGithub-API-CL/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ccqpein%2FGithub-API-CL/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ccqpein","download_url":"https://codeload.github.com/ccqpein/Github-API-CL/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244630153,"owners_count":20484325,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["common-lisp","github-api","rest-api"],"created_at":"2024-07-31T03:01:46.989Z","updated_at":"2025-03-20T14:31:19.850Z","avatar_url":"https://github.com/ccqpein.png","language":"Common Lisp","readme":"# README #\n\nThis repo is a simple client for the GitHub Rest V3 API. \n\nI didn't find a full API on one page, so I gathered it from many pages. You might have to put API details into a JSON file yourself. Check out `api.json` to see how.\n\nYou can find the documents [here](https://developer.github.com/v3/).\n\n## How to Use ##\n\nPlease refer to `./example`\n\n### Dependencies ###\n\nI use [yason](https://github.com/phmarek/yason) for json parser, [dexador](https://github.com/fukamachi/dexador) for http client.\n\n### Install ###\n\nThis repo has already been deployed to quicklisp. You can simply use `(ql:quickload \"github-api-cl\")` to install it.\n\n### Read api.json file ###\n\nSuppose we have `api.json` looks like:\n\n``` json\n{\n    \"repositories\": {\n        \"repositories\": {\n          \"List repositories for a user\": {\n                \"parameters\": [\n                  [\"type\", \"string\"],\n                  [\"sort\",\"string\"],\n                  [\"direction\",\"string\"]\n                ],\n                \"api\": \"GET /users/:username/repos\",\n                \"link\": \"https://developer.github.com/v3/repos/#list-repositories-for-a-user\"\n            }\n        }\n    }\n}\n```\n**Examples:**\n\n```lisp\n;; load system first\n(ql:quickload \"github-api-cl\")\n\n;; read api.json in this repo, path var is github-api-doc::*api-json-file-path*\n(github-api-doc:read-api-json) ;; =\u003e return a hashtable of this json\n\n;; OR you can give path specially\n(github-api-doc:read-api-json #P\"/path/to/api.json\")\n```\n\n### Generate api instance ###\n\nAfter read api.json file, you can generate api instance by using `github-api-doc:make-api-doc-from-json`\n\n**Examples:**\n\n``` lisp\n;; read api.json\n(defparameter *api-docs* (github-api-doc:read-api-json))\n\n;; \u0026rest arguments are the steps of reading json\n(defparameter *api-doc* (github-api-doc:make-api-doc-from-json *api-docs* \"repositories\" \"repositories\" \"List repositories for a user\"))\n\n;; Get api-doc: \n;;api-doc object:\n;;  api: GET /users/:username/repos,\n;;  http method: GET,\n;;  slots: (:username),\n;;  fmt-control: (/users/~a/repos)\n;;  parameters: ((type string) (sort string) (direction string))\n\n;; OR, you can make instance manually\n(setf *api-doc* (make-instance 'api-doc\n                               :api \"GET /users/:username/repos\"\n                               :parameters '((\"type\" \"string\") \n                                             (\"sort\" \"string\") \n                                             (\"direction\" \"string\")))\n```\n\nThe `api.json` file is very flexible as it's just a JSON file. You don't have to stick to the GitHub API structure if you don't want to. The only part that `github-api-cl` is concerned with is this section:\n\n```json\n{\n  \"parameters\": [\n    [\"type\", \"string\"],\n    [\"sort\",\"string\"],\n    [\"direction\",\"string\"]\n  ],\n  \"api\": \"GET /users/:username/repos\",\n}\n```\n\nYou can read this json file and `(github-api-doc:make-api-doc-from-json (github-api-doc:read-api-json #P\"this-simple-api.json\"))`\n\n### Make github-api client ###\n\nMaking github-api client:\n\n```lisp\n;; make instance of api-client\n(defparameter *client-without-token* (make-instance 'github-client:api-client))\n\n;; if you have token for github rest api call, make like this\n(defparameter *client-with-token* (make-instance 'github-client:api-client :token \"123\"))\n```\n\n### Call api ###\n\nWith client and api, now we can call api in our code:\n\n```lisp\n;; call api with client and api we made before\n(github-client:github-api-call *client-without-token*\n                               *api-doc*)\n\n;;; REPL will ask you to input `:username`, `type`, `sort`, and `direction`\n;;; Then, it will return the dex:http-response, you can find this MULTIPLE-VALUEs \n;;; return format in https://github.com/fukamachi/dexador#following-redirects-get-or-head\n\n;; call POST method api with additional :content keyword\n(github-client:github-api-call *client-without-token*\n                               *api-doc*\n                               :headers '((header0 . value0) (header1 . value1))\n                               :content \"this argument pass to dexador directly\")\n```\n\n`github-api-call` will call api with the default headers `'((\"Accept\" . \"application/vnd.github+json\"))`. Any other headers pass to `:headers` will been added `(\"Accept\" . \"application/vnd.github+json\")`.\n\nFrom now, `github-api-cl`'s job is done, left all http response back to you, you can do whatever you want.\n\nWait, if you do not want REPL ask you to input every slots and parameters:\n\n```lisp\n(github-client:github-api-call *client-without-token*\n                               *api-doc*\n                               :username \"lisp\"\n                               :type \"public\"\n                               :direction \"test\"\n                               :neither-slots-nor-parameter 1) ;; last keyword is redundant\n```\n\nWith keywords input, REPL won't ask you anything, just call `https://api.github.com/users/lisp/repos?type=\\\"public\\\"\u0026direction=\\\"test\\\"`. \n\nAs example shows, `:username` fills **api slot**, `:type` \u0026 `:direction`  are used for **parameters**. Meanwhile `:neither-slots-nor-parameter` doesn't play any role in this API.\n\nFor `POST` method api, `:content` is the keyword for add the content. It pass to `:content` keyword of `dexador`'s `POST` [method](https://github.com/fukamachi/dexador#function-post). Check `./example/github-gist-cl` to find how to create the gist.\n\n### Authorization ###\n\n**Token, user-name, and passd**\n\nWhen you need authorization, you can include `:token`, `:user-name` and `:passd` in `github-client:github-api-call` as keywords. \n\nHere's how it works:\n\n+ If you input `:token`, will use token you provided\n+ If no `:token` given but client has token already, it will use token stored in client\n+ If neither `:token` nor client's token is given, but has `:passd` keyword, will use `:user-name` \u0026 `passd` as authorization. (I just assume you give `:user-name` too, when you give `:passd`)\n","funding_links":[],"categories":["Common Lisp"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fccqpein%2FGithub-API-CL","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fccqpein%2FGithub-API-CL","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fccqpein%2FGithub-API-CL/lists"}