mirror of
https://github.com/qodo-ai/pr-agent.git
synced 2025-07-09 23:30:38 +08:00
Merge pull request #150 from Codium-ai/ok/handle_installation_id_properly
Github App: handle concurrent requests from multiple installations of app
This commit is contained in:
@ -5,6 +5,7 @@ from urllib.parse import urlparse
|
|||||||
|
|
||||||
from github import AppAuthentication, Auth, Github, GithubException
|
from github import AppAuthentication, Auth, Github, GithubException
|
||||||
from retry import retry
|
from retry import retry
|
||||||
|
from starlette_context import context
|
||||||
|
|
||||||
from pr_agent.config_loader import settings
|
from pr_agent.config_loader import settings
|
||||||
|
|
||||||
@ -17,7 +18,10 @@ from ..servers.utils import RateLimitExceeded
|
|||||||
class GithubProvider(GitProvider):
|
class GithubProvider(GitProvider):
|
||||||
def __init__(self, pr_url: Optional[str] = None, incremental=IncrementalPR(False)):
|
def __init__(self, pr_url: Optional[str] = None, incremental=IncrementalPR(False)):
|
||||||
self.repo_obj = None
|
self.repo_obj = None
|
||||||
self.installation_id = settings.get("GITHUB.INSTALLATION_ID")
|
try:
|
||||||
|
self.installation_id = context.get("installation_id", None)
|
||||||
|
except Exception:
|
||||||
|
self.installation_id = None
|
||||||
self.github_client = self._get_github_client()
|
self.github_client = self._get_github_client()
|
||||||
self.repo = None
|
self.repo = None
|
||||||
self.pr_num = None
|
self.pr_num = None
|
||||||
|
@ -4,6 +4,9 @@ import sys
|
|||||||
|
|
||||||
import uvicorn
|
import uvicorn
|
||||||
from fastapi import APIRouter, FastAPI, HTTPException, Request, Response
|
from fastapi import APIRouter, FastAPI, HTTPException, Request, Response
|
||||||
|
from starlette.middleware import Middleware
|
||||||
|
from starlette_context import context
|
||||||
|
from starlette_context.middleware import RawContextMiddleware
|
||||||
|
|
||||||
from pr_agent.agent.pr_agent import PRAgent
|
from pr_agent.agent.pr_agent import PRAgent
|
||||||
from pr_agent.config_loader import settings
|
from pr_agent.config_loader import settings
|
||||||
@ -21,23 +24,34 @@ async def handle_github_webhooks(request: Request, response: Response):
|
|||||||
"""
|
"""
|
||||||
logging.debug("Received a GitHub webhook")
|
logging.debug("Received a GitHub webhook")
|
||||||
|
|
||||||
|
body = await get_body(request)
|
||||||
|
|
||||||
|
logging.debug(f'Request body:\n{body}')
|
||||||
|
installation_id = body.get("installation", {}).get("id")
|
||||||
|
context["installation_id"] = installation_id
|
||||||
|
|
||||||
|
return await handle_request(body)
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/api/v1/marketplace_webhooks")
|
||||||
|
async def handle_marketplace_webhooks(request: Request, response: Response):
|
||||||
|
body = await get_body(request)
|
||||||
|
logging.info(f'Request body:\n{body}')
|
||||||
|
|
||||||
|
async def get_body(request):
|
||||||
try:
|
try:
|
||||||
body = await request.json()
|
body = await request.json()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error("Error parsing request body", e)
|
logging.error("Error parsing request body", e)
|
||||||
raise HTTPException(status_code=400, detail="Error parsing request body") from e
|
raise HTTPException(status_code=400, detail="Error parsing request body") from e
|
||||||
|
|
||||||
body_bytes = await request.body()
|
body_bytes = await request.body()
|
||||||
signature_header = request.headers.get('x-hub-signature-256', None)
|
signature_header = request.headers.get('x-hub-signature-256', None)
|
||||||
|
|
||||||
webhook_secret = getattr(settings.github, 'webhook_secret', None)
|
webhook_secret = getattr(settings.github, 'webhook_secret', None)
|
||||||
|
|
||||||
if webhook_secret:
|
if webhook_secret:
|
||||||
verify_signature(body_bytes, webhook_secret, signature_header)
|
verify_signature(body_bytes, webhook_secret, signature_header)
|
||||||
|
return body
|
||||||
|
|
||||||
logging.debug(f'Request body:\n{body}')
|
|
||||||
|
|
||||||
return await handle_request(body)
|
|
||||||
|
|
||||||
|
|
||||||
async def handle_request(body: Dict[str, Any]):
|
async def handle_request(body: Dict[str, Any]):
|
||||||
@ -48,8 +62,6 @@ async def handle_request(body: Dict[str, Any]):
|
|||||||
body: The request body.
|
body: The request body.
|
||||||
"""
|
"""
|
||||||
action = body.get("action")
|
action = body.get("action")
|
||||||
installation_id = body.get("installation", {}).get("id")
|
|
||||||
settings.set("GITHUB.INSTALLATION_ID", installation_id)
|
|
||||||
agent = PRAgent()
|
agent = PRAgent()
|
||||||
|
|
||||||
if action == 'created':
|
if action == 'created':
|
||||||
@ -85,7 +97,8 @@ async def root():
|
|||||||
def start():
|
def start():
|
||||||
# Override the deployment type to app
|
# Override the deployment type to app
|
||||||
settings.set("GITHUB.DEPLOYMENT_TYPE", "app")
|
settings.set("GITHUB.DEPLOYMENT_TYPE", "app")
|
||||||
app = FastAPI()
|
middleware = [Middleware(RawContextMiddleware)]
|
||||||
|
app = FastAPI(middleware=middleware)
|
||||||
app.include_router(router)
|
app.include_router(router)
|
||||||
|
|
||||||
uvicorn.run(app, host="0.0.0.0", port=3000)
|
uvicorn.run(app, host="0.0.0.0", port=3000)
|
||||||
|
@ -41,6 +41,7 @@ dependencies = [
|
|||||||
"aiohttp~=3.8.4",
|
"aiohttp~=3.8.4",
|
||||||
"atlassian-python-api==3.39.0",
|
"atlassian-python-api==3.39.0",
|
||||||
"GitPython~=3.1.32",
|
"GitPython~=3.1.32",
|
||||||
|
"starlette-context==0.3.6"
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.urls]
|
[project.urls]
|
||||||
|
Reference in New Issue
Block a user