AI Agents · Lezione

Panoramica della GitHub REST API

Libreria PyGitHub, personal access token e limiti di frequenza delle API

Lezione 1 di 413 passaggi

Panoramica della GitHub REST API è una lezione AI Agents gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento AI Agents, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso AI Agents include 4 lezioni in totale.

PyGitHub — il client Python per GitHub

PyGitHub è la libreria Python più popolare per l'API REST di GitHub. Incapsula l'API HTTP grezza con oggetti Python che rappresentano repository, issue, PR, commit e utenti. Quasi tutte le attività di automazione GitHub iniziano con Github(token=) e g.get_repo().

# Install: pip install PyGitHub
from github import Github
import os

# Authenticate with a personal access token
g = Github(token=os.environ['GITHUB_TOKEN'])

# Get the authenticated user
user = g.get_user()
print(f'Logged in as: {user.login}')
print(f'Name: {user.name}')
print(f'Public repos: {user.public_repos}')

# Get a specific repository
repo = g.get_repo('octocat/Hello-World')
print(f'Repo: {repo.full_name}')
print(f'Stars: {repo.stargazers_count}')

Autenticazione: token di accesso personale

Il metodo di autenticazione più semplice è un token di accesso personale (PAT), ovvero un token a lunga durata associato al Suo account GitHub. Ne crei uno in github.com → Impostazioni → Impostazioni per sviluppatori → Token di accesso personali. Lo memorizzi in una variabile d'ambiente, mai nel codice. Utilizzi PAT con autorizzazioni granulari per una maggiore sicurezza, limitandoli a repository specifici.

from github import Github, Auth
import os

# Method 1: Classic token (works with PyGitHub)
token = os.environ['GITHUB_TOKEN']
g = Github(token=token)

# Method 2: Auth object (recommended for PyGitHub >= 1.59)
auth = Auth.Token(os.environ['GITHUB_TOKEN'])
g = Github(auth=auth)

# Test authentication
try:
    user = g.get_user()
    print(f'Authenticated as {user.login}')
except Exception as e:
    print(f'Auth failed: {e}')
    print('Check: Is GITHUB_TOKEN set? Has it expired?')

g.close()  # close the connection when done

Autenticazione tramite GitHub App

Per gli agenti destinati alla produzione, le GitHub Apps sono preferibili ai PAT. Dispongono di autorizzazioni granulari, possono essere installate su repository specifici e utilizzano token di installazione a breve durata che ruotano automaticamente. Utilizzi github.GithubIntegration per generare token di installazione.

import os
import github

APP_ID = os.environ['GITHUB_APP_ID']
PRIVATE_KEY = os.environ['GITHUB_APP_PRIVATE_KEY']  # PEM content
INSTALLATION_ID = os.environ['GITHUB_INSTALLATION_ID']

# Create GitHub App client
auth = github.Auth.AppAuth(APP_ID, PRIVATE_KEY)
gi = github.GithubIntegration(auth=auth)

# Get installation access token (expires in 1 hour)
installation = gi.get_installation(int(INSTALLATION_ID))
access_token = gi.get_access_token(int(INSTALLATION_ID))

# Use the token with a standard Github client
g = github.Github(token=access_token.token)
print(f'App authenticated, token expires: {access_token.expires_at}')

Limiti di richieste: 5.000 richieste all'ora

L'API REST di GitHub consente 5.000 richieste all'ora agli utenti autenticati. Ogni chiamata API, anche quelle paginate, conta. Verifichi la quota rimanente prima di eseguire operazioni in batch: se la esaurisce, tutte le richieste restituiscono 403 Forbidden fino al ripristino del limite.

from github import Github
import os

g = Github(token=os.environ['GITHUB_TOKEN'])

# Check current rate limit status
rate_limit = g.get_rate_limit()
core = rate_limit.core

print(f'Remaining: {core.remaining}/{core.limit} requests')
print(f'Resets at: {core.reset}')

# Calculate time until reset
import datetime
now = datetime.datetime.utcnow()
reset_in = (core.reset.replace(tzinfo=None) - now).seconds
print(f'Reset in: {reset_in // 60}m {reset_in % 60}s')

# Check before heavy operations
if core.remaining < 100:
    print('WARNING: Rate limit nearly exhausted!')

Ottenere un oggetto repository

L'oggetto repo è il punto di partenza per quasi tutte le operazioni GitHub. Lo ottenga con g.get_repo('owner/name'). Contiene metadati (stelle, fork, descrizione, visibilità) e metodi per accedere a issue, PR, commit, release e altro.

from github import Github
import os

g = Github(token=os.environ['GITHUB_TOKEN'])
repo = g.get_repo('myorg/myrepo')

# Repository metadata
print(f'Full name: {repo.full_name}')
print(f'Description: {repo.description}')
print(f'Default branch: {repo.default_branch}')
print(f'Stars: {repo.stargazers_count}')
print(f'Forks: {repo.forks_count}')
print(f'Open issues: {repo.open_issues_count}')
print(f'Private: {repo.private}')
print(f'Language: {repo.language}')
print(f'Created: {repo.created_at}')
print(f'Last push: {repo.pushed_at}')

Paginazione dell'API — PaginatedList

Le chiamate all'API GitHub che restituiscono molti elementi, come issue, commit e PR, restituiscono un PaginatedList. Può iterarci come farebbe con una normale lista: PyGitHub recupera automaticamente le pagine durante l'iterazione. Tuttavia, chiamare len() su un PaginatedList recupera tutte le pagine, un'operazione che può essere costosa.

from github import Github
import os

g = Github(token=os.environ['GITHUB_TOKEN'])
repo = g.get_repo('myorg/myrepo')

# PaginatedList: fetch pages lazily as you iterate
issues = repo.get_issues(state='open')  # returns PaginatedList

# Iterate — fetches pages 30 at a time automatically
for issue in issues:
    print(f'#{issue.number}: {issue.title}')

# Get first N items without fetching everything
first_10 = list(issues[:10])  # only fetches first page

# Count (WARNING: fetches ALL pages)
total_open = issues.totalCount  # uses the count from API metadata, not iteration

Gestire le eccezioni relative al limite di richieste

Quando supera il limite di richieste, PyGitHub solleva github.GithubException.RateLimitExceededException. La gestisca verificando l'ora di ripristino e attendendo fino al ripristino del limite. Incorpori questa logica in un wrapper per i retry, così da rendere resiliente qualsiasi chiamata GitHub.

from github import Github
from github.GithubException import RateLimitExceededException
import os
import time
import datetime

g = Github(token=os.environ['GITHUB_TOKEN'])

def github_call_with_rate_limit(func, *args, **kwargs):
    while True:
        try:
            return func(*args, **kwargs)
        except RateLimitExceededException:
            rate_limit = g.get_rate_limit()
            reset_time = rate_limit.core.reset.replace(tzinfo=None)
            now = datetime.datetime.utcnow()
            wait_seconds = (reset_time - now).total_seconds() + 10

            print(f'Rate limit exceeded. Sleeping {wait_seconds:.0f}s until reset...')
            time.sleep(max(wait_seconds, 1))

# Usage
repo = github_call_with_rate_limit(
    g.get_repo, 'myorg/myrepo'
)

Cercare in GitHub

Utilizzi g.search_issues(), g.search_repositories() e g.search_code() per eseguire ricerche GitHub in tutti i repository pubblici e nei Suoi repository privati. Queste funzioni usano la Search API, che ha un limite di richieste separato pari a 30 richieste al minuto.

from github import Github
import os

g = Github(token=os.environ['GITHUB_TOKEN'])

# Search issues across all your repos
results = g.search_issues(
    query='is:open is:issue label:bug user:myorg',
    sort='created',
    order='desc'
)

print(f'Found {results.totalCount} open bugs')
for issue in results[:10]:
    print(f'{issue.repository.full_name}#{issue.number}: {issue.title}')

# Search for repos using a specific package
repos = g.search_repositories(
    query='topic:machine-learning language:python stars:>100'
)
for repo in repos[:5]:
    print(f'{repo.full_name}: {repo.stargazers_count} stars')

Lavorare con più repository

Gli agenti devono spesso operare su più repository di un'organizzazione. Utilizzi g.get_organization() per elencare tutti i repository di un'organizzazione, quindi li elabori in un ciclo. Filtri per linguaggio, stato di archiviazione o data dell'attività per evitare di elaborare repository inattivi.

from github import Github
import os
import datetime

g = Github(token=os.environ['GITHUB_TOKEN'])
org = g.get_organization('myorg')

# Get all active Python repos
cutoff = datetime.datetime.now() - datetime.timedelta(days=180)

active_repos = [
    repo
    for repo in org.get_repos(type='all')
    if (
        not repo.archived
        and repo.language == 'Python'
        and repo.pushed_at
        and repo.pushed_at.replace(tzinfo=None) > cutoff
    )
]

print(f'Active Python repos: {len(active_repos)}')
for repo in active_repos[:5]:
    print(f'  {repo.name}: last push {repo.pushed_at.date()}')

Leggere il contenuto dei file da un repository

Utilizzi repo.get_contents(path) per leggere qualsiasi file di un repository. Il contenuto è codificato in base64, ma PyGitHub lo decodifica automaticamente tramite la proprietà .decoded_content. Specifichi un branch o lo SHA di un commit con il parametro ref.

from github import Github
import os

g = Github(token=os.environ['GITHUB_TOKEN'])
repo = g.get_repo('myorg/myrepo')

# Read a file from the default branch
contents = repo.get_contents('README.md')
readme_text = contents.decoded_content.decode('utf-8')
print(f'README ({len(readme_text)} chars):')
print(readme_text[:200])

# Read from a specific branch
requirements = repo.get_contents(
    'requirements.txt',
    ref='feature/new-deps'
)
deps = requirements.decoded_content.decode('utf-8')
print('Dependencies:', deps[:300])

Gestire le eccezioni GitHub comuni

PyGitHub solleva GithubException per tutti gli errori dell'API. Sottoclassi comuni: UnknownObjectException (404 — repository o issue non trovati), BadCredentialsException (401 — token non valido), RateLimitExceededException (403 — limite di richieste superato). Intercetti sempre queste eccezioni in modo specifico.

from github import Github
from github.GithubException import (
    GithubException, UnknownObjectException,
    BadCredentialsException, RateLimitExceededException
)
import os

g = Github(token=os.environ['GITHUB_TOKEN'])

def get_repo_safely(repo_full_name):
    try:
        return g.get_repo(repo_full_name)
    except BadCredentialsException:
        print('ERROR: GitHub token is invalid or expired')
        return None
    except UnknownObjectException:
        print(f'ERROR: Repo not found: {repo_full_name}')
        print('Check: typo in name? Private repo you can\'t access?')
        return None
    except RateLimitExceededException:
        print('ERROR: GitHub rate limit exceeded, retry later')
        return None
    except GithubException as e:
        print(f'GitHub API error {e.status}: {e.data}')
        return None

Verifica rapida: limite di richieste

Verifichi la Sua comprensione dei limiti di richieste dell'API GitHub.

Riepilogo dell'API REST di GitHub

Ora è in grado di connettersi a GitHub con PyGitHub:

  • Github(token=) o Github(auth=Auth.Token(...)) per l'autenticazione tramite PAT
  • GitHub Apps con GithubIntegration per agenti destinati alla produzione con autorizzazioni granulari
  • Limite di richieste: 5.000 richieste all'ora; verifichi con g.get_rate_limit(); gestisca RateLimitExceededException
  • PaginatedList: iterazione lazy; utilizzi .totalCount per ottenere il numero di elementi senza recuperare tutte le pagine
  • g.get_repo('owner/name') — il punto di accesso per le operazioni a livello di repository
  • Intercetti esplicitamente UnknownObjectException (404) e BadCredentialsException (401)
Gratis per iniziare

Impara AI Agents con un tutor IA — gratis

Scrivi ed esegui vero codice nel tuo browser, ricevi aiuto istantaneo da un tutor IA disponibile 24/7, e riprendi da dove hai lasciato sul web o nell'app.

Corsi
60
Lezioni
239

Domande Frequenti

La lezione «Panoramica della GitHub REST API» è gratuita?

Sì — il testo completo di «Panoramica della GitHub REST API» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso AI Agents, passa a CoddyKit PRO. Il corso AI Agents include 4 lezioni in totale.

Cosa imparerò in «Panoramica della GitHub REST API»?

Libreria PyGitHub, personal access token e limiti di frequenza delle API Eserciti AI Agents con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare AI Agents?

Non è richiesta alcuna esperienza precedente. AI Agents su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.

Quanto tempo richiede la lezione «Panoramica della GitHub REST API»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione AI Agents?

Sì. Ogni lezione AI Agents include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Panoramica della GitHub REST API
  2. Elenco e gestione delle issue
  3. Commenti automatizzati nelle PR
  4. Cronologia dei commit e analisi dei diff
← Torna a AI Agents