Differences between regular GH and GHES API graphql endpoints
Hello,
I'm successfully using this library to interact with a GitHub Enterprise Server through the REST API.
As you may know, for GHES, the REST API endpoint is located at https://[hostname]/api/v3/ instead of https://api.github.com/.
So far so good as I can use the base_url parameter when building a GitHub object.
However, the troubles appear when I try to make a request using the graphql endpoint.
Indeed, GHES uses this endpoint for graphql : https://[hostname]/api/graphql/ (the v3/ suffix is no longer present) and I can no longer use base_url because it's different whether I use the REST or graphql API.
Sample code :
from githubkit import (
AppAuthStrategy,
GitHub,
)
INSTALLATION_ID: int = ...
auth_strategy: AppAuthStrategy = ...
gh = GitHub(
auth_strategy.as_installation(INSTALLATION_ID),
base_url='https://ghes-hostname/api/v3',
)
gh.graphql('query { viewer { login } }')
# >>> githubkit.exception.RequestFailed: Response(404 Not Found, data_model=typing.Any)
Here, githubkit successfully retrieves a token through the REST API to use for the graphql query but then this query is made against https://ghes-hostname/api/v3/graphql and a 404 response is returned.
I'd like to know your opinion on this as supporting GHES might not be your priority. Let me know if you need more information.
According to octokit, a workaround for GHES is needed. https://github.com/octokit/graphql.js/blob/dae781b027c19bcd458577cd9ac6ca888b2fdfeb/src/graphql.ts#L67-L72
Based on your findings, I wrote a quick workaround based on HTTPS's event hooks.
async def _fix_ghes_graphql_endpoint(request: httpx.Request) -> None:
GHES_GRAPHQL_SUFFIX_TOFIX = b"/api/v3/graphql"
if request.url.raw_path.endswith(GHES_GRAPHQL_SUFFIX_TOFIX):
request.url = request.url.copy_with(
raw_path=request.url.raw_path[: -len(GHES_GRAPHQL_SUFFIX_TOFIX)] + b"/api/graphql"
)
It can then be used during Client's creation and transparently fix URLs:
return httpx.Client(
**self._get_client_defaults(),
transport=transport,
event_hooks={'request': [_fix_ghes_graphql_endpoint]}
)
What's your opinion on this? I'm not totally satisfied because hooks make it harder to follow the flow of the request but here it seems a good fit.
FYI: I'll be away for the next two weeks or so, I can try to create a PR when I'm back.
Maybe a direct patch to endpoint url in graphql request function looks clearer. i will create a pr when i am free.
Hi @fau-st , i have just create a PR to fix this, but i do not have a GHES account to test this. Could you please test or review the code to verify the graphql endpoint? you can install the githubkit from the fix/ghes-graphql branch.
I just added some tests and docs about the base_url option in readme.
@yanyongyu Thank you very much, I tested your changes and everything seems to work great.