@@ -422,46 +422,13 @@ async def update_password(request: Request,
422422# No need for separate _get_eventhistory function
423423
424424
425- # TBD: Restrict response by Pydantic model
426- @app .get ('/events' )
427- async def get_events (request : Request ):
428- """Get all the events if no request parameters have passed.
429- Format: [{event1}, {event2}, ...] or if recursive is set to true,
430- then we add to each event the node information.
431- Get all the matching events otherwise.
432- Query parameters can be used to filter the events:
433- - limit: Number of events to return
434- - from: Start timestamp (unix epoch) to filter events
435- - kind: Event kind to filter events
436- - state: Event state to filter events
437- - result: Event result to filter events
438- - id / ids: Event document id(s) to filter events
439- - node_id: Node id to filter events (alias for data.id)
440- - recursive: Retrieve node together with event
441- This API endpoint is under development and may change in future.
425+ def _parse_event_id_filter (query_params : dict , event_id : str ,
426+ event_ids : str ) -> None :
427+ """Parse and validate event id/ids filter parameters.
428+
429+ Modifies query_params in place to add _id filter.
430+ Raises HTTPException on validation errors.
442431 """
443- metrics .add ('http_requests_total' , 1 )
444- query_params = dict (request .query_params )
445- recursive = query_params .pop ('recursive' , None )
446- limit = query_params .pop ('limit' , None )
447- kind = query_params .pop ('kind' , None )
448- state = query_params .pop ('state' , None )
449- result = query_params .pop ('result' , None )
450- from_ts = query_params .pop ('from' , None )
451- node_id = query_params .pop ('node_id' , None )
452- if node_id :
453- if 'data.id' in query_params :
454- raise HTTPException (
455- status_code = status .HTTP_400_BAD_REQUEST ,
456- detail = "Provide either node_id or data.id, not both"
457- )
458- query_params ['data.id' ] = node_id
459- # Support filtering by MongoDB _id.
460- # Accept `id=<hex>` for a single id or `ids=a,b,c` for multiple ids.
461- # Using `id` as query param is safe here because we remove it from the
462- # filter before passing to Mongo.
463- event_id = query_params .pop ('id' , None )
464- event_ids = query_params .pop ('ids' , None )
465432 if event_id and event_ids :
466433 raise HTTPException (
467434 status_code = status .HTTP_400_BAD_REQUEST ,
@@ -490,6 +457,34 @@ async def get_events(request: Request):
490457 detail = "ids must contain at least one id"
491458 )
492459 query_params ['_id' ] = {'$in' : ids_list }
460+
461+
462+ def _build_events_query (query_params : dict ) -> tuple :
463+ """Extract and process event query parameters.
464+
465+ Returns (recursive, processed_query_params).
466+ Raises HTTPException on validation errors.
467+ """
468+ recursive = query_params .pop ('recursive' , None )
469+ limit = query_params .pop ('limit' , None )
470+ kind = query_params .pop ('kind' , None )
471+ state = query_params .pop ('state' , None )
472+ result = query_params .pop ('result' , None )
473+ from_ts = query_params .pop ('from' , None )
474+ node_id = query_params .pop ('node_id' , None )
475+ event_id = query_params .pop ('id' , None )
476+ event_ids = query_params .pop ('ids' , None )
477+
478+ if node_id :
479+ if 'data.id' in query_params :
480+ raise HTTPException (
481+ status_code = status .HTTP_400_BAD_REQUEST ,
482+ detail = "Provide either node_id or data.id, not both"
483+ )
484+ query_params ['data.id' ] = node_id
485+
486+ _parse_event_id_filter (query_params , event_id , event_ids )
487+
493488 if from_ts :
494489 if isinstance (from_ts , str ):
495490 from_ts = datetime .fromisoformat (from_ts )
@@ -502,13 +497,38 @@ async def get_events(request: Request):
502497 query_params ['data.result' ] = result
503498 if limit :
504499 query_params ['limit' ] = int (limit )
505- # limit recursive to 1000
500+
506501 if recursive and (not limit or int (limit ) > 1000 ):
507- # generate error
508502 raise HTTPException (
509503 status_code = status .HTTP_400_BAD_REQUEST ,
510504 detail = "Recursive limit is too large, max is 1000"
511505 )
506+
507+ return recursive , query_params
508+
509+
510+ # TBD: Restrict response by Pydantic model
511+ @app .get ('/events' )
512+ async def get_events (request : Request ):
513+ """Get all the events if no request parameters have passed.
514+ Format: [{event1}, {event2}, ...] or if recursive is set to true,
515+ then we add to each event the node information.
516+ Get all the matching events otherwise.
517+ Query parameters can be used to filter the events:
518+ - limit: Number of events to return
519+ - from: Start timestamp (unix epoch) to filter events
520+ - kind: Event kind to filter events
521+ - state: Event state to filter events
522+ - result: Event result to filter events
523+ - id / ids: Event document id(s) to filter events
524+ - node_id: Node id to filter events (alias for data.id)
525+ - recursive: Retrieve node together with event
526+ This API endpoint is under development and may change in future.
527+ """
528+ metrics .add ('http_requests_total' , 1 )
529+ query_params = dict (request .query_params )
530+ recursive , query_params = _build_events_query (query_params )
531+
512532 resp = await db .find_by_attributes_nonpaginated (EventHistory , query_params )
513533 resp_list = []
514534 for item in resp :
0 commit comments