borodache's picture
Update README.md to follow the YAML requirements of Gradio Hugging Face
a10e9c2 verified
|
Raw
History Blame Contribute Delete
7.65 kB
---
title: Repo Summarizer
emoji: πŸ“š
colorFrom: blue
colorTo: indigo
sdk: gradio
sdk_version: "6.0.2"
python_version: "3.11"
app_file: app.py
pinned: false
short_description: Summarize GitHub repos β€” purpose, tech stack, layout.
---
# Repo Summarizer
A FastAPI service that takes a GitHub repository URL, fetches key files (README, `main.py`, requirements, directory tree), and returns an AI-generated **summary**, **technologies** list, and **structure** description using the Anthropic Claude API.
---
## Features
- **POST /summarize** β€” Accepts a GitHub repo URL and returns:
- **summary** β€” Short project description (from README, `main.py`, and the 10 longest Python files).
- **technologies** β€” List of technologies/dependencies (from `requirements*.txt` and file extensions in the repo).
- **structure** β€” One paragraph describing the project layout (from the repo’s directory tree).
- **GET /** β€” Web UI to paste a GitHub URL or local path and see the summary result (`index.html`).
- **`app.py`** β€” Gradio UI with the same behavior as the HTML page (for [Hugging Face Spaces](https://huggingface.co/docs/hub/spaces) and local runs).
- **GET /health** β€” Health check (`{"status": "ok"}`).
- Unified **error responses** in JSON: `{"status": "error", "message": "..."}`.
- Optional **GITHUB_TOKEN** for higher GitHub API rate limits.
- **Entry-point logging** via `log_entry()` (filename, line, function name) for tracing.
---
## Project structure
```
NebiusTest/
β”œβ”€β”€ main.py # FastAPI app, /summarize, /health, /, GitHub fetch, LLM calls
β”œβ”€β”€ app.py # Gradio UI (Space entry point); reuses main.py summarization logic
β”œβ”€β”€ logger.py # log_entry() for request/function tracing
β”œβ”€β”€ constants.py # FILE_EXTENSIONS (used for repo analysis)
β”œβ”€β”€ index.html # Frontend form for GitHub URL/local path β†’ summarize
β”œβ”€β”€ requirement.txt # Python dependencies
β”œβ”€β”€ README.md # This file
└── .gitignore
```
---
## Setup
### 1. Install dependencies
```bash
pip install -r requirement.txt
```
### 2. Environment variables
| Variable | Required | Description |
|----------|----------|-------------|
| `ANTHROPIC_API_KEY` | Yes | API key for Anthropic (Claude). Used for all summarization. |
| `GITHUB_TOKEN` | No | GitHub personal access token. Raises API rate limit (e.g. 5000/hr vs 60/hr without). |
| `SSL_CERT_FILE` / `REQUESTS_CA_BUNDLE` / `SSL_CA_BUNDLE` | No | PEM path with extra CAs (e.g. corporate HTTPS inspection). Overrides the default Mozilla bundle (`certifi`) used for GitHub + Anthropic `httpx` clients. |
| `HTTPX_VERIFY` | No | Set to `0`, `false`, or `no` to **disable TLS verification** (insecure; debugging only). |
Example (PowerShell):
```powershell
$env:ANTHROPIC_API_KEY = "sk-ant-..."
$env:GITHUB_TOKEN = "ghp_..." # optional
```
### 3. Run the server
```bash
python main.py
```
Server runs at **http://127.0.0.1:8000**.
Or with uvicorn:
```bash
uvicorn main:app --reload --host 127.0.0.1 --port 8000
```
### 4. Gradio UI (`app.py`)
`app.py` opens a Gradio interface that matches `index.html`: one text field for a **GitHub URL** or **local directory path**, a **Summarize** button, and sections for **Summary**, **Technologies**, and **Structure**, with errors shown at the top of the result area.
Run locally after installing dependencies (including Gradio from `requirement.txt`):
```bash
python app.py
```
Gradio prints a local URL in the terminal (defaults may differ by version). The underlying logic is shared with `main.py` (same GitHub vs. local detection and LLM pipeline).
**Hugging Face Spaces**
- Create a Space with the **Gradio** SDK and point it at this repo, or set the Space’s **App file** to `app.py` and ensure Gradio finds the global `demo` object (this project exposes `demo` at module level in `app.py`).
- Add **Secrets** for `ANTHROPIC_API_KEY` (required) and optionally `GITHUB_TOKEN`, same as for the FastAPI app.
- Spaces default to a `requirements.txt` file name. If your Space only sees `requirement.txt`, either add a `requirements.txt` mirroring those dependencies or configure the Space build to use `requirement.txt`.
- **Local paths** only work when Gradio runs on a machine that can read that folder. On Hugging Face, use **GitHub URLs** only.
---
## API
### POST /summarize
**Request body (JSON):**
```json
{
"github_url": "https://github.com/owner/repo"
}
```
**Success response (200):**
```json
{
"summary": "**ProjectName** is a ...",
"technologies": ["Python", "FastAPI", "httpx"],
"structure": "Main code lives in `src/`, tests in `tests/`, ..."
}
```
**Error response (4xx/5xx):**
All errors return JSON:
```json
{
"status": "error",
"message": "Description of what went wrong"
}
```
Example: repository not found, invalid URL, no text files, or LLM/rate-limit errors.
---
## Usage
### Browser (FastAPI + `index.html`)
1. Open http://127.0.0.1:8000/
2. Enter a GitHub repository URL or a local repository path.
3. Click **Summarize** and view summary, technologies, and structure.
### Gradio (`app.py`)
1. Run `python app.py`.
2. Open the URL shown in the terminal.
3. Enter the same kind of repository source (GitHub URL or local path) and submit.
### cURL
```bash
curl -X POST http://127.0.0.1:8000/summarize \
-H "Content-Type: application/json" \
-d "{\"github_url\": \"https://github.com/psf/requests\"}"
```
### Python client
From the repo root:
```python
from main import call_summarize
result = call_summarize("https://github.com/psf/requests")
print(result["summary"])
print(result["technologies"])
print(result["structure"])
```
---
## How summarization works
1. **Parse URL** β€” Extract `owner`/`repo` from the GitHub URL.
2. **Fetch repo data** (GitHub API):
- Default branch and recursive file tree.
- Contents of: README.md, `main.py`, the 10 longest other `.py` files, and `requirements*.txt`.
3. **Three sequential LLM calls** (to stay within Anthropic rate limits):
- **Summary** β€” From README + main.py + 10 longest Python files (Claude). Used the model claude-opus-4-6, since it works better with code
- **Technologies** β€” From requirements content + file extensions found in the project (`constants.FILE_EXTENSIONS`). Used the model claude-haiku-4-5 since it's liteweight and fast (the task here is pretty simple)
- **Structure** β€” From the directory tree (paths list). Used the model claude-sonnet-4-6, because this was the default model and I didn't see much difference from other models, and I guess this one is best for tree of structure.
4. **Response** β€” JSON with `summary`, `technologies` (one-line array), and `structure`.
---
## Dependencies
- **fastapi** β€” Web framework.
- **uvicorn** β€” ASGI server.
- **httpx** β€” Async HTTP client (GitHub API).
- **pydantic** β€” Request/validation.
- **anthropic** β€” Claude API client.
- **gradio** β€” Gradio UI in `app.py` (Spaces / local).
- **python-dotenv** β€” Loads `.env` for local development (used by `main.py`).
- **certifi** β€” Default CA bundle for TLS (used when custom CA env vars are not set).
---
## Logging
- **logger.py** provides `log_entry()`, which prints `[filename:line] Entering function_name()` for the caller.
- Used at entry of main request handlers and helpers to trace execution.
---
## License
Use and modify as needed for your project.