Question: installation and github app usage
yalattas opened this issue · 5 comments
configs
from conf.settings import settings
from githubkit import GitHub, AppInstallationAuthStrategy
from githubkit.retry import RetryChainDecision, RetryRateLimit, RetryServerError
with open('./static/private-key.pem', 'rb') as pem_file:
private_key = pem_file.read()
github = GitHub(
AppInstallationAuthStrategy(
app_id=settings.GITHUB_APP_ID,
private_key=private_key,
installation_id=settings.GITHUB_APP_INSTALLATION_ID,
client_id=settings.GITHUB_APP_CLIENT_ID,
client_secret=settings.GITHUB_APP_CLIENT_SECRET
),
base_url="https://api.github.com/",
accept_format="full+json",
previews=["starfox"],
user_agent="GitHubKit/Python",
follow_redirects=True,
timeout=None,
http_cache=True,
auto_retry=RetryChainDecision(RetryRateLimit(max_retry=1), RetryServerError(max_retry=1)),
)
API call
response = await github.rest("2022-11-28").repos.async_get(owner="My_organization", repo="MyRepository")
error
backend | 2024-05-24 18:23:43,000 - INFO - httptools_impl: 172.19.0.1:55210 - "GET /v1/github/graphql/ HTTP/1.1" 500
backend | ERROR: Exception in ASGI application
backend | Traceback (most recent call last):
backend | File "/usr/local/lib/python3.12/site-packages/githubkit/core.py", line 306, in _arequest
backend | return await client.request(
backend | ^^^^^^^^^^^^^^^^^^^^^
backend | File "/usr/local/lib/python3.12/site-packages/httpx/_client.py", line 1574, in request
backend | return await self.send(request, auth=auth, follow_redirects=follow_redirects)
backend | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
backend | File "/usr/local/lib/python3.12/site-packages/httpx/_client.py", line 1661, in send
backend | response = await self._send_handling_auth(
backend | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
backend | File "/usr/local/lib/python3.12/site-packages/httpx/_client.py", line 1686, in _send_handling_auth
backend | request = await auth_flow.__anext__()
backend | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
backend | File "/usr/local/lib/python3.12/site-packages/githubkit/auth/app.py", line 233, in async_auth_flow
backend | token_request.headers["Authorization"] = f"Bearer {await self.aget_jwt()}"
backend | ^^^^^^^^^^^^^^^^^^^^^
backend | File "/usr/local/lib/python3.12/site-packages/githubkit/auth/app.py", line 89, in aget_jwt
backend | token = self._create_jwt()
backend | ^^^^^^^^^^^^^^^^^^
backend | File "/usr/local/lib/python3.12/site-packages/githubkit/auth/app.py", line 70, in _create_jwt
backend | return jwt.encode(
backend | ^^^^^^^^^^
backend | AttributeError: module 'jwt' has no attribute 'encode'
backend |
backend | The above exception was the direct cause of the following exception:
backend |
backend | Traceback (most recent call last):
backend | File "/usr/local/lib/python3.12/site-packages/uvicorn/protocols/http/httptools_impl.py", line 411, in run_asgi
backend | result = await app( # type: ignore[func-returns-value]
backend | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
backend | File "/usr/local/lib/python3.12/site-packages/uvicorn/middleware/proxy_headers.py", line 69, in __call__
backend | return await self.app(scope, receive, send)
backend | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
backend | File "/usr/local/lib/python3.12/site-packages/fastapi/applications.py", line 1054, in __call__
backend | await super().__call__(scope, receive, send)
backend | File "/usr/local/lib/python3.12/site-packages/starlette/applications.py", line 123, in __call__
backend | await self.middleware_stack(scope, receive, send)
backend | File "/usr/local/lib/python3.12/site-packages/starlette/middleware/errors.py", line 186, in __call__
backend | raise exc
backend | File "/usr/local/lib/python3.12/site-packages/starlette/middleware/errors.py", line 164, in __call__
backend | await self.app(scope, receive, _send)
backend | File "/usr/local/lib/python3.12/site-packages/prometheus_fastapi_instrumentator/middleware.py", line 174, in __call__
backend | raise exc
backend | File "/usr/local/lib/python3.12/site-packages/prometheus_fastapi_instrumentator/middleware.py", line 172, in __call__
backend | await self.app(scope, receive, send_wrapper)
backend | File "/usr/local/lib/python3.12/site-packages/starlette/middleware/exceptions.py", line 65, in __call__
backend | await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
backend | File "/usr/local/lib/python3.12/site-packages/starlette/_exception_handler.py", line 64, in wrapped_app
backend | raise exc
backend | File "/usr/local/lib/python3.12/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
backend | await app(scope, receive, sender)
backend | File "/usr/local/lib/python3.12/site-packages/starlette/routing.py", line 756, in __call__
backend | await self.middleware_stack(scope, receive, send)
backend | File "/usr/local/lib/python3.12/site-packages/starlette/routing.py", line 776, in app
backend | await route.handle(scope, receive, send)
backend | File "/usr/local/lib/python3.12/site-packages/starlette/routing.py", line 297, in handle
backend | await self.app(scope, receive, send)
backend | File "/usr/local/lib/python3.12/site-packages/starlette/routing.py", line 77, in app
backend | await wrap_app_handling_exceptions(app, request)(scope, receive, send)
backend | File "/usr/local/lib/python3.12/site-packages/starlette/_exception_handler.py", line 64, in wrapped_app
backend | raise exc
backend | File "/usr/local/lib/python3.12/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
backend | await app(scope, receive, sender)
backend | File "/usr/local/lib/python3.12/site-packages/starlette/routing.py", line 72, in app
backend | response = await func(request)
backend | ^^^^^^^^^^^^^^^^^^^
backend | File "/usr/local/lib/python3.12/site-packages/fastapi/routing.py", line 278, in app
backend | raw_response = await run_endpoint_function(
backend | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
backend | File "/usr/local/lib/python3.12/site-packages/fastapi/routing.py", line 191, in run_endpoint_function
backend | return await dependant.call(**values)
backend | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
backend | File "/app/apps/github/urls.py", line 65, in success
backend | save = await EventHandler.process_event()
backend | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
backend | File "/app/apps/github/controller.py", line 10, in process_event
backend | response = await github.rest("2022-11-28").repos.async_get(owner="BarakahApp", repo="gitops")
backend | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
backend | File "/usr/local/lib/python3.12/site-packages/githubkit/versions/v2022_11_28/rest/repos.py", line 1232, in async_get
backend | return await self._github.arequest(
backend | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
backend | File "/usr/local/lib/python3.12/site-packages/githubkit/core.py", line 548, in arequest
backend | raw_resp = await self._arequest(
backend | ^^^^^^^^^^^^^^^^^^^^^
backend | File "/usr/local/lib/python3.12/site-packages/githubkit/core.py", line 320, in _arequest
backend | raise RequestError(repr(e)) from e
backend | githubkit.exception.RequestError: AttributeError("module 'jwt' has no attribute 'encode'")
it seems to be that I have jwt package but this kit requires PyJWT
[tool.poetry.dependencies]
PyJWT = { version = "^2.4.0", extras = ["crypto"], optional = true }
Yet, I don't think this is a problematic since I tried it with tokenStrategy and it worked.
But when I install PyJWT
, error is different and I am working to fix it on my end. Just thought to bring this to your attention
githubkit.exception.RequestError: RequestFailed(method=POST, url=https://api.github.com/app/installations/123456789/access_tokens, status_code=404 Not Found)
Appreciate your guidance.
In addition, I am pretty confused about the documentation. The call I am making to get repositories was a sample I found it online. From where can I find reference of the functionality ?
for example if I want to get a pull request comment or issue or action or anything ? and creating pull request or merge them and so on.
Finally, I am planning to use GraphQL. Hence, I choose this package and your effort are really amazing and appreciated. Appreciate a guidance or that as well.
How can I make a GraphQL call, validate the response and create commit via mutation using GraphQL
I just figured out the 404
error and was due having wrong installation ID for different app
Yet, for JWT package got resolved only after I change dependency from having jwt
to PyJWT
githubkit requires the PyJWT
package to work with GitHub APP. Please install the requirements with pip install githubkit[auth-app]
, as described in the docs. You do not need to install the pyjwt package by your self. If you follow the installation guide, the correct package will be installed automatically.
From where can I find reference of the functionality? for example if I want to get a pull request comment or issue or action or anything ? and creating pull request or merge them and so on.
You can find all the rest apis at the docs.github.com.
For example, if you want to get a issue, you can find the docs here. and you can work with githubkit like this: (if you use github app, sync example)
from githubkit import GitHub, App
# auth with your github app
g = GitHub(
AppAuthStrategy(
"<app_id>", "<private_key>"
)
)
# get the repo installation first
resp = g.rest.apps.get_repo_installation("owner", "repo")
installation_id = resp.parsed_data.id
# then, switch to installation auth
g_repo = g.with_auth(g.auth.as_installation(installation_id))
# you can now get all repo info by the installation authed rest api
resp = g_repo.rest.issues.get("owner", "repo", issue_number)
issue = resp.parsed_data
all the auth flow mentioned above, you can find the docs at GitHub APP Guide. GitHub APP cannot get the repo data directly since the owner of the repo should install the app first. then, the installation_id
will be created after the owner has installed the app. you can access the repo data now by auth with the installation_id
.
Other apis to create a pull request or merge it also can be found at the github rest docs, like the pulls
section.
How can I make a GraphQL call, validate the response and create commit via mutation using GraphQL
The GraphQL usage is very simple, the docs is here. You can first edit the graphql request body at the GitHub GraphQL Editor online then copy the graphql request to your code, send it, and the return value will be the response data. Note that, you still need to auth correctly like the rest example above.
Indeed I don't need to explicitly install PyJWT. Yet, I was using jwt
package in a different module and since I installed jwt
package explicitly and caused the mentioned error in GithubKit
When I removed jwt
package and refactored my code to use PyJWT
in the other module. GithubKit
issue was resolved directly. That's why I am mentioning it here.
In addition, everything is working now in GithubKit
Finally, as you're referring to Github
API as a documentation, which meant GithubKit
is relying on Github schema only and not supporting functionalities on top of Github API. Correct me if I wrong
Will continue to build on GithubKit. Will get back to you if I faced any issue
Thanks for developing this amazing app
What you mentioned is that module name of the two package jwt
and pyjwt
are same. If you think this is an issue, please report to them. It's not the error with githubkit and githubkit can not prevent you to install the jwt
. Both packages use the same module name will cause conflicts, you should not install them at the same time.
githubkit is a GitHub SDK, implements the GitHub API best practice and provide additional functionalities like data validation, auto retry, version switching. you should read the github docs first.
If you have any question about githubkit, feel free to open an issue.