Skip to content

Commit

Permalink
final exercise files
Browse files Browse the repository at this point in the history
  • Loading branch information
nnja committed Mar 20, 2019
1 parent 3631ac6 commit 65c9882
Show file tree
Hide file tree
Showing 17 changed files with 565 additions and 0 deletions.
12 changes: 12 additions & 0 deletions pyworkshop/2_intermediate_python/chapter3/gh_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class GitHubRepo:

def __init__(self, name, language, num_stars):
self.name = name
self.language = language
self.num_stars = num_stars

def __str__(self):
return f"-> {self.name} is a {self.language} repo with {self.num_stars} stars."

def __repr__(self):
return f'GitHubRepo({self.name}, {self.language}, {self.num_stars})'
13 changes: 13 additions & 0 deletions pyworkshop/2_intermediate_python/chapter4/gh_exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
"""
GitHub API Application: Custom Exception Classes
"""

class GitHubApiException(Exception):

def __init__(self, status_code):
if status_code == 403:
message = "Rate limit reached. Please wait a minute and try again."
else:
message = f"HTTP Status Code was: {status_code}."

super().__init__(message)
101 changes: 101 additions & 0 deletions pyworkshop/2_intermediate_python/chapter6/optional_adv_exercise.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#!/usr/bin/env python3

"""
A small command line Python program that uses the GitHub search API to list
the top projects by language, based on stars.
GitHub Search API documentation: https://developer.github.com/v3/search/
Requests to this endpoint are rate limited to 10 requests per
minute per IP address.
"""

import sys
import requests


GITHUB_API_URL = "https://api.github.com/search/repositories"


class GitHubApiException(Exception):

def __init__(self, status_code):
if status_code == 403:
message = "Rate limit reached. Please wait a minute and try again."
else:
message = f"HTTP Status Code was: {status_code}."

super().__init__("A GitHub API Error Occurred: " + message)


class GitHubRepo:
"""
A class used to represent a single GitHub Repository.
"""

def __init__(self, name, language, num_stars):
self.name = name
self.language = language
self.num_stars = num_stars

def __str__(self):
return f"-> {self.name} is a {self.language} repo with {self.num_stars} stars."

def __repr__(self):
return f'GitHubRepo({self.name}, {self.language}, {self.num_stars})'


def create_query(languages, min_stars):
"""
Create the query string for the GitHub search API,
based on the minimum amount of stars for a project, and
the provided programming languages.
"""
# Notice we are calling .strip() on each language, to clear it of leading
# and trailing whitespace
query = " ".join(f"language:{language.strip()}" for language in languages)
query = query + f" stars:>{min_stars}"
return query


def repos_with_most_stars(languages, min_stars=50000, sort="stars", order="desc"):
query = create_query(languages, min_stars)
parameters = {"q": query, "sort": sort, "order": order}
response = requests.get(GITHUB_API_URL, params=parameters)

if response.status_code != 200:
raise GitHubApiException(response.status_code)

response_json = response.json()
items = response_json["items"]
return [GitHubRepo(item["name"], item["language"], item["stargazers_count"]) for item in items]


if __name__ == "__main__":
# Accept an optional argument for minimum number of stars from the command line
# $ ./gh_api 100000 # means an input of 100,000 minimum stars.
script_arguments = sys.argv
min_stars = 50000

if len(script_arguments) >= 2:
try:
min_stars = int(script_arguments[1])
except ValueError:
sys.exit("Error: Command line argument must be a valid number.")

# Accept the list of languages from the user, or provide a default list.
languages = input(
"Enter a comma separated list of programming languages (or press ENTER for defaults): "
).strip()
if not languages:
languages = ["python", "javascript", "ruby"]
else:
languages = languages.split(",")

# Get the results
result_repos = repos_with_most_stars(languages=languages, min_stars=min_stars)
if not result_repos:
print("No Results Found.")
else:
for repo in result_repos:
print(repo)
40 changes: 40 additions & 0 deletions pyworkshop/2_intermediate_python/chapter8/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""
A Simple Flask Web Application interface
For viewing popular GitHub Repos sorted by stars using the
GitHub Search API.
To run:
(env) $ python -m pip install -r requirements.txt
(env) $ export FLASK_ENV=development; python3 -m flask run
"""
from flask import Flask, render_template, request

from repos.api import repos_with_most_stars
from repos.exceptions import GitHubApiException

app = Flask(__name__)

available_languages = ["Python", "JavaScript", "Ruby", "Java"]


@app.route('/', methods=['POST', 'GET'])
def index():
if request.method == 'GET':
# Use the list of all languages
selected_languages = available_languages
elif request.method == 'POST':
# Use the languages we selected in the request form
selected_languages = request.form.getlist("languages")

results = repos_with_most_stars(selected_languages)

return render_template(
'index.html',
selected_languages=selected_languages,
available_languages=available_languages,
results=results)


@app.errorhandler(GitHubApiException)
def handle_api_error(error):
return render_template('error.html', message=error)
Empty file.
34 changes: 34 additions & 0 deletions pyworkshop/2_intermediate_python/chapter8/repos/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import requests

from repos.exceptions import GitHubApiException
from repos.models import GitHubRepo


GITHUB_API_URL = "https://api.github.com/search/repositories"


def create_query(languages, min_stars):
"""
Create the query string for the GitHub search API,
based on the minimum amount of stars for a project, and
the provided programming languages.
"""
# Notice we are calling .strip() on each language,
# to clear it of leading and trailing whitespace
query = " ".join(f"language:{language.strip()}" for language in languages)
query = query + f" stars:>{min_stars}"
return query


def repos_with_most_stars(languages, min_stars=40000, sort="stars", order="desc"):
query = create_query(languages, min_stars)
parameters = {"q": query, "sort": sort, "order": order}
print(parameters)
response = requests.get(GITHUB_API_URL, params=parameters)

if response.status_code != 200:
raise GitHubApiException(response.status_code)

response_json = response.json()
items = response_json["items"]
return [GitHubRepo(item["name"], item["language"], item["stargazers_count"]) for item in items]
13 changes: 13 additions & 0 deletions pyworkshop/2_intermediate_python/chapter8/repos/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
"""
GitHub API Application: Custom Exception Classes
"""

class GitHubApiException(Exception):

def __init__(self, status_code):
if status_code == 403:
message = "Rate limit reached. Please wait a minute and try again."
else:
message = f"HTTP Status Code was: {status_code}."

super().__init__("A GitHub API Error Occurred: " + message)
19 changes: 19 additions & 0 deletions pyworkshop/2_intermediate_python/chapter8/repos/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"""
GitHub API Application: Custom Model Classes
"""

class GitHubRepo:
"""
A class used to represent a single GitHub Repository.
"""

def __init__(self, name, language, num_stars):
self.name = name
self.language = language
self.num_stars = num_stars

def __str__(self):
return f"-> {self.name} is a {self.language} repo with {self.num_stars} stars."

def __repr__(self):
return f'GitHubRepo({self.name}, {self.language}, {self.num_stars})'
2 changes: 2 additions & 0 deletions pyworkshop/2_intermediate_python/chapter8/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
flask
requests
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 65c9882

Please sign in to comment.