initial setting at 20-Aug-2025
This commit is contained in:
294
rog/views_apis/api_test.py
Executable file
294
rog/views_apis/api_test.py
Executable file
@ -0,0 +1,294 @@
|
||||
|
||||
|
||||
"""
|
||||
pip install psutil
|
||||
"""
|
||||
|
||||
# 既存のインポート部分に追加
|
||||
from rest_framework.decorators import api_view
|
||||
from rest_framework.response import Response
|
||||
from rest_framework import status
|
||||
import logging
|
||||
from django.utils import timezone
|
||||
import platform
|
||||
import sys
|
||||
import os
|
||||
import psutil
|
||||
import django
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
"""
|
||||
解説
|
||||
この実装では、サーバーの動作状態を確認するための診断エンドポイントを提供しています。このエンドポイントは以下の情報を返します:
|
||||
|
||||
1.基本情報:
|
||||
- サーバーの稼働状態
|
||||
- 現在のタイムスタンプ
|
||||
- アクティブなイベント数
|
||||
2.システム情報:
|
||||
- 使用しているOSやプラットフォーム
|
||||
- Pythonのバージョン
|
||||
- Djangoのバージョン
|
||||
3.リソース使用状況:
|
||||
- CPU使用率
|
||||
- メモリ使用率
|
||||
- ディスク使用率
|
||||
4.環境設定:
|
||||
- デバッグモードの状態
|
||||
- タイムゾーン設定
|
||||
5.サーバー稼働時間:
|
||||
- サーバープロセスの起動からの経過時間
|
||||
6.利用可能なAPIルート:
|
||||
- サーバーで設定されているURL設定から取得したルート情報
|
||||
|
||||
このエンドポイントは主に以下の目的で使用されます:
|
||||
- サーバーの正常性確認(ヘルスチェック)
|
||||
- サーバーの基本的な診断情報の取得
|
||||
- 動作環境の確認
|
||||
- 監視やデバッグのためのメトリクス収集
|
||||
|
||||
実際の運用環境では、このエンドポイントが本番環境で公開されている場合、
|
||||
セキュリティのためアクセス制限を設けることも検討すべきでしょう。
|
||||
"""
|
||||
|
||||
@api_view(['GET'])
|
||||
def test_gifuroge(request):
|
||||
"""
|
||||
サーバーの動作テスト用エンドポイント
|
||||
|
||||
機能:
|
||||
- サーバーが動作していることを確認
|
||||
- サーバーの基本情報を返す
|
||||
"""
|
||||
logger.info("test_gifuroge called")
|
||||
|
||||
try:
|
||||
# システム情報を収集
|
||||
server_info = {
|
||||
"status": "OK",
|
||||
"message": "GifuTabi Rogaining Server is running",
|
||||
"timestamp": timezone.now().strftime("%Y-%m-%d %H:%M:%S"),
|
||||
"system": {
|
||||
"platform": platform.platform(),
|
||||
"python_version": sys.version,
|
||||
"django_version": django.get_version(),
|
||||
},
|
||||
"resources": {
|
||||
"cpu_usage": f"{psutil.cpu_percent()}%",
|
||||
"memory_usage": f"{psutil.virtual_memory().percent}%",
|
||||
"disk_usage": f"{psutil.disk_usage('/').percent}%"
|
||||
},
|
||||
"env": {
|
||||
"debug_mode": os.environ.get("DEBUG", "False"),
|
||||
"timezone": str(timezone.get_current_timezone())
|
||||
}
|
||||
}
|
||||
|
||||
# アクティブなイベント数をカウント
|
||||
try:
|
||||
from rog.models import NewEvent2
|
||||
active_events = NewEvent2.objects.filter(event_active=True).count()
|
||||
server_info["active_events"] = active_events
|
||||
except:
|
||||
logger.warning("Unable to count active events")
|
||||
server_info["active_events"] = "Unknown"
|
||||
|
||||
# アプリケーション起動時間を計算(サーバープロセスの起動時間)
|
||||
try:
|
||||
process = psutil.Process(os.getpid())
|
||||
start_time = process.create_time()
|
||||
uptime_seconds = int(time.time() - start_time)
|
||||
days, remainder = divmod(uptime_seconds, 86400)
|
||||
hours, remainder = divmod(remainder, 3600)
|
||||
minutes, seconds = divmod(remainder, 60)
|
||||
|
||||
uptime_str = ""
|
||||
if days > 0:
|
||||
uptime_str += f"{days}日 "
|
||||
if hours > 0 or days > 0:
|
||||
uptime_str += f"{hours}時間 "
|
||||
if minutes > 0 or hours > 0 or days > 0:
|
||||
uptime_str += f"{minutes}分 "
|
||||
uptime_str += f"{seconds}秒"
|
||||
|
||||
server_info["uptime"] = uptime_str
|
||||
except:
|
||||
logger.warning("Unable to calculate uptime")
|
||||
server_info["uptime"] = "Unknown"
|
||||
|
||||
# ルート情報を追加
|
||||
root_paths = []
|
||||
for pattern in request.urlconf.urlpatterns:
|
||||
if hasattr(pattern, 'pattern'):
|
||||
root_paths.append(str(pattern.pattern))
|
||||
|
||||
server_info["available_api_roots"] = root_paths
|
||||
|
||||
# 応答を返す
|
||||
return Response(server_info)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error in test_gifuroge: {str(e)}")
|
||||
return Response({
|
||||
"status": "ERROR",
|
||||
"message": "サーバーテスト中にエラーが発生しました",
|
||||
"error": str(e)
|
||||
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||
|
||||
|
||||
# 既存のインポート部分に追加
|
||||
from rest_framework.decorators import api_view
|
||||
from rest_framework.response import Response
|
||||
from django.http import HttpResponse, JsonResponse
|
||||
import logging
|
||||
import random
|
||||
import json
|
||||
from django.utils import timezone
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
"""
|
||||
解説
|
||||
この/practiceエンドポイントは、主に以下の目的で使用される練習用・テスト用のエンドポイントです:
|
||||
|
||||
1.学習目的:
|
||||
- APIの基本的な使い方を学ぶための練習用エンドポイント
|
||||
- 異なるレスポンス形式(JSON、プレーンテキスト、HTML)を試すことができる
|
||||
- クエリパラメータの使い方を練習できる
|
||||
2.テスト・デバッグ目的:
|
||||
- APIクライアントのテストに使用できる
|
||||
- エラーレスポンスをシミュレートできる
|
||||
- さまざまなレスポンス形式の処理をテストできる
|
||||
3.機能デモンストレーション:
|
||||
- 岐阜ロゲに関連する簡単なクイズやヒントを提供
|
||||
- ランダムな要素を含むレスポンスを生成
|
||||
|
||||
このエンドポイントは特に実用的な機能を持たないシンプルな実装ですが、
|
||||
APIの使い方を学ぶユーザーや、APIクライアントのテストを行う開発者にとって便利なツールとなります。
|
||||
また、新機能開発時の参考実装としても活用できます。
|
||||
"""
|
||||
|
||||
@api_view(['GET'])
|
||||
def practice(request):
|
||||
"""
|
||||
練習用エンドポイント
|
||||
|
||||
機能:
|
||||
- APIの基本的な使い方を学ぶための練習用エンドポイント
|
||||
- リクエストパラメータに応じた簡単なレスポンスを返す
|
||||
- テスト・デバッグ用としても使用可能
|
||||
|
||||
パラメータ:
|
||||
- name: 名前 (オプション)
|
||||
- mode: レスポンスモード (json, text, html, random のいずれか。デフォルトは json)
|
||||
- error: エラーをシミュレーションする場合は true (オプション)
|
||||
"""
|
||||
logger.info("practice called")
|
||||
|
||||
# リクエストパラメータを取得
|
||||
name = request.query_params.get('name', 'ゲスト')
|
||||
mode = request.query_params.get('mode', 'json')
|
||||
simulate_error = request.query_params.get('error', 'false').lower() == 'true'
|
||||
|
||||
logger.debug(f"Parameters: name={name}, mode={mode}, error={simulate_error}")
|
||||
|
||||
# エラーシミュレーション
|
||||
if simulate_error:
|
||||
logger.warning("Simulating error response")
|
||||
return Response({
|
||||
"status": "ERROR",
|
||||
"message": "これはリクエストパラメータ 'error=true' によるシミュレーションエラーです"
|
||||
}, status=400)
|
||||
|
||||
# 現在時刻
|
||||
current_time = timezone.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
# ランダムな練習用データ
|
||||
practice_data = {
|
||||
"quiz_questions": [
|
||||
{"id": 1, "question": "岐阜県の県庁所在地は?", "answer": "岐阜市"},
|
||||
{"id": 2, "question": "ロゲイニングで重要なのは?", "answer": "戦略的なルート選択"},
|
||||
{"id": 3, "question": "岐阜県の有名な祭りは?", "answer": "高山祭"}
|
||||
],
|
||||
"tips": [
|
||||
"ロゲイニングでは水分補給が重要です",
|
||||
"地図の縮尺を確認しましょう",
|
||||
"無理なルートは避けて安全第一で"
|
||||
],
|
||||
"random_number": random.randint(1, 100)
|
||||
}
|
||||
|
||||
# モードに応じたレスポンス形式
|
||||
if mode == 'random':
|
||||
# ランダムでモードを選択
|
||||
mode = random.choice(['json', 'text', 'html'])
|
||||
|
||||
if mode == 'text':
|
||||
# テキスト形式のレスポンス
|
||||
response_text = f"""
|
||||
岐阜ロゲAPI練習用エンドポイント
|
||||
|
||||
こんにちは、{name}さん!
|
||||
現在時刻: {current_time}
|
||||
|
||||
今日のランダム数字: {practice_data['random_number']}
|
||||
|
||||
今日のヒント: {random.choice(practice_data['tips'])}
|
||||
|
||||
これはテスト用のレスポンスです。
|
||||
"""
|
||||
return HttpResponse(response_text, content_type='text/plain; charset=utf-8')
|
||||
|
||||
elif mode == 'html':
|
||||
# HTML形式のレスポンス
|
||||
response_html = f"""
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>岐阜ロゲAPI練習ページ</title>
|
||||
<style>
|
||||
body {{ font-family: Arial, sans-serif; margin: 20px; }}
|
||||
.container {{ max-width: 800px; margin: 0 auto; padding: 20px; border: 1px solid #ddd; border-radius: 5px; }}
|
||||
h1 {{ color: #0066cc; }}
|
||||
.info {{ background-color: #f5f5f5; padding: 10px; border-radius: 5px; }}
|
||||
.tip {{ color: #006600; font-weight: bold; }}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>岐阜ロゲAPI練習用ページ</h1>
|
||||
<p>こんにちは、<strong>{name}</strong>さん!</p>
|
||||
<div class="info">
|
||||
<p>現在時刻: {current_time}</p>
|
||||
<p>今日のランダム数字: {practice_data['random_number']}</p>
|
||||
</div>
|
||||
<h2>今日のヒント</h2>
|
||||
<p class="tip">{random.choice(practice_data['tips'])}</p>
|
||||
<h2>ロゲイニングクイズ</h2>
|
||||
<div id="quiz">
|
||||
<p><strong>問題:</strong> {random.choice(practice_data['quiz_questions'])['question']}</p>
|
||||
</div>
|
||||
<p><small>これはテスト用のHTMLレスポンスです。</small></p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
return HttpResponse(response_html, content_type='text/html; charset=utf-8')
|
||||
|
||||
else: # mode == 'json' (デフォルト)
|
||||
# JSON形式のレスポンス
|
||||
response_data = {
|
||||
"status": "OK",
|
||||
"message": f"こんにちは、{name}さん!",
|
||||
"timestamp": current_time,
|
||||
"request_info": {
|
||||
"ip": request.META.get('REMOTE_ADDR', 'unknown'),
|
||||
"user_agent": request.META.get('HTTP_USER_AGENT', 'unknown'),
|
||||
"parameters": dict(request.query_params.items())
|
||||
},
|
||||
"practice_data": practice_data
|
||||
}
|
||||
return JsonResponse(response_data)
|
||||
Reference in New Issue
Block a user