from fastapi import FastAPI, HTTPException, Query
from fastapi.responses import HTMLResponse
import requests
import os
from typing import Optional
app = FastAPI(
title="GitHub API Wrapper",
description="یک API بسیط برای تعامل با GitHub API",
version="2.0.0"
)
# توکن دسترسی GitHub (اختیاری - برای rate limit بالاتر)
GITHUB_TOKEN = os.getenv("GITHUB_TOKEN", "")
headers = {
"Authorization": f"token {GITHUB_TOKEN}" if GITHUB_TOKEN else "",
"Accept": "application/vnd.github.v3+json"
}
@app.get("/", response_class=HTMLResponse)
async def root():
"""صفحه اصلی API با ظاهر زیبا"""
return """
GitHub API Wrapper
✅ وضعیت سرویس: فعال
هم اکنون در حال اجرا
دریافت اطلاعات پایه هر کاربر GitHub شامل نام، بیو، تعداد ریپازیتوریها و...
GET /api/user/{username}
مثال: کاربر iYashar
جستجوی پیشرفته در بین میلیونها ریپازیتوری GitHub
GET /api/search/repos?q=query&limit=10
مثال: جستجوی FastAPI
بررسی میزان درخواستهای باقیمانده به GitHub API
GET /api/rate_limit
مشاهده وضعیت فعلی
"""
@app.get("/health")
async def health_check():
"""بررسی سلامت API"""
return {
"status": "healthy",
"message": "API در حال اجراست!",
"version": "2.0.0"
}
@app.get("/api/user/{username}")
async def get_user_info(username: str):
"""دریافت اطلاعات پایه یک کاربر GitHub"""
try:
response = requests.get(
f"https://api.github.com/users/{username}",
headers=headers,
timeout=10
)
if response.status_code == 404:
raise HTTPException(status_code=404, detail="کاربر در GitHub یافت نشد")
elif response.status_code != 200:
raise HTTPException(
status_code=response.status_code,
detail=f"خطا از سمت GitHub: {response.text}"
)
user_data = response.json()
return {
"success": True,
"username": user_data.get("login"),
"name": user_data.get("name"),
"bio": user_data.get("bio"),
"public_repos": user_data.get("public_repos"),
"followers": user_data.get("followers"),
"following": user_data.get("following"),
"avatar_url": user_data.get("avatar_url"),
"profile_url": user_data.get("html_url"),
"created_at": user_data.get("created_at"),
"location": user_data.get("location"),
"company": user_data.get("company")
}
except requests.exceptions.Timeout:
raise HTTPException(status_code=504, detail="اتصال به GitHub timeout خورد")
except requests.exceptions.ConnectionError:
raise HTTPException(status_code=503, detail="عدم توانایی در اتصال به GitHub")
except Exception as e:
raise HTTPException(status_code=500, detail=f"خطای داخلی: {str(e)}")
@app.get("/api/user/{username}/repos")
async def get_user_repos(
username: str,
limit: Optional[int] = Query(5, ge=1, le=100, description="تعداد ریپازیتوریها"),
sort: Optional[str] = Query("updated", description="مرتبسازی بر اساس: created, updated, pushed, full_name")
):
"""دریافت ریپازیتوریهای یک کاربر"""
try:
response = requests.get(
f"https://api.github.com/users/{username}/repos",
params={"sort": sort, "per_page": limit},
headers=headers,
timeout=10
)
if response.status_code == 404:
raise HTTPException(status_code=404, detail="کاربر یافت نشد")
elif response.status_code != 200:
raise HTTPException(status_code=response.status_code, detail="خطا در ارتباط با GitHub")
repos_data = response.json()
repos = []
for repo in repos_data:
repos.append({
"name": repo.get("name"),
"full_name": repo.get("full_name"),
"description": repo.get("description"),
"url": repo.get("html_url"),
"stars": repo.get("stargazers_count"),
"forks": repo.get("forks_count"),
"language": repo.get("language"),
"updated_at": repo.get("updated_at"),
"is_fork": repo.get("fork"),
"size": repo.get("size")
})
return {
"success": True,
"username": username,
"total_repos": len(repos_data),
"repos": repos
}
except Exception as e:
raise HTTPException(status_code=500, detail=f"خطای داخلی: {str(e)}")
@app.get("/api/search/repos")
async def search_repositories(
q: str = Query(..., description="عبارت جستجو"),
limit: Optional[int] = Query(10, ge=1, le=100, description="تعداد نتایج")
):
"""جستجوی ریپازیتوریها در GitHub"""
try:
response = requests.get(
"https://api.github.com/search/repositories",
params={"q": q, "per_page": limit},
headers=headers,
timeout=10
)
if response.status_code != 200:
raise HTTPException(status_code=response.status_code, detail="خطا در ارتباط با GitHub")
search_data = response.json()
results = []
for item in search_data.get("items", []):
results.append({
"name": item.get("name"),
"full_name": item.get("full_name"),
"description": item.get("description"),
"url": item.get("html_url"),
"stars": item.get("stargazers_count"),
"forks": item.get("forks_count"),
"language": item.get("language"),
"owner": item.get("owner", {}).get("login"),
"updated_at": item.get("updated_at"),
"license": item.get("license", {}).get("name") if item.get("license") else None
})
return {
"success": True,
"query": q,
"total_count": search_data.get("total_count"),
"results": results
}
except Exception as e:
raise HTTPException(status_code=500, detail=f"خطای داخلی: {str(e)}")
@app.get("/api/rate_limit")
async def get_rate_limit():
"""بررسی میزان درخواستهای باقیمانده"""
try:
response = requests.get("https://api.github.com/rate_limit", headers=headers, timeout=10)
rate_data = response.json()
return {
"success": True,
"rate_limit": rate_data.get("rate", {}),
"resources": rate_data.get("resources", {})
}
except Exception as e:
raise HTTPException(status_code=500, detail=f"خطای داخلی: {str(e)}")
if __name__ == "__main__":
import uvicorn
uvicorn.run(
"github_api_fixed:app",
host="0.0.0.0",
port=8000,
reload=True,
log_level="info"
)