앞에서 Flask-project start블로그에서 Flask를 이용하여 간단하게 Ping-Pong 엔드포인트를 구현해보았다.
이번에는 twitter의 주요기능들만 가지고 미니터(Minitter)라는 엔드포인트를 만들고자 한다
회원가입
로그인
트윗(twitt)
다른 회원 팔로우(follow)하기
다른 회원 언팔로우(unfollow)하기
타임라인(해당 사용자 그리고 사용자가 팔로우하는 사용자들의 트윗들)
미니터(Minitter)의 회원가입시 필요한 정보는 다음과 같다.
id
name
password
profile
{
"name": "string",
"password": "string",
"email": "string",
"profile": "string"
}
위와 같은 기능을 갖은 API를 구현하고자 app.py
를 다음과 같이 수정한다
# /develop/api/app.py
from flask import Flask, jsonify, request # 1)
app = Flask(__name__)
app.users = {} # 2)
app.id_count = 1 # 3)
@app.route("/signup", methods=['POST']) # 4)
def signup():
new_user = request.json # 5)
new_user["id"] = app.id_count # 6)
app.users[app.id_count] = new_user # 7)
app.id_count = app.id_count + 1 # 8)
return jsonify(new_user) 9)
1) 필요한 flask 모듈을 import한다.
request
모듈은 사용자가 HTTP요청을 통해 전송한 JSON 데이터를 읽어 들일 수 있다
jsonify
모듈은 dictionary 객체를 JSON으로 변환하여 HTTP응답으로 보낼 수 있다
2) 새로 가입한 사용자가 저장할 dictionary를 users
라는 변수에 정의한다. 앞으로 key:value 의 형태로 저장될 것이다
3) 회원가입하는 사용자의 id값을 저장한다. id는 1부터 시작하여 새로운 사용자가 회원가입하게되면 +1 씩 증가하여 id값이 증가하고 부여받는다.
4) '/ping'
엔드포인트와 마찬가지로 '/signup'
이라는 엔드포인트 주소로 지정한다. HTTP 메소드는 POST로 한다
5) HTTP 요청을 통해 전송된 회원정보를 읽어 들인다. request
는 엔드포인트에 전송된 HTTP 요청 정보(헤더, body등등)을 저장한다.
request.json
은 해당 HTTP 요청을 통해 전송된 JSOn 데이터를 파이썬 dictionary로 변환한다.
6) HTPP요청으로 전송된 회원가입 정보에 id값을 더하여 준다.
7) 회원가입을 사용자의 정보를 2)에서 생성한 dictionary에 저장한다.
8) id_count
즉, id값에 1을 더해준다. 따라서 다음회원이 가입시 id값이 겹치지 않고 순차적으로 들어올 수 있도록 준비한다.
9) 회원가입한 사용자의 정보를 jsonify를 사용해 dictionary를 JSON으로 변환하여 리턴해준다. 이때 status code는 200이 된다.
(develop) $ FLASK_ENV=development FLASK_APP=app.py flask run
* Serving Flask app "app.py" (lazy loading)
* Environment: development
* Debug mode: on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 391-025-249
FLASK_ENV
를 "development"로 정해 놓으면 debug mode가 실행된다.(develop) $ $ http -v POST localhost:5000/signup name=퐝이뇽 email=test@gmail.com password=12345678 profile='my name is pang'
POST /signup HTTP/1.1
Accept: application/json, */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 111
Content-Type: application/json
Host: localhost:5000
User-Agent: HTTPie/0.9.8
{
"email": "test@gmail.com",
"name": "퐝이뇽",
"password": "12345678",
"profile": "my name is pang"
}
HTTP/1.0 200 OK
Content-Length: 137
Content-Type: application/json
Date: Wed, 29 Jan 2020 13:04:27 GMT
Server: Werkzeug/0.16.1 Python/3.7.6
{
"email": "test@gmail.com",
"id": 1,
"name": "퐝이뇽",
"password": "12345678",
"profile": "my name is pang"
}
이번에는 미니터의 기능 중 트윗기능을 구현하고자 한다.
트윗기능은 다음과 같다
{
"id" : 1,
"twitter" : "string"
}
app.twitter = [] # 1)
@app.route('/twitter', methods=['POST']) # 2)
def twitter(): # 3)
payload = reuqest.json
user_id = int(payload['id'])
twitter = payload['twitter']
if user_id not in app.users: # 4)
return '사용자가 존재하지 않습니다.', 400
if len(twitter) > 300: # 5)
return '300자를 초과했습니다.', 400
user_id = int(payload['id']) # 6)
app.twitter.append({ # 7)
'user_id' : user_id,
'twitter' : twitter
})
return '', 200
1) 사용자들이 트위들을 저장할 디렉토리로, key는 사용자 id가 되고, value는 사용자들의 트윗들을 담을 리스트형태의 자료구조이다
2) 엔드포인트 주소는 '/twitter'
이고 HTTP 메소드는 POST이다
3) HTTP 요청으로 전송된 JSON 데이터에서 "twitter" 필드를 읽어 들여 사용자의 twitter 내용이 300자 넘었는지를 확인한다
4) 만일 해당 사용자 아이다가 존재하지 않으면 '사용자가 존재하지 않습니다' 라는 메세지와 함께 400 Bad Request 응답을 보낸다
5) 만일 사용자의 트윗이 300자를 넘었으면 '300자를 초과했습니다' 라는 메세지와 함께 400 Bad Request 응답을 보낸다
6) HTTP요청으로 전송된 JSON 데이터에서 사용자 id를 읽어 들인다
7) 해당 사용자 id와 트윗을 dictionary로 생성해서 app.twitter
리스트에 저장한다.
다음과 같이 파이썬 flask 가상환경에서 server를 구동한다
(develop) $ $ FLASK_ENV=development FLASK_APP=app.py flask run
* Serving Flask app "app.py" (lazy loading)
* Environment: development
* Debug mode: on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 391-025-249
그리고 httpie를 통해 트윗 API를 테스트한다
(develop) $ http -v POST localhost:5000/twitter id=1 twitter="My first Tweet"
POST /twitter HTTP/1.1
Accept: application/json, */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 40
Content-Type: application/json
Host: localhost:5000
User-Agent: HTTPie/0.9.8
{
"id": "1",
"twitter": "My first Tweet"
}
HTTP/1.0 200 OK
Content-Length: 0
Content-Type: text/html; charset=utf-8
Date: Wed, 29 Jan 2020 13:23:37 GMT
Server: Werkzeug/0.16.1 Python/3.7.6