# 🤖 LINE Bot Error Analyzer
[](https://badge.fury.io/py/linebot-error-analyzer)
[](https://pypi.org/project/linebot-error-analyzer/)
[](https://opensource.org/licenses/MIT)
LINE Bot のエラーを自動分析・診断する Python ライブラリです。
エラーの原因を特定して、具体的な解決策を提案する「エラー分析器」があなたの LINE Bot 開発をサポートします。
## 📋 要件
- **Python**: 3.9 以上(3.9, 3.10, 3.11, 3.12 でテスト済み)
- **LINE Bot SDK**: v2/v3 系に対応(オプション)
- **依存関係**: 標準ライブラリのみ(`typing_extensions`のみ追加)
## 特徴
- **自動分析**: LINE API のエラーを自動で分類・診断
- **詳細対処法**: 各エラーに対する具体的な解決策を提案
- **同期・非同期対応**: 同期/非同期処理の両方をサポート
- **SDK 両対応**: LINE Bot SDK v2/v3 系の両方に対応
- **フレームワーク対応**: Flask、FastAPI 等で使用可能
## インストール
### 基本インストール
```bash
pip install linebot-error-analyzer
```
### 開発環境用(テスト依存関係含む)
```bash
pip install linebot-error-analyzer[dev]
```
### LINE Bot SDK と一緒にインストール
```bash
# LINE Bot SDK v3 と一緒に
pip install linebot-error-analyzer linebot-sdk
# または全依存関係込み
pip install linebot-error-analyzer[all]
```
### 対応環境
- Python 3.9+
- Windows, macOS, Linux
- LINE Bot SDK v2/v3(オプション)
## 基本的な使用方法
```python
from linebot_error_analyzer import LineErrorAnalyzer
analyzer = LineErrorAnalyzer()
# エラーデータを分析
error_data = {
"status_code": 401,
"message": "Authentication failed",
"error_code": "40001"
}
result = analyzer.analyze(error_data)
print(f"カテゴリ: {result.category.value}") # AUTH_ERROR
print(f"対処法: {result.recommended_action}")
print(f"リトライ可能: {result.is_retryable}") # False
```
## LINE Bot SDK との統合
```python
from linebot.v3.messaging import ApiClient, MessagingApi
from linebot.v3.messaging.exceptions import ApiException
from linebot_error_analyzer import LineErrorAnalyzer
analyzer = LineErrorAnalyzer()
try:
# LINE API呼び出し
line_bot_api.reply_message(...)
except ApiException as e:
error_info = analyzer.analyze(e)
if error_info.category.value == "RATE_LIMIT":
print(f"レート制限: {error_info.retry_after}秒待機")
elif error_info.is_retryable:
print("リトライ可能なエラー")
else:
print(f"対処法: {error_info.recommended_action}")
```
## 非同期処理
```python
import asyncio
from linebot_error_analyzer import AsyncLineErrorAnalyzer
async def analyze_errors():
analyzer = AsyncLineErrorAnalyzer()
# 単一エラーの分析
result = await analyzer.analyze(error_data)
# 複数エラーの一括分析
errors = [error1, error2, error3]
results = await analyzer.analyze_batch(errors, batch_size=10)
asyncio.run(analyze_errors())
```
## 📚 ドキュメント
### 詳細ガイド
- **[📖 インストールガイド](docs/installation.md)** - 詳細なセットアップ手順
- **[🚀 クイックスタート](docs/quickstart.md)** - すぐに始められるガイド
- **[🎯 使用例集](docs/examples/)** - 実際のプロジェクトでの活用例
- **[🔧 統合ガイド](docs/integration/)** - FastAPI、Flask との統合
- **[🐛 エラーリファレンス](docs/errors/)** - 全エラーコード詳細とトラブルシューティング
### 実装例
本ライブラリには、実際の LINE Bot 開発で使用できる実装例を含んでいます:
- **[📁 Simple Examples](examples/)** - 実用的なシンプル実装例
- 署名検証、メッセージ送信、ユーザー管理、グループ操作
- 本番環境での使用を想定した実装
- **[📁 Complex Examples](examples/)** - 学習・研究用の詳細実装例
- エラーハンドリングパターンの包括的なデモンストレーション
- エラー分析器との統合例
- **注意**: 複雑版の `error_data` 辞書は、実際の LINE API で発生する可能性のあるエラーパターンを示すサンプルです
詳細は [📖 Examples Guide](examples/README.md) をご覧ください。
## 主要エラーカテゴリ
| カテゴリ | 説明 | 例 |
| --------------------- | ------------------ | -------------------- |
| `AUTH_ERROR` | 認証エラー | 無効なトークン |
| `RATE_LIMIT` | API 呼び出し制限 | 429 エラー |
| `INVALID_REPLY_TOKEN` | 無効な返信トークン | 期限切れトークン |
| `USER_NOT_FOUND` | ユーザー未発見 | 削除されたアカウント |
| `SERVER_ERROR` | サーバーエラー | 5xx 系エラー |
詳細なエラーコード対応表は [📖 エラーリファレンス](docs/errors/line_api_codes.md) をご覧ください。
## フレームワーク統合
### FastAPI
```python
from fastapi import FastAPI
from fastapi.responses import JSONResponse
from linebot_error_analyzer import LineErrorAnalyzer
app = FastAPI()
analyzer = LineErrorAnalyzer()
@app.exception_handler(ApiException)
async def line_api_exception_handler(request, exc):
error_info = analyzer.analyze(exc)
return JSONResponse(
status_code=error_info.status_code,
content={
"error": error_info.category.value,
"message": error_info.message,
"action": error_info.recommended_action
}
)
```
## テスト実行
```bash
# 基本テスト実行
python -m pytest tests/ -v
# テスト用依存関係のインストール
pip install pytest pytest-asyncio
```
## ライセンス
MIT License
## 免責事項
このライブラリは**サードパーティ製**です。LINE 株式会社とは関係ありません。
## 参考リンク
- [LINE Messaging API リファレンス](https://developers.line.biz/ja/reference/messaging-api/)
- [LINE Bot SDK for Python](https://github.com/line/linebot-sdk-python)
- [LINE Developers](https://developers.line.biz/ja/)
Raw data
{
"_id": null,
"home_page": "https://github.com/raiton-boo/linebot-error-analyzer",
"name": "linebot-error-analyzer",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "linebot, bot, error, analyzer, messaging-api, webhook, diagnostics, line, chatbot",
"author": "\u3089\u3044\u3068\u3093",
"author_email": "raitosongwe@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/62/8b/a07125cd56ba22f6dda3975f1c8f0c0d2e012b777ee6c1a7ac21a2404590/linebot_error_analyzer-2.0.3.tar.gz",
"platform": "any",
"description": "# \ud83e\udd16 LINE Bot Error Analyzer\n\n[](https://badge.fury.io/py/linebot-error-analyzer)\n[](https://pypi.org/project/linebot-error-analyzer/)\n[](https://opensource.org/licenses/MIT)\n\nLINE Bot \u306e\u30a8\u30e9\u30fc\u3092\u81ea\u52d5\u5206\u6790\u30fb\u8a3a\u65ad\u3059\u308b Python \u30e9\u30a4\u30d6\u30e9\u30ea\u3067\u3059\u3002\n\n\u30a8\u30e9\u30fc\u306e\u539f\u56e0\u3092\u7279\u5b9a\u3057\u3066\u3001\u5177\u4f53\u7684\u306a\u89e3\u6c7a\u7b56\u3092\u63d0\u6848\u3059\u308b\u300c\u30a8\u30e9\u30fc\u5206\u6790\u5668\u300d\u304c\u3042\u306a\u305f\u306e LINE Bot \u958b\u767a\u3092\u30b5\u30dd\u30fc\u30c8\u3057\u307e\u3059\u3002\n\n## \ud83d\udccb \u8981\u4ef6\n\n- **Python**: 3.9 \u4ee5\u4e0a\uff083.9, 3.10, 3.11, 3.12 \u3067\u30c6\u30b9\u30c8\u6e08\u307f\uff09\n- **LINE Bot SDK**: v2/v3 \u7cfb\u306b\u5bfe\u5fdc\uff08\u30aa\u30d7\u30b7\u30e7\u30f3\uff09\n- **\u4f9d\u5b58\u95a2\u4fc2**: \u6a19\u6e96\u30e9\u30a4\u30d6\u30e9\u30ea\u306e\u307f\uff08`typing_extensions`\u306e\u307f\u8ffd\u52a0\uff09\n\n## \u7279\u5fb4\n\n- **\u81ea\u52d5\u5206\u6790**: LINE API \u306e\u30a8\u30e9\u30fc\u3092\u81ea\u52d5\u3067\u5206\u985e\u30fb\u8a3a\u65ad\n- **\u8a73\u7d30\u5bfe\u51e6\u6cd5**: \u5404\u30a8\u30e9\u30fc\u306b\u5bfe\u3059\u308b\u5177\u4f53\u7684\u306a\u89e3\u6c7a\u7b56\u3092\u63d0\u6848\n- **\u540c\u671f\u30fb\u975e\u540c\u671f\u5bfe\u5fdc**: \u540c\u671f/\u975e\u540c\u671f\u51e6\u7406\u306e\u4e21\u65b9\u3092\u30b5\u30dd\u30fc\u30c8\n- **SDK \u4e21\u5bfe\u5fdc**: LINE Bot SDK v2/v3 \u7cfb\u306e\u4e21\u65b9\u306b\u5bfe\u5fdc\n- **\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u5bfe\u5fdc**: Flask\u3001FastAPI \u7b49\u3067\u4f7f\u7528\u53ef\u80fd\n\n## \u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\n\n### \u57fa\u672c\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\n\n```bash\npip install linebot-error-analyzer\n```\n\n### \u958b\u767a\u74b0\u5883\u7528\uff08\u30c6\u30b9\u30c8\u4f9d\u5b58\u95a2\u4fc2\u542b\u3080\uff09\n\n```bash\npip install linebot-error-analyzer[dev]\n```\n\n### LINE Bot SDK \u3068\u4e00\u7dd2\u306b\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\n\n```bash\n# LINE Bot SDK v3 \u3068\u4e00\u7dd2\u306b\npip install linebot-error-analyzer linebot-sdk\n\n# \u307e\u305f\u306f\u5168\u4f9d\u5b58\u95a2\u4fc2\u8fbc\u307f\npip install linebot-error-analyzer[all]\n```\n\n### \u5bfe\u5fdc\u74b0\u5883\n\n- Python 3.9+\n- Windows, macOS, Linux\n- LINE Bot SDK v2/v3\uff08\u30aa\u30d7\u30b7\u30e7\u30f3\uff09\n\n## \u57fa\u672c\u7684\u306a\u4f7f\u7528\u65b9\u6cd5\n\n```python\nfrom linebot_error_analyzer import LineErrorAnalyzer\n\nanalyzer = LineErrorAnalyzer()\n\n# \u30a8\u30e9\u30fc\u30c7\u30fc\u30bf\u3092\u5206\u6790\nerror_data = {\n \"status_code\": 401,\n \"message\": \"Authentication failed\",\n \"error_code\": \"40001\"\n}\n\nresult = analyzer.analyze(error_data)\n\nprint(f\"\u30ab\u30c6\u30b4\u30ea: {result.category.value}\") # AUTH_ERROR\nprint(f\"\u5bfe\u51e6\u6cd5: {result.recommended_action}\")\nprint(f\"\u30ea\u30c8\u30e9\u30a4\u53ef\u80fd: {result.is_retryable}\") # False\n```\n\n## LINE Bot SDK \u3068\u306e\u7d71\u5408\n\n```python\nfrom linebot.v3.messaging import ApiClient, MessagingApi\nfrom linebot.v3.messaging.exceptions import ApiException\nfrom linebot_error_analyzer import LineErrorAnalyzer\n\nanalyzer = LineErrorAnalyzer()\n\ntry:\n # LINE API\u547c\u3073\u51fa\u3057\n line_bot_api.reply_message(...)\nexcept ApiException as e:\n error_info = analyzer.analyze(e)\n\n if error_info.category.value == \"RATE_LIMIT\":\n print(f\"\u30ec\u30fc\u30c8\u5236\u9650: {error_info.retry_after}\u79d2\u5f85\u6a5f\")\n elif error_info.is_retryable:\n print(\"\u30ea\u30c8\u30e9\u30a4\u53ef\u80fd\u306a\u30a8\u30e9\u30fc\")\n else:\n print(f\"\u5bfe\u51e6\u6cd5: {error_info.recommended_action}\")\n```\n\n## \u975e\u540c\u671f\u51e6\u7406\n\n```python\nimport asyncio\nfrom linebot_error_analyzer import AsyncLineErrorAnalyzer\n\nasync def analyze_errors():\n analyzer = AsyncLineErrorAnalyzer()\n\n # \u5358\u4e00\u30a8\u30e9\u30fc\u306e\u5206\u6790\n result = await analyzer.analyze(error_data)\n\n # \u8907\u6570\u30a8\u30e9\u30fc\u306e\u4e00\u62ec\u5206\u6790\n errors = [error1, error2, error3]\n results = await analyzer.analyze_batch(errors, batch_size=10)\n\nasyncio.run(analyze_errors())\n```\n\n## \ud83d\udcda \u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\n\n### \u8a73\u7d30\u30ac\u30a4\u30c9\n\n- **[\ud83d\udcd6 \u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u30ac\u30a4\u30c9](docs/installation.md)** - \u8a73\u7d30\u306a\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u624b\u9806\n- **[\ud83d\ude80 \u30af\u30a4\u30c3\u30af\u30b9\u30bf\u30fc\u30c8](docs/quickstart.md)** - \u3059\u3050\u306b\u59cb\u3081\u3089\u308c\u308b\u30ac\u30a4\u30c9\n- **[\ud83c\udfaf \u4f7f\u7528\u4f8b\u96c6](docs/examples/)** - \u5b9f\u969b\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3067\u306e\u6d3b\u7528\u4f8b\n- **[\ud83d\udd27 \u7d71\u5408\u30ac\u30a4\u30c9](docs/integration/)** - FastAPI\u3001Flask \u3068\u306e\u7d71\u5408\n- **[\ud83d\udc1b \u30a8\u30e9\u30fc\u30ea\u30d5\u30a1\u30ec\u30f3\u30b9](docs/errors/)** - \u5168\u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u8a73\u7d30\u3068\u30c8\u30e9\u30d6\u30eb\u30b7\u30e5\u30fc\u30c6\u30a3\u30f3\u30b0\n\n### \u5b9f\u88c5\u4f8b\n\n\u672c\u30e9\u30a4\u30d6\u30e9\u30ea\u306b\u306f\u3001\u5b9f\u969b\u306e LINE Bot \u958b\u767a\u3067\u4f7f\u7528\u3067\u304d\u308b\u5b9f\u88c5\u4f8b\u3092\u542b\u3093\u3067\u3044\u307e\u3059\uff1a\n\n- **[\ud83d\udcc1 Simple Examples](examples/)** - \u5b9f\u7528\u7684\u306a\u30b7\u30f3\u30d7\u30eb\u5b9f\u88c5\u4f8b\n - \u7f72\u540d\u691c\u8a3c\u3001\u30e1\u30c3\u30bb\u30fc\u30b8\u9001\u4fe1\u3001\u30e6\u30fc\u30b6\u30fc\u7ba1\u7406\u3001\u30b0\u30eb\u30fc\u30d7\u64cd\u4f5c\n - \u672c\u756a\u74b0\u5883\u3067\u306e\u4f7f\u7528\u3092\u60f3\u5b9a\u3057\u305f\u5b9f\u88c5\n- **[\ud83d\udcc1 Complex Examples](examples/)** - \u5b66\u7fd2\u30fb\u7814\u7a76\u7528\u306e\u8a73\u7d30\u5b9f\u88c5\u4f8b\n - \u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0\u30d1\u30bf\u30fc\u30f3\u306e\u5305\u62ec\u7684\u306a\u30c7\u30e2\u30f3\u30b9\u30c8\u30ec\u30fc\u30b7\u30e7\u30f3\n - \u30a8\u30e9\u30fc\u5206\u6790\u5668\u3068\u306e\u7d71\u5408\u4f8b\n - **\u6ce8\u610f**: \u8907\u96d1\u7248\u306e `error_data` \u8f9e\u66f8\u306f\u3001\u5b9f\u969b\u306e LINE API \u3067\u767a\u751f\u3059\u308b\u53ef\u80fd\u6027\u306e\u3042\u308b\u30a8\u30e9\u30fc\u30d1\u30bf\u30fc\u30f3\u3092\u793a\u3059\u30b5\u30f3\u30d7\u30eb\u3067\u3059\n\n\u8a73\u7d30\u306f [\ud83d\udcd6 Examples Guide](examples/README.md) \u3092\u3054\u89a7\u304f\u3060\u3055\u3044\u3002\n\n## \u4e3b\u8981\u30a8\u30e9\u30fc\u30ab\u30c6\u30b4\u30ea\n\n| \u30ab\u30c6\u30b4\u30ea | \u8aac\u660e | \u4f8b |\n| --------------------- | ------------------ | -------------------- |\n| `AUTH_ERROR` | \u8a8d\u8a3c\u30a8\u30e9\u30fc | \u7121\u52b9\u306a\u30c8\u30fc\u30af\u30f3 |\n| `RATE_LIMIT` | API \u547c\u3073\u51fa\u3057\u5236\u9650 | 429 \u30a8\u30e9\u30fc |\n| `INVALID_REPLY_TOKEN` | \u7121\u52b9\u306a\u8fd4\u4fe1\u30c8\u30fc\u30af\u30f3 | \u671f\u9650\u5207\u308c\u30c8\u30fc\u30af\u30f3 |\n| `USER_NOT_FOUND` | \u30e6\u30fc\u30b6\u30fc\u672a\u767a\u898b | \u524a\u9664\u3055\u308c\u305f\u30a2\u30ab\u30a6\u30f3\u30c8 |\n| `SERVER_ERROR` | \u30b5\u30fc\u30d0\u30fc\u30a8\u30e9\u30fc | 5xx \u7cfb\u30a8\u30e9\u30fc |\n\n\u8a73\u7d30\u306a\u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u5bfe\u5fdc\u8868\u306f [\ud83d\udcd6 \u30a8\u30e9\u30fc\u30ea\u30d5\u30a1\u30ec\u30f3\u30b9](docs/errors/line_api_codes.md) \u3092\u3054\u89a7\u304f\u3060\u3055\u3044\u3002\n\n## \u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u7d71\u5408\n\n### FastAPI\n\n```python\nfrom fastapi import FastAPI\nfrom fastapi.responses import JSONResponse\nfrom linebot_error_analyzer import LineErrorAnalyzer\n\napp = FastAPI()\nanalyzer = LineErrorAnalyzer()\n\n@app.exception_handler(ApiException)\nasync def line_api_exception_handler(request, exc):\n error_info = analyzer.analyze(exc)\n return JSONResponse(\n status_code=error_info.status_code,\n content={\n \"error\": error_info.category.value,\n \"message\": error_info.message,\n \"action\": error_info.recommended_action\n }\n )\n```\n\n## \u30c6\u30b9\u30c8\u5b9f\u884c\n\n```bash\n# \u57fa\u672c\u30c6\u30b9\u30c8\u5b9f\u884c\npython -m pytest tests/ -v\n\n# \u30c6\u30b9\u30c8\u7528\u4f9d\u5b58\u95a2\u4fc2\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\npip install pytest pytest-asyncio\n```\n\n## \u30e9\u30a4\u30bb\u30f3\u30b9\n\nMIT License\n\n## \u514d\u8cac\u4e8b\u9805\n\n\u3053\u306e\u30e9\u30a4\u30d6\u30e9\u30ea\u306f**\u30b5\u30fc\u30c9\u30d1\u30fc\u30c6\u30a3\u88fd**\u3067\u3059\u3002LINE \u682a\u5f0f\u4f1a\u793e\u3068\u306f\u95a2\u4fc2\u3042\u308a\u307e\u305b\u3093\u3002\n\n## \u53c2\u8003\u30ea\u30f3\u30af\n\n- [LINE Messaging API \u30ea\u30d5\u30a1\u30ec\u30f3\u30b9](https://developers.line.biz/ja/reference/messaging-api/)\n- [LINE Bot SDK for Python](https://github.com/line/linebot-sdk-python)\n- [LINE Developers](https://developers.line.biz/ja/)\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "LINE Bot SDK \u306e\u30a8\u30e9\u30fc\u3092\u81ea\u52d5\u5206\u6790\u30fb\u8a3a\u65ad\u3059\u308b\u30e9\u30a4\u30d6\u30e9\u30ea",
"version": "2.0.3",
"project_urls": {
"Bug Reports": "https://github.com/raiton-boo/linebot-error-analyzer/issues",
"Changelog": "https://github.com/raiton-boo/linebot-error-analyzer/releases",
"Documentation": "https://github.com/raiton-boo/linebot-error-analyzer/tree/main/docs",
"Homepage": "https://github.com/raiton-boo/linebot-error-analyzer",
"Source": "https://github.com/raiton-boo/linebot-error-analyzer"
},
"split_keywords": [
"linebot",
" bot",
" error",
" analyzer",
" messaging-api",
" webhook",
" diagnostics",
" line",
" chatbot"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "7b4ae4c0e24857bdfc604b264888150642bb65993a4818a052e241f28c10966d",
"md5": "ea22130b36bfe68d4abe52aeaf9b6962",
"sha256": "15403bb66a9fcfae9e7d5a223221f12d995e7beec6063a64acbd83b5f8705e9c"
},
"downloads": -1,
"filename": "linebot_error_analyzer-2.0.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "ea22130b36bfe68d4abe52aeaf9b6962",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 27527,
"upload_time": "2025-07-25T15:22:21",
"upload_time_iso_8601": "2025-07-25T15:22:21.295819Z",
"url": "https://files.pythonhosted.org/packages/7b/4a/e4c0e24857bdfc604b264888150642bb65993a4818a052e241f28c10966d/linebot_error_analyzer-2.0.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "628ba07125cd56ba22f6dda3975f1c8f0c0d2e012b777ee6c1a7ac21a2404590",
"md5": "92d15d856ae2ee4de8a435711fa4248c",
"sha256": "72c7385755efb7b4046eeccd3ef4132f911d9a7c8540800dd0f8b40bd20ae269"
},
"downloads": -1,
"filename": "linebot_error_analyzer-2.0.3.tar.gz",
"has_sig": false,
"md5_digest": "92d15d856ae2ee4de8a435711fa4248c",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 25123,
"upload_time": "2025-07-25T15:22:22",
"upload_time_iso_8601": "2025-07-25T15:22:22.511651Z",
"url": "https://files.pythonhosted.org/packages/62/8b/a07125cd56ba22f6dda3975f1c8f0c0d2e012b777ee6c1a7ac21a2404590/linebot_error_analyzer-2.0.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-25 15:22:22",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "raiton-boo",
"github_project": "linebot-error-analyzer",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "pytest",
"specs": [
[
">=",
"8.0.0"
]
]
},
{
"name": "pytest-asyncio",
"specs": [
[
">=",
"0.23.0"
]
]
},
{
"name": "pytest-cov",
"specs": [
[
">=",
"4.0.0"
]
]
},
{
"name": "psutil",
"specs": [
[
">=",
"5.9.0"
]
]
},
{
"name": "typing_extensions",
"specs": [
[
">=",
"4.0.0"
]
]
},
{
"name": "black",
"specs": [
[
">=",
"24.0.0"
]
]
},
{
"name": "flake8",
"specs": [
[
">=",
"7.0.0"
]
]
},
{
"name": "mypy",
"specs": [
[
">=",
"1.8.0"
]
]
},
{
"name": "sphinx",
"specs": [
[
">=",
"7.0.0"
]
]
},
{
"name": "sphinx-rtd-theme",
"specs": [
[
">=",
"2.0.0"
]
]
}
],
"lcname": "linebot-error-analyzer"
}