Skip to content
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
57 changes: 0 additions & 57 deletions README.md

This file was deleted.

50 changes: 50 additions & 0 deletions README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
ADI Lab Technical Challenge Project Description
-----------------------------------------------

Author information
------------------
Name: Yuanyuting Wang
Email: [email protected]

Project Description:
--------------------
The project is implemented to accommodate two types of queries:

1. Query about density information in a specified building: by going to
/localhost:5000/information/<building_name>, the user can receive a list
of statistics representing the crowdedness, represented in percentage,
of the registered rooms in this building.

2. Query about the least crowded k placed on campus: by going to
/localhost:5000/information/<k>, with k being a positive integer, the
user can check out a list of k least crowded placed on campus according to
the latest data.

Running the Project:
--------------------
1. go to http://density.adicu.com/auth, and obtain the authentication token by
logging in using the user's own Columbia email.
2. go to project directory, and edit the .env file to contain the following line:
API_KEY=<the_token_you_just_acquired>
3. $ export FLASK_APP=app.py
4. $ flask run
5. enter queries with respect to /localhost:5000 in a new web page

Design Features:
----------------
1. The building name is not case sensitive, but assumes that all spaces
are replaced by underscores. If received invalid building name or negative
integers, an error message will pop up to notify the user.

2. The app interfaces with Density API through two urls:
http://density.adicu.com/latest and
http://density.adicu.com/latest/building/<building_name>. Before all requests,
a dictionary of building name-key pairs is compiled and stored to ensure later
direct interaction specifically with the second url.

3. The authentication token is saved in .env in the project folder and referenced
in app.py through using the package dotenv. The .env is not publicly shared,
which means users are required to set up their own environment following the steps
delineated in <Running the Project> and using their own Columbia emails. After much
thought, this is deemed as the best practice compared to other practices that
may involve web driver etc, for reasons of security and technical complexity.
Binary file added __pycache__/app.cpython-37.pyc
Binary file not shown.
63 changes: 60 additions & 3 deletions app.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,68 @@
from flask import Flask, render_template
import requests
import os
from dotenv import load_dotenv

app = Flask(__name__)
load_dotenv() # loading API key as stored in .env

building_dict = {} # the name-key dictionary for each building
AUTH = "?auth_token=" + os.getenv("API_KEY") # API key
URL_LATEST = "http://density.adicu.com/latest" # API for accessing latest data of all buildings
URL_BUILDING = "http://density.adicu.com/latest/building/" # API for accessing latest data of a certain building

@app.route('/', methods=['GET'])
def main():
return render_template('index.html')

# scans data from current and connected urls
def get_building_info(url):
building_info = []
while (True):
buildings = requests.get(url + AUTH).json()
building_info.extend(buildings['data'])
if ('next_page' not in list(buildings.keys())): break;
url = buildings['next_page']

return building_info


# before each request, scans building list and generates name-key dictionary
@app.before_request
def get_building_keys():
if (len(building_dict) > 0): return

buildings = get_building_info(URL_LATEST)
for building in buildings:
building_name = building['building_name'].strip().lower()
if (building_name not in list(building_dict.keys())):
if (' ' in building_name):
building_name = building_name.replace(' ', '_')
building_dict[building_name] = building['parent_id']


# render information about a certain building
@app.route('/information/<string:building_name>', methods=['GET'])
def print_buildings(building_name):
building_name_std = building_name.strip().lower()
# catching key error (the user input is not part of the listed buildings)
try:
queried_building = get_building_info(URL_BUILDING + str(building_dict[building_name_std]))
except:
return "building " + building_name + " not found :("

return render_template('building_page.html', buildings = queried_building, title = building_name + " information")


# render list of k emptiest places
@app.route('/information/<int:k>', methods=['GET'])
def print_k_emptiest(k):
buildings = get_building_info(URL_LATEST)
buildings.sort(key = lambda x : x['percent_full'])
return render_template('building_page.html', buildings = buildings[:k], title = str(k) + " emptiest places")


# saying hi
@app.route('/information')
def print_all_buildings():
return "hi, this is Yuanyuting Wang's ADI Lab Technical Challenge project :)"


if __name__ == '__main__':
Expand Down
Binary file added app.pyc
Binary file not shown.
20 changes: 20 additions & 0 deletions templates/building_page.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!DOCTYPE html>

<html>
<head>
<title>{{ title }}</title>
</head>
<body>

<ol>
<!-- For loop for rendering info of each building group -->
{%for building in buildings%}

<p>{{building['group_name']}} is {{building['percent_full']}}% full</p>

{%endfor%}

</ol>

</body>
</html>