tango-python 1.13.0__tar.gz → 1.15.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {tango_python-1.13.0 → tango_python-1.15.0}/CHANGELOG.md +17 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/PKG-INFO +10 -1
- {tango_python-1.13.0 → tango_python-1.15.0}/README.md +9 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/docs/API_REFERENCE.md +38 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/pyproject.toml +1 -1
- {tango_python-1.13.0 → tango_python-1.15.0}/tango/__init__.py +1 -1
- {tango_python-1.13.0 → tango_python-1.15.0}/tango/client.py +62 -1
- {tango_python-1.13.0 → tango_python-1.15.0}/tango/models.py +20 -5
- {tango_python-1.13.0 → tango_python-1.15.0}/tango/shapes/generated_overlay.py +4 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/test_client.py +57 -0
- tango_python-1.15.0/tests/test_opportunity_attachments.py +166 -0
- tango_python-1.13.0/tests/test_opportunity_attachments.py +0 -72
- {tango_python-1.13.0 → tango_python-1.15.0}/.gitignore +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/LICENSE +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/docs/CLIENT.md +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/docs/DYNAMIC_MODELS.md +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/docs/ERRORS.md +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/docs/PAGINATION.md +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/docs/SHAPES.md +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/docs/WEBHOOKS.md +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/scripts/README.md +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/scripts/check_filter_shape_conformance.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/scripts/check_shape_coverage.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/scripts/fetch_api_schema.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/scripts/generate_schemas_from_api.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/scripts/generate_shape_overlay.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/scripts/pr_review.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/scripts/probe_shape_types.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/scripts/refresh_contract.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/scripts/smoke_api_parity.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/scripts/test_production.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tango/exceptions.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tango/shapes/__init__.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tango/shapes/explicit_schemas.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tango/shapes/factory.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tango/shapes/generator.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tango/shapes/models.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tango/shapes/parser.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tango/shapes/schema.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tango/shapes/types.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tango/webhooks/__init__.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tango/webhooks/cli.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tango/webhooks/receiver.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tango/webhooks/signing.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tango/webhooks/simulate.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/__init__.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestAgenciesIntegration.test_get_agency +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestAgenciesIntegration.test_list_agencies +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestBusinessTypesIntegration.test_business_type_field_type_validation +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestBusinessTypesIntegration.test_business_type_parsing_consistency +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestBusinessTypesIntegration.test_list_business_types +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestContractsIntegration.test_combined_filters_work_together +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestContractsIntegration.test_contract_cursor_pagination +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestContractsIntegration.test_contract_data_object_parsing +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestContractsIntegration.test_contract_field_types +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestContractsIntegration.test_filter_parameter_mappings[keyword-software] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestContractsIntegration.test_filter_parameter_mappings[psc_code-R425] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestContractsIntegration.test_list_contracts_with_awarding_agency_filter +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestContractsIntegration.test_list_contracts_with_date_range_filter +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestContractsIntegration.test_list_contracts_with_flat +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestContractsIntegration.test_list_contracts_with_naics_code_filter +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestContractsIntegration.test_list_contracts_with_shapes[custom-key,piid,recipient(display_name),total_contract_value,award_date] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestContractsIntegration.test_list_contracts_with_shapes[default-None] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestContractsIntegration.test_list_contracts_with_shapes[detailed-key,piid,award_date,description,total_contract_value,obligated,fiscal_year,set_aside,recipient(display_name,uei),awarding_office(-),place_of_performa...ce114a3c47e2037aaa3c15d00b7031bd +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestContractsIntegration.test_list_contracts_with_shapes[minimal-key,piid,award_date,recipient(display_name),description,total_contract_value] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestContractsIntegration.test_new_expiring_filters +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestContractsIntegration.test_new_fiscal_year_range_filters +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestContractsIntegration.test_new_identifier_filters +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestContractsIntegration.test_search_contracts_with_filters +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestContractsIntegration.test_search_filters_object_with_new_parameters +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestContractsIntegration.test_sort_and_order_mapped_to_ordering[asc-] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestContractsIntegration.test_sort_and_order_mapped_to_ordering[desc--] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestEdgeCasesIntegration.test_api_schema_stability_detection_contracts +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestEdgeCasesIntegration.test_api_schema_stability_detection_entities +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestEdgeCasesIntegration.test_date_field_parsing_edge_cases +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestEdgeCasesIntegration.test_decimal_field_parsing_edge_cases +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestEdgeCasesIntegration.test_empty_list_responses +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestEdgeCasesIntegration.test_entity_parsing_with_various_address_formats +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestEdgeCasesIntegration.test_flattened_responses_with_flat_lists +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestEdgeCasesIntegration.test_list_field_parsing_consistency +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestEdgeCasesIntegration.test_parsing_nested_objects_with_missing_data +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestEdgeCasesIntegration.test_parsing_null_missing_fields_in_contracts +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestEdgeCasesIntegration.test_parsing_with_minimal_shape_sparse_data +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestEntitiesIntegration.test_entity_field_types +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestEntitiesIntegration.test_entity_location_parsing +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestEntitiesIntegration.test_entity_parsing_with_business_types +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestEntitiesIntegration.test_entity_with_various_identifiers +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestEntitiesIntegration.test_get_entity_budget_flows +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestEntitiesIntegration.test_get_entity_by_uei +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestEntitiesIntegration.test_list_entities_with_flat +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestEntitiesIntegration.test_list_entities_with_search +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestEntitiesIntegration.test_list_entities_with_shapes[comprehensive-uei,legal_business_name,dba_name,cage_code,business_types,primary_naics,naics_codes,psc_codes,email_address,entity_url,description,capabilities,ke...1603a7d52e211cf2b3bc7d32080238aa +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestEntitiesIntegration.test_list_entities_with_shapes[custom-uei,legal_business_name,cage_code] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestEntitiesIntegration.test_list_entities_with_shapes[minimal-uei,legal_business_name,cage_code,business_types] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestEntitiesIntegration.test_list_entities_with_shapes[with_address-uei,legal_business_name,cage_code,business_types,physical_address] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestForecastsIntegration.test_forecast_field_types +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestForecastsIntegration.test_list_forecasts_with_shapes[custom-id,title,anticipated_award_date] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestForecastsIntegration.test_list_forecasts_with_shapes[default-None] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestForecastsIntegration.test_list_forecasts_with_shapes[detailed-id,source_system,external_id,title,description,anticipated_award_date,fiscal_year,naics_code,status,is_active] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestForecastsIntegration.test_list_forecasts_with_shapes[minimal-id,title,anticipated_award_date,fiscal_year,naics_code,status] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestGrantsIntegration.test_grant_field_types +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestGrantsIntegration.test_grant_pagination +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestGrantsIntegration.test_list_grants_with_shapes[custom-grant_id,title,opportunity_number] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestGrantsIntegration.test_list_grants_with_shapes[default-None] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestGrantsIntegration.test_list_grants_with_shapes[detailed-grant_id,opportunity_number,title,status(-),agency_code,description,last_updated,cfda_numbers(number,title),applicant_types(-),funding_categories(-)] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestGrantsIntegration.test_list_grants_with_shapes[minimal-grant_id,opportunity_number,title,status(-),agency_code] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestIDVsIntegration.test_get_idv_uses_default_shape +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestIDVsIntegration.test_list_idv_awards_uses_default_shape +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestIDVsIntegration.test_list_idv_child_idvs_uses_default_shape +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestIDVsIntegration.test_list_idv_transactions +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestIDVsIntegration.test_list_idvs_uses_default_shape_and_keyset_params +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestITDashboardIntegration.test_filter_by_agency_code +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestITDashboardIntegration.test_filter_by_agency_name_text +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestITDashboardIntegration.test_filter_by_cio_rating +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestITDashboardIntegration.test_filter_by_cio_rating_max +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestITDashboardIntegration.test_filter_by_performance_risk +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestITDashboardIntegration.test_filter_by_type_of_investment +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestITDashboardIntegration.test_filter_by_updated_time_range +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestITDashboardIntegration.test_funding_and_cio_evaluation_expansions +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestITDashboardIntegration.test_get_itdashboard_investment_by_uii +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestITDashboardIntegration.test_itdashboard_pagination +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestITDashboardIntegration.test_list_itdashboard_investments_with_search +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestITDashboardIntegration.test_list_itdashboard_investments_with_shapes[custom-uii,agency_name,investment_title,updated_time] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestITDashboardIntegration.test_list_itdashboard_investments_with_shapes[default-None] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestITDashboardIntegration.test_list_itdashboard_investments_with_shapes[minimal-uii,agency_name,bureau_name,investment_title,type_of_investment,part_of_it_portfolio,updated_time,url] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestNaicsIntegration.test_list_naics +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestNoticesIntegration.test_list_notices_with_shapes[custom-notice_id,title,solicitation_number] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestNoticesIntegration.test_list_notices_with_shapes[default-None] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestNoticesIntegration.test_list_notices_with_shapes[detailed-notice_id,title,description,solicitation_number,posted_date,naics_code,set_aside,office(-),place_of_performance(-)] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestNoticesIntegration.test_list_notices_with_shapes[minimal-notice_id,title,solicitation_number,posted_date] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestNoticesIntegration.test_notice_field_types +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestNoticesIntegration.test_notice_pagination +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestNoticesIntegration.test_notice_with_meta_fields +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestOTAsIntegration.test_get_ota +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestOTAsIntegration.test_list_otas +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestOTIDVsIntegration.test_get_otidv +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestOTIDVsIntegration.test_list_otidvs +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestOfficesIntegration.test_get_office +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestOfficesIntegration.test_list_offices +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestOpportunitiesIntegration.test_list_opportunities_with_shapes[custom-opportunity_id,title,solicitation_number] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestOpportunitiesIntegration.test_list_opportunities_with_shapes[default-None] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestOpportunitiesIntegration.test_list_opportunities_with_shapes[detailed-opportunity_id,title,description,solicitation_number,response_deadline,first_notice_date,last_notice_date,active,naics_code,psc_code,set_asid...23b6b4502ddd665b7184afcff6c6d8d9 +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestOpportunitiesIntegration.test_list_opportunities_with_shapes[minimal-opportunity_id,title,solicitation_number,response_deadline,active] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestOpportunitiesIntegration.test_opportunity_field_types +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestOrganizationsIntegration.test_get_organization +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestOrganizationsIntegration.test_list_organizations +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestProtestsIntegration.test_get_protest_by_case_id +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestProtestsIntegration.test_list_protests_with_filter +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestProtestsIntegration.test_list_protests_with_shapes[custom-case_id,title,source_system,outcome] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestProtestsIntegration.test_list_protests_with_shapes[default-None] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestProtestsIntegration.test_list_protests_with_shapes[minimal-case_id,case_number,title,source_system,outcome,filed_date] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestProtestsIntegration.test_list_protests_with_shapes[with_dockets-case_id,case_number,title,outcome,filed_date,dockets(docket_number,filed_date,outcome)] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestProtestsIntegration.test_protest_pagination +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestSubawardsIntegration.test_list_subawards +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestTypeHintsIntegration.test_contracts_dict_access[custom-key,piid,description] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestTypeHintsIntegration.test_contracts_dict_access[minimal-key,piid,award_date,recipient(display_name),description,total_contract_value] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestTypeHintsIntegration.test_contracts_dict_access[ultra_minimal-key,piid,recipient(display_name),total_contract_value] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestTypeHintsIntegration.test_entities_dict_access[minimal-uei,legal_business_name,cage_code,business_types] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestTypeHintsIntegration.test_entities_dict_access[with_address-uei,legal_business_name,cage_code,business_types,physical_address] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestTypeHintsIntegration.test_notices_dict_access[detailed-notice_id,title,description,solicitation_number,posted_date,naics_code,set_aside,office(-),place_of_performance(-)] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestTypeHintsIntegration.test_notices_dict_access[minimal-notice_id,title,solicitation_number,posted_date] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestTypeHintsIntegration.test_opportunities_dict_access[detailed-opportunity_id,title,description,solicitation_number,response_deadline,first_notice_date,last_notice_date,active,naics_code,psc_code,set_aside,sam_url,office(-),place_of_performance(-)] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestTypeHintsIntegration.test_opportunities_dict_access[minimal-opportunity_id,title,solicitation_number,response_deadline,active] +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestVehiclesIntegration.test_get_vehicle_supports_joiner_and_flat_lists +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestVehiclesIntegration.test_get_vehicle_with_metrics_expansion +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestVehiclesIntegration.test_list_vehicle_awardees_uses_default_shape +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestVehiclesIntegration.test_list_vehicle_orders_uses_default_shape +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestVehiclesIntegration.test_list_vehicles_uses_default_shape_and_search +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/cassettes/TestVehiclesIntegration.test_list_vehicles_with_ordering +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/conftest.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/integration/README.md +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/integration/__init__.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/integration/conftest.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/integration/test_agencies_integration.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/integration/test_contracts_integration.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/integration/test_edge_cases_integration.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/integration/test_entities_integration.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/integration/test_forecasts_integration.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/integration/test_grants_integration.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/integration/test_itdashboard_integration.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/integration/test_naics_integration.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/integration/test_notices_integration.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/integration/test_offices_integration.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/integration/test_opportunities_integration.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/integration/test_organizations_integration.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/integration/test_otas_otidvs_integration.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/integration/test_protests_integration.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/integration/test_reference_data_integration.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/integration/test_subawards_integration.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/integration/test_vehicles_idvs_integration.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/integration/validation.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/production/__init__.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/production/conftest.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/production/test_production_smoke.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/test_api_parity.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/test_contract_appeals.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/test_dibbs_exclusions_sbir.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/test_ebuy.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/test_federal_register.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/test_models.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/test_opportunity_awards.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/test_organization_scope.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/test_shape_coverage_gate.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/test_shapes.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/test_sled.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/test_webhooks_cli.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/test_webhooks_receiver.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/test_webhooks_signing.py +0 -0
- {tango_python-1.13.0 → tango_python-1.15.0}/tests/test_webhooks_simulate.py +0 -0
|
@@ -7,6 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.15.0] - 2026-10-06
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **`matched_by` on agency-filter diagnostics** (Tango API 5.9.0). Each entry of `PaginatedResponse.meta["resolved_filters"][<filter name>]` that resolved now says how its token matched: `key` (an organization UUID), `code` (a 3-digit CGAC or 4-digit FPDS code), `name` (the organization's name, including a department's everyday name, a spelling variant or a rename), `alias` (an abbreviation or the organization's own alias) or `fuzzy` (a looser text match, worth checking against the resolved name). An entry that did not resolve has no `matched_by`. `meta` is passed through as the API sends it, so no code change was needed to receive the field; this release documents it and pins it with a test. `agency_warnings`, `unresolved_agency_tokens` and `resolved_agencies` are unchanged.
|
|
15
|
+
- **File and link counts on opportunities and notices** (Tango API 5.9.0). An attachment's `type` is `file` (a document attached to the notice; only files have extracted text) or `link` (a URL the notice lists), and the new fields count each: `meta.files_count` and `meta.links_count` on opportunities, `file_count` and `link_count` on notices. The existing `meta.attachments_count` and `attachment_count` still count every attachment, links included, and an attachment of any other type counts only there, so files plus links need not equal the total. The new fields are `None` until a record has been counted, so treat `None` as unknown, not zero. All four are accepted in custom shapes, as is `opportunity(meta(files_count,links_count))` on vehicles; no default SDK shape names them.
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- Re-vendored `contracts/filter_shape_contract.json` (Tango API 5.9.0) and regenerated `tango/shapes/generated_overlay.py`.
|
|
20
|
+
|
|
21
|
+
## [1.14.0] - 2026-10-02
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- **`PaginatedResponse.count_type`**: `"exact"` or `"approximate"`, read from the API's `X-Results-CountType` header on every list method (`None` when the API doesn't send it). Past 1,000 matches the contract, IDV, opportunity and notice lists may return a query-planner estimate as `count`, which can be well off; this is how a caller tells the two apart. It is taken from each response itself, so concurrent calls on one client can't see each other's value the way `last_response_headers` can.
|
|
26
|
+
|
|
10
27
|
## [1.13.0] - 2026-10-02
|
|
11
28
|
|
|
12
29
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: tango-python
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.15.0
|
|
4
4
|
Summary: Python SDK for the Tango API
|
|
5
5
|
Project-URL: Homepage, https://github.com/makegov/tango-python
|
|
6
6
|
Project-URL: Documentation, https://docs.makegov.com/tango-python
|
|
@@ -219,6 +219,15 @@ for warning in response.agency_warnings:
|
|
|
219
219
|
print(warning)
|
|
220
220
|
```
|
|
221
221
|
|
|
222
|
+
Each entry of `response.meta["resolved_filters"][<filter name>]` that resolved also says how its token matched, in `matched_by` (Tango API 5.9.0+): `key` (an organization UUID), `code` (a 3-digit CGAC or 4-digit FPDS code), `name` (the organization's name, including a department's everyday name, a spelling variant or a rename), `alias` (an abbreviation or the organization's own alias) or `fuzzy` (a looser text match).
|
|
223
|
+
A `fuzzy` match is the one worth checking against the resolved name:
|
|
224
|
+
|
|
225
|
+
```python
|
|
226
|
+
for entry in response.meta["resolved_filters"].get("awarding_agency", []):
|
|
227
|
+
if entry.get("matched_by") == "fuzzy":
|
|
228
|
+
print(f"{entry['token']!r} loosely matched {entry['resolved']['name']}")
|
|
229
|
+
```
|
|
230
|
+
|
|
222
231
|
If *every* token for a filter fails to resolve, the API returns `400` and the SDK raises
|
|
223
232
|
`TangoValidationError` naming the offending value, rather than an empty page.
|
|
224
233
|
|
|
@@ -165,6 +165,15 @@ for warning in response.agency_warnings:
|
|
|
165
165
|
print(warning)
|
|
166
166
|
```
|
|
167
167
|
|
|
168
|
+
Each entry of `response.meta["resolved_filters"][<filter name>]` that resolved also says how its token matched, in `matched_by` (Tango API 5.9.0+): `key` (an organization UUID), `code` (a 3-digit CGAC or 4-digit FPDS code), `name` (the organization's name, including a department's everyday name, a spelling variant or a rename), `alias` (an abbreviation or the organization's own alias) or `fuzzy` (a looser text match).
|
|
169
|
+
A `fuzzy` match is the one worth checking against the resolved name:
|
|
170
|
+
|
|
171
|
+
```python
|
|
172
|
+
for entry in response.meta["resolved_filters"].get("awarding_agency", []):
|
|
173
|
+
if entry.get("matched_by") == "fuzzy":
|
|
174
|
+
print(f"{entry['token']!r} loosely matched {entry['resolved']['name']}")
|
|
175
|
+
```
|
|
176
|
+
|
|
168
177
|
If *every* token for a filter fails to resolve, the API returns `400` and the SDK raises
|
|
169
178
|
`TangoValidationError` naming the offending value, rather than an empty page.
|
|
170
179
|
|
|
@@ -981,6 +981,27 @@ awarded = client.list_opportunities(
|
|
|
981
981
|
- The `awarded` and `awardee_uei` filters search every opportunity, not just active ones, so pass `active=True` to narrow to open opportunities.
|
|
982
982
|
- Notices accept `award_date`, `award_amount`, `awardee` and `awardee_uei` in `shape` too.
|
|
983
983
|
|
|
984
|
+
**Attachment counts — `meta(attachments_count, files_count, links_count)`:**
|
|
985
|
+
|
|
986
|
+
Tango API 5.9.0 splits an opportunity's attachment count by attachment `type`.
|
|
987
|
+
A `file` is a document attached to the notice, and only files have extracted text; a `link` is a URL the notice lists.
|
|
988
|
+
|
|
989
|
+
```python
|
|
990
|
+
opp = client.get_opportunity(
|
|
991
|
+
opportunity_id,
|
|
992
|
+
shape="opportunity_id,title,meta(attachments_count,files_count,links_count)",
|
|
993
|
+
)
|
|
994
|
+
files = opp["meta"]["files_count"]
|
|
995
|
+
if files is None:
|
|
996
|
+
print("not counted yet")
|
|
997
|
+
```
|
|
998
|
+
|
|
999
|
+
- `meta.files_count` counts the files and `meta.links_count` counts the links.
|
|
1000
|
+
- `meta.attachments_count` still counts every attachment, links included. An attachment of any other type counts only there, so `files_count + links_count` need not equal it.
|
|
1001
|
+
- **`None` means unknown, not zero.** Both new fields are null until the record has been counted.
|
|
1002
|
+
- None of the three is in the SDK's default shape, so name the ones you want.
|
|
1003
|
+
- The opportunity embedded in a vehicle accepts them too: `opportunity(meta(files_count,links_count))`.
|
|
1004
|
+
|
|
984
1005
|
---
|
|
985
1006
|
|
|
986
1007
|
## Notices
|
|
@@ -1053,6 +1074,23 @@ for notice in notices.results:
|
|
|
1053
1074
|
- `posted_date` - Date posted
|
|
1054
1075
|
- `naics_code` - Industry code
|
|
1055
1076
|
|
|
1077
|
+
**Attachment counts — `attachment_count`, `file_count`, `link_count`:**
|
|
1078
|
+
|
|
1079
|
+
Tango API 5.9.0 splits a notice's attachment count by attachment `type`.
|
|
1080
|
+
A `file` is a document attached to the notice, and only files have extracted text; a `link` is a URL the notice lists.
|
|
1081
|
+
|
|
1082
|
+
```python
|
|
1083
|
+
notices = client.list_notices(
|
|
1084
|
+
agency="GSA",
|
|
1085
|
+
shape="notice_id,title,attachment_count,file_count,link_count",
|
|
1086
|
+
)
|
|
1087
|
+
```
|
|
1088
|
+
|
|
1089
|
+
- `file_count` counts the files and `link_count` counts the links.
|
|
1090
|
+
- `attachment_count` still counts every attachment, links included. An attachment of any other type counts only there, so `file_count + link_count` need not equal it.
|
|
1091
|
+
- **`None` means unknown, not zero.** Both new fields are null until the notice has been counted.
|
|
1092
|
+
- The API returns all three when no `shape` is sent, but the SDK's default `NOTICES_MINIMAL` shape does not name them, so ask for them.
|
|
1093
|
+
|
|
1056
1094
|
---
|
|
1057
1095
|
|
|
1058
1096
|
## Grants
|
|
@@ -71,6 +71,9 @@ from tango.shapes import (
|
|
|
71
71
|
build_parser_registry_from_client,
|
|
72
72
|
)
|
|
73
73
|
|
|
74
|
+
# Where `_request` stores a list response's `X-Results-CountType` header so each `PaginatedResponse` reads its own, not the shared `last_response_headers`.
|
|
75
|
+
_COUNT_TYPE_KEY = "_tango_count_type"
|
|
76
|
+
|
|
74
77
|
|
|
75
78
|
class TangoClient:
|
|
76
79
|
"""Tango API Client"""
|
|
@@ -180,7 +183,11 @@ class TangoClient:
|
|
|
180
183
|
|
|
181
184
|
self._raise_for_status(response)
|
|
182
185
|
|
|
183
|
-
|
|
186
|
+
data = response.json() if response.content else {}
|
|
187
|
+
count_type = response.headers.get("X-Results-CountType")
|
|
188
|
+
if isinstance(count_type, str) and isinstance(data, dict) and "count" in data:
|
|
189
|
+
data[_COUNT_TYPE_KEY] = count_type.lower()
|
|
190
|
+
return data
|
|
184
191
|
|
|
185
192
|
except httpx.HTTPError as e:
|
|
186
193
|
raise TangoAPIError(f"Request failed: {str(e)}") from e
|
|
@@ -495,6 +502,7 @@ class TangoClient:
|
|
|
495
502
|
return PaginatedResponse(
|
|
496
503
|
count=data["count"],
|
|
497
504
|
next=data.get("next"),
|
|
505
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
498
506
|
previous=data.get("previous"),
|
|
499
507
|
results=[
|
|
500
508
|
ag
|
|
@@ -530,6 +538,7 @@ class TangoClient:
|
|
|
530
538
|
return PaginatedResponse(
|
|
531
539
|
count=data.get("count", 0),
|
|
532
540
|
next=data.get("next"),
|
|
541
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
533
542
|
previous=data.get("previous"),
|
|
534
543
|
results=data.get("results", []),
|
|
535
544
|
meta=data.get("meta"),
|
|
@@ -583,6 +592,7 @@ class TangoClient:
|
|
|
583
592
|
return PaginatedResponse(
|
|
584
593
|
count=data.get("count", 0),
|
|
585
594
|
next=data.get("next"),
|
|
595
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
586
596
|
previous=data.get("previous"),
|
|
587
597
|
results=results,
|
|
588
598
|
meta=data.get("meta"),
|
|
@@ -795,6 +805,7 @@ class TangoClient:
|
|
|
795
805
|
return PaginatedResponse(
|
|
796
806
|
count=data["count"],
|
|
797
807
|
next=data.get("next"),
|
|
808
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
798
809
|
previous=data.get("previous"),
|
|
799
810
|
results=results,
|
|
800
811
|
cursor=data.get("cursor"),
|
|
@@ -857,6 +868,7 @@ class TangoClient:
|
|
|
857
868
|
return PaginatedResponse(
|
|
858
869
|
count=int(data.get("count") or len(results)),
|
|
859
870
|
next=data.get("next"),
|
|
871
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
860
872
|
previous=data.get("previous"),
|
|
861
873
|
results=results,
|
|
862
874
|
cursor=data.get("cursor"),
|
|
@@ -880,6 +892,7 @@ class TangoClient:
|
|
|
880
892
|
return PaginatedResponse(
|
|
881
893
|
count=int(data.get("count") or len(data.get("results") or [])),
|
|
882
894
|
next=data.get("next"),
|
|
895
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
883
896
|
previous=data.get("previous"),
|
|
884
897
|
results=data.get("results") or [],
|
|
885
898
|
cursor=data.get("cursor"),
|
|
@@ -984,6 +997,7 @@ class TangoClient:
|
|
|
984
997
|
return PaginatedResponse(
|
|
985
998
|
count=int(data.get("count") or len(results)),
|
|
986
999
|
next=data.get("next"),
|
|
1000
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
987
1001
|
previous=data.get("previous"),
|
|
988
1002
|
results=results,
|
|
989
1003
|
cursor=data.get("cursor"),
|
|
@@ -1087,6 +1101,7 @@ class TangoClient:
|
|
|
1087
1101
|
return PaginatedResponse(
|
|
1088
1102
|
count=int(data.get("count") or len(results)),
|
|
1089
1103
|
next=data.get("next"),
|
|
1104
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
1090
1105
|
previous=data.get("previous"),
|
|
1091
1106
|
results=results,
|
|
1092
1107
|
cursor=data.get("cursor"),
|
|
@@ -1133,6 +1148,7 @@ class TangoClient:
|
|
|
1133
1148
|
return PaginatedResponse(
|
|
1134
1149
|
count=int(data.get("count") or len(results)),
|
|
1135
1150
|
next=data.get("next"),
|
|
1151
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
1136
1152
|
previous=data.get("previous"),
|
|
1137
1153
|
results=results,
|
|
1138
1154
|
cursor=data.get("cursor"),
|
|
@@ -1151,6 +1167,7 @@ class TangoClient:
|
|
|
1151
1167
|
return PaginatedResponse(
|
|
1152
1168
|
count=int(data.get("count") or len(data.get("results") or [])),
|
|
1153
1169
|
next=data.get("next"),
|
|
1170
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
1154
1171
|
previous=data.get("previous"),
|
|
1155
1172
|
results=data.get("results") or [],
|
|
1156
1173
|
cursor=data.get("cursor"),
|
|
@@ -1234,6 +1251,7 @@ class TangoClient:
|
|
|
1234
1251
|
return PaginatedResponse(
|
|
1235
1252
|
count=int(data.get("count") or len(results)),
|
|
1236
1253
|
next=data.get("next"),
|
|
1254
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
1237
1255
|
previous=data.get("previous"),
|
|
1238
1256
|
results=results,
|
|
1239
1257
|
cursor=data.get("cursor"),
|
|
@@ -1340,6 +1358,7 @@ class TangoClient:
|
|
|
1340
1358
|
return PaginatedResponse(
|
|
1341
1359
|
count=int(data.get("count") or len(results)),
|
|
1342
1360
|
next=data.get("next"),
|
|
1361
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
1343
1362
|
previous=data.get("previous"),
|
|
1344
1363
|
results=results,
|
|
1345
1364
|
cursor=data.get("cursor"),
|
|
@@ -1417,6 +1436,7 @@ class TangoClient:
|
|
|
1417
1436
|
return PaginatedResponse(
|
|
1418
1437
|
count=int(data.get("count") or len(results)),
|
|
1419
1438
|
next=data.get("next"),
|
|
1439
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
1420
1440
|
previous=data.get("previous"),
|
|
1421
1441
|
results=results,
|
|
1422
1442
|
cursor=data.get("cursor"),
|
|
@@ -1474,6 +1494,7 @@ class TangoClient:
|
|
|
1474
1494
|
return PaginatedResponse(
|
|
1475
1495
|
count=data.get("count", 0),
|
|
1476
1496
|
next=data.get("next"),
|
|
1497
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
1477
1498
|
previous=data.get("previous"),
|
|
1478
1499
|
results=results,
|
|
1479
1500
|
meta=data.get("meta"),
|
|
@@ -1559,6 +1580,7 @@ class TangoClient:
|
|
|
1559
1580
|
return PaginatedResponse(
|
|
1560
1581
|
count=data.get("count", 0),
|
|
1561
1582
|
next=data.get("next"),
|
|
1583
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
1562
1584
|
previous=data.get("previous"),
|
|
1563
1585
|
results=results,
|
|
1564
1586
|
meta=data.get("meta"),
|
|
@@ -1671,6 +1693,7 @@ class TangoClient:
|
|
|
1671
1693
|
return PaginatedResponse(
|
|
1672
1694
|
count=data.get("count", 0),
|
|
1673
1695
|
next=data.get("next"),
|
|
1696
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
1674
1697
|
previous=data.get("previous"),
|
|
1675
1698
|
results=results,
|
|
1676
1699
|
meta=data.get("meta"),
|
|
@@ -1841,6 +1864,7 @@ class TangoClient:
|
|
|
1841
1864
|
return PaginatedResponse(
|
|
1842
1865
|
count=data["count"],
|
|
1843
1866
|
next=data.get("next"),
|
|
1867
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
1844
1868
|
previous=data.get("previous"),
|
|
1845
1869
|
results=results,
|
|
1846
1870
|
meta=data.get("meta"),
|
|
@@ -1923,6 +1947,7 @@ class TangoClient:
|
|
|
1923
1947
|
return PaginatedResponse(
|
|
1924
1948
|
count=data["count"],
|
|
1925
1949
|
next=data.get("next"),
|
|
1950
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
1926
1951
|
previous=data.get("previous"),
|
|
1927
1952
|
results=results,
|
|
1928
1953
|
meta=data.get("meta"),
|
|
@@ -1972,6 +1997,7 @@ class TangoClient:
|
|
|
1972
1997
|
return PaginatedResponse(
|
|
1973
1998
|
count=data["count"],
|
|
1974
1999
|
next=data.get("next"),
|
|
2000
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
1975
2001
|
previous=data.get("previous"),
|
|
1976
2002
|
results=results,
|
|
1977
2003
|
meta=data.get("meta"),
|
|
@@ -2007,6 +2033,7 @@ class TangoClient:
|
|
|
2007
2033
|
return PaginatedResponse(
|
|
2008
2034
|
count=data["count"],
|
|
2009
2035
|
next=data.get("next"),
|
|
2036
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
2010
2037
|
previous=data.get("previous"),
|
|
2011
2038
|
results=results,
|
|
2012
2039
|
meta=data.get("meta"),
|
|
@@ -2059,6 +2086,7 @@ class TangoClient:
|
|
|
2059
2086
|
return PaginatedResponse(
|
|
2060
2087
|
count=data.get("count", 0),
|
|
2061
2088
|
next=data.get("next"),
|
|
2089
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
2062
2090
|
previous=data.get("previous"),
|
|
2063
2091
|
results=data.get("results", []),
|
|
2064
2092
|
meta=data.get("meta"),
|
|
@@ -2146,6 +2174,7 @@ class TangoClient:
|
|
|
2146
2174
|
return PaginatedResponse(
|
|
2147
2175
|
count=data["count"],
|
|
2148
2176
|
next=data.get("next"),
|
|
2177
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
2149
2178
|
previous=data.get("previous"),
|
|
2150
2179
|
results=results,
|
|
2151
2180
|
meta=data.get("meta"),
|
|
@@ -2203,6 +2232,7 @@ class TangoClient:
|
|
|
2203
2232
|
return PaginatedResponse(
|
|
2204
2233
|
count=int(data.get("count", 0)),
|
|
2205
2234
|
next=data.get("next"),
|
|
2235
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
2206
2236
|
previous=data.get("previous"),
|
|
2207
2237
|
results=list(data.get("results") or []),
|
|
2208
2238
|
meta=data.get("meta"),
|
|
@@ -2296,6 +2326,7 @@ class TangoClient:
|
|
|
2296
2326
|
return PaginatedResponse(
|
|
2297
2327
|
count=data["count"],
|
|
2298
2328
|
next=data.get("next"),
|
|
2329
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
2299
2330
|
previous=data.get("previous"),
|
|
2300
2331
|
results=results,
|
|
2301
2332
|
meta=data.get("meta"),
|
|
@@ -2427,6 +2458,7 @@ class TangoClient:
|
|
|
2427
2458
|
return PaginatedResponse(
|
|
2428
2459
|
count=data["count"],
|
|
2429
2460
|
next=data.get("next"),
|
|
2461
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
2430
2462
|
previous=data.get("previous"),
|
|
2431
2463
|
results=results,
|
|
2432
2464
|
meta=data.get("meta"),
|
|
@@ -2542,6 +2574,7 @@ class TangoClient:
|
|
|
2542
2574
|
return PaginatedResponse(
|
|
2543
2575
|
count=data["count"],
|
|
2544
2576
|
next=data.get("next"),
|
|
2577
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
2545
2578
|
previous=data.get("previous"),
|
|
2546
2579
|
results=results,
|
|
2547
2580
|
meta=data.get("meta"),
|
|
@@ -2664,6 +2697,7 @@ class TangoClient:
|
|
|
2664
2697
|
return PaginatedResponse(
|
|
2665
2698
|
count=data["count"],
|
|
2666
2699
|
next=data.get("next"),
|
|
2700
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
2667
2701
|
previous=data.get("previous"),
|
|
2668
2702
|
results=results,
|
|
2669
2703
|
meta=data.get("meta"),
|
|
@@ -2802,6 +2836,7 @@ class TangoClient:
|
|
|
2802
2836
|
return PaginatedResponse(
|
|
2803
2837
|
count=data["count"],
|
|
2804
2838
|
next=data.get("next"),
|
|
2839
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
2805
2840
|
previous=data.get("previous"),
|
|
2806
2841
|
results=results,
|
|
2807
2842
|
meta=data.get("meta"),
|
|
@@ -2940,6 +2975,7 @@ class TangoClient:
|
|
|
2940
2975
|
return PaginatedResponse(
|
|
2941
2976
|
count=data["count"],
|
|
2942
2977
|
next=data.get("next"),
|
|
2978
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
2943
2979
|
previous=data.get("previous"),
|
|
2944
2980
|
results=results,
|
|
2945
2981
|
meta=data.get("meta"),
|
|
@@ -3080,6 +3116,7 @@ class TangoClient:
|
|
|
3080
3116
|
return PaginatedResponse(
|
|
3081
3117
|
count=data["count"],
|
|
3082
3118
|
next=data.get("next"),
|
|
3119
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
3083
3120
|
previous=data.get("previous"),
|
|
3084
3121
|
results=results,
|
|
3085
3122
|
meta=data.get("meta"),
|
|
@@ -3288,6 +3325,7 @@ class TangoClient:
|
|
|
3288
3325
|
return PaginatedResponse(
|
|
3289
3326
|
count=data["count"],
|
|
3290
3327
|
next=data.get("next"),
|
|
3328
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
3291
3329
|
previous=data.get("previous"),
|
|
3292
3330
|
results=results,
|
|
3293
3331
|
meta=data.get("meta"),
|
|
@@ -3408,6 +3446,7 @@ class TangoClient:
|
|
|
3408
3446
|
return PaginatedResponse(
|
|
3409
3447
|
count=data["count"],
|
|
3410
3448
|
next=data.get("next"),
|
|
3449
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
3411
3450
|
previous=data.get("previous"),
|
|
3412
3451
|
results=results,
|
|
3413
3452
|
meta=data.get("meta"),
|
|
@@ -3546,6 +3585,7 @@ class TangoClient:
|
|
|
3546
3585
|
return PaginatedResponse(
|
|
3547
3586
|
count=data["count"],
|
|
3548
3587
|
next=data.get("next"),
|
|
3588
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
3549
3589
|
previous=data.get("previous"),
|
|
3550
3590
|
results=results,
|
|
3551
3591
|
meta=data.get("meta"),
|
|
@@ -3695,6 +3735,7 @@ class TangoClient:
|
|
|
3695
3735
|
return PaginatedResponse(
|
|
3696
3736
|
count=data["count"],
|
|
3697
3737
|
next=data.get("next"),
|
|
3738
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
3698
3739
|
previous=data.get("previous"),
|
|
3699
3740
|
results=results,
|
|
3700
3741
|
meta=data.get("meta"),
|
|
@@ -3826,6 +3867,7 @@ class TangoClient:
|
|
|
3826
3867
|
return PaginatedResponse(
|
|
3827
3868
|
count=data["count"],
|
|
3828
3869
|
next=data.get("next"),
|
|
3870
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
3829
3871
|
previous=data.get("previous"),
|
|
3830
3872
|
results=results,
|
|
3831
3873
|
meta=data.get("meta"),
|
|
@@ -3947,6 +3989,7 @@ class TangoClient:
|
|
|
3947
3989
|
return PaginatedResponse(
|
|
3948
3990
|
count=data["count"],
|
|
3949
3991
|
next=data.get("next"),
|
|
3992
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
3950
3993
|
previous=data.get("previous"),
|
|
3951
3994
|
results=results,
|
|
3952
3995
|
meta=data.get("meta"),
|
|
@@ -4155,6 +4198,7 @@ class TangoClient:
|
|
|
4155
4198
|
return PaginatedResponse(
|
|
4156
4199
|
count=data["count"],
|
|
4157
4200
|
next=data.get("next"),
|
|
4201
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
4158
4202
|
previous=data.get("previous"),
|
|
4159
4203
|
results=results,
|
|
4160
4204
|
meta=data.get("meta"),
|
|
@@ -4267,6 +4311,7 @@ class TangoClient:
|
|
|
4267
4311
|
return PaginatedResponse(
|
|
4268
4312
|
count=data["count"],
|
|
4269
4313
|
next=data.get("next"),
|
|
4314
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
4270
4315
|
previous=data.get("previous"),
|
|
4271
4316
|
results=results,
|
|
4272
4317
|
meta=data.get("meta"),
|
|
@@ -4391,6 +4436,7 @@ class TangoClient:
|
|
|
4391
4436
|
return PaginatedResponse(
|
|
4392
4437
|
count=data["count"],
|
|
4393
4438
|
next=data.get("next"),
|
|
4439
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
4394
4440
|
previous=data.get("previous"),
|
|
4395
4441
|
results=results,
|
|
4396
4442
|
meta=data.get("meta"),
|
|
@@ -4792,6 +4838,7 @@ class TangoClient:
|
|
|
4792
4838
|
return PaginatedResponse(
|
|
4793
4839
|
count=data.get("count", 0),
|
|
4794
4840
|
next=data.get("next"),
|
|
4841
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
4795
4842
|
previous=data.get("previous"),
|
|
4796
4843
|
results=results,
|
|
4797
4844
|
meta=data.get("meta"),
|
|
@@ -4844,6 +4891,7 @@ class TangoClient:
|
|
|
4844
4891
|
return PaginatedResponse(
|
|
4845
4892
|
count=int(data.get("count") or len(data.get("results") or [])),
|
|
4846
4893
|
next=data.get("next"),
|
|
4894
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
4847
4895
|
previous=data.get("previous"),
|
|
4848
4896
|
results=data.get("results") or [],
|
|
4849
4897
|
meta=data.get("meta"),
|
|
@@ -4872,6 +4920,7 @@ class TangoClient:
|
|
|
4872
4920
|
return PaginatedResponse(
|
|
4873
4921
|
count=int(data.get("count") or len(data.get("results") or [])),
|
|
4874
4922
|
next=data.get("next"),
|
|
4923
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
4875
4924
|
previous=data.get("previous"),
|
|
4876
4925
|
results=data.get("results") or [],
|
|
4877
4926
|
meta=data.get("meta"),
|
|
@@ -4966,6 +5015,7 @@ class TangoClient:
|
|
|
4966
5015
|
return PaginatedResponse(
|
|
4967
5016
|
count=data["count"],
|
|
4968
5017
|
next=data.get("next"),
|
|
5018
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
4969
5019
|
previous=data.get("previous"),
|
|
4970
5020
|
results=results,
|
|
4971
5021
|
meta=data.get("meta"),
|
|
@@ -5059,6 +5109,7 @@ class TangoClient:
|
|
|
5059
5109
|
return PaginatedResponse(
|
|
5060
5110
|
count=int(data.get("count", len(results))),
|
|
5061
5111
|
next=data.get("next"),
|
|
5112
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
5062
5113
|
previous=data.get("previous"),
|
|
5063
5114
|
results=results,
|
|
5064
5115
|
meta=data.get("meta"),
|
|
@@ -5244,6 +5295,7 @@ class TangoClient:
|
|
|
5244
5295
|
return PaginatedResponse(
|
|
5245
5296
|
count=int(data.get("count", len(results))),
|
|
5246
5297
|
next=data.get("next"),
|
|
5298
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
5247
5299
|
previous=data.get("previous"),
|
|
5248
5300
|
results=results,
|
|
5249
5301
|
meta=data.get("meta"),
|
|
@@ -5462,6 +5514,7 @@ class TangoClient:
|
|
|
5462
5514
|
return PaginatedResponse(
|
|
5463
5515
|
count=int(data.get("count", 0)),
|
|
5464
5516
|
next=data.get("next"),
|
|
5517
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
5465
5518
|
previous=data.get("previous"),
|
|
5466
5519
|
results=list(data.get("results") or []),
|
|
5467
5520
|
meta=data.get("meta"),
|
|
@@ -5500,6 +5553,7 @@ class TangoClient:
|
|
|
5500
5553
|
return PaginatedResponse(
|
|
5501
5554
|
count=int(data.get("count", 0)),
|
|
5502
5555
|
next=data.get("next"),
|
|
5556
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
5503
5557
|
previous=data.get("previous"),
|
|
5504
5558
|
results=list(data.get("results") or []),
|
|
5505
5559
|
meta=data.get("meta"),
|
|
@@ -5601,6 +5655,7 @@ class TangoClient:
|
|
|
5601
5655
|
return PaginatedResponse(
|
|
5602
5656
|
count=int(data.get("count", 0)),
|
|
5603
5657
|
next=data.get("next"),
|
|
5658
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
5604
5659
|
previous=data.get("previous"),
|
|
5605
5660
|
results=list(data.get("results") or []),
|
|
5606
5661
|
meta=data.get("meta"),
|
|
@@ -5648,6 +5703,7 @@ class TangoClient:
|
|
|
5648
5703
|
return PaginatedResponse(
|
|
5649
5704
|
count=int(data.get("count", 0)),
|
|
5650
5705
|
next=data.get("next"),
|
|
5706
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
5651
5707
|
previous=data.get("previous"),
|
|
5652
5708
|
results=list(data.get("results") or []),
|
|
5653
5709
|
meta=data.get("meta"),
|
|
@@ -5716,6 +5772,7 @@ class TangoClient:
|
|
|
5716
5772
|
return PaginatedResponse(
|
|
5717
5773
|
count=int(data.get("count") or len(results)),
|
|
5718
5774
|
next=data.get("next"),
|
|
5775
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
5719
5776
|
previous=data.get("previous"),
|
|
5720
5777
|
results=results,
|
|
5721
5778
|
cursor=data.get("cursor"),
|
|
@@ -5894,6 +5951,7 @@ class TangoClient:
|
|
|
5894
5951
|
return PaginatedResponse(
|
|
5895
5952
|
count=int(data.get("count", 0)),
|
|
5896
5953
|
next=data.get("next"),
|
|
5954
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
5897
5955
|
previous=data.get("previous"),
|
|
5898
5956
|
results=results,
|
|
5899
5957
|
meta=data.get("meta"),
|
|
@@ -5925,6 +5983,7 @@ class TangoClient:
|
|
|
5925
5983
|
return PaginatedResponse(
|
|
5926
5984
|
count=int(data.get("count", 0)),
|
|
5927
5985
|
next=data.get("next"),
|
|
5986
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
5928
5987
|
previous=data.get("previous"),
|
|
5929
5988
|
results=list(data.get("results") or []),
|
|
5930
5989
|
meta=data.get("meta"),
|
|
@@ -5966,6 +6025,7 @@ class TangoClient:
|
|
|
5966
6025
|
return PaginatedResponse(
|
|
5967
6026
|
count=int(data.get("count", 0)),
|
|
5968
6027
|
next=data.get("next"),
|
|
6028
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
5969
6029
|
previous=data.get("previous"),
|
|
5970
6030
|
results=list(data.get("results") or []),
|
|
5971
6031
|
meta=data.get("meta"),
|
|
@@ -6022,6 +6082,7 @@ class TangoClient:
|
|
|
6022
6082
|
return PaginatedResponse(
|
|
6023
6083
|
count=int(data.get("count") or len(results)),
|
|
6024
6084
|
next=data.get("next"),
|
|
6085
|
+
count_type=data.get(_COUNT_TYPE_KEY),
|
|
6025
6086
|
previous=data.get("previous"),
|
|
6026
6087
|
results=results,
|
|
6027
6088
|
cursor=data.get("cursor"),
|
|
@@ -571,6 +571,12 @@ class Opportunity:
|
|
|
571
571
|
The award fields (``award_date``, ``award_amount``, ``awardee``, ``awardee_uei``) are filled only where SAM.gov posted an award notice, and ``award_amount`` is the text SAM.gov published, not a number.
|
|
572
572
|
SAM.gov often posts an award as its own opportunity; when that award notice references its solicitation, ``solicitation_opportunity_id`` points back to it, and the solicitation's ``awards(...)`` expand lists up to ten of the most recent linked awards, with ``award_count`` giving the full count.
|
|
573
573
|
An award notice that does not reference its solicitation is not linked.
|
|
574
|
+
|
|
575
|
+
The ``meta(...)`` expand counts an opportunity's attachments three ways (Tango API 5.9.0).
|
|
576
|
+
An attachment's ``type`` is ``file`` (a document attached to the notice; only files have extracted text) or ``link`` (a URL the notice lists).
|
|
577
|
+
``meta.files_count`` and ``meta.links_count`` count each, and ``meta.attachments_count`` counts every attachment, links included.
|
|
578
|
+
An attachment of any other type counts only in the total, so files plus links need not equal it.
|
|
579
|
+
``files_count`` and ``links_count`` are null until the record has been counted, so treat null as unknown, not zero.
|
|
574
580
|
"""
|
|
575
581
|
|
|
576
582
|
opportunity_id: str
|
|
@@ -600,6 +606,10 @@ class Notice:
|
|
|
600
606
|
Both must be named, e.g. ``attachments(name,url,doc_role,doc_role_alt)``, because ``attachments(*)`` does not include them.
|
|
601
607
|
An attachment Tango has not classified omits both keys rather than returning null, so read them with ``.get()``.
|
|
602
608
|
A Free-plan request that names them gets the response without them, plus an entry in ``meta.upgrade_hints``.
|
|
609
|
+
|
|
610
|
+
``file_count`` and ``link_count`` (Tango API 5.9.0) split ``attachment_count`` by attachment ``type``: ``file`` is a document attached to the notice (only files have extracted text) and ``link`` is a URL the notice lists.
|
|
611
|
+
``attachment_count`` still counts every attachment, links included, and an attachment of any other type counts only there, so files plus links need not equal it.
|
|
612
|
+
``file_count`` and ``link_count`` are null until the notice has been counted, so treat null as unknown, not zero.
|
|
603
613
|
"""
|
|
604
614
|
|
|
605
615
|
notice_id: str
|
|
@@ -613,6 +623,9 @@ class Notice:
|
|
|
613
623
|
award_amount: str | None = None
|
|
614
624
|
awardee: str | None = None
|
|
615
625
|
awardee_uei: str | None = None
|
|
626
|
+
attachment_count: int | None = None
|
|
627
|
+
file_count: int | None = None
|
|
628
|
+
link_count: int | None = None
|
|
616
629
|
|
|
617
630
|
|
|
618
631
|
@dataclass
|
|
@@ -1454,14 +1467,15 @@ class PaginatedResponse[T]:
|
|
|
1454
1467
|
results: List of result items (type depends on shape parameter)
|
|
1455
1468
|
cursor: Cursor token for cursor-based pagination (None if not available)
|
|
1456
1469
|
meta: Response-level metadata the API attached to this page, when present.
|
|
1457
|
-
Currently carries agency-filter diagnostics: ``resolved_filters`` maps
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
:meth:`agency_warnings` and :meth:`unresolved_agency_tokens`.
|
|
1470
|
+
Currently carries agency-filter diagnostics: ``resolved_filters`` maps each agency filter to the organizations its ``|``-separated tokens resolved to (or ``None``), and ``warnings`` lists human-readable notes about tokens that were dropped or matched loosely.
|
|
1471
|
+
Each ``resolved_filters`` entry that resolved also carries ``matched_by`` (Tango API 5.9.0+), saying how the token matched: ``"key"`` (an organization UUID), ``"code"`` (a 3-digit CGAC or 4-digit FPDS code), ``"name"`` (the organization's name, including a department's everyday name, a spelling variant or a rename), ``"alias"`` (an abbreviation or the organization's own alias) or ``"fuzzy"`` (a looser text match, worth checking against the resolved ``name``).
|
|
1472
|
+
An entry that did not resolve has no ``matched_by``.
|
|
1473
|
+
See :meth:`agency_warnings`, :meth:`unresolved_agency_tokens` and :meth:`resolved_agencies`.
|
|
1462
1474
|
page_metadata: Always ``None`` — the API has never emitted a
|
|
1463
1475
|
``page_metadata`` key. Retained so existing attribute access keeps
|
|
1464
1476
|
working; use ``meta`` instead.
|
|
1477
|
+
count_type: ``"exact"`` or ``"approximate"``, from the API's ``X-Results-CountType`` header; ``None`` when the endpoint doesn't send it.
|
|
1478
|
+
The contract, IDV, opportunity and notice lists can switch to a query-planner estimate past 1,000 matches, which can be well off.
|
|
1465
1479
|
|
|
1466
1480
|
Examples:
|
|
1467
1481
|
>>> from tango import TangoClient, ShapeConfig
|
|
@@ -1482,6 +1496,7 @@ class PaginatedResponse[T]:
|
|
|
1482
1496
|
cursor: str | None = None
|
|
1483
1497
|
meta: dict[str, Any] | None = None
|
|
1484
1498
|
page_metadata: dict[str, Any] | None = None
|
|
1499
|
+
count_type: str | None = None
|
|
1485
1500
|
|
|
1486
1501
|
@property
|
|
1487
1502
|
def agency_warnings(self) -> list[str]:
|
|
@@ -641,6 +641,8 @@ META2_SCHEMA: dict[str, FieldSchema] = {
|
|
|
641
641
|
"attachments_count": FieldSchema(
|
|
642
642
|
name="attachments_count", type=int, is_optional=True, is_list=False
|
|
643
643
|
),
|
|
644
|
+
"files_count": FieldSchema(name="files_count", type=int, is_optional=True, is_list=False),
|
|
645
|
+
"links_count": FieldSchema(name="links_count", type=int, is_optional=True, is_list=False),
|
|
644
646
|
"notice_type": FieldSchema(
|
|
645
647
|
name="notice_type", type=dict, is_optional=True, is_list=False, nested_model="NoticeType"
|
|
646
648
|
),
|
|
@@ -2252,6 +2254,8 @@ GENERATED_OVERLAY: dict[str, dict[str, FieldSchema]] = {
|
|
|
2252
2254
|
"award_date": FieldSchema(name="award_date", type=date, is_optional=True, is_list=False),
|
|
2253
2255
|
"awardee": FieldSchema(name="awardee", type=str, is_optional=True, is_list=False),
|
|
2254
2256
|
"awardee_uei": FieldSchema(name="awardee_uei", type=str, is_optional=True, is_list=False),
|
|
2257
|
+
"file_count": FieldSchema(name="file_count", type=int, is_optional=True, is_list=False),
|
|
2258
|
+
"link_count": FieldSchema(name="link_count", type=int, is_optional=True, is_list=False),
|
|
2255
2259
|
"meta": FieldSchema(
|
|
2256
2260
|
name="meta", type=dict, is_optional=True, is_list=False, nested_model="Meta"
|
|
2257
2261
|
),
|