10xgraph-api 0.7.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (203) hide show
  1. 10xgraph_api-0.7.0.dist-info/METADATA +618 -0
  2. 10xgraph_api-0.7.0.dist-info/RECORD +203 -0
  3. 10xgraph_api-0.7.0.dist-info/WHEEL +5 -0
  4. 10xgraph_api-0.7.0.dist-info/entry_points.txt +3 -0
  5. 10xgraph_api-0.7.0.dist-info/licenses/LICENSE +21 -0
  6. 10xgraph_api-0.7.0.dist-info/top_level.txt +2 -0
  7. agentflow_cli/__init__.py +69 -0
  8. tenxgraph_api/__init__.py +23 -0
  9. tenxgraph_api/cli/__init__.py +6 -0
  10. tenxgraph_api/cli/capabilities.py +127 -0
  11. tenxgraph_api/cli/commands/__init__.py +49 -0
  12. tenxgraph_api/cli/commands/api.py +262 -0
  13. tenxgraph_api/cli/commands/audit.py +213 -0
  14. tenxgraph_api/cli/commands/build.py +305 -0
  15. tenxgraph_api/cli/commands/config.py +71 -0
  16. tenxgraph_api/cli/commands/demo.py +93 -0
  17. tenxgraph_api/cli/commands/eval.py +909 -0
  18. tenxgraph_api/cli/commands/init.py +531 -0
  19. tenxgraph_api/cli/commands/skills.py +532 -0
  20. tenxgraph_api/cli/commands/test.py +113 -0
  21. tenxgraph_api/cli/commands/version.py +47 -0
  22. tenxgraph_api/cli/config_editor/__init__.py +15 -0
  23. tenxgraph_api/cli/config_editor/schema.py +566 -0
  24. tenxgraph_api/cli/config_editor/server.py +240 -0
  25. tenxgraph_api/cli/config_editor/static/app.css +2 -0
  26. tenxgraph_api/cli/config_editor/static/app.js +3 -0
  27. tenxgraph_api/cli/config_editor/static/favicon.svg +11 -0
  28. tenxgraph_api/cli/config_editor/static/index.html +20 -0
  29. tenxgraph_api/cli/config_editor/store.py +120 -0
  30. tenxgraph_api/cli/config_editor/validation.py +377 -0
  31. tenxgraph_api/cli/constants.py +112 -0
  32. tenxgraph_api/cli/context.py +46 -0
  33. tenxgraph_api/cli/core/__init__.py +0 -0
  34. tenxgraph_api/cli/core/animations.py +550 -0
  35. tenxgraph_api/cli/core/config.py +279 -0
  36. tenxgraph_api/cli/core/output.py +625 -0
  37. tenxgraph_api/cli/core/prompts.py +220 -0
  38. tenxgraph_api/cli/core/screen.py +287 -0
  39. tenxgraph_api/cli/core/steps.py +621 -0
  40. tenxgraph_api/cli/core/theme.py +242 -0
  41. tenxgraph_api/cli/core/validation.py +251 -0
  42. tenxgraph_api/cli/exceptions.py +129 -0
  43. tenxgraph_api/cli/logger.py +84 -0
  44. tenxgraph_api/cli/main.py +936 -0
  45. tenxgraph_api/cli/templates/__init__.py +0 -0
  46. tenxgraph_api/cli/templates/defaults.py +844 -0
  47. tenxgraph_api/cli/templates/dev/.env.example +1 -0
  48. tenxgraph_api/cli/templates/dev/10xgraph.json +16 -0
  49. tenxgraph_api/cli/templates/dev/graph/__init__.py +0 -0
  50. tenxgraph_api/cli/templates/dev/graph/agent.py +63 -0
  51. tenxgraph_api/cli/templates/prod/.env.example +75 -0
  52. tenxgraph_api/cli/templates/prod/.pre-commit-config.yaml +50 -0
  53. tenxgraph_api/cli/templates/prod/.python-version +1 -0
  54. tenxgraph_api/cli/templates/prod/10xgraph.json +42 -0
  55. tenxgraph_api/cli/templates/prod/auth/__init__.py +0 -0
  56. tenxgraph_api/cli/templates/prod/auth/agent_auth.py +46 -0
  57. tenxgraph_api/cli/templates/prod/evals/__init__.py +0 -0
  58. tenxgraph_api/cli/templates/prod/evals/user_simulator_eval.py +76 -0
  59. tenxgraph_api/cli/templates/prod/evals/weather_agents_eval.py +53 -0
  60. tenxgraph_api/cli/templates/prod/graph/__init__.py +0 -0
  61. tenxgraph_api/cli/templates/prod/graph/agent.py +50 -0
  62. tenxgraph_api/cli/templates/prod/graph/state.py +5 -0
  63. tenxgraph_api/cli/templates/prod/graph/thread_name_generator.py +7 -0
  64. tenxgraph_api/cli/templates/prod/graph/tools/__init__.py +0 -0
  65. tenxgraph_api/cli/templates/prod/graph/tools/weather_tool.py +43 -0
  66. tenxgraph_api/cli/templates/prod/graph/validators/__init__.py +0 -0
  67. tenxgraph_api/cli/templates/prod/graph/validators/lifecyle.py +107 -0
  68. tenxgraph_api/cli/templates/prod/graph/validators/manager.py +9 -0
  69. tenxgraph_api/cli/templates/prod/graph/validators/validators.py +21 -0
  70. tenxgraph_api/cli/templates/prod/pyproject.toml +79 -0
  71. tenxgraph_api/cli/templates/prod/tests/__init__.py +0 -0
  72. tenxgraph_api/cli/templates/prod/tests/conftest.py +6 -0
  73. tenxgraph_api/cli/templates/prod/tests/test_agent_eval.py +78 -0
  74. tenxgraph_api/cli/templates/prod/tests/test_catalog_tools.py +47 -0
  75. tenxgraph_api/cli/templates/prod/tests/test_graph_nodes.py +57 -0
  76. tenxgraph_api/cli/templates/skills/10xgraph/SKILL.md +92 -0
  77. tenxgraph_api/cli/templates/skills/10xgraph/references/agents-and-tools.md +389 -0
  78. tenxgraph_api/cli/templates/skills/10xgraph/references/api-client.md +61 -0
  79. tenxgraph_api/cli/templates/skills/10xgraph/references/api-configuration.md +75 -0
  80. tenxgraph_api/cli/templates/skills/10xgraph/references/api-settings-and-middleware.md +89 -0
  81. tenxgraph_api/cli/templates/skills/10xgraph/references/architecture.md +91 -0
  82. tenxgraph_api/cli/templates/skills/10xgraph/references/auth-and-authorization.md +149 -0
  83. tenxgraph_api/cli/templates/skills/10xgraph/references/callbacks-and-command.md +283 -0
  84. tenxgraph_api/cli/templates/skills/10xgraph/references/checkpointing-and-threads.md +63 -0
  85. tenxgraph_api/cli/templates/skills/10xgraph/references/cli-commands.md +73 -0
  86. tenxgraph_api/cli/templates/skills/10xgraph/references/client-auth-and-errors.md +94 -0
  87. tenxgraph_api/cli/templates/skills/10xgraph/references/client-messages-invoke-stream.md +115 -0
  88. tenxgraph_api/cli/templates/skills/10xgraph/references/client-threads-memory-files.md +80 -0
  89. tenxgraph_api/cli/templates/skills/10xgraph/references/context-id-background.md +80 -0
  90. tenxgraph_api/cli/templates/skills/10xgraph/references/dependency-injection.md +58 -0
  91. tenxgraph_api/cli/templates/skills/10xgraph/references/evaluation.md +500 -0
  92. tenxgraph_api/cli/templates/skills/10xgraph/references/id-and-thread-name-generators.md +69 -0
  93. tenxgraph_api/cli/templates/skills/10xgraph/references/media-and-files.md +66 -0
  94. tenxgraph_api/cli/templates/skills/10xgraph/references/memory-and-store.md +70 -0
  95. tenxgraph_api/cli/templates/skills/10xgraph/references/prebuilt-agents-and-tools.md +394 -0
  96. tenxgraph_api/cli/templates/skills/10xgraph/references/production-runtime.md +56 -0
  97. tenxgraph_api/cli/templates/skills/10xgraph/references/providers-and-adapters.md +89 -0
  98. tenxgraph_api/cli/templates/skills/10xgraph/references/publishers-and-runtime-protocols.md +84 -0
  99. tenxgraph_api/cli/templates/skills/10xgraph/references/rate-limiting.md +194 -0
  100. tenxgraph_api/cli/templates/skills/10xgraph/references/realtime.md +172 -0
  101. tenxgraph_api/cli/templates/skills/10xgraph/references/remote-tools.md +55 -0
  102. tenxgraph_api/cli/templates/skills/10xgraph/references/rest-api-and-errors.md +97 -0
  103. tenxgraph_api/cli/templates/skills/10xgraph/references/security-and-validators.md +86 -0
  104. tenxgraph_api/cli/templates/skills/10xgraph/references/state-and-messages.md +68 -0
  105. tenxgraph_api/cli/templates/skills/10xgraph/references/state-graph.md +232 -0
  106. tenxgraph_api/cli/templates/skills/10xgraph/references/stream-emitter.md +144 -0
  107. tenxgraph_api/cli/templates/skills/10xgraph/references/streaming.md +53 -0
  108. tenxgraph_api/cli/templates/skills/10xgraph/references/testing-and-evaluation.md +64 -0
  109. tenxgraph_api/cli/templates/skills/10xgraph/references/unit-testing.md +202 -0
  110. tenxgraph_api/cli/templates/skills/copilot/10xgraph.instructions.md +108 -0
  111. tenxgraph_api/py.typed +0 -0
  112. tenxgraph_api/src/__init__.py +0 -0
  113. tenxgraph_api/src/app/__init__.py +13 -0
  114. tenxgraph_api/src/app/core/__init__.py +15 -0
  115. tenxgraph_api/src/app/core/auth/__init__.py +0 -0
  116. tenxgraph_api/src/app/core/auth/auth_backend.py +38 -0
  117. tenxgraph_api/src/app/core/auth/authorization.py +379 -0
  118. tenxgraph_api/src/app/core/auth/base_auth.py +27 -0
  119. tenxgraph_api/src/app/core/auth/jwt_auth.py +122 -0
  120. tenxgraph_api/src/app/core/auth/ownership_resolver.py +170 -0
  121. tenxgraph_api/src/app/core/auth/permissions.py +354 -0
  122. tenxgraph_api/src/app/core/auth/request_config.py +130 -0
  123. tenxgraph_api/src/app/core/auth/route_guard.py +105 -0
  124. tenxgraph_api/src/app/core/config/__init__.py +0 -0
  125. tenxgraph_api/src/app/core/config/graph_config.py +532 -0
  126. tenxgraph_api/src/app/core/config/media_settings.py +72 -0
  127. tenxgraph_api/src/app/core/config/sentry_config.py +60 -0
  128. tenxgraph_api/src/app/core/config/settings.py +202 -0
  129. tenxgraph_api/src/app/core/config/setup_logs.py +65 -0
  130. tenxgraph_api/src/app/core/config/setup_middleware.py +483 -0
  131. tenxgraph_api/src/app/core/config/worker_middleware.py +99 -0
  132. tenxgraph_api/src/app/core/exceptions/__init__.py +17 -0
  133. tenxgraph_api/src/app/core/exceptions/general_exception.py +58 -0
  134. tenxgraph_api/src/app/core/exceptions/handle_errors.py +363 -0
  135. tenxgraph_api/src/app/core/exceptions/resources_exceptions.py +72 -0
  136. tenxgraph_api/src/app/core/exceptions/user_exception.py +58 -0
  137. tenxgraph_api/src/app/core/middleware/__init__.py +25 -0
  138. tenxgraph_api/src/app/core/middleware/rate_limit/__init__.py +15 -0
  139. tenxgraph_api/src/app/core/middleware/rate_limit/base.py +27 -0
  140. tenxgraph_api/src/app/core/middleware/rate_limit/factory.py +98 -0
  141. tenxgraph_api/src/app/core/middleware/rate_limit/keying.py +133 -0
  142. tenxgraph_api/src/app/core/middleware/rate_limit/memory.py +98 -0
  143. tenxgraph_api/src/app/core/middleware/rate_limit/middleware.py +90 -0
  144. tenxgraph_api/src/app/core/middleware/rate_limit/redis.py +115 -0
  145. tenxgraph_api/src/app/core/middleware/request_limits.py +154 -0
  146. tenxgraph_api/src/app/core/middleware/security_headers.py +239 -0
  147. tenxgraph_api/src/app/core/utils/__init__.py +14 -0
  148. tenxgraph_api/src/app/core/utils/log_sanitizer.py +216 -0
  149. tenxgraph_api/src/app/loader.py +516 -0
  150. tenxgraph_api/src/app/main.py +180 -0
  151. tenxgraph_api/src/app/routers/__init__.py +4 -0
  152. tenxgraph_api/src/app/routers/ag_ui/__init__.py +10 -0
  153. tenxgraph_api/src/app/routers/ag_ui/converter.py +195 -0
  154. tenxgraph_api/src/app/routers/ag_ui/event_mapper.py +353 -0
  155. tenxgraph_api/src/app/routers/ag_ui/router.py +90 -0
  156. tenxgraph_api/src/app/routers/ag_ui/service.py +193 -0
  157. tenxgraph_api/src/app/routers/checkpointer/__init__.py +1 -0
  158. tenxgraph_api/src/app/routers/checkpointer/router.py +482 -0
  159. tenxgraph_api/src/app/routers/checkpointer/schemas/__init__.py +1 -0
  160. tenxgraph_api/src/app/routers/checkpointer/schemas/checkpointer_schemas.py +121 -0
  161. tenxgraph_api/src/app/routers/checkpointer/services/__init__.py +1 -0
  162. tenxgraph_api/src/app/routers/checkpointer/services/checkpointer_service.py +300 -0
  163. tenxgraph_api/src/app/routers/evals/__init__.py +6 -0
  164. tenxgraph_api/src/app/routers/evals/router.py +38 -0
  165. tenxgraph_api/src/app/routers/evals/services/__init__.py +1 -0
  166. tenxgraph_api/src/app/routers/evals/services/eval_report_service.py +354 -0
  167. tenxgraph_api/src/app/routers/graph/__init__.py +6 -0
  168. tenxgraph_api/src/app/routers/graph/realtime_guard.py +161 -0
  169. tenxgraph_api/src/app/routers/graph/router.py +821 -0
  170. tenxgraph_api/src/app/routers/graph/schemas/__init__.py +1 -0
  171. tenxgraph_api/src/app/routers/graph/schemas/graph_schemas.py +386 -0
  172. tenxgraph_api/src/app/routers/graph/services/__init__.py +1 -0
  173. tenxgraph_api/src/app/routers/graph/services/graph_service.py +1219 -0
  174. tenxgraph_api/src/app/routers/graph/services/multimodal_preprocessor.py +164 -0
  175. tenxgraph_api/src/app/routers/media/__init__.py +506 -0
  176. tenxgraph_api/src/app/routers/media/router.py +242 -0
  177. tenxgraph_api/src/app/routers/media/schemas.py +39 -0
  178. tenxgraph_api/src/app/routers/ping/__init__.py +4 -0
  179. tenxgraph_api/src/app/routers/ping/router.py +28 -0
  180. tenxgraph_api/src/app/routers/setup_router.py +60 -0
  181. tenxgraph_api/src/app/routers/store/__init__.py +4 -0
  182. tenxgraph_api/src/app/routers/store/router.py +200 -0
  183. tenxgraph_api/src/app/routers/store/schemas/__init__.py +28 -0
  184. tenxgraph_api/src/app/routers/store/schemas/store_schemas.py +200 -0
  185. tenxgraph_api/src/app/routers/store/services/__init__.py +4 -0
  186. tenxgraph_api/src/app/routers/store/services/store_service.py +203 -0
  187. tenxgraph_api/src/app/tasks/__init__.py +0 -0
  188. tenxgraph_api/src/app/tasks/user_tasks.py +38 -0
  189. tenxgraph_api/src/app/utils/__init__.py +12 -0
  190. tenxgraph_api/src/app/utils/callable_helper.py +26 -0
  191. tenxgraph_api/src/app/utils/media/__init__.py +15 -0
  192. tenxgraph_api/src/app/utils/media/extractor.py +172 -0
  193. tenxgraph_api/src/app/utils/media/pipeline.py +83 -0
  194. tenxgraph_api/src/app/utils/parse_output.py +17 -0
  195. tenxgraph_api/src/app/utils/response_helper.py +129 -0
  196. tenxgraph_api/src/app/utils/schemas/__init__.py +11 -0
  197. tenxgraph_api/src/app/utils/schemas/output_schemas.py +28 -0
  198. tenxgraph_api/src/app/utils/schemas/user_schemas.py +13 -0
  199. tenxgraph_api/src/app/utils/snowflake_id_generator.py +90 -0
  200. tenxgraph_api/src/app/utils/swagger_helper.py +160 -0
  201. tenxgraph_api/src/app/utils/telemetry_store.py +123 -0
  202. tenxgraph_api/src/app/utils/thread_name_generator.py +304 -0
  203. tenxgraph_api/src/app/worker.py +91 -0
@@ -0,0 +1,202 @@
1
+ import logging
2
+ import os
3
+ from functools import lru_cache
4
+
5
+ from pydantic import ConfigDict, Field, field_validator, model_validator
6
+ from pydantic_settings import BaseSettings
7
+
8
+
9
+ IS_PRODUCTION = False
10
+ LOGGER_NAME = os.getenv("LOGGER_NAME", "10xgraph-api")
11
+
12
+ logger = logging.getLogger(LOGGER_NAME)
13
+
14
+
15
+ class Settings(BaseSettings):
16
+ """
17
+ This class defines the configuration settings for the application.
18
+
19
+ Attributes:
20
+ APP_NAME (str): The name of the application.
21
+ APP_VERSION (str): The version of the application.
22
+ MODE (str): The mode in which the application is running (e.g., development, production).
23
+ LOG_LEVEL (int): The logging level for the application.
24
+ SUMMARY (str): A brief summary of the application. Default is "Backend Base".
25
+
26
+ ORIGINS (str): CORS allowed origins.
27
+ ALLOWED_HOST (str): CORS allowed hosts.
28
+ REDIS_URL (str): The URL for the Redis server.
29
+
30
+ SENTRY_DSN (str): The DSN for Sentry error tracking.
31
+
32
+ Config:
33
+ extra (str): Configuration for handling extra fields. Default is "allow".
34
+ """
35
+
36
+ APP_NAME: str = "MyApp"
37
+ APP_VERSION: str = "0.1.0"
38
+ MODE: str = "development"
39
+ # CRITICAL = 50
40
+ # FATAL = CRITICAL
41
+ # ERROR = 40
42
+ # WARNING = 30
43
+ # WARN = WARNING
44
+ # INFO = 20
45
+ # DEBUG = 10
46
+ # NOTSET = 0
47
+ LOG_LEVEL: str = "INFO"
48
+ IS_DEBUG: bool = True
49
+
50
+ #################################
51
+ ###### Request Limits ###########
52
+ #################################
53
+ MAX_REQUEST_SIZE: int = 10 * 1024 * 1024 # 10MB default
54
+
55
+ #################################
56
+ ###### Security Headers #########
57
+ #################################
58
+ SECURITY_HEADERS_ENABLED: bool = True
59
+ HSTS_ENABLED: bool = True
60
+ HSTS_MAX_AGE: int = 31536000 # 1 year in seconds
61
+ HSTS_INCLUDE_SUBDOMAINS: bool = True
62
+ HSTS_PRELOAD: bool = False
63
+ FRAME_OPTIONS: str = "DENY" # DENY, SAMEORIGIN, or ALLOW-FROM
64
+ CONTENT_TYPE_OPTIONS: str = "nosniff"
65
+ XSS_PROTECTION: str = "1; mode=block"
66
+ REFERRER_POLICY: str = "strict-origin-when-cross-origin"
67
+ PERMISSIONS_POLICY: str | None = None # Uses default if None
68
+ CSP_POLICY: str | None = None # Uses default if None
69
+
70
+ SUMMARY: str = "10xGraph Backend"
71
+
72
+ #################################
73
+ ###### CORS Config ##############
74
+ #################################
75
+ ORIGINS: str = "*"
76
+ ALLOWED_HOST: str = "*"
77
+ # Whether cross-origin requests may carry credentials (cookies / auth headers).
78
+ #
79
+ # Combined with ORIGINS="*" this is the dangerous case: Starlette reflects the
80
+ # request's Origin back with Access-Control-Allow-Credentials: true, which
81
+ # effectively makes EVERY origin a trusted, credentialed origin. In production
82
+ # that combination is refused at startup (see setup_middleware); set explicit
83
+ # ORIGINS, or set CORS_ALLOW_CREDENTIALS=false to serve a public,
84
+ # non-credentialed API from any origin.
85
+ CORS_ALLOW_CREDENTIALS: bool = True
86
+
87
+ #################################
88
+ ###### Paths ####################
89
+ #################################
90
+ ROOT_PATH: str = "/"
91
+ DOCS_PATH: str = "/docs"
92
+ REDOCS_PATH: str = "/redocs"
93
+
94
+ #################################
95
+ ###### REDIS Config ##########
96
+ #################################
97
+ REDIS_URL: str | None = None
98
+
99
+ #################################
100
+ ###### sentry Config ############
101
+ #################################
102
+ SENTRY_DSN: str | None = None
103
+ # Share of requests traced / profiled. 1.0 sends every request, which is costly and
104
+ # rarely wanted in production.
105
+ SENTRY_TRACES_SAMPLE_RATE: float = Field(default=0.1, ge=0.0, le=1.0)
106
+ SENTRY_PROFILES_SAMPLE_RATE: float = Field(default=0.0, ge=0.0, le=1.0)
107
+
108
+ #################################
109
+ ###### Auth ############
110
+ #################################
111
+ SNOWFLAKE_EPOCH: int = 1609459200000
112
+ SNOWFLAKE_NODE_ID: int = 1
113
+ SNOWFLAKE_WORKER_ID: int = 2
114
+ SNOWFLAKE_TIME_BITS: int = 39
115
+ SNOWFLAKE_NODE_BITS: int = 5
116
+ SNOWFLAKE_WORKER_BITS: int = 8
117
+
118
+ #################################
119
+ ###### JWT Config ###############
120
+ #################################
121
+ JWT_SECRET_KEY: str | None = None
122
+ JWT_ALGORITHM: str = "HS256"
123
+ # When set, tokens must carry a matching ``iss`` / ``aud`` claim, so a token minted for
124
+ # another service that shares the signing key is not accepted here.
125
+ JWT_ISSUER: str | None = None
126
+ JWT_AUDIENCE: str | None = None
127
+
128
+ #################################
129
+ ###### OTEL Config ##############
130
+ #################################
131
+ OTEL_ENABLED: bool = False
132
+ OTEL_SERVICE_NAME: str = "10xgraph-api"
133
+ OTEL_EXPORTER_OTLP_ENDPOINT: str | None = None
134
+ OTEL_LEVEL: str = "standard" # spans | standard | full
135
+
136
+ @field_validator("MODE", mode="before")
137
+ @classmethod
138
+ def normalize_mode(cls, v: str | None) -> str:
139
+ """Normalize MODE to lowercase."""
140
+ return v.lower() if v else "development"
141
+
142
+ @field_validator("ORIGINS")
143
+ @classmethod
144
+ def warn_cors_wildcard(cls, v: str) -> str:
145
+ """Warn if CORS is set to wildcard in production."""
146
+ mode = os.environ.get("MODE", "development").lower()
147
+ if v == "*" and mode == "production":
148
+ logger.warning(
149
+ "⚠️ SECURITY WARNING: CORS ORIGINS='*' in production.\n"
150
+ " This allows any website to make requests to your API.\n"
151
+ " Set ORIGINS to specific domains (e.g., https://yourdomain.com)"
152
+ )
153
+ return v
154
+
155
+ @model_validator(mode="after")
156
+ def check_production_security(self):
157
+ """Check for insecure configurations in production mode."""
158
+ if self.MODE == "production":
159
+ # Docs (and the OpenAPI schema behind them) are off in production unless a path
160
+ # was set explicitly.
161
+ for field in ("DOCS_PATH", "REDOCS_PATH"):
162
+ if field not in self.model_fields_set:
163
+ setattr(self, field, "")
164
+
165
+ warnings = []
166
+
167
+ if self.IS_DEBUG:
168
+ warnings.append(
169
+ "⚠️ DEBUG mode is enabled in production. This may expose sensitive information."
170
+ )
171
+
172
+ if self.DOCS_PATH or self.REDOCS_PATH:
173
+ warnings.append(
174
+ "⚠️ API documentation endpoints are enabled in production. "
175
+ "Consider disabling DOCS_PATH and REDOCS_PATH."
176
+ )
177
+
178
+ if self.ALLOWED_HOST == "*":
179
+ warnings.append(
180
+ "⚠️ ALLOWED_HOST='*' in production. "
181
+ "Set to specific hostnames for better security."
182
+ )
183
+
184
+ if warnings:
185
+ logger.warning("\n".join(["\n🔒 PRODUCTION SECURITY WARNINGS:", *warnings]))
186
+
187
+ return self
188
+
189
+ model_config = ConfigDict(extra="allow")
190
+
191
+
192
+ @lru_cache
193
+ def get_settings() -> Settings:
194
+ """
195
+ Retrieve and return the application settings.
196
+ If not in production, load settings from a specific environment file.
197
+ Returns:
198
+ Settings: An instance of the Settings class containing
199
+ application configurations.
200
+ """
201
+ logger.info("Loading settings from environment variables and .env if present")
202
+ return Settings() # type: ignore
@@ -0,0 +1,65 @@
1
+ import logging
2
+ import sys
3
+
4
+ from fastapi.logger import logger as fastapi_logger
5
+
6
+ from tenxgraph_api.src.app.core.config.settings import LOGGER_NAME
7
+ from tenxgraph_api.src.app.core.utils.log_sanitizer import SanitizingFormatter
8
+
9
+
10
+ # Top-level names of the loggers the API server writes to; children ("tenxgraph_api.media",
11
+ # "tenxgraph_api.rate_limit", ...) reach these handlers through propagation.
12
+ APP_LOGGER_NAMES = (LOGGER_NAME, "10xgraph-api", "tenxgraph_api", "tenxgraph_api")
13
+
14
+
15
+ def init_logger(level: int | str = logging.INFO) -> None:
16
+ """
17
+ Initializes and configures logging for the application.
18
+
19
+ This function sets up various loggers used in the application, including
20
+ those for Gunicorn, Uvicorn, FastAPI, database clients, Tortoise ORM, and
21
+ custom loggers. It also configures a console handler to output logs to
22
+ stdout.
23
+
24
+ Args:
25
+ level (int): The logging level to set for the loggers.
26
+ """
27
+ # GCLOUD SETUP
28
+ # client = Client()
29
+ # client.get_default_handler()
30
+ # client.setup_logging()
31
+
32
+ # setup logging
33
+ gunicorn_error_logger = logging.getLogger("gunicorn.error")
34
+ # gunicorn_logger = logging.getLogger("gunicorn")
35
+ uvicorn_access_logger = logging.getLogger("uvicorn.access")
36
+ uvicorn_access_logger.handlers = gunicorn_error_logger.handlers
37
+ fastapi_logger.handlers = gunicorn_error_logger.handlers
38
+ fastapi_logger.setLevel(level)
39
+
40
+ # Create console handler and set level to DEBUG
41
+ console_handler = logging.StreamHandler(sys.stdout)
42
+ console_handler.setLevel(level)
43
+
44
+ # Create formatter
45
+ base_formatter = logging.Formatter(
46
+ "%(asctime)s - %(name)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s"
47
+ )
48
+ # Wrap with sanitizing formatter to prevent sensitive data in logs
49
+ formatter = SanitizingFormatter(base_formatter)
50
+
51
+ # Add formatter to console handler
52
+ console_handler.setFormatter(formatter)
53
+ # Add console handler to logger
54
+ fastapi_logger.addHandler(console_handler)
55
+
56
+ # Route application loggers through the same sanitizing console handler. They stop
57
+ # propagating so an unsanitized copy does not also reach the root (or last-resort) handler.
58
+ for logger_name in dict.fromkeys(APP_LOGGER_NAMES):
59
+ app_logger = logging.getLogger(logger_name)
60
+ app_logger.setLevel(level)
61
+ for handler in list(app_logger.handlers):
62
+ if isinstance(handler.formatter, SanitizingFormatter):
63
+ app_logger.removeHandler(handler) # init_logger may run more than once
64
+ app_logger.addHandler(console_handler)
65
+ app_logger.propagate = False