Python 100 project #13: Google Trends Wordcloud on Flask

I have integrated my previous project of Google Wordcloud Project into Flask. With this, I can generate wordcloud without using terminal. And it’s ready to publish on the web. Still there are some improvement required especially for the double bytes font(Chinese, Korean etc, Japanese is already integrated as it’s my primary language).

 

Output Example:

 

Here is the code:

import base64
from io import BytesIO

from pytrends.request import TrendReq


def get_latest_trends(pn='p1'):
    pytrend = TrendReq()

    trending_searches_df = pytrend.trending_searches(pn=pn)

    trending_dict = {}

    for id, row in trending_searches_df.iterrows():
        trending_dict[row.title] = row.trafficBucketLowerBound

    return trending_dict


def get_wordcloud(word_dict, mask_image=None):
    from wordcloud import WordCloud
    import numpy as np
    from PIL import Image

    # macOS needs to specify Fonts
    fpath = "/System/Library/Fonts/ヒラギノ角ゴシック W8.ttc"

    if mask_image is not None:
        mask = np.array(Image.open(mask_image))
        wordcloud = WordCloud(mask=mask, font_path=fpath)
    else:
        wordcloud = WordCloud(font_path=fpath)

    wordcloud.generate_from_frequencies(frequencies=word_dict)

    image = wordcloud.to_image()

    return image


def return_image(country):
    word_dict = get_latest_trends(pn=country)
    image = get_wordcloud(word_dict)
    buffered = BytesIO()
    image.save(buffered, format="JPEG")
    img_str = base64.b64encode(buffered.getvalue())

    return img_str.decode('utf-8')
from flask import render_template, flash, request

from app import app, func
from app.forms import CountrySelectForm
from app.func import *
from facts import COUNTRYDICT

@app.route('/')
@app.route('/index')
def index():
    msg = 'Hello World!'

    return render_template('index.html', title='Home', msg=msg)

@app.route('/gtrends_wordcloud', methods=['GET', 'POST'])
def gen_gtrends_wordcloud():
    form = CountrySelectForm()
    if request.method == 'POST':
        image_str = func.return_image(form.country.data)
        country_name = COUNTRYDICT[form.country.data]
        flash('Google Trends Wordcloud requested for {}.'.format(
            country_name,
        ))
        return render_template('gtrends_wc.html', title='Google Trends Wordcloud',
                               form=form, image=image_str)
    return render_template('gtrends_wc.html', title='Google Trends Wordcloud', form=form)

<html>
    <head>
      {% if title %}
      <title>{{ title }} - Webtest</title>
      {% else %}
      <title>Welcome to Webtest</title>
      {% endif %}
    </head>
    <body>
        <hr>
        {% with messages = get_flashed_messages() %}
        {% if messages %}
        <ul>
            {% for message in messages %}
            <li>{{ message }}</li>
            {% endfor %}
        </ul>
        {% endif %}
        {% endwith %}
        {% block content %}{% endblock %}
    </body>
</html>
{% extends "base.html" %}

{% block content %}
    <h1>Google Trends Wordcloud generator</h1>
    <form action="" method="post">
        <p>
            {{ form.country.label }} {{ form.country() }}<br>
            {% for error in form.country.errors %}
            <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </p>
        <p>{{ form.submit() }}</p>
    </form>

    <div>
        <img src="data:image/jpeg;base64,{{ image }}">
    </div>
{% endblock %}