Skip to content
This repository has been archived by the owner on May 25, 2020. It is now read-only.

Moving over to using Flask blueprints #15

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
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
25 changes: 10 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,44 +15,44 @@

#### Courses
```
/courses/<term>/<code>
/v0/courses/<term>/<code>
```

#### Classes
```
/class/<class_number>/<term>
/v0/class/<class_number>/<term>
```

#### Lab Status
```
/lab_status/<lab_name>
/v0/lab_status/<lab_name>
```

#### Laundry Status
For simple laundry status:
```
/laundry/simple/<location>
/v0/laundry/simple/<location>
```

For detailed laundry status:
```
/laundry/detailed/<location>
/v0/laundry/detailed/<location>
```

#### People
```
/people/<query>
/v0/people/<query>
```

#### Shuttles
For shuttle routes:
```
/shuttle/routes
/v0/shuttle/routes
```

For shuttle vehicle points:
```
/shuttle/points
/v0/shuttle/points
```

For shuttle arrivals:
Expand All @@ -68,17 +68,12 @@ For shuttle stop estimates:
#### Textbooks
If the term is to be specified:
```
/textbook/<department_code>/<course_name>/<instructor>/<term>
```

If the term is not to be specified:
```
/textbook/<department_code>/<course_name>/<instructor>
/v0/textbook/<department_code>/<course_name>/<instructor>/<term>
```

#### News
```
/news/<feed>/<max_news_items>
/v0/news/<feed>/<max_news_items>
```


Expand Down
2 changes: 1 addition & 1 deletion apiwrapper/PittAPI
30 changes: 30 additions & 0 deletions apiwrapper/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"""
Web Wrapper for PittAPI, web app for REST endpoints for the PittAPI
Copyright (C) 2015 Ritwik Gupta

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""
from flask import Flask
from flask_cors import CORS

from apiwrapper.v0 import apiv0_bp

cors = CORS()


def create_app():
app = Flask(__name__)
cors.init_app(app)
app.register_blueprint(apiv0_bp, url_prefix='/v0')
return app
26 changes: 26 additions & 0 deletions apiwrapper/v0/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"""
Web Wrapper for PittAPI, web app for REST endpoints for the PittAPI
Copyright (C) 2015 Ritwik Gupta

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""
from flask import Blueprint
from flask_restful import Api

from apiwrapper.v0.views import add_resources

apiv0_bp = Blueprint('rest_api', __name__)
apiv0 = Api(apiv0_bp)

add_resources()
111 changes: 55 additions & 56 deletions apiwrapper/views.py → apiwrapper/v0/views.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
'''
"""
Web Wrapper for PittAPI, web app for REST endpoints for the PittAPI
Copyright (C) 2015 Ritwik Gupta

Expand All @@ -14,120 +14,129 @@
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
'''
from flask import Flask, make_response
from flask_restful import Api, Resource
from flask_cors import CORS, cross_origin
from .PittAPI.PittAPI import course, lab, laundry, people, shuttle, textbook, news
import json
"""
import inspect
import sys

app = Flask(__name__)
CORS(app)
api = Api(app)
from flask_restful import Resource

@api.representation('application/json')
def output_json(data, code, headers=None):
"""Makes a Flask response with a JSON encoded body"""
resp = make_response(json.dumps(data), code)
resp.headers.extend(headers or {})
return resp
from apiwrapper.PittAPI.PittAPI import course, lab, laundry, people, shuttle, textbook, news


@app.errorhandler(404)
def page_not_found(e):
return output_json({'error': 'Invalid request'}, 404)
class CourseGet(Resource):
PATH = '/courses/<term>/<code>'


class CourseGetAPI(Resource):
def get(self, term, code):
try:
return course.get_courses(term, code)
except Exception as e:
return {'error': str(e)}


class ClassAPI(Resource):
class Class(Resource):
PATH = '/class/<class_number>/<term>'

def get(self, term, class_number):
try:
return course.get_class(term, class_number)
except Exception as e:
return {'error': str(e)}


class LabStatusAPI(Resource):
class LabStatus(Resource):
PATH = '/lab_status/<lab_name>'

def get(self, lab_name):
try:
return lab.get_status(lab_name)
except Exception as e:
return {'error': str(e)}


class LaundryStatusAPI(Resource):
class LaundryStatus(Resource):
PATH = '/laundry/simple/<location>'

def get(self, location):
try:
return laundry.get_status_simple(location)
except Exception as e:
return {'error': str(e)}


class LaundryStatusDetailedAPI(Resource):
class LaundryStatusDetailed(Resource):
PATH = '/laundry/detailed/<location>'

def get(self, location):
try:
return laundry.get_status_detailed(location)
except Exception as e:
return {'error': str(e)}


class PeopleAPI(Resource):
class People(Resource):
PATH = '/people/<query>'

def get(self, query):
try:
return people.get_person(query)
except Exception as e:
return {'error': str(e)}

class TextbookAPI(Resource):

class Textbook(Resource):
PATH = '/textbook/<department_code>/<course_name>/<instructor>/<term>'

def get(self, department_code, course_name, instructor, term):
try:
return textbook.get_books_data([{'department_code': department_code, 'course_name': course_name, 'instructor': instructor, 'term': term}])
return textbook.get_books_data([{'department_code': department_code, 'course_name': course_name,
'instructor': instructor, 'term': term}])
except Exception as e:
return {'error': str(e)}

class TextbookNoTermAPI(Resource):
def get(self, department_code, course_name, instructor, term='2600'):
try:
return textbook.get_books_data([{'department_code': department_code, 'course_name': course_name, 'instructor': instructor, 'term': term}])
except Exception as e:
return {'error': str(e)}

class ShuttleRoutesAPI(Resource):
class ShuttleRoutes(Resource):
PATH = '/shuttle/routes'

def get(self):
try:
return shuttle.get_routes()
except Exception as e:
return {'error': str(e)}

class ShuttleVehiclePointsAPI(Resource):

class ShuttleVehiclePoints(Resource):
PATH = '/shuttle/points'

def get(self):
try:
return shuttle.get_map_vehicle_points()
except Exception as e:
return {'error': str(e)}

class ShuttleStopArrivalsAPI(Resource):

class ShuttleStopArrivals(Resource):
PATH = '/shuttle/arrivals/<times_per_stop>'

def get(self, times_per_stop=1):
try:
return shuttle.get_route_stop_arrivals("8882812681",times_per_stop)
return shuttle.get_route_stop_arrivals("8882812681", times_per_stop)
except Exception as e:
return {'error': str(e)}

class ShuttleStopEstimatesAPI(Resource):

class ShuttleStopEstimates(Resource):
PATH = '/shuttle/estimates/<vehicle_id>/<quantity>'

def get(self, vehicle_id, quantity=2):
try:
return shuttle.get_vehicle_route_stop_estimates(vehicle_id, quantity)
except Exception as e:
return {'error': str(e)}

class NewsAPI(Resource):

class News(Resource):
PATH = '/news/<feed>/<max_news_items>'

def get(self, feed, max_news_items):
try:
max_news_items = int(max_news_items)
Expand All @@ -136,19 +145,9 @@ def get(self, feed, max_news_items):
return {'error': str(e)}


api.add_resource(CourseGetAPI, '/courses/<term>/<code>')
api.add_resource(ClassAPI, '/class/<class_number>/<term>')
api.add_resource(LabStatusAPI, '/lab_status/<lab_name>')
api.add_resource(LaundryStatusAPI, '/laundry/simple/<location>')
api.add_resource(LaundryStatusDetailedAPI, '/laundry/detailed/<location>')
api.add_resource(PeopleAPI, '/people/<query>')
api.add_resource(ShuttleRoutesAPI, '/shuttle/routes')
api.add_resource(ShuttleVehiclePointsAPI, '/shuttle/points')
api.add_resource(ShuttleStopArrivalsAPI, '/shuttle/arrivals/<times_per_stop>')
api.add_resource(ShuttleStopEstimatesAPI, '/shuttle/estimates/<vehicle_id>/<quantity>')
api.add_resource(TextbookAPI, '/textbook/<department_code>/<course_name>/<instructor>/<term>')
api.add_resource(TextbookNoTermAPI, '/textbook/<department_code>/<course_name>/<instructor>/')
api.add_resource(NewsAPI, '/news/<feed>/<max_news_items>')

if __name__ is '__main__':
app.run(debug=True, port=8000)
def add_resources():
from apiwrapper.v0 import apiv0
clsmembers = inspect.getmembers(sys.modules[__name__], inspect.isclass)
clsmembers = [cls[1] for cls in clsmembers if cls[0] != 'Resource']
for cls in clsmembers:
apiv0.add_resource(cls, cls.PATH)
7 changes: 4 additions & 3 deletions server.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
'''
"""
Web Wrapper for PittAPI, web app for REST endpoints for the PittAPI
Copyright (C) 2015 Ritwik Gupta

Expand All @@ -14,7 +14,8 @@
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
'''
from apiwrapper.views import app
"""
from apiwrapper import create_app

app = create_app()
app.run(host="0.0.0.0", port=5000)
8 changes: 5 additions & 3 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,18 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
'''

from apiwrapper.views import app
import unittest

from apiwrapper import create_app


class APITest(unittest.TestCase):
def setUp(self):
self.app = app.test_client()
self.app = create_app().test_client()
self.app.testing = True

def test_lab_status_cath_g62(self):
result = self.app.get("/lab_status/cath_g62")
result = self.app.get("/v0/lab_status/cath_g62")
self.assertEqual(result.status_code, 200)
self.assertTrue("status" in result.get_data(True))