-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
164 lines (133 loc) · 4.14 KB
/
app.py
File metadata and controls
164 lines (133 loc) · 4.14 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
163
164
from flask import Flask, jsonify, request, current_app
from flask import Flask
from flask.json import JSONEncoder
from .secrets import db_username, db_password, db_host, db_port, db_database
from sqlalchemy import create_engine, text
db = {
'username': db_username,
'password': db_password,
'host': db_host,
'port': db_port,
'database': db_database
}
'''
이 코드는 그냥 쓰면 에러를 발생시킨다.
set 모듈이 JSON 으로 변경될 수 없기 때문.
이를 해결하기 위해 custom json encoder를 구현해야 한다. -> 위에 CustomJSONEncoder class 참고
'''
class CustomJSONEncoder(JSONEncoder):
def default(self, obj):
if isinstance(obj, set):
return list(obj)
return JSONEncoder.default(self, obj)
def get_user(user_id):
user = current_app.database.execute(text("""
SELECT
id,
name,
email,
profile
FROM users
WHERE id = :user_id
"""), {
'user_id': user_id
}).fetchone()
return {
'id': user['id'],
'name': user['name'],
'email': user['email'],
'profile': user['profile']
} if user else None
def insert_user(user):
return current_app.database.execute(text("""
INSERT INTO users (
name,
email,
profile,
hashed_password
) VALUES (
:name,
:email,
:profile,
:password
)
"""), user).lastrowid
def insert_tweet(user_tweet):
return current_app.database.execute(text("""
INSERT INTO tweets (
user_id,
tweet
) VALUES (
:id,
:tweet
)
"""), user_tweet).rowcount
def insert_follow(user_follow):
current_app.database.execute(text("""
INSERT INTO users_follow_list (user_id, follow_user_id) VALUES (:id, :follow)
"""), user_follow)
def insert_unfollow(user_unfollow):
current_app.database.execute(text("""
DELETE FROM users_follow_list
WHERE user_id = :id
AND follow_user_id = :unfollow
"""), user_unfollow).rowcount
def get_timeline(user_id):
timeline = current_app.database.execute(text("""
SELECT
t.user_id,
t.tweet
FROM tweets t
LEFT JOIN users_follow_list ufl ON ufl.user_id = :user_id
WHERE t.user_id = :user_id
OR t.user_id = ufl.follow_user_id
"""),{
'user_id': user_id
}).fetchall()
return [{
'user_id': tweet['user_id'],
'tweet': tweet['tweet']
} for tweet in timeline]
def create_app():
app = Flask(__name__)
app.debug = True
app.json_encoder = CustomJSONEncoder
db_url = f"mysql+mysqlconnector://{db['username']}:{db['password']}@" \
f"{db['host']}:{db['port']}/{db['database']}?charset=utf8"
database = create_engine(db_url, encoding='utf-8', max_overflow=0)
app.database = database
@app.route("/ping", methods=['GET'])
def ping():
return "ponggggsss"
@app.route("/sign-up", methods=['POST', 'GET'])
def sign_up():
new_user = request.json
new_user_id = insert_user(new_user)
new_user = get_user(new_user_id)
return jsonify(new_user)
@app.route("/tweet", methods=['POST'])
def tweet():
user_tweet = request.json
tweet = user_tweet['tweet']
if len(tweet) > 300:
return '300자 초과', 400
else:
insert_tweet(user_tweet)
return 'tweet success', 200
@app.route("/follow", methods=['POST'])
def follow():
payload = request.json
insert_follow(payload)
return 'follow success', 200
@app.route("/unfollow", methods=['POST'])
def unfollow():
payload = request.json
insert_unfollow(payload)
return '', 200
@app.route("/timeline/<int:user_id>", methods=['GET'])
def timeline(user_id):
return jsonify({
'user_id': user_id,
'timeline': get_timeline(user_id)
})
return app