Implementation:OpenHands OpenHands GithubFactory Create View
| Knowledge Sources | |
|---|---|
| Domains | Platform_Integration, GitHub_API |
| Last Updated | 2026-02-11 21:00 GMT |
Overview
Concrete tool for creating typed GitHub view objects from raw webhook payloads using the Factory pattern, provided by the OpenHands enterprise integration layer.
Description
GithubFactory.create_github_view_from_payload is a factory function that accepts a raw Message object (containing the deserialized webhook JSON) and a Keycloak user identifier, then produces a typed ResolverViewInterface implementation. The function discriminates among four concrete view types based on the payload structure:
- GithubIssue -- A new issue or an issue body edit
- GithubIssueComment -- A comment on an issue
- GithubPRComment -- A top-level comment on a pull request
- GithubInlinePRComment -- An inline review comment on a specific line of a pull request diff
Each concrete type is a @dataclass that implements the ResolverViewInterface protocol, exposing uniform properties such as issue_number, full_repo_name, installation_id, is_public_repo, and methods like initialize_new_conversation().
The type alias GithubViewType is defined as the union of all four concrete types:
GithubViewType = GithubInlinePRComment | GithubPRComment | GithubIssueComment | GithubIssue
Usage
This factory is called by GithubManager.receive_message after the permission check passes. It is the sole point of construction for view objects within the GitHub integration, ensuring consistent initialization and validation.
Code Reference
Source Location
- Repository: OpenHands
- File:
enterprise/integrations/github/github_view.py - Lines: L741-887 (factory function), L565+ (factory class)
Signature
@staticmethod
def create_github_view_from_payload(
message: Message,
keycloak_user_id: str,
) -> ResolverViewInterface:
Import
from integrations.github.github_view import GithubFactory
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| message | Message |
Yes | Pydantic model containing the raw webhook payload. The message field holds the JSON dict from which the event type is discriminated.
|
| keycloak_user_id | str |
Yes | The Keycloak identity of the user associated with the GitHub App installation, used for conversation ownership and access control. |
Outputs
| Name | Type | Description |
|---|---|---|
| view | ResolverViewInterface |
A polymorphic view object -- one of GithubIssue, GithubIssueComment, GithubPRComment, or GithubInlinePRComment -- populated with fields extracted from the webhook payload.
|
Discrimination Logic
The factory inspects the following payload fields to determine the concrete type:
| Condition | Resulting Type |
|---|---|
Payload contains pull_request key AND comment has in_reply_to field |
GithubInlinePRComment
|
Payload contains pull_request key AND has a comment object |
GithubPRComment
|
Payload contains issue key AND has a comment object |
GithubIssueComment
|
Payload contains issue key without a comment object |
GithubIssue
|
Concrete View Types
GithubIssue
Represents a newly created issue or an issue body edit. Contains fields: issue_number, installation_id, full_repo_name, is_public_repo, user_info, raw_payload, title, description, previous_comments, v1_enabled.
GithubIssueComment
Represents a comment on an issue thread. Adds comment_id and comment_body to the base issue fields.
GithubPRComment
Represents a top-level comment on a pull request. Includes PR-specific fields like head_sha and base_branch.
GithubInlinePRComment
Represents an inline review comment on a specific diff line. Adds diff_hunk, path, position, and in_reply_to_id.
Usage Examples
Basic Usage
from integrations.github.github_view import GithubFactory
from integrations.models import Message, SourceType
message = Message(
source=SourceType.GITHUB,
message=webhook_payload_dict,
ephemeral=False,
)
view = GithubFactory.create_github_view_from_payload(
message=message,
keycloak_user_id="user-uuid-1234",
)
# The view implements ResolverViewInterface
print(view.issue_number) # e.g., 42
print(view.full_repo_name) # e.g., "All-Hands-AI/OpenHands"
print(view.installation_id) # e.g., "12345678"
Type-Specific Handling
from integrations.github.github_view import (
GithubIssue,
GithubIssueComment,
GithubPRComment,
GithubInlinePRComment,
)
match view:
case GithubInlinePRComment():
print(f"Inline comment on {view.path} at line {view.position}")
case GithubPRComment():
print(f"PR comment on PR #{view.issue_number}")
case GithubIssueComment():
print(f"Issue comment on #{view.issue_number}")
case GithubIssue():
print(f"Issue #{view.issue_number}: {view.title}")