@@ -568,6 +568,7 @@ def __init__( # pylint: disable=too-many-statements
568
568
self .callback_map = {}
569
569
# same deps as a list to catch duplicate outputs, and to send to the front end
570
570
self ._callback_list = []
571
+ self .callback_api_paths = {}
571
572
572
573
# list of inline scripts
573
574
self ._inline_scripts = []
@@ -778,6 +779,42 @@ def _setup_routes(self):
778
779
# catch-all for front-end routes, used by dcc.Location
779
780
self ._add_url ("<path:path>" , self .index )
780
781
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
+
781
818
def _setup_plotlyjs (self ):
782
819
# pylint: disable=import-outside-toplevel
783
820
from plotly .offline import get_plotlyjs_version
@@ -1346,6 +1383,7 @@ def callback(self, *_args, **_kwargs) -> Callable[..., Any]:
1346
1383
config_prevent_initial_callbacks = self .config .prevent_initial_callbacks ,
1347
1384
callback_list = self ._callback_list ,
1348
1385
callback_map = self .callback_map ,
1386
+ callback_api_paths = self .callback_api_paths ,
1349
1387
** _kwargs ,
1350
1388
)
1351
1389
@@ -1496,6 +1534,7 @@ def dispatch(self):
1496
1534
def _setup_server (self ):
1497
1535
if self ._got_first_request ["setup_server" ]:
1498
1536
return
1537
+
1499
1538
self ._got_first_request ["setup_server" ] = True
1500
1539
1501
1540
# Apply _force_eager_loading overrides from modules
0 commit comments