Coverage for src / rasp_shutter / util.py: 84%

21 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-02-13 00:10 +0900

1#!/usr/bin/env python3 

2""" 

3rasp-shutter アプリケーション用のユーティリティ関数 

4""" 

5 

6import functools 

7import os 

8from collections.abc import Callable 

9from typing import TypeVar 

10 

11F = TypeVar("F", bound=Callable) 

12 

13 

14def is_dummy_mode() -> bool: 

15 """DUMMY_MODEが有効かどうかを返す 

16 

17 テストやハードウェアなしでの動作確認時に使用される 

18 環境変数 DUMMY_MODE が "true" の場合に True を返す 

19 

20 Returns 

21 ------- 

22 bool: DUMMY_MODEが有効な場合 True 

23 

24 """ 

25 return os.environ.get("DUMMY_MODE", "false") == "true" 

26 

27 

28def check_dummy_mode_for_api() -> tuple[dict[str, str], int] | None: 

29 """テストAPIのDUMMY_MODEチェック 

30 

31 DUMMY_MODEが有効でない場合にエラーレスポンスを返す 

32 テスト用APIで共通して使用するガード関数 

33 

34 Returns 

35 ------- 

36 tuple[dict[str, str], int] | None: 

37 DUMMY_MODEが無効の場合はエラーレスポンス (dict, 403) 

38 DUMMY_MODEが有効の場合は None 

39 

40 Examples 

41 -------- 

42 >>> error = check_dummy_mode_for_api() 

43 >>> if error: 

44 >>> return error 

45 

46 """ 

47 if not is_dummy_mode(): 47 ↛ 48line 47 didn't jump to line 48 because the condition on line 47 was never true

48 return {"error": "Test API is only available in DUMMY_MODE"}, 403 

49 return None 

50 

51 

52def is_pytest_running() -> bool: 

53 """pytest実行中かどうかを返す 

54 

55 テスト環境でのみ特定の処理を行う場合に使用する。 

56 環境変数 PYTEST_CURRENT_TEST が設定されている場合に True を返す。 

57 

58 Returns 

59 ------- 

60 bool: pytest実行中の場合 True 

61 

62 """ 

63 return bool(os.environ.get("PYTEST_CURRENT_TEST")) 

64 

65 

66def require_dummy_mode(f: F) -> F: 

67 """DUMMY_MODE必須デコレータ 

68 

69 テスト用APIでDUMMY_MODEが有効でない場合に403エラーを返す。 

70 各関数でのインラインチェックを不要にする。 

71 

72 Examples 

73 -------- 

74 >>> @blueprint.route("/api/test/example", methods=["POST"]) 

75 >>> @require_dummy_mode 

76 >>> def test_example(): 

77 >>> return {"success": True} 

78 

79 """ 

80 

81 @functools.wraps(f) 

82 def decorated_function(*args, **kwargs): 

83 error = check_dummy_mode_for_api() 

84 if error: 84 ↛ 85line 84 didn't jump to line 85 because the condition on line 84 was never true

85 return error 

86 return f(*args, **kwargs) 

87 

88 # functools.wraps で型情報が保持されないため 

89 return decorated_function # type: ignore[return-value]