# How github.py Integrates with the hiring-agent Project: Complete Technical Architecture

> Understand github.py integration with hiring agent. Explore its technical architecture for authenticated GitHub data fetching, rate-limit handling, and LLM-powered project selection.

- Repository: [HackerRank/hiring-agent](https://github.com/interviewstreet/hiring-agent)
- Tags: architecture
- Published: 2026-07-15

---

**[`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py) serves as the central GitHub API bridge for the interviewstreet/hiring-agent repository, providing authenticated data fetching, rate-limit handling, and LLM-powered project selection that enriches candidate profiles with real-time repository statistics.**

The [`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py) module is the primary integration point between the hiring-agent evaluation pipeline and GitHub's public API. It encapsulates all external API communication, caching strategies, and data normalization logic required to transform raw GitHub URLs into structured candidate intelligence that the scoring engine consumes.

## Core Responsibilities and Implementation

### Cache Handling and Development Mode

To minimize redundant API calls during development, [`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py) implements a deterministic file-based caching system. The `_create_cache_filename` function (lines 18-26 in [`main/github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/main/github.py)) generates predictable cache keys based on request parameters. When `DEVELOPMENT_MODE` is enabled, the module checks for existing cached JSON responses before issuing live API requests, significantly accelerating iterative development and testing cycles.

### Authenticated API Requests with GITHUB_TOKEN

All outbound requests route through `_fetch_github_api` (lines 30-34), which automatically injects authentication headers when the `GITHUB_TOKEN` environment variable is present. This authentication is critical for increasing rate limits from 60 to 5,000 requests per hour and accessing private repository metadata when evaluating candidates with restricted project visibility.

### Rate-Limit Management and Throttling

The module implements sophisticated rate-limit awareness within `_fetch_github_api` (lines 55-96) to prevent API quota exhaustion. It parses GitHub's `X-RateLimit-Remaining` and `X-RateLimit-Reset` headers, automatically sleeping until quota reset when remaining calls drop below a safe threshold, and caps maximum wait times to prevent indefinite blocking during high-volume candidate processing.

### Username Extraction and Profile Fetching

For handling varied input formats, `extract_github_username` (lines 16-38) robustly parses both full GitHub URLs (`https://github.com/username`) and raw handles into standardized usernames. The `fetch_github_profile` function (lines 41-78) then contacts `https://api.github.com/users/<username>` and maps the JSON response to a `GitHubProfile` model defined in [`main/models.py`](https://github.com/interviewstreet/hiring-agent/blob/main/main/models.py), capturing follower counts, public repository tallies, and account creation dates.

### Repository Enumeration and Classification

The `fetch_all_github_repos` function (lines 18-94) paginates through a user's repositories, filters out forks to focus on original work, gathers contributor statistics, and classifies each repository as either **open_source** (collaborative) or **self_project** (personal). This classification enables the scoring engine to weight community contributions differently from solo portfolio projects.

### LLM-Driven Project Selection

Rather than returning all repositories, `generate_projects_json` (lines 34-41 and 65-30) converts the raw repo list to JSON and prompts a language model to identify the top 7 most representative projects based on complexity, relevance, and impact. The system falls back to the first 7 repositories chronologically if the LLM invocation fails, ensuring pipeline reliability.

## Integration Points with Downstream Modules

### score.py Integration

The primary consumer is [`main/score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/main/score.py), which imports the high-level façade at line 7:

```python
from github import fetch_and_display_github_info

```

During candidate evaluation (line 312), it invokes:

```python
github_data = fetch_and_display_github_info(github_profile.url)

```

The returned dictionary contains a **`profile`** section (populated by `generate_profile_json`) and a **`projects`** list (produced by `generate_projects_json`). The scoring pipeline subsequently weighs real contributions, star counts, and project types to calculate technical proficiency metrics.

### models.py Type Definitions

[`main/models.py`](https://github.com/interviewstreet/hiring-agent/blob/main/main/models.py) defines the `GitHubProfile` dataclass (constructor call at lines 54-68) that [`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py) populates. This typed container ensures that downstream evaluation modules access candidate metadata through a consistent interface with validated field types, eliminating runtime errors from API response variations.

### LLM Infrastructure Dependencies

The project selection logic relies on [`main/prompt.py`](https://github.com/interviewstreet/hiring-agent/blob/main/main/prompt.py) and [`main/llm_utils.py`](https://github.com/interviewstreet/hiring-agent/blob/main/main/llm_utils.py) for LLM provider initialization (`initialize_llm_provider`) and response parsing (`extract_json_from_response`). These utilities abstract the specific LLM backend while standardizing JSON extraction from model outputs, allowing [`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py) to remain agnostic to the underlying AI provider.

## Usage Examples

### Complete Profile and Project Fetch

For full candidate enrichment, use the unified entry point:

```python
from github import fetch_and_display_github_info

candidate_url = "https://github.com/awesome-dev"
result = fetch_and_display_github_info(candidate_url)

print("Profile:", result["profile"])
print("Top projects:", result["projects"][:3])

```

### Granular Data Access

For partial data requirements or custom processing:

```python
from github import fetch_github_profile, fetch_all_github_repos

profile = fetch_github_profile("https://github.com/awesome-dev")
repos = fetch_all_github_repos("https://github.com/awesome-dev", max_repos=20)

print(f"{profile.name} has {len(repos)} repositories")

```

Both examples automatically leverage the file-based caching mechanism when `DEVELOPMENT_MODE` is set, and they respect GitHub rate limits via the built-in throttling logic in `_fetch_github_api`.

### CLI Debugging

The module includes a standalone entry point for manual testing:

```python

# Run from project root

python main/github.py https://github.com/username

```

## Summary

- **[`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py)** acts as the data-ingestion layer, handling authentication, caching, rate-limiting, and data normalization for all GitHub API interactions in the hiring-agent project.
- **Key functions** include `fetch_and_display_github_info` for unified data retrieval, `fetch_github_profile` for user metadata, and `fetch_all_github_repos` for repository enumeration with classification.
- **Rate protection** is implemented via `_fetch_github_api` (lines 55-96), which monitors quota headers and pauses execution until rate limits reset.
- **Integration flow** follows: [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py) → [`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py) → [`models.py`](https://github.com/interviewstreet/hiring-agent/blob/main/models.py), with LLM support from [`prompt.py`](https://github.com/interviewstreet/hiring-agent/blob/main/prompt.py) and [`llm_utils.py`](https://github.com/interviewstreet/hiring-agent/blob/main/llm_utils.py) for intelligent project selection.

## Frequently Asked Questions

### How does github.py handle GitHub API rate limits?

The `_fetch_github_api` function inspects response headers for `X-RateLimit-Remaining` and `X-RateLimit-Reset`. When remaining calls approach zero, it calculates the sleep duration until the quota resets, pausing execution while logging the wait time. This prevents hard failures during bulk candidate processing and ensures continuous pipeline operation.

### What authentication method does github.py use for the GitHub API?

The module checks for a `GITHUB_TOKEN` environment variable at runtime. When present, it adds an `Authorization: token <GITHUB_TOKEN>` header to all requests via `_fetch_github_api` (lines 30-34). This token-based authentication increases rate limits from 60 to 5,000 requests per hour and enables access to private repository data when evaluating candidates.

### How does the hiring-agent project select which repositories to analyze?

Rather than analyzing every public repository, [`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py) uses `generate_projects_json` to serialize the complete repo list and prompt an LLM to identify the top 7 most impressive and relevant projects. The model considers factors like star count, complexity, and language diversity. If the LLM call fails or returns invalid JSON, the system falls back to selecting the first 7 repositories returned by the GitHub API.

### Can github.py operate independently of the main scoring pipeline?

Yes. The module includes a `main` function (lines 84-92) that serves as a CLI entry point, allowing developers to run `python main/github.py <github_url>` for standalone testing and debugging. This independence facilitates rapid iteration on the GitHub integration without invoking the full candidate scoring workflow in [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py).