Coverage for mindsdb / api / http / start.py: 0%

42 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-01-21 00:36 +0000

1import gc 

2from importlib import import_module 

3 

4gc.disable() 

5 

6from flask import Flask 

7from starlette.applications import Starlette 

8from starlette.routing import Mount, Route 

9from starlette.responses import JSONResponse 

10from a2wsgi import WSGIMiddleware 

11import uvicorn 

12 

13from mindsdb.api.http.initialize import initialize_app 

14from mindsdb.interfaces.storage import db 

15from mindsdb.utilities import log 

16from mindsdb.utilities.config import config 

17from mindsdb.utilities.functions import init_lexer_parsers 

18from mindsdb.integrations.libs.ml_exec_base import process_cache 

19from mindsdb.api.common.middleware import PATAuthMiddleware 

20 

21gc.enable() 

22 

23logger = log.getLogger(__name__) 

24 

25 

26async def _health_check(request): 

27 """Async health check that bypasses the WSGI worker pool for the mindsdb API.""" 

28 return JSONResponse({"status": "ok"}) 

29 

30 

31def _mount_optional_api(name: str, mount_path: str, get_app_fn, routes): 

32 try: 

33 optional_app = get_app_fn() 

34 except ImportError as exc: 

35 logger.warning( 

36 "%s support is disabled (%s). To enable it, install the %s extra: pip install 'mindsdb[%s]'", 

37 name, 

38 exc, 

39 name, 

40 name.lower(), 

41 ) 

42 return 

43 

44 optional_app.add_middleware(PATAuthMiddleware) 

45 routes.append(Mount(mount_path, app=optional_app)) 

46 

47 

48def start(verbose, app: Flask = None, is_restart: bool = False): 

49 db.init() 

50 init_lexer_parsers() 

51 

52 if app is None: 

53 app = initialize_app(is_restart) 

54 

55 port = config["api"]["http"]["port"] 

56 host = config["api"]["http"]["host"] 

57 

58 process_cache.init() 

59 

60 routes = [] 

61 

62 # Health check FIRST - async endpoint that bypasses WSGI worker pool 

63 # This ensures health checks respond even when all workers are blocked 

64 routes.append(Route("/api/util/ping", _health_check, methods=["GET"])) 

65 

66 _mount_optional_api( 

67 "A2A", 

68 "/a2a", 

69 lambda: import_module("mindsdb.api.a2a").get_a2a_app(), 

70 routes, 

71 ) 

72 _mount_optional_api( 

73 "MCP", 

74 "/mcp", 

75 lambda: import_module("mindsdb.api.mcp").get_mcp_app(), 

76 routes, 

77 ) 

78 

79 # Root app LAST so it won't shadow the others 

80 routes.append( 

81 Mount( 

82 "/", 

83 app=WSGIMiddleware( 

84 app, 

85 workers=config["api"]["http"]["a2wsgi"]["workers"], 

86 send_queue_size=config["api"]["http"]["a2wsgi"]["send_queue_size"], 

87 ), 

88 ) 

89 ) 

90 

91 # Setting logging to None makes uvicorn use the existing logging configuration 

92 uvicorn.run(Starlette(routes=routes, debug=verbose), host=host, port=int(port), log_level=None, log_config=None)