{"id":13509636,"url":"https://github.com/edgurgel/tentacat","last_synced_at":"2025-05-14T04:03:08.796Z","repository":{"id":8945535,"uuid":"10680522","full_name":"edgurgel/tentacat","owner":"edgurgel","description":"Simple Elixir wrapper for the GitHub API","archived":false,"fork":false,"pushed_at":"2024-12-20T00:09:32.000Z","size":692,"stargazers_count":452,"open_issues_count":20,"forks_count":156,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-05-12T08:06:56.006Z","etag":null,"topics":["api","elixir","github","http"],"latest_commit_sha":null,"homepage":"https://hexdocs.pm/tentacat","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/edgurgel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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":"2013-06-14T02:40:28.000Z","updated_at":"2025-04-17T06:02:38.000Z","dependencies_parsed_at":"2022-08-07T05:00:20.760Z","dependency_job_id":"b7536ea5-f1a9-4234-ad20-6c31938db0fd","html_url":"https://github.com/edgurgel/tentacat","commit_stats":{"total_commits":400,"total_committers":86,"mean_commits":4.651162790697675,"dds":0.7150000000000001,"last_synced_commit":"52a1c3cf82d020c566b08b1bb2ebef743db55e89"},"previous_names":[],"tags_count":38,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edgurgel%2Ftentacat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edgurgel%2Ftentacat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edgurgel%2Ftentacat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edgurgel%2Ftentacat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/edgurgel","download_url":"https://codeload.github.com/edgurgel/tentacat/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254067097,"owners_count":22009078,"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":["api","elixir","github","http"],"created_at":"2024-08-01T02:01:10.750Z","updated_at":"2025-05-14T04:03:08.729Z","avatar_url":"https://github.com/edgurgel.png","language":"Elixir","funding_links":[],"categories":["Third Party APIs","Elixir"],"sub_categories":[],"readme":"# Tentacat\n\n[![Coverage Status](http://img.shields.io/coveralls/edgurgel/tentacat.svg)](https://coveralls.io/r/edgurgel/tentacat)\n[![Inline docs](http://inch-ci.org/github/edgurgel/tentacat.svg)](http://inch-ci.org/github/edgurgel/tentacat)\n[![Module Version](https://img.shields.io/hexpm/v/tentacat.svg)](https://hex.pm/packages/tentacat)\n[![Hex Docs](https://img.shields.io/badge/hex-docs-lightgreen.svg)](https://hexdocs.pm/tentacat/)\n[![Total Download](https://img.shields.io/hexpm/dt/tentacat.svg)](https://hex.pm/packages/tentacat)\n[![License](https://img.shields.io/hexpm/l/tentacat.svg)](https://github.com/edgurgel/tentacat/blob/master/LICENSE)\n[![Last Updated](https://img.shields.io/github/last-commit/edgurgel/tentacat.svg)](https://github.com/edgurgel/tentacat/commits/master)\n\nSimple Elixir wrapper for the [GitHub API](http://developer.github.com/).\n\nTentacool + Cat = Tentacat\n\n## Features\n\n* Gitignore\n* Contents\n* Trees\n* Projects\n* Issues\n  * Comments\n  * Events\n  * Labels\n* Pulls\n  * Comments\n  * Commits\n  * Files\n  * Reviews\n  * Review Requests\n* Organizations\n  * Members\n  * Teams\n  * Webhooks\n  * Projects\n* Teams\n  * Members\n* Users\n  * Emails\n  * Keys\n  * Projects\n* Repositories\n  * Webhooks\n  * Branches\n  * Statuses\n  * Deployments\n  * Collaborators\n  * Contributors\n  * Projects\n\nDocumentation can be found [here](https://hexdocs.pm/tentacat)\n\n## Quickstart\n\nFirst, add Tentacat to your `mix.exs` dependencies:\n\n```elixir\ndef deps do\n  [\n    {:tentacat, \"~\u003e 2.0\"}\n  ]\nend\n```\n\nFetching dependencies and running on elixir console:\n\n```console\nmix deps.get\niex -S mix\n```\n\nYou will something like this:\n\n```elixir\nErlang/OTP 17 [erts-6.0] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]\n\nInteractive Elixir (0.13.3) - press Ctrl+C to exit (type h() ENTER for help)\niex(1)\u003e\n```\n\nNow you can run the examples!\n\n## Examples\n\nEvery call to GitHub needs a client, but if you want to use unauthenticated requests we will provide an unauthenticated client for you. Keep in mind that GitHub has different [rate-limits](https://developer.github.com/v3/#rate-limiting) if you authenticate or not.\n\nGetting info from a user using a client:\n\n```elixir\niex\u003e client = Tentacat.Client.new\n%Tentacat.Client{auth: nil, endpoint: \"https://api.github.com/\"}\niex\u003e Tentacat.Users.find client, \"edgurgel\"\n{200,\n %{\"avatar_url\" =\u003e \"https://avatars0.githubusercontent.com/u/30873?v=4\",\n   \"bio\" =\u003e \"INSUFFICIENT DATA FOR MEANINGFUL ANSWER\",\n   \"blog\" =\u003e \"http://gurgel.me\", \"company\" =\u003e nil,\n   \"created_at\" =\u003e \"2008-10-24T17:05:04Z\", \"email\" =\u003e nil,\n   \"events_url\" =\u003e \"https://api.github.com/users/edgurgel/events{/privacy}\",\n   \"followers\" =\u003e 220,\n   \"followers_url\" =\u003e \"https://api.github.com/users/edgurgel/followers\",\n   \"following\" =\u003e 75,\n   \"following_url\" =\u003e \"https://api.github.com/users/edgurgel/following{/other_user}\",\n   \"gists_url\" =\u003e \"https://api.github.com/users/edgurgel/gists{/gist_id}\",\n   \"gravatar_id\" =\u003e \"\", \"hireable\" =\u003e nil,\n   \"html_url\" =\u003e \"https://github.com/edgurgel\", \"id\" =\u003e 30873,\n   \"location\" =\u003e \"Wellington, New Zealand\", \"login\" =\u003e \"edgurgel\",\n   \"name\" =\u003e \"Eduardo Gurgel\",\n   \"organizations_url\" =\u003e \"https://api.github.com/users/edgurgel/orgs\",\n   \"public_gists\" =\u003e 13, \"public_repos\" =\u003e 59,\n   \"received_events_url\" =\u003e \"https://api.github.com/users/edgurgel/received_events\",\n   \"repos_url\" =\u003e \"https://api.github.com/users/edgurgel/repos\",\n   \"site_admin\" =\u003e false,\n   \"starred_url\" =\u003e \"https://api.github.com/users/edgurgel/starred{/owner}{/repo}\",\n   \"subscriptions_url\" =\u003e \"https://api.github.com/users/edgurgel/subscriptions\",\n   \"type\" =\u003e \"User\", \"updated_at\" =\u003e \"2018-02-05T23:24:42Z\",\n   \"url\" =\u003e \"https://api.github.com/users/edgurgel\"},\n %HTTPoison.Response{body: %{\"avatar_url\" =\u003e \"https://avatars0.githubusercontent.com/u/30873?v=4\",\n    \"bio\" =\u003e \"INSUFFICIENT DATA FOR MEANINGFUL ANSWER\",\n    \"blog\" =\u003e \"http://gurgel.me\", \"company\" =\u003e nil,\n    \"created_at\" =\u003e \"2008-10-24T17:05:04Z\", \"email\" =\u003e nil,\n    \"events_url\" =\u003e \"https://api.github.com/users/edgurgel/events{/privacy}\",\n    \"followers\" =\u003e 220,\n    \"followers_url\" =\u003e \"https://api.github.com/users/edgurgel/followers\",\n    \"following\" =\u003e 75,\n    \"following_url\" =\u003e \"https://api.github.com/users/edgurgel/following{/other_user}\",\n    \"gists_url\" =\u003e \"https://api.github.com/users/edgurgel/gists{/gist_id}\",\n    \"gravatar_id\" =\u003e \"\", \"hireable\" =\u003e nil,\n    \"html_url\" =\u003e \"https://github.com/edgurgel\", \"id\" =\u003e 30873,\n    \"location\" =\u003e \"Wellington, New Zealand\", \"login\" =\u003e \"edgurgel\",\n    \"name\" =\u003e \"Eduardo Gurgel\",\n    \"organizations_url\" =\u003e \"https://api.github.com/users/edgurgel/orgs\",\n    \"public_gists\" =\u003e 13, \"public_repos\" =\u003e 59,\n    \"received_events_url\" =\u003e \"https://api.github.com/users/edgurgel/received_events\",\n    \"repos_url\" =\u003e \"https://api.github.com/users/edgurgel/repos\",\n    \"site_admin\" =\u003e false,\n    \"starred_url\" =\u003e \"https://api.github.com/users/edgurgel/starred{/owner}{/repo}\",\n    \"subscriptions_url\" =\u003e \"https://api.github.com/users/edgurgel/subscriptions\",\n    \"type\" =\u003e \"User\", \"updated_at\" =\u003e \"2018-02-05T23:24:42Z\",\n    \"url\" =\u003e \"https://api.github.com/users/edgurgel\"},\n  headers: [{\"Date\", \"Mon, 05 Feb 2018 23:25:36 GMT\"},\n   {\"Content-Type\", \"application/json; charset=utf-8\"},\n   {\"Content-Length\", \"1187\"}, {\"Server\", \"GitHub.com\"}, {\"Status\", \"200 OK\"},\n   {\"X-RateLimit-Limit\", \"60\"}, {\"X-RateLimit-Remaining\", \"59\"},\n   {\"X-RateLimit-Reset\", \"1517876736\"},\n   {\"Cache-Control\", \"public, max-age=60, s-maxage=60\"}, {\"Vary\", \"Accept\"},\n   {\"ETag\", \"\\\"ec2653a252e614a96afacfaeb88d0c39\\\"\"},\n   {\"Last-Modified\", \"Mon, 05 Feb 2018 23:24:42 GMT\"},\n   {\"X-GitHub-Media-Type\", \"github.v3; format=json\"},\n   {\"Access-Control-Expose-Headers\",\n    \"ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval\"},\n   {\"Access-Control-Allow-Origin\", \"*\"},\n   {\"Content-Security-Policy\", \"default-src 'none'\"},\n   {\"Strict-Transport-Security\",\n    \"max-age=31536000; includeSubdomains; preload\"},\n   {\"X-Content-Type-Options\", \"nosniff\"}, {\"X-Frame-Options\", \"deny\"},\n   {\"X-XSS-Protection\", \"1; mode=block\"}, {\"X-Runtime-rack\", \"0.030182\"},\n   {\"Vary\", \"Accept-Encoding\"},\n   {\"X-GitHub-Request-Id\", \"054D:2BC4A:82C2C:A4560:5A78E7EF\"}],\n  request_url: \"https://api.github.com/users/edgurgel\", status_code: 200}}\n```\n\nGetting info from a user without a defined client:\n\n```elixir\niex\u003e {200, data, _response} = Tentacat.Users.find(\"edgurgel\")\n\niex\u003e get_in(data, [\"name\"])\n\"Eduardo Gurgel\"\n```\n\nGetting info from the authenticated user:\n\n* Using user and password:\n\n```elixir\niex\u003e client = Tentacat.Client.new(%{user: \"user\", password: \"password\"})\n%Tentacat.Client{auth: %{user: \"user\", password: \"password\"}, endpoint: \"https://api.github.com/\"}\niex\u003e Tentacat.Users.me(client)\n```\n\n* Using a personal access token [Github personal API token](https://github.com/blog/1509-personal-api-tokens):\n\n```elixir\niex\u003e client = Tentacat.Client.new(%{access_token: \"928392873982932\"})\n%Tentacat.Client{auth: %{access_token: \"928392873982932\"}, endpoint: \"https://api.github.com/\"}\niex\u003e Tentacat.Users.me(client)\n```\n\nAccessing another endpoint:\n\n```elixir\niex\u003e client = Tentacat.Client.new(%{access_token: \"928392873982932\"}, \"https://ghe.example.com/api/v3/\")\n%Tentacat.Client{auth: %{access_token: \"928392873982932\"}, endpoint: \"https://ghe.example.com/api/v3/\"}\niex\u003e Tentacat.Users.me(client)\n```\n\n## Misc\n\nHaving that Github Reviews API is still in a pre-release state\nyou need to set an additional header in your config.\n\n```elixir\nconfig :tentacat, :extra_headers, [{\"Accept\", \"application/vnd.github.black-cat-preview+json\"}]\n```\n\n### Deserialization Options\n\nYou can pass deserialization options to the library used to decode JSON\nusing:\n\n```elixir\n# To have Atom keys\nconfig :tentacat, :deserialization_options, [keys: :atoms]\n```\n\nSee: https://hexdocs.pm/jason/Jason.html#decode/2-options for available options.\n\n## Contributing\n\nStart by forking this repo.\n\nThen run this command to fetch dependencies and run tests:\n\n```console\nMIX_ENV=test mix do deps.get, test\n```\n\nIf you are using Intellij and debugging the test suite - be sure to set `'INTELLIJ_ELIXIR_DEBUG_BLACKLIST=hackney'` in the Elixir Mix Eunit configuration - if you fail to do so the mocked hackney module will be reloaded from disk and tests will behave abnormally.\n\nPull requests are greatly appreciated.\n\n## Copyright and License\n\nCopyright (c) 2013 Eduardo Gurgel Pinho\n\nReleased under the MIT License, which can be found in the repository in\n[LICENSE.md](./LICENSE.md) file.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fedgurgel%2Ftentacat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fedgurgel%2Ftentacat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fedgurgel%2Ftentacat/lists"}