@@ -749,56 +749,37 @@ async def list_incidents(
749749
750750 # Process severity parameter
751751 if severity :
752- # If it's already an enum, use its value
752+ # If it's an enum, get its value
753753 if isinstance (severity , IncidentSeverity ):
754754 params ["severity" ] = severity .value
755- # If it's a string, validate and convert
755+ # If it's a string, pass it through directly
756+ # The API will handle validation and support comma-separated values
756757 elif isinstance (severity , str ):
757- try :
758- # Convert to enum to validate, then get the value
759- params ["severity" ] = IncidentSeverity (severity .lower ()).value
760- except ValueError :
761- valid_values = [e .value for e in IncidentSeverity ]
762- logger .warning (f"Invalid severity value: { severity } . Must be one of { valid_values } " )
763- raise ValueError (f"Invalid severity value: { severity } . Must be one of { valid_values } " )
758+ params ["severity" ] = severity
764759 else :
765760 raise TypeError ("severity must be a string or IncidentSeverity enum" )
766761
767762 # Process status parameter
768763 if status :
769- # If it's already an enum, use its value
764+ # If it's an enum, get its value
770765 if isinstance (status , IncidentStatus ):
771766 params ["status" ] = status .value
772- # If it's a string, validate and convert
767+ # If it's a string, pass it through directly
768+ # The API will handle validation and support comma-separated values
773769 elif isinstance (status , str ):
774- try :
775- # For status, we need to check if it's uppercase already
776- if status in [e .value for e in IncidentStatus ]:
777- params ["status" ] = status
778- else :
779- # Try with uppercase for compatibility
780- params ["status" ] = IncidentStatus (status .upper ()).value
781- except ValueError :
782- valid_values = [e .value for e in IncidentStatus ]
783- logger .warning (f"Invalid status value: { status } . Must be one of { valid_values } " )
784- raise ValueError (f"Invalid status value: { status } . Must be one of { valid_values } " )
770+ params ["status" ] = status
785771 else :
786772 raise TypeError ("status must be a string or IncidentStatus enum" )
787773
788774 # Process validity parameter
789775 if validity :
790- # If it's already an enum, use its value
776+ # If it's an enum, get its value
791777 if isinstance (validity , IncidentValidity ):
792778 params ["validity" ] = validity .value
793- # If it's a string, validate and convert
779+ # If it's a string, pass it through directly
780+ # The API will handle validation and support comma-separated values
794781 elif isinstance (validity , str ):
795- try :
796- # Convert to enum to validate, then get the value
797- params ["validity" ] = IncidentValidity (validity .lower ()).value
798- except ValueError :
799- valid_values = [e .value for e in IncidentValidity ]
800- logger .warning (f"Invalid validity value: { validity } . Must be one of { valid_values } " )
801- raise ValueError (f"Invalid validity value: { validity } . Must be one of { valid_values } " )
782+ params ["validity" ] = validity
802783 else :
803784 raise TypeError ("validity must be a string or IncidentValidity enum" )
804785
@@ -987,7 +968,13 @@ async def get_current_token_info(self) -> dict[str, Any]:
987968
988969 # If we already have token info, return it
989970 if self ._token_info is not None :
990- return self ._token_info
971+ # Convert Pydantic model to dict if needed
972+ if hasattr (self ._token_info , "model_dump" ):
973+ return self ._token_info .model_dump ()
974+ elif isinstance (self ._token_info , dict ):
975+ return self ._token_info
976+ else :
977+ return await self ._request ("GET" , "/api_tokens/self" )
991978
992979 # Otherwise fetch from the API
993980 return await self ._request ("GET" , "/api_tokens/self" )
@@ -1579,119 +1566,6 @@ async def get_source_by_name(
15791566 logger .error (f"Error getting source by name: { str (e )} " )
15801567 return None
15811568
1582- async def list_repo_incidents_directly (
1583- self ,
1584- repository_name : str ,
1585- from_date : str | None = None ,
1586- to_date : str | None = None ,
1587- presence : str | None = None ,
1588- tags : list [str ] | None = None ,
1589- exclude_tags : list [str ] | None = None ,
1590- per_page : int = 20 ,
1591- cursor : str | None = None ,
1592- ordering : str | None = None ,
1593- get_all : bool = False ,
1594- mine : bool = True ,
1595- ) -> dict [str , Any ]:
1596- """List incidents for a repository in a single API call.
1597-
1598- This method offers better performance than the two-step process of
1599- getting occurrences first and then incidents separately.
1600-
1601- Args:
1602- repository_name: Name of the repository
1603- from_date: Filter incidents created after this date (ISO format)
1604- to_date: Filter incidents created before this date (ISO format)
1605- presence: Filter by presence status
1606- tags: Filter by tags
1607- exclude_tags: Exclude incidents with these tag names
1608- per_page: Number of results per page
1609- cursor: Pagination cursor
1610- ordering: Sort field
1611- get_all: Whether to fetch all results using pagination
1612- mine: If True, only show incidents assigned to the current user
1613-
1614- Returns:
1615- Dictionary containing the incidents and pagination info
1616- """
1617- logger .info (f"Directly listing incidents for repository: { repository_name } " )
1618-
1619- # First get the source ID for the repository name
1620- source = await self .get_source_by_name (repository_name )
1621-
1622- if not source :
1623- return {
1624- "repository_info" : {"name" : repository_name },
1625- "incidents" : [],
1626- "message" : f"Repository '{ repository_name } ' not found or not accessible" ,
1627- }
1628-
1629- source_id = source .get ("id" )
1630- logger .info (f"Found source ID { source_id } for repository { repository_name } " )
1631-
1632- # Prepare parameters for the API call
1633- params = {}
1634- if from_date :
1635- params ["from_date" ] = from_date
1636- if to_date :
1637- params ["to_date" ] = to_date
1638- if presence :
1639- params ["presence" ] = presence
1640- if tags :
1641- params ["tags" ] = "," .join (tags ) if isinstance (tags , list ) else tags
1642- if exclude_tags :
1643- params ["exclude_tags" ] = "," .join (exclude_tags ) if isinstance (exclude_tags , list ) else exclude_tags
1644- if per_page :
1645- params ["per_page" ] = per_page
1646- if cursor :
1647- params ["cursor" ] = cursor
1648- if ordering :
1649- params ["ordering" ] = ordering
1650- if mine :
1651- params ["assigned_to_me" ] = "true"
1652-
1653- try :
1654- if get_all :
1655- # Use pagination to get all results
1656- incidents_result = await self .paginate_all (f"/sources/{ source_id } /incidents/secrets" , params )
1657- if isinstance (incidents_result , list ):
1658- return {
1659- "repository_info" : source ,
1660- "incidents" : incidents_result ,
1661- "total_count" : len (incidents_result ),
1662- }
1663- # If it's already a dict with structure, return it
1664- return incidents_result
1665-
1666- # Get a single page of results
1667- incidents_result = await self .list_source_incidents (source_id , ** params )
1668-
1669- # Make sure incidents_result is a dictionary before using .get()
1670- if isinstance (incidents_result , dict ):
1671- return {
1672- "repository_info" : source ,
1673- "incidents" : incidents_result .get ("data" , []),
1674- "next_cursor" : incidents_result .get ("next_cursor" ),
1675- "total_count" : incidents_result .get ("total_count" , 0 ),
1676- }
1677- elif isinstance (incidents_result , list ):
1678- return {
1679- "repository_info" : source ,
1680- "incidents" : incidents_result ,
1681- "total_count" : len (incidents_result ),
1682- }
1683- else :
1684- return {
1685- "repository_info" : source ,
1686- "incidents" : [],
1687- "total_count" : 0 ,
1688- "error" : "Unexpected response format from API" ,
1689- }
1690-
1691- except Exception as e :
1692- logger .error (f"Error listing repository incidents directly: { str (e )} " )
1693- return {"error" : f"Failed to list repository incidents: { str (e )} " }
1694-
16951569 async def create_code_fix_request (self , locations : list [dict [str , Any ]]) -> dict [str , Any ]:
16961570 """Create code fix requests for multiple secret incidents with their locations.
16971571
@@ -1714,4 +1588,18 @@ async def create_code_fix_request(self, locations: list[dict[str, Any]]) -> dict
17141588 404: API key not configured)
17151589 """
17161590 logger .info (f"Creating code fix request for { len (locations )} issue(s)" )
1717- return await self ._request ("POST" , "/v1/code-fix-requests" , json = {"locations" : locations })
1591+ return await self ._request ("POST" , "/code-fix-requests" , json = {"locations" : locations })
1592+
1593+ async def list_members (self , params ):
1594+ """List all users in the account."""
1595+ return await self ._request ("GET" , "/members" , params = params , return_headers = True )
1596+
1597+ async def get_member (self , member_id ):
1598+ """Get a specific user's information."""
1599+ return await self ._request ("GET" , f"/members/{ member_id } " )
1600+
1601+ async def get_current_member (self ):
1602+ """Get the current user's information."""
1603+ data = await self .get_current_token_info ()
1604+ member_id = data ["member_id" ]
1605+ return await self .get_member (member_id )
0 commit comments