Source Code

countstars(json_format=False)

Counts the stars of a specified user and gives a nice comment to the user

Optional[bool] = False

decides wether json or plain text format is required

int

number of stars

Source code in professional_python_exercises_2_githubcli\github_cli.py
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
@app.command()
def countstars(json_format: Optional[bool] = False) -> int:
    """
    Counts the stars of a specified user and gives a nice comment to the user

    Parameters:
    json_format : Optional[bool] = False
      decides wether json or plain text format is required

    Returns:
    starCount : int
      number of stars
    """
    typer.echo("Enter user to count stars for.")
    user = get_user_form_input()
    name = user.name

    repositories = user.get_repos()
    star_count = 0
    for repo in repositories:
        stars = repo.stargazers_count
        star_count += stars
    if json_format:
        output = {}
        output["username"] = name
        output["stars"] = star_count
        print(json.dumps(output))
    else:
        typer.echo(f"User: {name} has {star_count}⭐ in {repositories.totalCount} repositories.")
        typer.echo(_rate_stars_to_repos(star_count, repositories.totalCount))
    return star_count

get_github_token()

Checks, if API Key is set as an environment variable. If not, the user is asked to input it in the console. Length checks enabled for the API key. If key has non-valid length (!=32) the user is asked again to enter a valid key. The key is saved into a local .env file.

str

API Key for the Open Weather Map

Source code in professional_python_exercises_2_githubcli\github_cli.py
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
def get_github_token() -> str:
    """
    Checks, if API Key is set as an environment variable. If not, the user is
    asked to input it in the console. Length checks enabled for the API key. If
    key has non-valid length (!=32) the user is asked again to enter a valid key.
    The key is saved into a local .env file.
    Returns:
    github_token : str
      API Key for the Open Weather Map
    """

    dotenv_file = dotenv.find_dotenv()
    if dotenv_file == "":
        with open(os.getcwd() + "\\.env", mode="w", encoding="utf-8").close():
            pass
        dotenv_file = dotenv.find_dotenv()
    dotenv.load_dotenv(dotenv_file)

    if "TNT_EX2_GITHUB_TOKEN" not in os.environ:
        print(
            "No API Key found in your environment variables. \nPlease look at "
            "https://github.com/settings/tokens for getting an API key and enter "
            "it in the following line:",
            file=sys.stderr,
        )
        os.environ["TNT_EX2_GITHUB_TOKEN"] = input("Please enter your API Key now: \n-->").strip()
    api_key = os.environ["TNT_EX2_GITHUB_TOKEN"]
    if len(api_key) != 40:
        print(
            "Wrong sized GitHub Accoss Token inputted (correct length: 40), "
            f"key found: {api_key}, \nplease look at https://github.com/settings/tokens "
            "for getting an API key and enter it in the following line:",
            file=sys.stderr,
        )
        os.environ["TNT_EX2_GITHUB_TOKEN"] = input("Please enter your API Key now:\n-->").strip()
        return get_github_token()

    dotenv.set_key(dotenv_file, "TNT_EX2_GITHUB_TOKEN", api_key)  # save the API key to .env file
    return api_key

get_user_form_input()

Method used in the app commands to get the user from user input:

user : NamedUser

Source code in professional_python_exercises_2_githubcli\github_cli.py
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
def get_user_form_input() -> NamedUser:
    """
    Method used in the app commands to get the user from user input:

    Returns:
    user : NamedUser
    """
    name = input("User: ")
    if name == "":
        typer.echo("Empty Value inputted, try again")
        sys.exit("Failed to get user input")
    token = get_github_token()
    github_session = Github(token)
    if github_session.search_users(name).totalCount == 0:
        typer.echo("User not found, please try again.")
        sys.exit("Failed to find user.")
    user = github_session.get_user(name)
    return user

getdetails(json_format=False)

Gets the details for a specified user.

Optional[bool] = False

Decides wether nomal text output or json is required

json

Raw details in json format fron the get details request

Source code in professional_python_exercises_2_githubcli\github_cli.py
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
@app.command()
def getdetails(json_format: Optional[bool] = False) -> json:
    """
    Gets the details for a specified user.

    Parameters:
    json_format: Optional[bool] = False
      Decides wether nomal text output or json is required

    Returns:
    raw : json
      Raw details in json format fron the get details request
    """

    typer.echo("Enter user to get details for.")
    user = get_user_form_input()
    name = user.name
    typer.echo(f"Getting the detials for: {name}")

    bio = user.bio
    repocount = user.get_repos().totalCount
    star_count = 0
    for repo in user.get_repos():
        stars = repo.stargazers_count
        star_count += stars
    followers = user.get_followers()
    following = user.get_following()
    blog = user.blog
    company = user.company
    contributions = user.contributions
    created = user.created_at
    email = user.email
    organizations = user.get_orgs()
    avatar_url = user.avatar_url
    starred = user.get_starred()
    subs = user.get_subscriptions()
    watched = user.get_watched()
    location = user.location
    hireable = user.hireable

    raw = user.raw_data

    if json_format:
        print(raw)
    else:
        typer.echo(f"Details about user:{user}, created at {created}, bio: {bio}")
        typer.echo(
            f"Stars: {star_count}, repos: {repocount}, followers: {followers.totalCount}"
            f", following: {following.totalCount}"
        )
        typer.echo(
            f"Contributions: {contributions}, orgs: {organizations.totalCount},"
            f" starred: {starred.totalCount}, subs: {subs.totalCount},"
            f" watched: {watched.totalCount}"
        )
        typer.echo(f"Get a visual impression at:{avatar_url}")
        typer.echo(f"The blog: {blog}")
        typer.echo(f"Mail: {email}, hireable: {hireable}, location: {location}, company: {company}")
    return raw

setstatus()

Sets the status to something related to this repository: Drinking tea.

bool

success if successful status change could be accomplished

Source code in professional_python_exercises_2_githubcli\github_cli.py
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
@app.command()
def setstatus() -> bool:
    """
    Sets the status to something related to this repository: Drinking tea.
    Returns:
    success : bool
      success if successful status change could be accomplished
    """

    mutation = """mutation {
    changeUserStatus(input:{emoji:":tea:", message:"Drinking tea"}) {
        status{
            emoji
            message
        }
    }
    }
    """
    headers = {"Authorization": f"token {get_github_token()}"}
    request = requests.post(
        "https://api.github.com/graphql", json={"query": mutation}, headers=headers, timeout=30
    )
    if request.status_code == 200:
        typer.echo("Success")
        return True
    typer.echo(f"Mutation failed to run by returning code of {request.status_code}. {mutation}")
    return False