@@ -396,27 +396,73 @@ def list_contracts(
396396 flat_lists: If True, flatten arrays using indexed keys (e.g., items.0.field)
397397 filters: Optional SearchFilters object or dict for backward compatibility.
398398 Filter parameters can also be passed as keyword arguments.
399- **kwargs: Filter parameters (keyword, award_date_gte, award_date_lte,
400- award_amount_gte, award_amount_lte, awarding_agency, funding_agency,
401- recipient_name, recipient_uei, naics_code, psc_code,
402- place_of_performance_state, place_of_performance_zip, cfda_number,
403- contract_type, award_type, set_aside_type, extent_competed,
404- fiscal_year, sort, order)
399+ **kwargs: Filter parameters
400+
401+ Text search:
402+ - keyword: Search contract descriptions (mapped to 'search' API param)
403+
404+ Date filters:
405+ - award_date_gte: Award date >= (YYYY-MM-DD)
406+ - award_date_lte: Award date <= (YYYY-MM-DD)
407+ - pop_start_date_gte: Period of performance start date >=
408+ - pop_start_date_lte: Period of performance start date <=
409+ - pop_end_date_gte: Period of performance end date >=
410+ - pop_end_date_lte: Period of performance end date <=
411+ - expiring_gte: Expiring on or after date
412+ - expiring_lte: Expiring on or before date
413+
414+ Party filters:
415+ - awarding_agency: Awarding agency code (e.g., "4700" for GSA)
416+ - funding_agency: Funding agency code
417+ - recipient_name: Vendor/recipient name (mapped to 'recipient' API param)
418+ - recipient_uei: Vendor UEI (mapped to 'uei' API param)
419+
420+ Classification filters:
421+ - naics_code: NAICS code (mapped to 'naics' API param)
422+ - psc_code: PSC code (mapped to 'psc' API param)
423+ - set_aside_type: Set-aside type (mapped to 'set_aside' API param)
424+
425+ Type filters:
426+ - fiscal_year: Fiscal year (exact match)
427+ - fiscal_year_gte: Fiscal year >=
428+ - fiscal_year_lte: Fiscal year <=
429+ - award_type: Award type code
430+
431+ Identifiers:
432+ - piid: Procurement Instrument Identifier
433+ - solicitation_identifier: Solicitation ID
434+
435+ Sorting:
436+ - sort: Field to sort by (combined with 'order')
437+ - order: Sort order ('asc' or 'desc', default 'asc')
405438
406439 Examples:
407440 >>> # Simple usage
408441 >>> contracts = client.list_contracts(limit=10)
409442
410443 >>> # With keyword arguments
411444 >>> contracts = client.list_contracts(
412- ... awarding_agency="GSA",
445+ ... awarding_agency="4700", # GSA
413446 ... award_date_gte="2023-01-01",
414447 ... limit=25
415448 ... )
416449
417- >>> # With SearchFilters object
418- >>> filters = SearchFilters(keyword="IT", awarding_agency="GSA")
450+ >>> # Text search
451+ >>> contracts = client.list_contracts(keyword="software development")
452+
453+ >>> # With SearchFilters object (legacy)
454+ >>> filters = SearchFilters(
455+ ... keyword="IT",
456+ ... awarding_agency="4700",
457+ ... fiscal_year=2024
458+ ... )
419459 >>> contracts = client.list_contracts(filters=filters)
460+
461+ >>> # Using new date range filters
462+ >>> contracts = client.list_contracts(
463+ ... expiring_gte="2025-01-01",
464+ ... expiring_lte="2025-12-31"
465+ ... )
420466 """
421467 # Start with explicit parameters
422468 params : dict [str , Any ] = {"page" : page , "limit" : min (limit , 100 )}
@@ -471,21 +517,31 @@ def list_contracts(
471517 # Map Python parameter names to API parameter names
472518 # The API may expect different parameter names than our Python interface
473519 api_param_mapping = {
474- "naics_code" : "naics" , # API expects 'naics' not 'naics_code' for filtering
520+ "naics_code" : "naics" , # API expects 'naics' not 'naics_code'
521+ "keyword" : "search" , # API expects 'search' not 'keyword'
522+ "psc_code" : "psc" , # API expects 'psc' not 'psc_code'
523+ "recipient_name" : "recipient" , # API expects 'recipient' not 'recipient_name'
524+ "recipient_uei" : "uei" , # API expects 'uei' not 'recipient_uei'
525+ "set_aside_type" : "set_aside" , # API expects 'set_aside' not 'set_aside_type'
475526 }
476527
528+ # Handle sort + order → ordering conversion
529+ # API expects single 'ordering' parameter with '-' prefix for descending
530+ sort_field = filter_params .pop ("sort" , None )
531+ sort_order = filter_params .pop ("order" , None )
532+ if sort_field :
533+ # Prefix with '-' for descending order
534+ prefix = "-" if sort_order == "desc" else ""
535+ filter_params ["ordering" ] = f"{ prefix } { sort_field } "
536+
477537 # Apply parameter name mapping and process values
478538 api_params = {}
479539 for key , value in filter_params .items ():
480540 if value is None :
481541 continue # Skip None values
482542 # Map to API parameter name if needed
483543 api_key = api_param_mapping .get (key , key )
484- # Convert Decimal/numeric values to strings for award amounts
485- if key in ("award_amount_gte" , "award_amount_lte" ):
486- api_params [api_key ] = str (value )
487- else :
488- api_params [api_key ] = value
544+ api_params [api_key ] = value
489545
490546 # Update params with all filter parameters
491547 # This is the same pattern as other endpoints use
0 commit comments