Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions .github/workflows/python-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,7 @@ jobs:
- name: uv sync
run: uv sync

- name: Debug CLI
- name: Get CLI version
run: |
source .venv/bin/activate
github-rest-cli -h
env:
GITHUB_AUTH_TOKEN: f@k3-t0k3n
github-rest-cli --version
16 changes: 14 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
# GitHub REST API

### Usage
## Installation

Install using `pip`:
```shell
pip install github-rest-cli
```

Install using `uv`:
```shell
uv pip install github-rest-cli
```

## Usage

Set up python package dependencies in `pyproject.toml`:
```shell
Expand All @@ -24,7 +36,7 @@ export GITHUB_AUTH_TOKEN="<github-auth-token>"

Run cli:
```shell
github-rest-cli -h
github-rest-cli -v
```

### Dynaconf
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "github-rest-cli"
version = "1.0.0"
version = "1.0.1"
description = "GitHub REST API cli"
authors = [
{ name = "lbrealdev", email = "lbrealdeveloper@gmail.com" }
Expand Down
1 change: 0 additions & 1 deletion src/github_rest_cli/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
__version__ = "0.1.0"
42 changes: 30 additions & 12 deletions src/github_rest_cli/api.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import requests
from github_rest_cli.globals import GITHUB_URL, HEADERS
from github_rest_cli.globals import GITHUB_URL, get_headers
from github_rest_cli.utils import rich_output, rprint


Expand Down Expand Up @@ -40,21 +40,34 @@ def build_url(*segments: str) -> str:
return f"{base}/{path}"


def fetch_user():
def fetch_user() -> str:
headers = get_headers()
url = build_url("user")
response = request_with_handling("GET", url, headers=HEADERS)
response = request_with_handling("GET", url, headers=headers)
if response:
data = response.json()
return data.get("login")
return None


def get_repository(owner: str, name: str, org: str = None):
def get_repository(name: str, org: str = None):
owner = fetch_user()
headers = get_headers()
url = build_url("repos", org or owner, name)
response = request_with_handling("GET", url, headers=HEADERS)
response = request_with_handling(
"GET",
url,
headers=headers,
error_msg={
401: "Unauthorized access. Please check your token or credentials.",
404: "The requested repository does not exist.",
},
)

if response:
data = response.json()
rprint(data)
return None


def create_repository(owner: str, name: str, visibility: str, org: str = None):
Expand All @@ -67,12 +80,13 @@ def create_repository(owner: str, name: str, visibility: str, org: str = None):
if visibility == "private":
data["private"] = True

headers = get_headers()
url = build_url("orgs", org, "repos") if org else build_url("user", "repos")

return request_with_handling(
"POST",
url,
headers=HEADERS,
headers=headers,
json=data,
success_msg=f"Repository successfully created in {owner or org }/{name}",
error_msg={
Expand All @@ -83,21 +97,23 @@ def create_repository(owner: str, name: str, visibility: str, org: str = None):


def delete_repository(owner: str, name: str, org: str = None):
headers = get_headers()
url = build_url("repos", org, name) if org else build_url("repos", owner, name)

return request_with_handling(
"DELETE",
url,
headers=HEADERS,
headers=headers,
success_msg=f"Repository sucessfully deleted in {owner or org}/{name}",
error_msg={
403: "The authenticated user does not have sufficient permissions to delete this repository.",
404: "The requested repository was not found.",
404: "The requested repository does not exist.",
},
)


def list_repositories(page: int, property: str, role: str):
headers = get_headers()
url = build_url("user", "repos")

params = {"per_page": page, "sort": property, "type": role}
Expand All @@ -106,7 +122,7 @@ def list_repositories(page: int, property: str, role: str):
"GET",
url,
params=params,
headers=HEADERS,
headers=headers,
error_msg={401: "Unauthorized access. Please check your token or credentials."},
)

Expand All @@ -121,6 +137,7 @@ def list_repositories(page: int, property: str, role: str):
def dependabot_security(owner: str, name: str, enabled: bool, org: str = None):
is_enabled = bool(enabled)

headers = get_headers()
url = build_url("repos", org, name) if org else build_url("repos", owner, name)
security_urls = ["vulnerability-alerts", "automated-security-fixes"]

Expand All @@ -130,7 +147,7 @@ def dependabot_security(owner: str, name: str, enabled: bool, org: str = None):
request_with_handling(
"PUT",
url=full_url,
headers=HEADERS,
headers=headers,
success_msg=f"Enabled {endpoint}",
error_msg={
401: "Unauthorized. Please check your credentials.",
Expand All @@ -141,13 +158,14 @@ def dependabot_security(owner: str, name: str, enabled: bool, org: str = None):
request_with_handling(
"DELETE",
url=full_url,
headers=HEADERS,
headers=headers,
success_msg=f"Dependabot has been disabled on repository {owner or org}/{name}.",
error_msg={401: "Unauthorized. Please check your credentials."},
)


def deployment_environment(owner: str, name: str, env: str, org: str = None):
headers = get_headers()
url = (
build_url("repos", org, name, "environments", env)
if org
Expand All @@ -157,7 +175,7 @@ def deployment_environment(owner: str, name: str, env: str, org: str = None):
return request_with_handling(
"PUT",
url,
headers=HEADERS,
headers=headers,
success_msg=f"Environment {env} has been created successfully in {owner or org}/{name}.",
error_msg={
422: f"Failed to create repository enviroment {owner or org}/{name}"
Expand Down
23 changes: 10 additions & 13 deletions src/github_rest_cli/config.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
from dynaconf import Dynaconf, Validator

settings = Dynaconf(
# Default environment variables prefix.
envvar_prefix="GITHUB",
# Source configuration files.
settings_files=["../../settings.toml", "../../.secrets.toml"],
environments=["development", "testing", "production"],
env_switcher="SET_ENV",
# The script will not work if the variables
# defined in the Validator class are not defined.
validators=[
Validator(
"AUTH_TOKEN",
must_exist=True,
messages={
"must_exist_true": "Environment variable GITHUB_AUTH_TOKEN is not set. Please set it and try again."
},
),
],
)

# The CLI will not work if the variable
# defined in the Validator class are not defined.
AUTH_TOKEN_VALIDATOR = Validator(
"AUTH_TOKEN",
must_exist=True,
messages={
"must_exist_true": "Environment variable GITHUB_AUTH_TOKEN is not set. Please set it and try again."
},
)

# `envvar_prefix` = export envvars with `export DYNACONF_FOO=bar`.
Expand Down
25 changes: 18 additions & 7 deletions src/github_rest_cli/globals.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
from github_rest_cli.config import settings
from github_rest_cli.config import settings, AUTH_TOKEN_VALIDATOR
from dynaconf.base import ValidationError
import logging


GITHUB_URL = "https://api.github.com"
GITHUB_TOKEN = f"{settings.AUTH_TOKEN}"
logger = logging.getLogger(__name__)


def get_headers():
try:
AUTH_TOKEN_VALIDATOR.validate(settings)
except ValidationError as e:
logger.error(str(e))
raise SystemExit(1)

HEADERS = {
"Accept": "application/vnd.github+json",
"X-GitHub-Api-Version": "2022-11-28",
"Authorization": f"token {GITHUB_TOKEN}",
}
return {
"Accept": "application/vnd.github+json",
"X-GitHub-Api-Version": "2022-11-28",
"Authorization": f"token {settings.AUTH_TOKEN}",
}
Loading