-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
162 lines (127 loc) · 4.7 KB
/
app.py
File metadata and controls
162 lines (127 loc) · 4.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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
150
151
152
153
154
155
156
157
158
159
160
161
162
"""
API for the Salty Hacker Build Week Project
API Developers:
Iuliia Stanina
Robert Sharp
"""
from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer
from flask import Flask, make_response, request, jsonify
from models import db, migrate, Comment, parse_records, Hacker
from bs4 import BeautifulSoup
from random import choice, randint
import requests
import os
# from dotenv import load_dotenv
# load_dotenv()
DATABASE_URL = os.getenv("DATABASE_URL")
app = Flask(__name__)
db.init_app(app)
migrate.init_app(app, db)
app.config['SQLALCHEMY_DATABASE_URI'] = DATABASE_URL
sid_obj = SentimentIntensityAnalyzer()
def sentiment_score(sentence: str) -> int:
sentiment_dict = sid_obj.polarity_scores(sentence)
return int(-sentiment_dict['compound'] * 100)
@app.route('/sentiment/<text>')
def sentiment(text):
return jsonify(text=text, score=sentiment_score(text))
@app.route('/')
def home():
return jsonify((
'Project: The Saltiest Hacker API',
'Developers: Iuliia Stanina & Robert Sharp',
))
@app.route('/docs')
def docs():
return jsonify(routes={
'/': 'API home page',
'/docs': 'This page',
'/comments-by-author/<author>': 'Most salty comments',
'/score-by-author/<author>': 'Average saltiness',
'/comment-by-id/<comment_id>': 'Comment by id',
'/top-hackers/<number>': 'Most salty hackers, ordered by saltiness',
'/recent': 'Most recent 30 comments, ordered by saltiness',
'/sentiment/<text>': 'Live sentiment analysis',
'/random-comment': 'Random comment with saltiness',
'/random-author': 'Random author with their most salty comments',
})
@app.before_request
def before_request():
""" CORS preflight, required for off-server access """
def _build_cors_prelight_response():
response = make_response()
response.headers.add("Access-Control-Allow-Origin", "*")
response.headers.add("Access-Control-Allow-Headers", "*")
response.headers.add("Access-Control-Allow-Methods", "*")
return response
if request.method == "OPTIONS":
return _build_cors_prelight_response()
@app.after_request
def after_request(response):
""" CORS headers, required for off-server access """
header = response.headers
header['Access-Control-Allow-Origin'] = '*'
return response
@app.route('/comments-by-author/<author>')
def comments_by_author(author):
""" Returns list of the top 3 most salty comments for any author
/comments-by-author/po """
comments = Comment.query.filter_by(author=author)
parsed = parse_records(comments.order_by(Comment.saltiness).all())
ordered = [{
'id': item['id'],
'comment': item['comment'],
'saltiness': item['saltiness'] // 100,
} for item in reversed(parsed[-3:])]
return jsonify(ordered)
@app.route('/score-by-author/<author>')
def score_by_author(author):
""" Returns the average saltiness of a hacker's comments
/score-by-author/po """
return jsonify(score=Hacker.query.filter_by(name=author).first().score // 100)
@app.route('/comment-by-id/<comment_id>')
def comment_by_id(comment_id):
""" Comment text by comment_id
/comment-by-id/42 """
comment = Comment.query.filter_by(id=comment_id).first()
return jsonify({
'author': comment.author,
'comment': comment.comment,
'saltiness': comment.saltiness // 100,
})
@app.route('/recent')
def recent():
page = requests.get("https://news.ycombinator.com/newcomments")
soup = BeautifulSoup(page.content, features='html.parser')
comments = []
usr_com = zip(soup.find_all('a', class_='hnuser'),
soup.find_all('div', class_='comment'),
soup.find_all('span', class_='onstory'))
for usr, com, head in usr_com:
text = com.get_text().strip()
comments.append({
'author': usr.get_text(),
'saltiness': sentiment_score(text),
'headline': head.find('a').get_text(),
'comment': text,
})
comments.sort(key=lambda x: x['saltiness'], reverse=True)
return jsonify(data=comments)
@app.route('/top-hackers/<number>')
def top_hackers(number):
hackers = Hacker.query.limit(number).all()
return jsonify([{
'rank': hacker.rank,
'name': hacker.name,
'score': hacker.score // 100,
} for hacker in hackers])
@app.route('/random-comment')
def random_comment():
return comment_by_id(randint(0, 230702))
@app.route('/random-author')
def random_author():
author = choice([hacker.name for hacker in Hacker.query.all()])
comments = comments_by_author(author).json
return jsonify(author=author, comments=comments)
if __name__ == '__main__':
app.run()