10강 React와 플라스크(Flask) 연동하기
이번 시간에는 만들어진 워드 클라우드(Word Cloud) API를 웹 상에서 접근할 수 있는 방법에 대해서 알아보도록 하겠습니다. 웹 상에서 특정한 이미지 파일 등에 접근하기 위해서는 정적 폴더(Static Folder)를 설정해야 합니다.
▶ word_cloud.py
# 단어구름에 필요한 라이브러리를 불러옵니다.
from wordcloud import WordCloud
# 한국어 자연어 처리 라이브러리를 불러옵니다.
from konlpy.tag import Twitter
# 명사의 출현 빈도를 세는 라이브러리를 불러옵니다.
from collections import Counter
# 그래프 생성에 필요한 라이브러리를 불러옵니다.
import matplotlib.pyplot as plt
# Flask 웹 서버 구축에 필요한 라이브러리를 불러옵니다.
from flask import Flask, request, jsonify
# 플라스크 웹 서버 객체를 생성합니다.
app = Flask(__name__, static_folder='outputs')
# 폰트 경로 설정
font_path = 'NanumGothic.ttf'
def get_tags(text, max_count, min_length):
# 명사만 추출합니다.
t = Twitter()
nouns = t.nouns(text)
processed = [n for n in nouns if len(n) >= min_length]
# 모든 명사의 출현 빈도를 계산합니다.
count = Counter(processed)
result = {}
# 출현 빈도가 높은 max_count 개의 명사만을 추출합니다.
for n, c in count.most_common(max_count):
result[n] = c
# 추출된 단어가 하나도 없는 경우 '내용이 없습니다.'를 화면에 보여줍니다.
if len(result) == 0:
result["내용이 없습니다."] = 1
return result
def make_cloud_image(tags, file_name):
# 만들고자 하는 워드 클라우드의 기본 설정을 진행합니다.
word_cloud = WordCloud(
font_path=font_path,
width=800,
height=800,
background_color="white",
)
# 추출된 단어 빈도수 목록을 이용해 워드 클라우드 객체를 초기화 합니다.
word_cloud = word_cloud.generate_from_frequencies(tags)
# 워드 클라우드를 이미지로 그립니다.
fig = plt.figure(figsize=(10, 10))
plt.imshow(word_cloud)
plt.axis("off")
# 만들어진 이미지 객체를 파일 형태로 저장합니다.
fig.savefig("outputs/{0}.png".format(file_name))
def process_from_text(text, max_count, min_length, words, file_name):
# 최대 max_count 개의 단어 및 등장 횟수를 추출합니다.
tags = get_tags(text, max_count, min_length)
# 단어 가중치를 적용합니다.
for n, c in words.items():
if n in tags:
tags[n] = tags[n] * int(words[n])
# 명사의 출현 빈도 정보를 통해 워드 클라우드 이미지를 생성합니다.
make_cloud_image(tags, file_name)
@app.route("/process", methods=['GET', 'POST'])
def process():
content = request.json
words = {}
if content['words'] is not None:
for data in content['words'].values():
words[data['word']] = data['weight']
process_from_text(content['text'], content['maxCount'], content['minLength'], words, content['textID'])
result = {'result': True}
return jsonify(result)
@app.route('/outputs', methods=['GET', 'POST'])
def output():
text_id = request.args.get('textID')
return app.send_static_file(text_id + '.png')
if __name__ == '__main__':
app.run('0.0.0.0', port=5000)
▶ 이미지 생성
이미지 생성에는 textID라는 파라미터를 추가적으로 넣어주세요.
▶ 이미지 접근
이미지에 접근할 때는 다음과 같이 파라미터로 접근하면 됩니다.
▶ word_cloud.py
이러한 이미지에 실제로 클라이언트에서 효과적으로 접근할 수 있도록 이미지가 존재하는지 확인하기 위한 validate() 함수를 추가적으로 만들어 주었습니다.
# 단어구름에 필요한 라이브러리를 불러옵니다.
from wordcloud import WordCloud
# 한국어 자연어 처리 라이브러리를 불러옵니다.
from konlpy.tag import Twitter
# 명사의 출현 빈도를 세는 라이브러리를 불러옵니다.
from collections import Counter
# 그래프 생성에 필요한 라이브러리를 불러옵니다.
import matplotlib.pyplot as plt
# Flask 웹 서버 구축에 필요한 라이브러리를 불러옵니다.
from flask import Flask, request, jsonify
# 테스트를 위하여 CORS를 처리합니다.
from flask_cors import CORS
# 파일에 접근하기 위한 라이브러리를 불러옵니다.
import os
# 플라스크 웹 서버 객체를 생성합니다.
app = Flask(__name__, static_folder='outputs')
CORS(app)
# 폰트 경로 설정
font_path = 'NanumGothic.ttf'
def get_tags(text, max_count, min_length):
# 명사만 추출합니다.
t = Twitter()
nouns = t.nouns(text)
processed = [n for n in nouns if len(n) >= min_length]
# 모든 명사의 출현 빈도를 계산합니다.
count = Counter(processed)
result = {}
# 출현 빈도가 높은 max_count 개의 명사만을 추출합니다.
for n, c in count.most_common(max_count):
result[n] = c
# 추출된 단어가 하나도 없는 경우 '내용이 없습니다.'를 화면에 보여줍니다.
if len(result) == 0:
result["내용이 없습니다."] = 1
return result
def make_cloud_image(tags, file_name):
# 만들고자 하는 워드 클라우드의 기본 설정을 진행합니다.
word_cloud = WordCloud(
font_path=font_path,
width=800,
height=800,
background_color="white",
)
# 추출된 단어 빈도수 목록을 이용해 워드 클라우드 객체를 초기화 합니다.
word_cloud = word_cloud.generate_from_frequencies(tags)
# 워드 클라우드를 이미지로 그립니다.
fig = plt.figure(figsize=(10, 10))
plt.imshow(word_cloud)
plt.axis("off")
# 만들어진 이미지 객체를 파일 형태로 저장합니다.
path = "outputs/{0}.png".format(file_name)
# 이미 파일이 존재하는 경우 덮어쓰기합니다.
if os.path.isfile(path):
os.remove(path)
fig.savefig(path)
def process_from_text(text, max_count, min_length, words, file_name):
# 최대 max_count 개의 단어 및 등장 횟수를 추출합니다.
tags = get_tags(text, max_count, min_length)
# 단어 가중치를 적용합니다.
for n, c in words.items():
if n in tags:
tags[n] = tags[n] * int(words[n])
# 명사의 출현 빈도 정보를 통해 워드 클라우드 이미지를 생성합니다.
make_cloud_image(tags, file_name)
@app.route("/process", methods=['GET', 'POST'])
def process():
content = request.json
words = {}
if content['words'] is not None:
for data in content['words'].values():
words[data['word']] = data['weight']
process_from_text(content['text'], content['maxCount'], content['minLength'], words, content['textID'])
result = {'result': True}
return jsonify(result)
@app.route('/outputs', methods=['GET', 'POST'])
def output():
text_id = request.args.get('textID')
return app.send_static_file(text_id + '.png')
@app.route('/validate', methods=['GET',' POST'])
def validate():
text_id = request.args.get('textID')
path = "outputs/{0}.png".format(text_id)
result = {}
# 해당 이미지 파일이 존재하는지 확인합니다.
if os.path.isfile(path):
result['result'] = True
else:
result['result'] = False
return jsonify(result)
if __name__ == '__main__':
app.run('0.0.0.0', port=5000, threaded=True) # 처리 속도 향상을 위해 쓰레드를 적용합니다.
▶ Detail.js
이제 Detail.js 파일을 수정합니다. 기본적으로 React에서 이미지(Image) 태그의 정보가 수정될 때에는 브라우저 캐시(Cache)가 동작하지 않도록, 별도의 랜덤 파라미터를 추가적으로 붙여 줄 수 있습니다.
※ 실행 결과 ※
먼저 하나의 텍스트를 추가해보도록 하겠습니다.
이어서 만들어진 텍스트를 확인해보도록 하겠습니다.
처음에는 워드 클라우드가 존재하지 않는 상황입니다.
워드 클라우드를 생성한 이후에는 다음과 같이 정상적으로 출력됩니다.
또한 만들어진 이후에 [다시 만들기] 버튼을 누르면 새롭게 워드 클라우드가 생성됩니다.
'React와 Firebase로 만드는 Word Cloud 웹앱' 카테고리의 다른 글
12강 AWS EC2에서 플라스크(Flask) 웹 서버 구동시키기 (2) | 2019.01.12 |
---|---|
11강 워드 클라우드(Word Cloud) 상세 수치 설정하기 (0) | 2019.01.12 |
9강 플라스크(Flask)로 워드 클라우드 API 구현하기 (0) | 2019.01.11 |
8강 React에 웹 폰트(Web Font) 적용하기 (0) | 2019.01.09 |
7강 React로 텍스트 파일(Text File) 업로드 및 상세 페이지로 이동하기 (0) | 2019.01.09 |