system_router.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. import logging
  2. import textwrap
  3. from datetime import datetime, timezone
  4. import psutil
  5. from fastapi import Depends
  6. from core.base import R2RException
  7. from core.base.api.models import (
  8. GenericMessageResponse,
  9. WrappedGenericMessageResponse,
  10. WrappedServerStatsResponse,
  11. WrappedSettingsResponse,
  12. )
  13. from ...abstractions import R2RProviders, R2RServices
  14. from ...config import R2RConfig
  15. from .base_router import BaseRouterV3
  16. class SystemRouter(BaseRouterV3):
  17. def __init__(
  18. self,
  19. providers: R2RProviders,
  20. services: R2RServices,
  21. config: R2RConfig,
  22. ):
  23. logging.info("Initializing SystemRouter")
  24. super().__init__(providers, services, config)
  25. self.start_time = datetime.now(timezone.utc)
  26. def _setup_routes(self):
  27. @self.router.get(
  28. "/health",
  29. openapi_extra={
  30. "x-codeSamples": [
  31. {
  32. "lang": "Python",
  33. "source": textwrap.dedent("""
  34. from r2r import R2RClient
  35. client = R2RClient()
  36. # when using auth, do client.login(...)
  37. result = client.system.health()
  38. """),
  39. },
  40. {
  41. "lang": "JavaScript",
  42. "source": textwrap.dedent("""
  43. const { r2rClient } = require("r2r-js");
  44. const client = new r2rClient();
  45. function main() {
  46. const response = await client.system.health();
  47. }
  48. main();
  49. """),
  50. },
  51. {
  52. "lang": "cURL",
  53. "source": textwrap.dedent("""
  54. curl -X POST "https://api.example.com/v3/health"\\
  55. -H "Content-Type: application/json" \\
  56. -H "Authorization: Bearer YOUR_API_KEY" \\
  57. """),
  58. },
  59. ]
  60. },
  61. )
  62. @self.base_endpoint
  63. async def health_check() -> WrappedGenericMessageResponse:
  64. return GenericMessageResponse(message="ok") # type: ignore
  65. @self.router.get(
  66. "/system/settings",
  67. dependencies=[Depends(self.rate_limit_dependency)],
  68. openapi_extra={
  69. "x-codeSamples": [
  70. {
  71. "lang": "Python",
  72. "source": textwrap.dedent("""
  73. from r2r import R2RClient
  74. client = R2RClient()
  75. # when using auth, do client.login(...)
  76. result = client.system.settings()
  77. """),
  78. },
  79. {
  80. "lang": "JavaScript",
  81. "source": textwrap.dedent("""
  82. const { r2rClient } = require("r2r-js");
  83. const client = new r2rClient();
  84. function main() {
  85. const response = await client.system.settings();
  86. }
  87. main();
  88. """),
  89. },
  90. {
  91. "lang": "cURL",
  92. "source": textwrap.dedent("""
  93. curl -X POST "https://api.example.com/v3/system/settings" \\
  94. -H "Content-Type: application/json" \\
  95. -H "Authorization: Bearer YOUR_API_KEY" \\
  96. """),
  97. },
  98. ]
  99. },
  100. )
  101. @self.base_endpoint
  102. async def app_settings(
  103. auth_user=Depends(self.providers.auth.auth_wrapper()),
  104. ) -> WrappedSettingsResponse:
  105. if not auth_user.is_superuser:
  106. raise R2RException(
  107. "Only a superuser can call the `system/settings` endpoint.",
  108. 403,
  109. )
  110. return await self.services.management.app_settings()
  111. @self.router.get(
  112. "/system/status",
  113. dependencies=[Depends(self.rate_limit_dependency)],
  114. openapi_extra={
  115. "x-codeSamples": [
  116. {
  117. "lang": "Python",
  118. "source": textwrap.dedent("""
  119. from r2r import R2RClient
  120. client = R2RClient()
  121. # when using auth, do client.login(...)
  122. result = client.system.status()
  123. """),
  124. },
  125. {
  126. "lang": "JavaScript",
  127. "source": textwrap.dedent("""
  128. const { r2rClient } = require("r2r-js");
  129. const client = new r2rClient();
  130. function main() {
  131. const response = await client.system.status();
  132. }
  133. main();
  134. """),
  135. },
  136. {
  137. "lang": "cURL",
  138. "source": textwrap.dedent("""
  139. curl -X POST "https://api.example.com/v3/system/status" \\
  140. -H "Content-Type: application/json" \\
  141. -H "Authorization: Bearer YOUR_API_KEY" \\
  142. """),
  143. },
  144. ]
  145. },
  146. )
  147. @self.base_endpoint
  148. async def server_stats(
  149. auth_user=Depends(self.providers.auth.auth_wrapper()),
  150. ) -> WrappedServerStatsResponse:
  151. if not auth_user.is_superuser:
  152. raise R2RException(
  153. "Only an authorized user can call the `system/status` endpoint.",
  154. 403,
  155. )
  156. return { # type: ignore
  157. "start_time": self.start_time.isoformat(),
  158. "uptime_seconds": (
  159. datetime.now(timezone.utc) - self.start_time
  160. ).total_seconds(),
  161. "cpu_usage": psutil.cpu_percent(),
  162. "memory_usage": psutil.virtual_memory().percent,
  163. }