0
1

初心者向け!Quartで始めるPython非同期Webアプリの作り方

Posted at

第1章: Quartの概要

Quartは、Pythonの非同期Webフレームワークです。FlaskのAPIと互換性がありながら、非同期処理をサポートしています。

from quart import Quart

app = Quart(__name__)

@app.route('/')
async def hello():
    return 'Hello, Quart!'

if __name__ == '__main__':
    app.run()

このコードは、基本的なQuartアプリケーションを作成し、ルートURLにアクセスすると「Hello, Quart!」と表示します。

第2章: Quartのインストールと設定

Quartをインストールするには、以下のコマンドを使用します:

pip install quart

プロジェクトの構造は以下のようになります:

myproject/
    ├── app.py
    ├── requirements.txt
    └── venv/

requirements.txtファイルには以下を記述します:

quart

第3章: ルーティングとビュー

Quartでは、デコレータを使用してルートを定義します。

from quart import Quart

app = Quart(__name__)

@app.route('/')
async def index():
    return 'Welcome to the homepage'

@app.route('/about')
async def about():
    return 'About us page'

if __name__ == '__main__':
    app.run()

このコードは、ホームページと「About」ページの2つのルートを定義しています。

第4章: リクエストとレスポンス

Quartでは、requestオブジェクトを使用してリクエストデータにアクセスし、様々な形式でレスポンスを返すことができます。

from quart import Quart, request, jsonify

app = Quart(__name__)

@app.route('/echo', methods=['POST'])
async def echo():
    data = await request.get_json()
    return jsonify(data)

if __name__ == '__main__':
    app.run()

このコードは、POSTリクエストのJSONデータをそのまま返すエコーサービスを実装しています。

第5章: テンプレートの使用

Quartは、Jinja2テンプレートエンジンを使用してHTMLを生成します。

from quart import Quart, render_template

app = Quart(__name__)

@app.route('/hello/<name>')
async def hello(name):
    return await render_template('hello.html', name=name)

if __name__ == '__main__':
    app.run()

templates/hello.html:

<!DOCTYPE html>
<html>
<head>
    <title>Hello</title>
</head>
<body>
    <h1>Hello, {{ name }}!</h1>
</body>
</html>

第6章: 静的ファイルの提供

静的ファイル(CSS、JavaScript、画像など)はstaticフォルダに配置します。

from quart import Quart, send_file

app = Quart(__name__)

@app.route('/logo')
async def logo():
    return await send_file('static/logo.png')

if __name__ == '__main__':
    app.run()

第7章: データベース連携

QuartでSQLAlchemyを使用してデータベースを操作する例を示します。

from quart import Quart
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

app = Quart(__name__)
engine = create_engine('sqlite:///example.db')
Session = sessionmaker(bind=engine)
Base = declarative_base()

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String)

Base.metadata.create_all(engine)

@app.route('/user/<name>')
async def add_user(name):
    session = Session()
    new_user = User(name=name)
    session.add(new_user)
    session.commit()
    return f'User {name} added'

if __name__ == '__main__':
    app.run()

第8章: フォーム処理

Quartでフォームデータを処理する方法を示します。

from quart import Quart, request, render_template

app = Quart(__name__)

@app.route('/form', methods=['GET', 'POST'])
async def form():
    if request.method == 'POST':
        name = (await request.form)['name']
        return f'Hello, {name}!'
    return await render_template('form.html')

if __name__ == '__main__':
    app.run()

templates/form.html:

<!DOCTYPE html>
<html>
<body>
    <form method="post">
        <input type="text" name="name">
        <input type="submit" value="Submit">
    </form>
</body>
</html>

第9章: エラーハンドリング

Quartでのエラーハンドリングの例を示します。

from quart import Quart, abort

app = Quart(__name__)

@app.route('/user/<int:user_id>')
async def get_user(user_id):
    if user_id > 100:
        abort(404)
    return f'User {user_id}'

@app.errorhandler(404)
async def not_found(error):
    return 'Page not found', 404

if __name__ == '__main__':
    app.run()

第10章: ミドルウェア

Quartでミドルウェアを使用する例を示します。

from quart import Quart, request

app = Quart(__name__)

@app.before_request
async def before_request():
    print('Before request')

@app.after_request
async def after_request(response):
    print('After request')
    return response

@app.route('/')
async def index():
    return 'Hello, World!'

if __name__ == '__main__':
    app.run()

第11章: WebSocket

QuartでWebSocketを使用する例を示します。

from quart import Quart, websocket

app = Quart(__name__)

@app.websocket('/ws')
async def ws():
    while True:
        data = await websocket.receive()
        await websocket.send(f"Echo: {data}")

@app.route('/')
async def index():
    return await app.send_static_file('index.html')

if __name__ == '__main__':
    app.run()

static/index.html:

<!DOCTYPE html>
<html>
<body>
    <script>
        var ws = new WebSocket('ws://' + location.host + '/ws');
        ws.onmessage = function(event) {
            console.log(event.data);
        };
        function sendMessage() {
            ws.send('Hello, WebSocket!');
        }
    </script>
    <button onclick="sendMessage()">Send Message</button>
</body>
</html>

第12章: ユニットテスト

Quartアプリケーションのユニットテストの例を示します。

from quart import Quart
import pytest

app = Quart(__name__)

@app.route('/')
async def hello():
    return 'Hello, World!'

@pytest.mark.asyncio
async def test_hello():
    test_client = app.test_client()
    response = await test_client.get('/')
    assert response.status_code == 200
    assert await response.get_data(as_text=True) == 'Hello, World!'

第13章: 設定管理

Quartアプリケーションの設定を管理する方法を示します。

from quart import Quart

app = Quart(__name__)

app.config.from_object('config.DevelopmentConfig')

@app.route('/')
async def index():
    return f"Database URL: {app.config['DATABASE_URL']}"

if __name__ == '__main__':
    app.run()

config.py:

class Config:
    DEBUG = False
    TESTING = False
    DATABASE_URL = 'sqlite:///production.db'

class DevelopmentConfig(Config):
    DEBUG = True
    DATABASE_URL = 'sqlite:///development.db'

class TestingConfig(Config):
    TESTING = True
    DATABASE_URL = 'sqlite:///test.db'

第14章: ログイン認証

Quartでログイン認証を実装する例を示します。

from quart import Quart, request, session, redirect, url_for
from werkzeug.security import generate_password_hash, check_password_hash

app = Quart(__name__)
app.secret_key = 'your-secret-key'

users = {'username': 'password'}

@app.route('/login', methods=['GET', 'POST'])
async def login():
    if request.method == 'POST':
        username = (await request.form)['username']
        password = (await request.form)['password']
        if username in users and check_password_hash(users[username], password):
            session['username'] = username
            return redirect(url_for('protected'))
    return '''
        <form method="post">
            <p><input type=text name=username>
            <p><input type=password name=password>
            <p><input type=submit value=Login>
        </form>
    '''

@app.route('/protected')
async def protected():
    if 'username' not in session:
        return redirect(url_for('login'))
    return f'Logged in as {session["username"]}'

if __name__ == '__main__':
    app.run()

第15章: RESTful API

QuartでRESTful APIを実装する例を示します。

from quart import Quart, jsonify, request

app = Quart(__name__)

todos = []

@app.route('/todos', methods=['GET'])
async def get_todos():
    return jsonify(todos)

@app.route('/todos', methods=['POST'])
async def create_todo():
    todo = await request.get_json()
    todos.append(todo)
    return jsonify(todo), 201

@app.route('/todos/<int:todo_id>', methods=['PUT'])
async def update_todo(todo_id):
    todo = await request.get_json()
    todos[todo_id] = todo
    return jsonify(todo)

@app.route('/todos/<int:todo_id>', methods=['DELETE'])
async def delete_todo(todo_id):
    todos.pop(todo_id)
    return '', 204

if __name__ == '__main__':
    app.run()

以上の15章で、Quartの基本から応用までを網羅しています。各章のコード例を実際に試してみることで、Quartの理解を深めることができるでしょう。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1