Coverage for mcpgateway / utils / orjson_response.py: 100%

7 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-02-11 07:10 +0000

1# -*- coding: utf-8 -*- 

2"""Custom JSON response class using orjson for high-performance JSON serialization. 

3 

4This module provides ORJSONResponse, a drop-in replacement for FastAPI's default 

5JSONResponse that uses orjson for 2-3x faster JSON serialization/deserialization. 

6 

7orjson is a fast, correct JSON library for Python implemented in Rust. It provides 

8significant performance improvements over the standard library's json module, especially 

9for large payloads (tool lists, server lists, bulk exports). 

10 

11Performance improvements: 

12- 2-3x faster serialization than stdlib json 

13- 1.5-2x faster deserialization than stdlib json 

14- 30-40% less memory usage 

15- Smaller output size (more compact) 

16 

17References: 

18- orjson: https://github.com/ijl/orjson 

19- FastAPI Custom Response: https://fastapi.tiangolo.com/advanced/custom-response/ 

20""" 

21 

22# Standard 

23from typing import Any 

24 

25# Third-Party 

26from fastapi.responses import JSONResponse 

27import orjson 

28 

29 

30class ORJSONResponse(JSONResponse): 

31 """Custom JSON response class using orjson for faster serialization. 

32 

33 orjson is 2-3x faster than stdlib json and produces more compact output. 

34 It handles datetime, UUID, and numpy types natively. 

35 

36 This response class is designed to be a drop-in replacement for FastAPI's 

37 default JSONResponse with no breaking changes to API behavior. 

38 

39 Features: 

40 - Fast: 2-3x faster than stdlib json, uses Rust implementation 

41 - Strict: RFC 8259 compliant, catches serialization errors early 

42 - Compact: Produces smaller output than stdlib json 

43 - Type Support: datetime, UUID, numpy arrays, dataclasses, Pydantic models 

44 - Binary Output: Returns bytes directly (no string→bytes conversion overhead) 

45 

46 Example: 

47 >>> from mcpgateway.utils.orjson_response import ORJSONResponse 

48 >>> response = ORJSONResponse(content={"message": "Hello World"}) 

49 >>> response.media_type 

50 'application/json' 

51 

52 Options used: 

53 - OPT_NON_STR_KEYS: Allow non-string dict keys (ints, etc.) 

54 - OPT_SERIALIZE_NUMPY: Support numpy arrays if present 

55 

56 For datetime serialization, orjson uses RFC 3339 format (ISO 8601 with timezone). 

57 Naive datetimes are treated as UTC by default. 

58 """ 

59 

60 media_type = "application/json" 

61 

62 def render(self, content: Any) -> bytes: 

63 """Render content to JSON bytes using orjson. 

64 

65 Args: 

66 content: The content to serialize to JSON. Can be dict, list, str, 

67 int, float, bool, None, datetime, UUID, Pydantic models, etc. 

68 

69 Returns: 

70 JSON bytes ready for HTTP response (no additional encoding needed). 

71 

72 Options: 

73 - OPT_NON_STR_KEYS: Allow non-string dict keys (ints, UUID, etc.) 

74 - OPT_SERIALIZE_NUMPY: Support numpy arrays if numpy is installed 

75 

76 Note: 

77 orjson returns bytes directly, unlike stdlib json.dumps() which returns str. 

78 This eliminates the string→bytes encoding step, improving performance. 

79 

80 Raises: 

81 orjson.JSONEncodeError: If content cannot be serialized to JSON. 

82 """ 

83 return orjson.dumps( 

84 content, 

85 option=orjson.OPT_NON_STR_KEYS | orjson.OPT_SERIALIZE_NUMPY, 

86 )