{"id":91,"library":"PyGithub","title":"GitHub API (PyGithub)","description":"Community-maintained Python library for GitHub REST API v3. Current version is 2.8.1 (Feb 2026). Note: package name on PyPI is 'PyGithub' (capital P and G) but imports as 'github' (lowercase). Not an official GitHub SDK.","status":"active","version":"2.8.1","language":"python","source_language":"en","source_url":"https://github.com/PyGithub/PyGithub","tags":["github","git","api","rest","vcs","python"],"install":[{"cmd":"pip install PyGithub","lang":"bash","label":"Python"}],"dependencies":[],"imports":[{"note":"Package installs as PyGithub but imports as github. import PyGithub raises ModuleNotFoundError.","wrong":"import PyGithub","symbol":"Github, Auth","correct":"from github import Github, Auth"}],"quickstart":{"code":"from github import Github, Auth\n\nauth = Auth.Token(\"your_token\")\ng = Github(auth=auth)\n\nrepo = g.get_repo(\"owner/repo\")\nfor issue in repo.get_issues(state='open'):\n    print(issue.title)\n\ng.close()","lang":"python","description":"Minimal authenticated GitHub API call using PyGithub 2.x auth pattern."},"warnings":[{"fix":"auth = Auth.Token('ghp_...'); g = Github(auth=auth)","message":"Github(login_or_token='token') is the old 1.x pattern. In 2.x use Auth.Token() and pass via auth= argument.","severity":"breaking","affected_versions":"< 2.0"},{"fix":"Use commit.files.totalCount or iterate instead of len()","message":"Commit.files used to return list[File], now returns PaginatedList[File]. len(commit.files) raises TypeError.","severity":"breaking","affected_versions":"< 2.4"},{"fix":"Use .totalCount property instead of len()","message":"repo.compare().commits used to return list[Commit], now returns PaginatedList[Commit]. len() raises TypeError.","severity":"breaking","affected_versions":"< 2.2"},{"fix":"Add tzinfo=timezone.utc to any datetime instances used in comparisons","message":"datetime objects returned by the API are now timezone-aware (UTC). Comparing with naive datetime instances breaks.","severity":"breaking","affected_versions":"< 2.0"},{"fix":"pip install PyGithub && from github import Github","message":"pip install name is PyGithub (capital P, G) but the import is 'from github import Github'. The casing mismatch trips up agents constantly.","severity":"gotcha","affected_versions":"all"},{"fix":"Use as context manager: with Github(auth=auth) as g: ...","message":"g.close() must be called after use to close the underlying connection pool. Omitting causes ResourceWarning in tests.","severity":"gotcha","affected_versions":"all"},{"fix":"Replace position=N with line=N","message":"PullRequest.create_review_comment argument renamed from position= to line=. Keyword callers break silently.","severity":"gotcha","affected_versions":"< 1.57"},{"fix":"For official REST access use requests + Authorization header directly, or use PyGithub.","message":"This is a community SDK, not an official GitHub product. GitHub has no official Python SDK. Agents often assume otherwise.","severity":"gotcha","affected_versions":"all"},{"fix":"Ensure the GitHub token is correct, not expired, and has the required scopes for the API calls being made. Check GitHub token settings or regenerate a new token with appropriate permissions.","message":"The provided GitHub token is invalid, expired, or lacks the necessary permissions (e.g., 'public_repo' for public repos, 'repo' for private). This results in a BadCredentialsException.","severity":"breaking","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-05-12T07:58:39.537Z","next_check":"2026-06-17T00:00:00.000Z","problems":[{"fix":"Ensure PyGithub is installed in your current environment using: pip install PyGithub","cause":"The PyGithub package is not installed or is installed in a different Python environment.","error":"ModuleNotFoundError: No module named 'github'"},{"fix":"Use the older authentication method: from github import Github; g = Github('access_token')","cause":"The 'Auth' module is not available in the installed version of PyGithub.","error":"ImportError: cannot import name 'Auth' from 'github'"},{"fix":"Correct the import statement to: from github import Github","cause":"The class name is case-sensitive; 'GitHub' should be 'Github'.","error":"ImportError: cannot import name 'GitHub' from 'github'"},{"fix":"Use the 'get_dir_contents' method instead: contents = repo.get_dir_contents('path')","cause":"The 'get_contents' method is not available in the 'Repository' class.","error":"AttributeError: 'Repository' object has no attribute 'get_contents'"},{"fix":"Ensure the repository or user exists and is accessible: repo = g.get_repo('owner/repo')","cause":"A method returned None, possibly due to an invalid repository or user.","error":"TypeError: 'NoneType' object is not iterable"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":80,"quickstart_tag":"verified","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.82,"mem_mb":17.2,"disk_size":"44.7M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.61,"mem_mb":17.2,"disk_size":"45M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.11,"mem_mb":19.9,"disk_size":"48.3M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.93,"mem_mb":19.8,"disk_size":"49M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.38,"mem_mb":19.7,"disk_size":"39.8M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.37,"mem_mb":19.7,"disk_size":"40M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.87,"mem_mb":18.8,"disk_size":"39.5M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.91,"mem_mb":18.8,"disk_size":"40M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.81,"mem_mb":17.9,"disk_size":"44.8M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.71,"mem_mb":17.9,"disk_size":"45M"}]},"quickstart_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"quickstart runs on critical runtimes, recently tested","results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]}}