@@ -123,6 +123,7 @@ class Operation(CachedPropertyModel):
123123 response : str = ''
124124 additional_responses : Dict [Union [str , int ], Dict [str , str ]] = {}
125125 return_type : str = ''
126+ callbacks : Dict [UsefulStr , List ["Operation" ]] = {}
126127
127128 @cached_property
128129 def type (self ) -> UsefulStr :
@@ -472,10 +473,53 @@ def parse_operation(
472473 self ._temporary_operation ['snake_case_arguments' ] = self .get_arguments (
473474 snake_case = True , path = path
474475 )
476+ main_operation = self ._temporary_operation
477+
478+ # Handle callbacks. This iterates over callbacks, shifting each one
479+ # into the `_temporary_operation` and parsing it. Parsing could be
480+ # refactored into a recursive operation to simplify this routine.
481+ cb_ctr = 0
482+ callbacks : Dict [UsefulStr , list [Operation ]] = {}
483+ if 'callbacks' in raw_operation :
484+ raw_callbacks = raw_operation .pop ('callbacks' )
485+ for key , routes in raw_callbacks .items ():
486+ if key not in callbacks :
487+ callbacks [key ] = []
488+ for route , methods in routes .items ():
489+ for method , cb_op in methods .items ():
490+ # Since the path is often generated dynamically from
491+ # the contents of the original request (such as by
492+ # passing a `callbackUrl`), it won't work to generate
493+ # a function name from the path. Instead, inject a
494+ # placeholder `operationId` in order to get a unique
495+ # and reasonable function name for the operation.
496+ if 'operationId' not in cb_op :
497+ cb_op ['operationId' ] = f"{ method } _{ key } _{ cb_ctr } "
498+ cb_ctr += 1
499+
500+ self ._temporary_operation = {'_parameters' : []}
501+ cb_path = path + ['callbacks' , key , route , method ]
502+ super ().parse_operation (cb_op , cb_path )
503+ self ._temporary_operation ['arguments' ] = self .get_arguments (
504+ snake_case = False , path = cb_path
505+ )
506+ self ._temporary_operation ['snake_case_arguments' ] = (
507+ self .get_arguments (snake_case = True , path = cb_path )
508+ )
509+
510+ callbacks [key ].append (
511+ Operation (
512+ ** cb_op ,
513+ ** self ._temporary_operation ,
514+ path = route ,
515+ method = method , # type: ignore
516+ )
517+ )
475518
476519 self .operations [resolved_path ] = Operation (
477520 ** raw_operation ,
478- ** self ._temporary_operation ,
521+ ** main_operation ,
522+ callbacks = callbacks ,
479523 path = f'/{ path_name } ' , # type: ignore
480524 method = method , # type: ignore
481525 )
0 commit comments