Skip to content

Commit

Permalink
Merge pull request #10 from planetterp/updates-for-pypi-package
Browse files Browse the repository at this point in the history
Prepare for pypi package publishing
  • Loading branch information
saewitz authored Jan 6, 2021
2 parents b079526 + 97c1611 commit ab961e2
Show file tree
Hide file tree
Showing 8 changed files with 204 additions and 119 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
.idea/*
.DS_Store
*.pyc
dist/
build/
*.egg-info
__pycache__/
97 changes: 0 additions & 97 deletions PlanetTerp.py

This file was deleted.

25 changes: 20 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
# PlanetTerp API Python Wrapper
This API Example includes an object, **PlanetTerp.py**, which can be created and called in order to access information from the PlanetTerp API.

The `PlanetTerp` object uses the `requests` and `json` packages. One or both of these may already be installed for you. To install them to your computer, use something like `pip3` or `brew`.
This is a Python wrapper around the [PlanetTerp API](http://api.planetterp.com).

The `requests` package allows the `PlanetTerp` object to access data from the internet, enabling it to make API calls. The `json` package converts the JSON data provided by the PlanetTerp API into a Python dictionary for easier use.
To install, either use [the code on GitHub](https://github.com/planetterp/PlanetTerp-API-Python-Wrapper), or install with `pip install planetterp` (you might need to run `pip3 install planetterp`).

You can find examples of how to use a PlanetTerp object in the **sample_usage.py** file.
### Example usage

To use this code to access the API, simply download or clone this repository, and make your own file in the same folder as **PlanetTerp.py** and **sample_usage.py**.
```python
import planetterp

course = planetterp.course(name="MATH140", reviews=True)
courses = planetterp.courses(department="MATH", limit=2)
# replace Jon Snow with the name of any professor
prof = planetterp.professor(name="Jon Snow", reviews="true")
profs = planetterp.professors(type_="ta", limit=2)
# same here
grades = planetterp.grades(course="MATH140", professor="Jon Snow")

print(course)
print(courses)
print(prof)
print(profs)
print(grades)
```
137 changes: 137 additions & 0 deletions planetterp/PlanetTerp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import requests
import json
from urllib.parse import urlencode, quote

BASE_URL = 'https://api.planetterp.com/v1/'

def course(name, reviews = False):
"""
Get a course.
Parameters
----------
name: string
The name of the course.
reviews: bool, optional
Whether to also return reviews for the course, specifically reviews for
professors that taught the course and have the course listed as the one
being reviewed. Defaults to False.
"""
params = {"name" : name, "reviews": "true" if reviews else "false"}
url = BASE_URL + "course?" + urlencode(params)

return requests.get(url).json()


def courses(department = None, reviews = False, limit = 100, offset = 0):
"""
Get all courses meeting some criteria.
Parameters
----------
department: string, optional
Only return courses in the given department. The department name must be
four characters. Defaults to all departments.
reviews: bool, optional
Also return reviews for the course, specifically reviews for
professors that taught the course and have the course listed as the one
being reviewed. Defaults to False.
limit: int, optional
Maximum number of courses to return. Must be between 1 and 1000
inclusive. Defaults to 100.
offset: int, optional
Number of courses to skip (offered for pagination). Defaults to 0.
"""
params = {"department" : department,
"reviews": "true" if reviews else "false",
"limit": limit, "offset": offset}

# filter out None args
params = {k:v for k, v in params.items() if v is not None}
url = BASE_URL + "courses?" + urlencode(params)

return requests.get(url).json()


def professor(name, reviews = False):
"""
Get a professor.
Parameters
----------
name: str
The name of the professor.
reviews: bool, optional
Whether to also return reviews for the given professor. Defaults to
false.
"""
params = {"name" : name, "reviews": "true" if reviews else "false"}
url = BASE_URL + "professor?" + urlencode(params)

return requests.get(url).json()


def professors(type_ = None, reviews = False, limit = 100, offset = 0):
"""
Get all professors meeting some criteria.
Parameters
----------
type_: {"professor", "ta"}, optional
Only return reviews for the specified instructor type, either professors
or TAs. Defaults to returning both.
reviews: bool, optional
Whether to also return reviews for the instructors. Defaults to false.
limit: int, optional
Maximum number of instructors to return. Must be between 1 and 1000
inclusive. Defaults to 100.
offset: int, optional
Number of instructors to skip (offered for pagination). Defaults to 0.
"""
if type_ and type_ not in ["professor", "ta"]:
raise ValueError("Expected type to be one of ['professor', 'ta'], got "
+ str(type_))

params = {"type" : type_, "reviews": "true" if reviews else "false",
"limit": limit, "offset": offset}

# filter out None args
params = {k:v for k, v in params.items() if v is not None}
url = BASE_URL + "professors?" + urlencode(params)

return requests.get(url).json()


def grades(course = None, professor = None, semester = None, section = None):
"""
Get grades for a given course, professor, semester, section, or combination
thereof.
Parameters
----------
course: str
Limit the grades returned to only this course. Defaults to all courses.
Either `course` or `professor` must be passed.
professor: str
The name of the professor to return grades for. Defaults to all
professors. Either `course` or `professor` must be passed.
semester: str, optional
The semester to return grades for. This should be passed as the year
followed by the semester code. The spring semester code is 01 and the
fall semester code is 08. For example, 202001 is Spring 2020.
section: str, optional
Limit the grades returned to only this section. Defaults to all
sections.
Notes
-----
Either `course` or `professor` must be passed.
"""
params = {"course" : course, "professor": professor, "semester": semester,
"section": section}

# filter out None args
params = {k:v for k, v in params.items() if v is not None}
url = BASE_URL + "grades?" + urlencode(params)

return requests.get(url).json()
6 changes: 6 additions & 0 deletions planetterp/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from planetterp.PlanetTerp import (course, courses, professor, professors,
grades)
from planetterp.version import __version__

__all__ = ["course", "courses", "professor", "professors", "grades",
"__version__"]
1 change: 1 addition & 0 deletions planetterp/version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__version__ = "1.0.0"
17 changes: 0 additions & 17 deletions sample_usage.py

This file was deleted.

36 changes: 36 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import setuptools
import re

with open("README.md", "r", encoding="utf-8") as f:
long_description = f.read()

# https://stackoverflow.com/a/7071358
VERSION = "Unknown"
VERSION_RE = r"^__version__ = ['\"]([^'\"]*)['\"]"

with open("planetterp/version.py") as f:
match = re.search(VERSION_RE, f.read())
if match:
VERSION = match.group(1)
else:
raise RuntimeError("Unable to find version string in planetterp/version.py")


setuptools.setup(
name="planetterp",
version=VERSION,
author="PlanetTerp",
author_email="admin@planetterp.com",
description="PlanetTerp API Python wrapper",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/planetterp/PlanetTerp-API-Python-Wrapper",
packages=setuptools.find_packages(),
classifiers=[
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
install_requires=[
"requests"
]
)

0 comments on commit ab961e2

Please sign in to comment.