Files
rogaining_srv/rog/views_apis/api_test.py
2025-08-20 19:15:19 +09:00

295 lines
11 KiB
Python
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
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)