@@ -568,6 +568,7 @@ def __init__( # pylint: disable=too-many-statements
568568 self .callback_map = {}
569569 # same deps as a list to catch duplicate outputs, and to send to the front end
570570 self ._callback_list = []
571+ self .callback_api_paths = {}
571572
572573 # list of inline scripts
573574 self ._inline_scripts = []
@@ -778,6 +779,42 @@ def _setup_routes(self):
778779 # catch-all for front-end routes, used by dcc.Location
779780 self ._add_url ("<path:path>" , self .index )
780781
782+ def setup_apis (self ):
783+ # Copy over global callback data structures assigned with `dash.callback`
784+ for k in list (_callback .GLOBAL_API_PATHS ):
785+ if k in self .callback_api_paths :
786+ raise DuplicateCallback (
787+ f"The callback `{ k } ` provided with `dash.callback` was already "
788+ "assigned with `app.callback`."
789+ )
790+ self .callback_api_paths [k ] = _callback .GLOBAL_API_PATHS .pop (k )
791+
792+ def make_parse_body (func ):
793+ def _parse_body ():
794+ if flask .request .is_json :
795+ data = flask .request .get_json ()
796+ return flask .jsonify (func (** data ))
797+ return flask .jsonify ({})
798+
799+ return _parse_body
800+
801+ def make_parse_body_async (func ):
802+ async def _parse_body_async ():
803+ if flask .request .is_json :
804+ data = flask .request .get_json ()
805+ result = await func (** data )
806+ return flask .jsonify (result )
807+ return flask .jsonify ({})
808+
809+ return _parse_body_async
810+
811+ for path , func in self .callback_api_paths .items ():
812+ print (path )
813+ if asyncio .iscoroutinefunction (func ):
814+ self ._add_url (path , make_parse_body_async (func ), ["POST" ])
815+ else :
816+ self ._add_url (path , make_parse_body (func ), ["POST" ])
817+
781818 def _setup_plotlyjs (self ):
782819 # pylint: disable=import-outside-toplevel
783820 from plotly .offline import get_plotlyjs_version
@@ -1346,6 +1383,7 @@ def callback(self, *_args, **_kwargs) -> Callable[..., Any]:
13461383 config_prevent_initial_callbacks = self .config .prevent_initial_callbacks ,
13471384 callback_list = self ._callback_list ,
13481385 callback_map = self .callback_map ,
1386+ callback_api_paths = self .callback_api_paths ,
13491387 ** _kwargs ,
13501388 )
13511389
@@ -1496,6 +1534,7 @@ def dispatch(self):
14961534 def _setup_server (self ):
14971535 if self ._got_first_request ["setup_server" ]:
14981536 return
1537+
14991538 self ._got_first_request ["setup_server" ] = True
15001539
15011540 # Apply _force_eager_loading overrides from modules
0 commit comments