AutoReadmeAgent / server.py
bogeumkim's picture
Add json.loads() to handle result
1eb338d
import modal
HF_SECRET_NAME = "hf-secret"
MODEL_ID = "google/gemma-3-12b-it"
image = (
modal.Image.debian_slim(python_version="3.12")
.apt_install("git")
.pip_install(
"smolagents[toolkit]",
"huggingface_hub",
"transformers",
"duckduckgo-search",
"fastapi",
"uvicorn",
"GitPython"
)
)
app = modal.App("auto-readme-agent")
@app.function(
image=image,
gpu="A10G",
secrets=[modal.Secret.from_name("hf-secret")],
timeout=180,
)
@modal.asgi_app()
def fastapi_app():
import os
import tempfile
import shutil
from git import Repo
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from smolagents import CodeAgent, HfApiModel, DuckDuckGoSearchTool
class RepoRequest(BaseModel):
repo_url: str
agent = CodeAgent(
model=HfApiModel(),
tools=[],
stream_outputs=True
)
app = FastAPI()
def analyze_repo(repo_path):
repo_summary = []
for root, dirs, files in os.walk(repo_path):
# Skip hidden directories
dirs[:] = [d for d in dirs if not d.startswith('.')]
rel_path = os.path.relpath(root, repo_path)
repo_summary.append(f"Directory: {rel_path}")
for file in files:
if file.endswith(('.py')):
file_path = os.path.join(root, file)
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read() # Read first 1000 characters
filtered_lines = [
line for line in content.splitlines()
if not (
line.strip().startswith('#')
or line.strip().startswith('import')
or line.strip().startswith('from')
)
]
filtered_content = "\n".join(filtered_lines)
repo_summary.append(f"File: {file}\n Content: {filtered_content}...")
except Exception:
raise f"File: {file} [Error reading file]"
return "\n".join(repo_summary)[:500]
@app.post("/")
async def generate_readme(req: RepoRequest):
temp_dir = tempfile.mkdtemp()
try:
# Clone repository
Repo.clone_from(req.repo_url, temp_dir, branch='main', depth=1)
# Analyze repository
repo_analysis = analyze_repo(temp_dir)
# Create prompt
prompt = f"""Create a comprehensive README.md for this GitHub repository based on its structure and contents.
Repository Structure:
{repo_analysis}
It would be good if the README.md includes the following contents:
- Repository name
- Project description
- Contributing guidelines
Format using markdown with proper sections.
Here is an example of the style and detail you should provide:
---
# ExampleProject
A Python package for advanced data analysis and visualization.
## Installation
```
pip install exampleproject
```
## Usage
```
from exampleproject import analyze
analyze('data.csv')
```
## Contribution
Contributions are welcome! Please open an issue or submit a pull request.
...
"""
# Generate README
result = agent.run(prompt)
return {"readme": result}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
finally:
shutil.rmtree(temp_dir, ignore_errors=True)
return app