敵のいない勉強部屋

日々学んだことや感じたことを書きます

英語字幕DB作成への道_Docker編① (Ubuntuメジャーバージョンアップ)

docker-desktopが対応しているubuntuのバージョンは21.10か22.04。
私のノートPCのUbuntuのバージョンは20.04...

ということで、Ubuntuのメジャーバージョンアップをしました。

参考サイトはこちら
itsfoss.com

私の英語力でもわりとスラスラ読めるサイトでした。ありがたい。

実質使ったコマンドは2つだけ。簡単!

sudo apt update && sudo apt dist-upgrade
sudo do-release-upgrade

※注意点として、ubuntu標準以外のリポジトリが無効化されるそうです。

今日も勉強になりました!

英語字幕DB作成への道_Test編① (pytest)

今日はpythonのテストツールであるpytestを使ってみました。
テストツールは色々ありましたが、flaskのtest関連のページで紹介されていたのがpytestだったのでこれにしました。

参考ページはこちら
docs.pytest.org

test_と名前のついたファイルや、Testから始まるクラスを自動で実行して、
成否を確かめてくれるようです。これは便利!

さらに、エラーになったときは変数の中身を展開した状態でプロンプトに表示してくれる親切設計。

fixtureだけはいまいち便利さがまだ分かってませんが、ここはおいおい勉強していくこととしましょう。

今日も新しいことが学べて良かった!

英語字幕DB作成への道_SQLite編③ (bulk_insert)

今日はこちらを参考に、bulk_insertを実装してみました。
docs.python.org

data = [
    ("Monty Python Live at the Hollywood Bowl", 1982, 7.9),
    ("Monty Python's The Meaning of Life", 1983, 7.5),
    ("Monty Python's Life of Brian", 1979, 8.0),
]
cur.executemany("INSERT INTO movie VALUES(?, ?, ?)", data)
con.commit()  # Remember to commit the transaction after executing INSERT.

100〜200件くらいのデータは全く問題なくinsertできました。
30分程度のドラマの1話分ならこれで全部賄えそうです。

毎度のことだけど、sqlite3はシンプルで使いやすい!
今日も新しいことが学べて良かったです。

英語字幕DB作成への道_SQLite編② (Flaskとの連携)

今日はこちらのサイトを参考に、FlaskとSQLiteを連携してみました。
flask.palletsprojects.com

ポイント① DBのコネクションを使いわす & 必ず閉じる

import sqlite3
from flask import g

DATABASE = '/path/to/database.db'

def get_db():
    db = getattr(g, '_database', None)
    if db is None:
        db = g._database = sqlite3.connect(DATABASE)
    return db

@app.teardown_appcontext
def close_connection(exception):
    db = getattr(g, '_database', None)
    if db is not None:
        db.close()

上記のコードを書くことで、「1つのリクエストの中で1つのコネクションを使い回せる」&「リクエスト終了時に自動的にコネクションを閉じる」ということができるようになるようです。
要は無駄なコネクションを作りすぎたり、消し忘れたりすることがなくなるってことですね。
正直なところ、これをやらなかったときにどんなリスクがあるかは分かっていないので、
それはまた別の機会に調べてみたいと思います。

ポイント② DBの初期化はこう書いておくと便利

def init_db():
    with app.app_context():
        db = get_db()
        with app.open_resource('schema.sql', mode='r') as f:
            db.cursor().executescript(f.read())
        db.commit()

こんな風にapp_context()を使って書くことで、
pythonのshellから get_db()を使うことができて便利だそうです。
これはアプリケーションコンテキストを理解していないと、
便利さを完全には理解できなさそうです。

from yourapplication import init_db
init_db()

少し込み入った話になってきました!
勉強することも増えてきたので、ドキュメントを読み込まなくては。
今日も一歩前進できて良かったです

英語字幕DB作成への道_SQLite編① (Tutorial)

こちらのサイトを参考に、はじめてSQLite3を使ってみました。
docs.python.org

デフォルトのモジュールに含まれているらしく、
pipでインストールすらいらないことに驚きました。

テーブル作成とINSERT

import sqlite3
con = sqlite3.connect('example.db')

cur = con.cursor()

cur.execute('''CREATE TABLE stocks
               (date text, trans text, symbol text, qty real, price real)''')

cur.execute("INSERT INTO stocks VALUES ('2006-01-05','BUY','RHAT',100,35.14)")

con.commit()
con.close()

SELECT

import sqlite3
con = sqlite3.connect('example.db')
cur = con.cursor()
res = cur.execute('SELECT count(rowid) FROM stocks')
print(res.fetchone())

シンプル! これでSQL使い放題です。とりあえず何か問題が起きるまではDBはsqlite3を使うことにしました。

今日も新しいことを学べてよかった!

英語字幕DB作成への道_Flask編③ (Variable Rules)

前回作成したコードには問題がありました。
それは、URLから取得した変数の値が、すべてstr型になってしまっていること。

解決策はこちらにありました。
flask.palletsprojects.com

from markupsafe import escape

@app.route('/user/<username>')
def show_user_profile(username):
    # show the user profile for that user
    return f'User {escape(username)}'

@app.route('/post/<int:post_id>')
def show_post(post_id):
    # show the post with the given id, the id is an integer
    return f'Post {post_id}'

@app.route('/path/<path:subpath>')
def show_subpath(subpath):
    # show the subpath after /path/
    return f'Subpath {escape(subpath)}'

要は <型:変数名> の書式で書けば良いようです。
とても簡単! この辺はDjangoと同じですね。

シンプルで使いやすい!

英語字幕DB作成への道_Flask編② (API with JSON)

今回はFlaskを使って、簡単なAPIの雛形を作ってみました。

import json
import uuid
from flask import Flask
from flask import request

app = Flask(__name__)


@app.route(
    "/disneyplus/tv_show/<series_name>/<season_num>/<episode_num>", methods=["POST"]
)
def fetch_vtt_with_epicode_num(series_name, season_num, episode_num):
    req_data = json.loads(request.data)
    series_url = req_data["series_url"]
    res_data = {
        "series_url": series_url,
        "series_name": series_name,
        "season_number": season_num,
        "episode_num": episode_num,
        "jobid": uuid.uuid4(),
    }
    return res_data

シンプルで書きやすい!
これならあまり苦労せず色々なAPIを作れそうです。

今回は非同期のAPIになることが予想されるので、乱数を生成してjobidを作るようにしてみました。
色々と機能を追加していくのが楽しみです。

参考:
flask.palletsprojects.com