Metadata-Version: 2.4
Name: github_modules
Version: 1.0.1
Summary: Modules for interacting with GitHub API.
Home-page: https://github.com/python-codelover/github-modules
Author: Pavan Bhatt
Author-email: pavanhbhatt1@gmail.com
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Requires-Dist: requests
Dynamic: author
Dynamic: author-email
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

The best way to interact with GitHub API.

> **Note:** _This module is useful for the GitHub API_ <br>
> Your GitHub API URL should be: https://api.github.com


# Prerequisites
```python
from github_module import GitHubHelper
```

# Getting Started

## Connectivity to GitHub

Instantiate the `GitHubHelper` class with your GitHub API URL and Personal Access Token:

```python
github_helper = GitHubHelper(GITHUB_API, API_TOKEN)
```
______________________________________________________________________________
______________________________________________________________________________
# Rate Limit & Token
______________________________________________________________________________
______________________________________________________________________________
## 1. Get the current API rate limit

```python
github_helper = GitHubHelper(GITHUB_API, API_TOKEN)

remaining = github_helper.get_rate_limit()
print(f"Remaining requests: {remaining}")
```

Return:
- `int`: Remaining API requests.
- `-1`: If there was an error.
______________________________________________________________________________
## 2. Get PAT token expiry days

```python
github_helper = GitHubHelper(GITHUB_API, API_TOKEN)

days = github_helper.get_token_expiry_days()
if days >= 0:
    print(f"Token expires in {days} days.")
elif days == -1:
    print("Token has no expiration.")
else:
    print("Error checking token expiration.")
```

Return:
- `int`: Number of days until token expires.
- `-1`: Token has no expiration.
- `-2`: Error occurred.
______________________________________________________________________________
______________________________________________________________________________
# Repository Operations
______________________________________________________________________________
______________________________________________________________________________
## 3. Check if a repository exists

```python
github_helper = GitHubHelper(GITHUB_API, API_TOKEN)

result = github_helper.check_repository(owner="octocat", repo="Hello-World")
print(result["status"])   # "exists", "not_found", "forbidden", "rate_limit_exceeded", or "error"
print(result["message"])
```

Parameters:
- `owner` (str): Username or organization that owns the repository.
- `repo` (str): Name of the repository.

Return:
- `dict` with keys `status` and `message`.
______________________________________________________________________________
## 4. Check if a repository is read-only

```python
github_helper = GitHubHelper(GITHUB_API, API_TOKEN)

result = github_helper.is_repo_read_only(owner="octocat", repo="Hello-World")
if result is True:
    print("Repository is read-only.")
elif result is False:
    print("Repository is writable.")
else:
    print("Could not determine (error or rate limit).")
```

Parameters:
- `owner` (str): Username or organization that owns the repository.
- `repo` (str): Name of the repository.

Return:
- `True`: Repository is read-only.
- `False`: Repository is writable.
- `None`: Error or rate limit too low.
______________________________________________________________________________
## 5. Get repository details

```python
github_helper = GitHubHelper(GITHUB_API, API_TOKEN)

details = github_helper.get_repo_details(owner="octocat", repo="Hello-World")
if details:
    print(f"Language: {details['language']}")
    print(f"Stars: {details['stars']}")
    print(f"Default branch: {details['default_branch']}")
```

Parameters:
- `owner` (str): Username or organization.
- `repo` (str): Repository name.

Return:
- `Dictionary` with keys: `name`, `full_name`, `description`, `private`, `language`, `stars`, `forks`, `open_issues`, `default_branch`, `created_at`, `updated_at`, `url`.
- `None`: If the request fails.
______________________________________________________________________________
## 6. List repositories

```python
github_helper = GitHubHelper(GITHUB_API, API_TOKEN)

# List org repos
repos = github_helper.list_repos(org="my-org")

# List your own repos
repos = github_helper.list_repos()

if repos:
    for repo in repos:
        print(f"{repo['full_name']} - {'private' if repo['private'] else 'public'}")
```

Parameters:
- `org` (str, optional): Organization name. If None, lists repos for authenticated user.
- `repo_type` (str, optional): Filter type — 'all', 'public', 'private', 'forks', 'sources', 'member'. Default 'all'.
- `per_page` (int, optional): Results per page (max 100). Default 100.

Return:
- `List` of dicts with `name`, `full_name`, `private`, `url`.
- `None`: If the request fails.
______________________________________________________________________________
## 7. Create a repository

```python
github_helper = GitHubHelper(GITHUB_API, API_TOKEN)

# Create in user account
repo_url = github_helper.create_repo("my-new-repo", private=True, description="My new repo")

# Create in an organization
repo_url = github_helper.create_repo("my-new-repo", private=True, org="my-org")

if repo_url:
    print(f"Created: {repo_url}")
```

Parameters:
- `name` (str): Name of the repository.
- `private` (bool, optional): Whether the repo should be private. Default `True`.
- `description` (str, optional): Repository description.
- `org` (str, optional): Organization to create the repo in. If None, creates in user's account.

Return:
- `URL` (str): URL of the created repository.
- `None`: If creation failed.
______________________________________________________________________________
## 8. Delete a repository

```python
github_helper = GitHubHelper(GITHUB_API, API_TOKEN)

if github_helper.delete_repo(owner="octocat", repo="old-repo"):
    print("Repository deleted.")
else:
    print("Failed to delete repository.")
```

Parameters:
- `owner` (str): Username or organization.
- `repo` (str): Repository name.

Return:
- `True`: If deleted successfully.
- `False`: If the operation failed.
______________________________________________________________________________
______________________________________________________________________________
# Branch Operations
______________________________________________________________________________
______________________________________________________________________________
## 9. List branches

```python
github_helper = GitHubHelper(GITHUB_API, API_TOKEN)

branches = github_helper.list_branches(owner="octocat", repo="Hello-World")
if branches:
    print(f"Branches: {', '.join(branches)}")
```

Parameters:
- `owner` (str): Username or organization.
- `repo` (str): Repository name.

Return:
- `List` of branch name strings.
- `None`: If the request fails.
______________________________________________________________________________
## 10. Create a branch

```python
github_helper = GitHubHelper(GITHUB_API, API_TOKEN)

# Create from default branch
if github_helper.create_branch("octocat", "Hello-World", "feature/my-feature"):
    print("Branch created.")

# Create from a specific branch
if github_helper.create_branch("octocat", "Hello-World", "hotfix/bug", from_branch="main"):
    print("Branch created.")
```

Parameters:
- `owner` (str): Username or organization.
- `repo` (str): Repository name.
- `branch_name` (str): Name of the new branch.
- `from_branch` (str, optional): Source branch. Defaults to the repo's default branch.

Return:
- `True`: If created successfully.
- `False`: If the operation failed.
______________________________________________________________________________
## 11. Delete a branch

```python
github_helper = GitHubHelper(GITHUB_API, API_TOKEN)

if github_helper.delete_branch("octocat", "Hello-World", "feature/old-feature"):
    print("Branch deleted.")
else:
    print("Failed to delete branch.")
```

Parameters:
- `owner` (str): Username or organization.
- `repo` (str): Repository name.
- `branch_name` (str): Name of the branch to delete.

Return:
- `True`: If deleted successfully.
- `False`: If the operation failed.
______________________________________________________________________________
______________________________________________________________________________
# File Operations
______________________________________________________________________________
______________________________________________________________________________
## 12. Get file content

```python
github_helper = GitHubHelper(GITHUB_API, API_TOKEN)

file = github_helper.get_file_content("octocat", "Hello-World", "README.md")
if file:
    print(file["content"])
    print(f"SHA: {file['sha']}")
```

Parameters:
- `owner` (str): Username or organization.
- `repo` (str): Repository name.
- `path` (str): Path to the file in the repo.
- `branch` (str, optional): Branch to read from. Defaults to the repo's default branch.

Return:
- `Dictionary` with `content` (decoded string), `sha`, and `path`.
- `None`: If the request fails.
______________________________________________________________________________
## 13. Create or update a file

```python
github_helper = GitHubHelper(GITHUB_API, API_TOKEN)

# Create a new file
url = github_helper.create_or_update_file(
    "octocat", "Hello-World",
    path="docs/notes.md",
    content="# Notes\n\nSome notes here.",
    message="Add notes file"
)

# Update an existing file (sha is required)
file = github_helper.get_file_content("octocat", "Hello-World", "docs/notes.md")
url = github_helper.create_or_update_file(
    "octocat", "Hello-World",
    path="docs/notes.md",
    content="# Updated Notes\n\nUpdated content.",
    message="Update notes file",
    sha=file["sha"]
)

if url:
    print(f"File available at: {url}")
```

Parameters:
- `owner` (str): Username or organization.
- `repo` (str): Repository name.
- `path` (str): Path for the file in the repo.
- `content` (str): File content as a plain string.
- `message` (str): Commit message.
- `branch` (str, optional): Branch to commit to. Defaults to the default branch.
- `sha` (str, optional): SHA of the existing file (required for updates, omit for new files).

Return:
- `URL` (str): URL of the file on GitHub.
- `None`: If the operation failed.
______________________________________________________________________________
______________________________________________________________________________
# Pull Request Operations
______________________________________________________________________________
______________________________________________________________________________
## 14. List pull requests

```python
github_helper = GitHubHelper(GITHUB_API, API_TOKEN)

prs = github_helper.list_pull_requests("octocat", "Hello-World", state="open")
if prs:
    for pr in prs:
        print(f"#{pr['number']} {pr['title']} — {pr['url']}")
```

Parameters:
- `owner` (str): Username or organization.
- `repo` (str): Repository name.
- `state` (str, optional): 'open', 'closed', or 'all'. Default 'open'.

Return:
- `List` of dicts with `number`, `title`, `state`, `author`, `head`, `base`, `url`, `created_at`.
- `None`: If the request fails.
______________________________________________________________________________
## 15. Create a pull request

```python
github_helper = GitHubHelper(GITHUB_API, API_TOKEN)

pr_url = github_helper.create_pull_request(
    owner="octocat",
    repo="Hello-World",
    title="Add new feature",
    head="feature/my-feature",
    base="main",
    body="This PR adds a new feature."
)
if pr_url:
    print(f"PR created: {pr_url}")
```

Parameters:
- `owner` (str): Username or organization.
- `repo` (str): Repository name.
- `title` (str): Title of the pull request.
- `head` (str): Branch containing the changes.
- `base` (str): Branch to merge into.
- `body` (str, optional): Description of the pull request.

Return:
- `URL` (str): URL of the created PR.
- `None`: If creation failed.
______________________________________________________________________________
______________________________________________________________________________
# Issue Operations
______________________________________________________________________________
______________________________________________________________________________
## 16. List issues

```python
github_helper = GitHubHelper(GITHUB_API, API_TOKEN)

# List all open issues
issues = github_helper.list_issues("octocat", "Hello-World")

# List closed issues with a specific label
issues = github_helper.list_issues("octocat", "Hello-World", state="closed", labels="bug")

if issues:
    for issue in issues:
        print(f"#{issue['number']} {issue['title']} — {issue['url']}")
```

Parameters:
- `owner` (str): Username or organization.
- `repo` (str): Repository name.
- `state` (str, optional): 'open', 'closed', or 'all'. Default 'open'.
- `labels` (str, optional): Comma-separated label names to filter by.

Return:
- `List` of dicts with `number`, `title`, `state`, `author`, `labels`, `url`, `created_at`.
- `None`: If the request fails.
______________________________________________________________________________
# Data Privacy Note

🔒 **We respect your privacy**: This module does **not** store any of your data anywhere. It simply interacts with the GitHub API to perform the requested operations. Ensure you manage your connection details securely.

# Release Notes

## Latest Release: 1.0.0 (June 2025)
- Restructured the entire module — each function now has proper input validation and error handling
- Fixed `datetime.utcnow()` deprecation (Python 3.12+) — now uses `timezone.utc`
- Fixed `is_repo_read_only` `KeyError` when `permissions` field is absent
- Added input validation to all functions
- **New functions:**
  - `get_repo_details` — Full repository metadata
  - `list_repos` — List repos for a user or organization
  - `create_repo` — Create a new repository
  - `delete_repo` — Delete a repository
  - `list_branches` — List all branches
  - `create_branch` — Create a new branch
  - `delete_branch` — Delete a branch
  - `get_file_content` — Read a file from a repo
  - `create_or_update_file` — Create or update a file in a repo
  - `list_pull_requests` — List pull requests
  - `create_pull_request` — Create a pull request
  - `list_issues` — List issues

## Previous Releases:
- 0.4.2 — Package renamed from github_module to github_modules
- 0.4.1 (21 Aug 2024) — README updates
- 0.4 (21 Aug 2024) — Added `get_token_expiry_days`
- 0.3 (05 Aug 2024) — Added `is_repo_read_only`
- 0.2 (05 Aug 2024) — Added `check_repository`
- 0.1 (05 Aug 2024) — Initial release with `get_rate_limit`
