Asyncio Programming について
Python開発者向けにasyncioを学ぶスキルです。async/await、並行処理、非同期I/O、非同期Webアプリを扱い、プロジェクト演習とテスト・デバッグの指針も含みます。
主な機能
- 01async/awaitとコルーチンの学習
- 02タスクと並行処理の管理
- 03非同期I/Oの利用
- 04非同期Webアプリの構築
- 05ガイド付きプロジェクトで演習
- 06非同期コードのデバッグとテスト
活用シーン
- 01asyncioの基礎を学習
- 02複数サイトから並行してデータを取得
- 03WebSocketチャットサーバーを構築
- 04分散タスク処理を演習
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ pluginagentmarketplace/ custom-plugin-python --skill asyncio-programmingインストール後、Claude Code で/asyncio-programmingを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
assets/config.yamlreferences/GUIDE.mdscripts/helper.py詳細
Asyncio プログラミング
概要
asyncio を使って、Python の非同期プログラミングを習得しましょう。I/O 待ちの処理を効率よく扱う並行コードの書き方、非同期 Web アプリケーションの構築方法、async/await のパラダイムについて学びます。
学習目標
- 非同期プログラミングの概念を理解する
- async/await 構文で非同期関数を書く
- asyncio で並行処理を管理する
- 非同期 Web アプリケーションを構築する
- 非同期 I/O 処理を効率的に扱う
- 非同期コードをデバッグしてテストする
主なトピック
1. async/await の基礎
- コルーチンを理解する
- async/await 構文
- イベントループの基礎
- 非同期関数の実行
- 非同期実行と同期実行の違い
- よくある落とし穴
コード例:
import asyncio
import time
# Synchronous version (slow)
def fetch_data_sync(url):
print(f"Fetching {url}...")
time.sleep(2) # Simulating network delay
return f"Data from {url}"
def main_sync():
urls = ['url1', 'url2', 'url3']
results = []
for url in urls:
data = fetch_data_sync(url)
results.append(data)
return results
# Takes 6 seconds (2 * 3)
start = time.time()
main_sync()
print(f"Sync took: {time.time() - start:.2f}s")
# Asynchronous version (fast)
async def fetch_data_async(url):
print(f"Fetching {url}...")
await asyncio.sleep(2) # Non-blocking sleep
return f"Data from {url}"
async def main_async():
urls = ['url1', 'url2', 'url3']
# Create tasks and run concurrently
tasks = [fetch_data_async(url) for url in urls]
results = await asyncio.gather(*tasks)
return results
# Takes 2 seconds (concurrent execution)
start = time.time()
asyncio.run(main_async())
print(f"Async took: {time.time() - start:.2f}s")
2. asyncio のタスクとコルーチン
- タスクの作成と管理
- asyncio.gather() と asyncio.wait() の違い
- タスクのキャンセル
- タスクグループ(Python 3.11+)
- タスク内の例外処理
- タイムアウト
コード例:
import asyncio
async def process_item(item_id, delay):
print(f"Processing item {item_id}")
await asyncio.sleep(delay)
if item_id == 3:
raise ValueError(f"Item {item_id} failed!")
return f"Result {item_id}"
async def main():
# Method 1: gather (returns results in order)
tasks = [
process_item(1, 1),
process_item(2, 2),
process_item(3, 1),
]
try:
results = await asyncio.gather(*tasks, return_exceptions=True)
for i, result in enumerate(results):
if isinstance(result, Exception):
print(f"Task {i} failed: {result}")
else:
print(f"Task {i} result: {result}")
except Exception as e:
print(f"Error: {e}")
# Method 2: wait (returns done/pending sets)
tasks = [
asyncio.create_task(process_item(i, i))
for i in range(1, 4)
]
done, pending = await asyncio.wait(tasks, timeout=2.5)
print(f"Completed: {len(done)}, Pending: {len(pending)}")
# Cancel pending tasks
for task in pending:
task.cancel()
# Method 3: Task groups (Python 3.11+)
async with asyncio.TaskGroup() as tg:
for i in range(1, 4):
tg.create_task(process_item(i, 1))
# All tasks completed or exception raised
asyncio.run(main())
3. 非同期 I/O 処理
- 非同期ファイル操作(aiofiles)
- 非同期 HTTP リクエスト(aiohttp)
- 非同期データベース操作(asyncpg、motor)
- 非同期メッセージング(aio-pika)
- ストリームとプロトコル
コード例:
import asyncio
import aiohttp
import aiofiles
from typing import List
# Async HTTP requests
async def fetch_url(session, url):
async with session.get(url) as response:
return await response.text()
async def fetch_multiple_urls(urls: List[str]):
async with aiohttp.ClientSession() as session:
tasks = [fetch_url(session, url) for url in urls]
results = await asyncio.gather(*tasks)
return results
# Async file operations
async def read_file_async(filepath):
async with aiofiles.open(filepath, 'r') as f:
content = await f.read()
return content
async def write_file_async(filepath, content):
async with aiofiles.open(filepath, 'w') as f:
await f.write(content)
# Async database operations (example with asyncpg)
import asyncpg
async def fetch_users():
conn = await asyncpg.connect(
user='user',
password='password',
database='mydb',
host='localhost'
)
try:
rows = await conn.fetch('SELECT * FROM users')
return rows
finally:
await conn.close()
# Usage
async def main():
# Fetch URLs concurrently
urls = [
'https://api.example.com/data1',
'https://api.example.com/data2',
'https://api.example.com/data3',
]
results = await fetch_multiple_urls(urls)
# Read/write files
content = await read_file_async('input.txt')
await write_file_async('output.txt', content.upper())
# Database operations
users = await fetch_users()
print(f"Found {len(users)} users")
asyncio.run(main())
4. 非同期 Web フレームワーク
- FastAPI の非同期ルート
- aiohttp Web サーバー
- WebSocket の処理
- バックグラウンドタスク
- ミドルウェアと依存関係
コード例:
# FastAPI async example
from fastapi import FastAPI, BackgroundTasks
import asyncio
app = FastAPI()
# Async route
@app.get("/users/{user_id}")
async def get_user(user_id: int):
# Async database call
user = await fetch_user_from_db(user_id)
return user
# Background task
async def send_notification(email: str, message: str):
await asyncio.sleep(2) # Simulate email sending
print(f"Sent email to {email}: {message}")
@app.post("/orders/")
async def create_order(order_data: dict, background_tasks: BackgroundTasks):
# Process order synchronously
order_id = save_order(order_data)
# Send notification in background
background_tasks.add_task(
send_notification,
order_data['customer_email'],
f"Order #{order_id} created"
)
return {"order_id": order_id}
# aiohttp web server
from aiohttp import web
async def handle_request(request):
name = request.match_info.get('name', 'Anonymous')
await asyncio.sleep(1) # Async operation
return web.json_response({'message': f'Hello {name}'})
app = web.Application()
app.add_routes([web.get('/{name}', handle_request)])
# WebSocket example
async def websocket_handler(request):
ws = web.WebSocketResponse()
await ws.prepare(request)
async for msg in ws:
if msg.type == web.WSMsgType.TEXT:
await ws.send_str(f"Echo: {msg.data}")
elif msg.type == web.WSMsgType.ERROR:
print(f'Error: {ws.exception()}')
return ws
app.add_routes([web.get('/ws', websocket_handler)])
実践演習
プロジェクト 1:非同期 Web スクレイパー
レート制限機能を備えた並行 Web スクレイパーを構築します。
要件:
- 複数の Web サイトを並行してスクレイピングする
- レート制限を実装する
- エラーを適切に処理する
- 結果を非同期データベースに保存する
- 進捗を追跡する
- 失敗したリクエストを再試行する
主なスキル: aiohttp、非同期 I/O、エラー処理
プロジェクト 2:リアルタイムチャットサーバー
WebSocket ベースのチャットアプリケーションを作成します。
要件:
- aiohttp による WebSocket サーバー
- 複数のチャットルーム
- ユーザー認証
- メッセージのブロードキャスト
- 接続管理
- メッセージ履歴の永続化
主なスキル: WebSocket、非同期サーバー、状態管理
プロジェクト 3:非同期タスクキュー
分散タスク処理システムを構築します。
要件:
- Redis/RabbitMQ によるタスクキュー
- ワーカープールの管理
- タスクの優先順位付け
- 結果のキャッシュ
- 進捗のモニタリング
- グレースフルシャットダウン
主なスキル: メッセージキュー、並行ワーカー、クリーンアップ
評価基準
- async/await の意味と動作を理解している
- 効率的な並行コードを書ける
- 非同期例外を適切に処理できる
- asyncio タスクを効果的に使える
- 非同期 Web アプリケーションを構築できる
- 非同期コードをデバッグできる
- 非同期リソースを管理できる(クリーンアップ)
リソース
公式ドキュメント
- asyncio Docs - 公式ドキュメント
- aiohttp - 非同期 HTTP クライアント/サーバー
- FastAPI - 最新の非同期 Web フレームワーク
学習プラットフォーム
- Using Asyncio in Python - Real Python のガイド
- Python Concurrency - O'Reilly の書籍
- Asyncio Recipes - 実践的な例
ツール
次のステップ
asyncio を習得したら、次のトピックを学びましょう。
- Multiprocessing - CPU 負荷の高い処理の並列化
- Celery - 分散タスクキュー
- gRPC - 非同期 RPC フレームワーク
- Kafka - 非同期イベントストリーミング
コメント
Markdown 対応