tango-python 1.0.0__tar.gz → 1.1.1__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.
Files changed (222) hide show
  1. tango_python-1.1.1/.github/workflows/lint.yml +96 -0
  2. {tango_python-1.0.0 → tango_python-1.1.1}/CHANGELOG.md +64 -0
  3. {tango_python-1.0.0 → tango_python-1.1.1}/PKG-INFO +5 -4
  4. {tango_python-1.0.0 → tango_python-1.1.1}/README.md +4 -0
  5. {tango_python-1.0.0 → tango_python-1.1.1}/pyproject.toml +1 -5
  6. {tango_python-1.0.0 → tango_python-1.1.1}/scripts/check_filter_shape_conformance.py +3 -0
  7. {tango_python-1.0.0 → tango_python-1.1.1}/tango/__init__.py +3 -1
  8. {tango_python-1.0.0 → tango_python-1.1.1}/tango/client.py +441 -12
  9. {tango_python-1.0.0 → tango_python-1.1.1}/tango/models.py +149 -10
  10. {tango_python-1.0.0 → tango_python-1.1.1}/tango/shapes/explicit_schemas.py +7 -9
  11. {tango_python-1.0.0 → tango_python-1.1.1}/tango/webhooks/cli.py +2 -2
  12. tango_python-1.1.1/tests/cassettes/TestContractsIntegration.test_combined_filters_work_together +152 -0
  13. tango_python-1.1.1/tests/cassettes/TestContractsIntegration.test_contract_cursor_pagination +347 -0
  14. tango_python-1.0.0/tests/cassettes/TestContractsIntegration.test_contract_cursor_pagination → tango_python-1.1.1/tests/cassettes/TestContractsIntegration.test_contract_data_object_parsing +35 -35
  15. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestContractsIntegration.test_contract_field_types +97 -0
  16. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestContractsIntegration.test_filter_parameter_mappings[keyword-software] +87 -0
  17. tango_python-1.1.1/tests/cassettes/TestContractsIntegration.test_filter_parameter_mappings[psc_code-R425] +175 -0
  18. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestContractsIntegration.test_list_contracts_with_awarding_agency_filter +1 -1
  19. tango_python-1.1.1/tests/cassettes/TestContractsIntegration.test_list_contracts_with_date_range_filter +172 -0
  20. tango_python-1.1.1/tests/cassettes/TestContractsIntegration.test_list_contracts_with_flat +174 -0
  21. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestContractsIntegration.test_list_contracts_with_naics_code_filter +197 -0
  22. tango_python-1.1.1/tests/cassettes/TestContractsIntegration.test_list_contracts_with_shapes[custom-key,piid,recipient(display_name),total_contract_value,award_date] +162 -0
  23. tango_python-1.1.1/tests/cassettes/TestContractsIntegration.test_list_contracts_with_shapes[default-None] +174 -0
  24. tango_python-1.1.1/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 +203 -0
  25. tango_python-1.1.1/tests/cassettes/TestContractsIntegration.test_list_contracts_with_shapes[minimal-key,piid,award_date,recipient(display_name),description,total_contract_value] +174 -0
  26. tango_python-1.1.1/tests/cassettes/TestContractsIntegration.test_new_expiring_filters +173 -0
  27. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestContractsIntegration.test_new_fiscal_year_range_filters +89 -0
  28. tango_python-1.1.1/tests/cassettes/TestContractsIntegration.test_new_identifier_filters +152 -0
  29. tango_python-1.1.1/tests/cassettes/TestContractsIntegration.test_search_contracts_with_filters +172 -0
  30. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestContractsIntegration.test_search_filters_object_with_new_parameters +1 -1
  31. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestContractsIntegration.test_sort_and_order_mapped_to_ordering[asc-] +81 -0
  32. tango_python-1.1.1/tests/cassettes/TestContractsIntegration.test_sort_and_order_mapped_to_ordering[desc--] +174 -0
  33. tango_python-1.1.1/tests/cassettes/TestEdgeCasesIntegration.test_api_schema_stability_detection_contracts +172 -0
  34. tango_python-1.1.1/tests/cassettes/TestEdgeCasesIntegration.test_date_field_parsing_edge_cases +268 -0
  35. tango_python-1.1.1/tests/cassettes/TestEdgeCasesIntegration.test_decimal_field_parsing_edge_cases +252 -0
  36. tango_python-1.1.1/tests/cassettes/TestEdgeCasesIntegration.test_empty_list_responses +152 -0
  37. tango_python-1.1.1/tests/cassettes/TestEdgeCasesIntegration.test_flattened_responses_with_flat_lists +174 -0
  38. tango_python-1.1.1/tests/cassettes/TestEdgeCasesIntegration.test_parsing_nested_objects_with_missing_data +482 -0
  39. tango_python-1.1.1/tests/cassettes/TestEdgeCasesIntegration.test_parsing_null_missing_fields_in_contracts +252 -0
  40. tango_python-1.1.1/tests/cassettes/TestEdgeCasesIntegration.test_parsing_with_minimal_shape_sparse_data +172 -0
  41. tango_python-1.1.1/tests/cassettes/TestTypeHintsIntegration.test_contracts_dict_access[custom-key,piid,description] +164 -0
  42. tango_python-1.1.1/tests/cassettes/TestTypeHintsIntegration.test_contracts_dict_access[minimal-key,piid,award_date,recipient(display_name),description,total_contract_value] +174 -0
  43. tango_python-1.1.1/tests/cassettes/TestTypeHintsIntegration.test_contracts_dict_access[ultra_minimal-key,piid,recipient(display_name),total_contract_value] +162 -0
  44. {tango_python-1.0.0 → tango_python-1.1.1}/tests/test_shapes.py +19 -0
  45. tango_python-1.0.0/.github/workflows/lint.yml +0 -43
  46. tango_python-1.0.0/tests/cassettes/TestContractsIntegration.test_combined_filters_work_together +0 -76
  47. tango_python-1.0.0/tests/cassettes/TestContractsIntegration.test_contract_data_object_parsing +0 -86
  48. tango_python-1.0.0/tests/cassettes/TestContractsIntegration.test_filter_parameter_mappings[psc_code-R425] +0 -86
  49. tango_python-1.0.0/tests/cassettes/TestContractsIntegration.test_list_contracts_with_date_range_filter +0 -86
  50. tango_python-1.0.0/tests/cassettes/TestContractsIntegration.test_list_contracts_with_flat +0 -86
  51. tango_python-1.0.0/tests/cassettes/TestContractsIntegration.test_list_contracts_with_shapes[custom-key,piid,recipient(display_name),total_contract_value,award_date] +0 -81
  52. tango_python-1.0.0/tests/cassettes/TestContractsIntegration.test_list_contracts_with_shapes[default-None] +0 -86
  53. tango_python-1.0.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 -100
  54. tango_python-1.0.0/tests/cassettes/TestContractsIntegration.test_list_contracts_with_shapes[minimal-key,piid,award_date,recipient(display_name),description,total_contract_value] +0 -86
  55. tango_python-1.0.0/tests/cassettes/TestContractsIntegration.test_new_expiring_filters +0 -86
  56. tango_python-1.0.0/tests/cassettes/TestContractsIntegration.test_new_identifier_filters +0 -76
  57. tango_python-1.0.0/tests/cassettes/TestContractsIntegration.test_search_contracts_with_filters +0 -86
  58. tango_python-1.0.0/tests/cassettes/TestContractsIntegration.test_sort_and_order_mapped_to_ordering[desc--] +0 -86
  59. tango_python-1.0.0/tests/cassettes/TestEdgeCasesIntegration.test_api_schema_stability_detection_contracts +0 -86
  60. tango_python-1.0.0/tests/cassettes/TestEdgeCasesIntegration.test_date_field_parsing_edge_cases +0 -131
  61. tango_python-1.0.0/tests/cassettes/TestEdgeCasesIntegration.test_decimal_field_parsing_edge_cases +0 -126
  62. tango_python-1.0.0/tests/cassettes/TestEdgeCasesIntegration.test_empty_list_responses +0 -76
  63. tango_python-1.0.0/tests/cassettes/TestEdgeCasesIntegration.test_flattened_responses_with_flat_lists +0 -86
  64. tango_python-1.0.0/tests/cassettes/TestEdgeCasesIntegration.test_parsing_nested_objects_with_missing_data +0 -224
  65. tango_python-1.0.0/tests/cassettes/TestEdgeCasesIntegration.test_parsing_null_missing_fields_in_contracts +0 -126
  66. tango_python-1.0.0/tests/cassettes/TestEdgeCasesIntegration.test_parsing_with_minimal_shape_sparse_data +0 -86
  67. tango_python-1.0.0/tests/cassettes/TestTypeHintsIntegration.test_contracts_dict_access[custom-key,piid,description] +0 -81
  68. tango_python-1.0.0/tests/cassettes/TestTypeHintsIntegration.test_contracts_dict_access[minimal-key,piid,award_date,recipient(display_name),description,total_contract_value] +0 -86
  69. tango_python-1.0.0/tests/cassettes/TestTypeHintsIntegration.test_contracts_dict_access[ultra_minimal-key,piid,recipient(display_name),total_contract_value] +0 -81
  70. {tango_python-1.0.0 → tango_python-1.1.1}/.github/workflows/docs-dispatch.yml +0 -0
  71. {tango_python-1.0.0 → tango_python-1.1.1}/.github/workflows/publish.yml +0 -0
  72. {tango_python-1.0.0 → tango_python-1.1.1}/.github/workflows/test.yml +0 -0
  73. {tango_python-1.0.0 → tango_python-1.1.1}/.gitignore +0 -0
  74. {tango_python-1.0.0 → tango_python-1.1.1}/LICENSE +0 -0
  75. {tango_python-1.0.0 → tango_python-1.1.1}/docs/API_REFERENCE.md +0 -0
  76. {tango_python-1.0.0 → tango_python-1.1.1}/docs/CLIENT.md +0 -0
  77. {tango_python-1.0.0 → tango_python-1.1.1}/docs/DYNAMIC_MODELS.md +0 -0
  78. {tango_python-1.0.0 → tango_python-1.1.1}/docs/ERRORS.md +0 -0
  79. {tango_python-1.0.0 → tango_python-1.1.1}/docs/PAGINATION.md +0 -0
  80. {tango_python-1.0.0 → tango_python-1.1.1}/docs/SHAPES.md +0 -0
  81. {tango_python-1.0.0 → tango_python-1.1.1}/docs/WEBHOOKS.md +0 -0
  82. {tango_python-1.0.0 → tango_python-1.1.1}/scripts/README.md +0 -0
  83. {tango_python-1.0.0 → tango_python-1.1.1}/scripts/fetch_api_schema.py +0 -0
  84. {tango_python-1.0.0 → tango_python-1.1.1}/scripts/generate_schemas_from_api.py +0 -0
  85. {tango_python-1.0.0 → tango_python-1.1.1}/scripts/pr_review.py +0 -0
  86. {tango_python-1.0.0 → tango_python-1.1.1}/scripts/smoke_api_parity.py +0 -0
  87. {tango_python-1.0.0 → tango_python-1.1.1}/scripts/test_production.py +0 -0
  88. {tango_python-1.0.0 → tango_python-1.1.1}/tango/exceptions.py +0 -0
  89. {tango_python-1.0.0 → tango_python-1.1.1}/tango/shapes/__init__.py +0 -0
  90. {tango_python-1.0.0 → tango_python-1.1.1}/tango/shapes/factory.py +0 -0
  91. {tango_python-1.0.0 → tango_python-1.1.1}/tango/shapes/generator.py +0 -0
  92. {tango_python-1.0.0 → tango_python-1.1.1}/tango/shapes/models.py +0 -0
  93. {tango_python-1.0.0 → tango_python-1.1.1}/tango/shapes/parser.py +0 -0
  94. {tango_python-1.0.0 → tango_python-1.1.1}/tango/shapes/schema.py +0 -0
  95. {tango_python-1.0.0 → tango_python-1.1.1}/tango/shapes/types.py +0 -0
  96. {tango_python-1.0.0 → tango_python-1.1.1}/tango/webhooks/__init__.py +0 -0
  97. {tango_python-1.0.0 → tango_python-1.1.1}/tango/webhooks/receiver.py +0 -0
  98. {tango_python-1.0.0 → tango_python-1.1.1}/tango/webhooks/signing.py +0 -0
  99. {tango_python-1.0.0 → tango_python-1.1.1}/tango/webhooks/simulate.py +0 -0
  100. {tango_python-1.0.0 → tango_python-1.1.1}/tests/__init__.py +0 -0
  101. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestAgenciesIntegration.test_get_agency +0 -0
  102. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestAgenciesIntegration.test_list_agencies +0 -0
  103. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestBusinessTypesIntegration.test_business_type_field_type_validation +0 -0
  104. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestBusinessTypesIntegration.test_business_type_parsing_consistency +0 -0
  105. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestBusinessTypesIntegration.test_list_business_types +0 -0
  106. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestEdgeCasesIntegration.test_api_schema_stability_detection_entities +0 -0
  107. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestEdgeCasesIntegration.test_entity_parsing_with_various_address_formats +0 -0
  108. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestEdgeCasesIntegration.test_list_field_parsing_consistency +0 -0
  109. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestEntitiesIntegration.test_entity_field_types +0 -0
  110. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestEntitiesIntegration.test_entity_location_parsing +0 -0
  111. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestEntitiesIntegration.test_entity_parsing_with_business_types +0 -0
  112. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestEntitiesIntegration.test_entity_with_various_identifiers +0 -0
  113. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestEntitiesIntegration.test_get_entity_by_uei +0 -0
  114. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestEntitiesIntegration.test_list_entities_with_flat +0 -0
  115. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestEntitiesIntegration.test_list_entities_with_search +0 -0
  116. {tango_python-1.0.0 → tango_python-1.1.1}/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
  117. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestEntitiesIntegration.test_list_entities_with_shapes[custom-uei,legal_business_name,cage_code] +0 -0
  118. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestEntitiesIntegration.test_list_entities_with_shapes[minimal-uei,legal_business_name,cage_code,business_types] +0 -0
  119. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestEntitiesIntegration.test_list_entities_with_shapes[with_address-uei,legal_business_name,cage_code,business_types,physical_address] +0 -0
  120. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestForecastsIntegration.test_forecast_field_types +0 -0
  121. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestForecastsIntegration.test_list_forecasts_with_shapes[custom-id,title,anticipated_award_date] +0 -0
  122. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestForecastsIntegration.test_list_forecasts_with_shapes[default-None] +0 -0
  123. {tango_python-1.0.0 → tango_python-1.1.1}/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
  124. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestForecastsIntegration.test_list_forecasts_with_shapes[minimal-id,title,anticipated_award_date,fiscal_year,naics_code,status] +0 -0
  125. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestGrantsIntegration.test_grant_field_types +0 -0
  126. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestGrantsIntegration.test_grant_pagination +0 -0
  127. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestGrantsIntegration.test_list_grants_with_shapes[custom-grant_id,title,opportunity_number] +0 -0
  128. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestGrantsIntegration.test_list_grants_with_shapes[default-None] +0 -0
  129. {tango_python-1.0.0 → tango_python-1.1.1}/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
  130. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestGrantsIntegration.test_list_grants_with_shapes[minimal-grant_id,opportunity_number,title,status(-),agency_code] +0 -0
  131. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestIDVsIntegration.test_get_idv_uses_default_shape +0 -0
  132. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestIDVsIntegration.test_list_idv_awards_uses_default_shape +0 -0
  133. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestIDVsIntegration.test_list_idv_child_idvs_uses_default_shape +0 -0
  134. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestIDVsIntegration.test_list_idv_transactions +0 -0
  135. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestIDVsIntegration.test_list_idvs_uses_default_shape_and_keyset_params +0 -0
  136. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestITDashboardIntegration.test_filter_by_agency_code +0 -0
  137. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestITDashboardIntegration.test_filter_by_agency_name_text +0 -0
  138. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestITDashboardIntegration.test_filter_by_cio_rating +0 -0
  139. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestITDashboardIntegration.test_filter_by_cio_rating_max +0 -0
  140. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestITDashboardIntegration.test_filter_by_performance_risk +0 -0
  141. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestITDashboardIntegration.test_filter_by_type_of_investment +0 -0
  142. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestITDashboardIntegration.test_filter_by_updated_time_range +0 -0
  143. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestITDashboardIntegration.test_funding_and_cio_evaluation_expansions +0 -0
  144. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestITDashboardIntegration.test_get_itdashboard_investment_by_uii +0 -0
  145. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestITDashboardIntegration.test_itdashboard_pagination +0 -0
  146. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestITDashboardIntegration.test_list_itdashboard_investments_with_search +0 -0
  147. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestITDashboardIntegration.test_list_itdashboard_investments_with_shapes[custom-uii,agency_name,investment_title,updated_time] +0 -0
  148. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestITDashboardIntegration.test_list_itdashboard_investments_with_shapes[default-None] +0 -0
  149. {tango_python-1.0.0 → tango_python-1.1.1}/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
  150. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestNaicsIntegration.test_list_naics +0 -0
  151. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestNoticesIntegration.test_list_notices_with_shapes[custom-notice_id,title,solicitation_number] +0 -0
  152. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestNoticesIntegration.test_list_notices_with_shapes[default-None] +0 -0
  153. {tango_python-1.0.0 → tango_python-1.1.1}/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
  154. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestNoticesIntegration.test_list_notices_with_shapes[minimal-notice_id,title,solicitation_number,posted_date] +0 -0
  155. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestNoticesIntegration.test_notice_field_types +0 -0
  156. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestNoticesIntegration.test_notice_pagination +0 -0
  157. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestNoticesIntegration.test_notice_with_meta_fields +0 -0
  158. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestOTAsIntegration.test_get_ota +0 -0
  159. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestOTAsIntegration.test_list_otas +0 -0
  160. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestOTIDVsIntegration.test_get_otidv +0 -0
  161. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestOTIDVsIntegration.test_list_otidvs +0 -0
  162. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestOfficesIntegration.test_get_office +0 -0
  163. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestOfficesIntegration.test_list_offices +0 -0
  164. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestOpportunitiesIntegration.test_list_opportunities_with_shapes[custom-opportunity_id,title,solicitation_number] +0 -0
  165. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestOpportunitiesIntegration.test_list_opportunities_with_shapes[default-None] +0 -0
  166. {tango_python-1.0.0 → tango_python-1.1.1}/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
  167. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestOpportunitiesIntegration.test_list_opportunities_with_shapes[minimal-opportunity_id,title,solicitation_number,response_deadline,active] +0 -0
  168. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestOpportunitiesIntegration.test_opportunity_field_types +0 -0
  169. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestOrganizationsIntegration.test_get_organization +0 -0
  170. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestOrganizationsIntegration.test_list_organizations +0 -0
  171. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestProtestsIntegration.test_get_protest_by_case_id +0 -0
  172. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestProtestsIntegration.test_list_protests_with_filter +0 -0
  173. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestProtestsIntegration.test_list_protests_with_shapes[custom-case_id,title,source_system,outcome] +0 -0
  174. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestProtestsIntegration.test_list_protests_with_shapes[default-None] +0 -0
  175. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestProtestsIntegration.test_list_protests_with_shapes[minimal-case_id,case_number,title,source_system,outcome,filed_date] +0 -0
  176. {tango_python-1.0.0 → tango_python-1.1.1}/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
  177. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestProtestsIntegration.test_protest_pagination +0 -0
  178. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestSubawardsIntegration.test_list_subawards +0 -0
  179. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestTypeHintsIntegration.test_entities_dict_access[minimal-uei,legal_business_name,cage_code,business_types] +0 -0
  180. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestTypeHintsIntegration.test_entities_dict_access[with_address-uei,legal_business_name,cage_code,business_types,physical_address] +0 -0
  181. {tango_python-1.0.0 → tango_python-1.1.1}/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
  182. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestTypeHintsIntegration.test_notices_dict_access[minimal-notice_id,title,solicitation_number,posted_date] +0 -0
  183. {tango_python-1.0.0 → tango_python-1.1.1}/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
  184. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestTypeHintsIntegration.test_opportunities_dict_access[minimal-opportunity_id,title,solicitation_number,response_deadline,active] +0 -0
  185. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestVehiclesIntegration.test_get_vehicle_supports_joiner_and_flat_lists +0 -0
  186. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestVehiclesIntegration.test_get_vehicle_with_metrics_expansion +0 -0
  187. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestVehiclesIntegration.test_list_vehicle_awardees_uses_default_shape +0 -0
  188. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestVehiclesIntegration.test_list_vehicle_orders_uses_default_shape +0 -0
  189. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestVehiclesIntegration.test_list_vehicles_uses_default_shape_and_search +0 -0
  190. {tango_python-1.0.0 → tango_python-1.1.1}/tests/cassettes/TestVehiclesIntegration.test_list_vehicles_with_ordering +0 -0
  191. {tango_python-1.0.0 → tango_python-1.1.1}/tests/conftest.py +0 -0
  192. {tango_python-1.0.0 → tango_python-1.1.1}/tests/integration/README.md +0 -0
  193. {tango_python-1.0.0 → tango_python-1.1.1}/tests/integration/__init__.py +0 -0
  194. {tango_python-1.0.0 → tango_python-1.1.1}/tests/integration/conftest.py +0 -0
  195. {tango_python-1.0.0 → tango_python-1.1.1}/tests/integration/test_agencies_integration.py +0 -0
  196. {tango_python-1.0.0 → tango_python-1.1.1}/tests/integration/test_contracts_integration.py +0 -0
  197. {tango_python-1.0.0 → tango_python-1.1.1}/tests/integration/test_edge_cases_integration.py +0 -0
  198. {tango_python-1.0.0 → tango_python-1.1.1}/tests/integration/test_entities_integration.py +0 -0
  199. {tango_python-1.0.0 → tango_python-1.1.1}/tests/integration/test_forecasts_integration.py +0 -0
  200. {tango_python-1.0.0 → tango_python-1.1.1}/tests/integration/test_grants_integration.py +0 -0
  201. {tango_python-1.0.0 → tango_python-1.1.1}/tests/integration/test_itdashboard_integration.py +0 -0
  202. {tango_python-1.0.0 → tango_python-1.1.1}/tests/integration/test_naics_integration.py +0 -0
  203. {tango_python-1.0.0 → tango_python-1.1.1}/tests/integration/test_notices_integration.py +0 -0
  204. {tango_python-1.0.0 → tango_python-1.1.1}/tests/integration/test_offices_integration.py +0 -0
  205. {tango_python-1.0.0 → tango_python-1.1.1}/tests/integration/test_opportunities_integration.py +0 -0
  206. {tango_python-1.0.0 → tango_python-1.1.1}/tests/integration/test_organizations_integration.py +0 -0
  207. {tango_python-1.0.0 → tango_python-1.1.1}/tests/integration/test_otas_otidvs_integration.py +0 -0
  208. {tango_python-1.0.0 → tango_python-1.1.1}/tests/integration/test_protests_integration.py +0 -0
  209. {tango_python-1.0.0 → tango_python-1.1.1}/tests/integration/test_reference_data_integration.py +0 -0
  210. {tango_python-1.0.0 → tango_python-1.1.1}/tests/integration/test_subawards_integration.py +0 -0
  211. {tango_python-1.0.0 → tango_python-1.1.1}/tests/integration/test_vehicles_idvs_integration.py +0 -0
  212. {tango_python-1.0.0 → tango_python-1.1.1}/tests/integration/validation.py +0 -0
  213. {tango_python-1.0.0 → tango_python-1.1.1}/tests/production/__init__.py +0 -0
  214. {tango_python-1.0.0 → tango_python-1.1.1}/tests/production/conftest.py +0 -0
  215. {tango_python-1.0.0 → tango_python-1.1.1}/tests/production/test_production_smoke.py +0 -0
  216. {tango_python-1.0.0 → tango_python-1.1.1}/tests/test_api_parity.py +0 -0
  217. {tango_python-1.0.0 → tango_python-1.1.1}/tests/test_client.py +0 -0
  218. {tango_python-1.0.0 → tango_python-1.1.1}/tests/test_models.py +0 -0
  219. {tango_python-1.0.0 → tango_python-1.1.1}/tests/test_webhooks_cli.py +0 -0
  220. {tango_python-1.0.0 → tango_python-1.1.1}/tests/test_webhooks_receiver.py +0 -0
  221. {tango_python-1.0.0 → tango_python-1.1.1}/tests/test_webhooks_signing.py +0 -0
  222. {tango_python-1.0.0 → tango_python-1.1.1}/tests/test_webhooks_simulate.py +0 -0
@@ -0,0 +1,96 @@
1
+ name: Linting
2
+
3
+ # Lint gate runs on every PR and push to main.
4
+ #
5
+ # - ruff format + ruff check are HARD gates (block the PR).
6
+ # - mypy is ADVISORY for now (continue-on-error): the package carries ~28
7
+ # pre-existing type errors that predate CI enforcement. Tracked for burn-down
8
+ # in makegov/tango-python; flip `continue-on-error` off once that's clear.
9
+ # - The SDK filter/shape conformance check needs the canonical manifest from the
10
+ # private makegov/tango repo, which requires a TANGO_API_REPO_ACCESS_TOKEN
11
+ # secret the public CI does not have. The conformance job SKIPS cleanly when
12
+ # the token is absent (rather than failing red) and becomes a real gate the
13
+ # moment the secret is configured.
14
+ on:
15
+ workflow_dispatch:
16
+ push:
17
+ branches: [ main ]
18
+ pull_request:
19
+ branches: [ main ]
20
+
21
+ jobs:
22
+ lint:
23
+ runs-on: ubuntu-latest
24
+
25
+ steps:
26
+ - uses: actions/checkout@v4
27
+
28
+ - name: Install uv
29
+ uses: astral-sh/setup-uv@v4
30
+ with:
31
+ version: "latest"
32
+
33
+ - name: Set up Python
34
+ run: uv python install 3.12
35
+
36
+ - name: Install dependencies
37
+ run: uv sync --all-extras
38
+
39
+ - name: Check formatting with ruff
40
+ run: uv run ruff format --check tango/
41
+
42
+ - name: Lint with ruff
43
+ run: uv run ruff check tango/
44
+
45
+ - name: Type check with mypy (advisory)
46
+ continue-on-error: true
47
+ run: uv run mypy tango/
48
+
49
+ conformance:
50
+ # Requires the canonical filter_shape manifest from the private makegov/tango
51
+ # repo. When TANGO_API_REPO_ACCESS_TOKEN is not configured, every real step
52
+ # is skipped and the job passes (rather than failing on an empty token).
53
+ # Configure the secret to turn this into a hard gate automatically.
54
+ runs-on: ubuntu-latest
55
+
56
+ steps:
57
+ - name: Determine token availability
58
+ id: gate
59
+ env:
60
+ TANGO_API_REPO_ACCESS_TOKEN: ${{ secrets.TANGO_API_REPO_ACCESS_TOKEN }}
61
+ run: |
62
+ if [ -n "$TANGO_API_REPO_ACCESS_TOKEN" ]; then
63
+ echo "ready=true" >> "$GITHUB_OUTPUT"
64
+ else
65
+ echo "ready=false" >> "$GITHUB_OUTPUT"
66
+ echo "::notice::Skipping SDK conformance check — TANGO_API_REPO_ACCESS_TOKEN not configured."
67
+ fi
68
+
69
+ - uses: actions/checkout@v4
70
+ if: steps.gate.outputs.ready == 'true'
71
+
72
+ - name: Checkout tango API repo (manifest source)
73
+ if: steps.gate.outputs.ready == 'true'
74
+ uses: actions/checkout@v4
75
+ with:
76
+ repository: makegov/tango
77
+ path: tango-api
78
+ token: ${{ secrets.TANGO_API_REPO_ACCESS_TOKEN }}
79
+
80
+ - name: Install uv
81
+ if: steps.gate.outputs.ready == 'true'
82
+ uses: astral-sh/setup-uv@v4
83
+ with:
84
+ version: "latest"
85
+
86
+ - name: Set up Python
87
+ if: steps.gate.outputs.ready == 'true'
88
+ run: uv python install 3.12
89
+
90
+ - name: Install dependencies
91
+ if: steps.gate.outputs.ready == 'true'
92
+ run: uv sync --all-extras
93
+
94
+ - name: Check SDK filter/shape conformance
95
+ if: steps.gate.outputs.ready == 'true'
96
+ run: uv run python scripts/check_filter_shape_conformance.py --manifest tango-api/contracts/filter_shape_contract.json
@@ -7,6 +7,70 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.1.1] - 2026-05-29
11
+
12
+ ### Removed
13
+ - The `notebooks` optional extra (`jupyter`, `ipykernel`). It only powered local
14
+ editing of `docs/quick_start.ipynb`, which still renders on GitHub/PyPI without
15
+ it, and its transitive tree (jupyter-server, jupyterlab, nbconvert, tornado,
16
+ etc.) accounted for the bulk of the repo's open Dependabot alerts. Contributors
17
+ who want to re-run the notebook can `pip install jupyter` directly. The shipped
18
+ SDK is unaffected — its only runtime dependency remains `httpx`.
19
+
20
+ ### Changed
21
+ - Refreshed the dev/test dependency lock to clear the remaining Dependabot
22
+ alerts (patched `idna`, `pygments`, `pytest`, `python-dotenv`; dropped
23
+ `urllib3`/`requests` transitives). Dev-tool majors moved forward
24
+ (`mypy` 1.18→2.1, `pytest` 8→9, `ruff` 0.14→0.15, `vcrpy` 7→8); all lint,
25
+ type, and test gates stay green. No change to the shipped SDK's runtime deps.
26
+
27
+ ## [1.1.0] - 2026-05-29
28
+
29
+ ### Fixed
30
+ - `_parse_webhook_alert`: aligned the parser output with the `WebhookAlert`
31
+ type contract. Sparse server payloads now hydrate `query_type` and `filters`
32
+ as `""` / `{}` (matching their declared non-null types) rather than `None`,
33
+ and `status` is typed as the `Literal["active", "paused"]` the model promises.
34
+ Clears the four type-check errors this introduced; no change for full payloads.
35
+ - `Contract` model: removed dead fields (`id`, `award_id`, `recipient_name`,
36
+ `award_amount`, `awarding_agency`, `funding_agency`) and added the real API
37
+ fields (`key`, `piid`, `obligated`, `total_contract_value`,
38
+ `base_and_exercised_options_value`, `awarding_office`, `funding_office`,
39
+ `naics_code`, `psc_code`, `set_aside`, `solicitation_identifier`,
40
+ `parent_award`, `legislative_mandates`, `subawards_summary`,
41
+ `place_of_performance`). The deprecated fields remain declared with `None`
42
+ defaults for one minor cycle (they never returned data) and will be removed
43
+ in `2.0.0`. New `OrganizationOfficePayload` dataclass for the office fields.
44
+ (`Contract` is a documentation-only dataclass — not instantiated or exported
45
+ — so there is no runtime impact.)
46
+ - `list_contracts`: no longer sends `page=1` to the cursor-only `/api/contracts/`
47
+ endpoint. When no cursor is supplied, neither `page` nor `cursor` is sent and
48
+ the API returns the first page by default.
49
+ - Shape validation: registered the `ContractOrIDVCompetition` nested schema
50
+ (alias of `Competition`) so nested selections like
51
+ `competition(extent_competed,number_of_offers_received)` on contract / IDV
52
+ shapes validate instead of raising `ShapeValidationError`.
53
+
54
+ ### Added
55
+ - Budget accounts surface (tango v4.6.8): `list_budget_accounts`,
56
+ `get_budget_account`, `get_budget_account_quarters`,
57
+ `get_budget_account_recipients`. New `BudgetAccount` dataclass exported from
58
+ the top-level package, plus `ShapeConfig.BUDGET_ACCOUNTS_MINIMAL`.
59
+ - Singleton detail GETs: `get_contract`, `get_contract_subawards`,
60
+ `get_contract_transactions`, `get_forecast`, `get_grant`, `get_notice`,
61
+ `get_opportunity`, `get_subaward`.
62
+ - `get_entity_budget_flows(uei)` for `/api/entities/{uei}/budget-flows/`.
63
+ - `list_otidv_awards(key)` for `/api/otidvs/{key}/awards/` (parity with Node).
64
+ - `grant_id` filter kwarg on `list_grants` (supports multi-value OR via `|`).
65
+
66
+ ### CI
67
+ - Re-enabled `lint.yml` as a PR + push-to-main gate. `ruff format` and
68
+ `ruff check` are hard gates; `mypy` runs advisory (continue-on-error) pending
69
+ burn-down of ~28 pre-existing type errors. The filter/shape conformance check
70
+ is a separate job that skips cleanly until a `TANGO_API_REPO_ACCESS_TOKEN`
71
+ secret for the private manifest repo is configured, at which point it becomes
72
+ a hard gate.
73
+
10
74
  ## [1.0.0] - 2026-05-13
11
75
 
12
76
  > First stable release. `tango-python` is now at full API parity with the
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tango-python
3
- Version: 1.0.0
3
+ Version: 1.1.1
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
@@ -48,15 +48,16 @@ Requires-Dist: pytest>=8.0; extra == 'dev'
48
48
  Requires-Dist: python-dotenv>=1.0.0; extra == 'dev'
49
49
  Requires-Dist: pyyaml>=6.0; extra == 'dev'
50
50
  Requires-Dist: ruff>=0.3.0; extra == 'dev'
51
- Provides-Extra: notebooks
52
- Requires-Dist: ipykernel>=6.25.0; extra == 'notebooks'
53
- Requires-Dist: jupyter>=1.0.0; extra == 'notebooks'
54
51
  Provides-Extra: webhooks
55
52
  Requires-Dist: click>=8.1; extra == 'webhooks'
56
53
  Description-Content-Type: text/markdown
57
54
 
58
55
  # Tango Python SDK
59
56
 
57
+ [![PyPI](https://img.shields.io/pypi/v/tango-python.svg)](https://pypi.org/project/tango-python/)
58
+ [![Python Versions](https://img.shields.io/pypi/pyversions/tango-python.svg)](https://pypi.org/project/tango-python/)
59
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
60
+
60
61
  A modern Python SDK for the [Tango API](https://tango.makegov.com) by MakeGov, featuring dynamic response shaping and comprehensive type hints.
61
62
 
62
63
  ## Features
@@ -1,5 +1,9 @@
1
1
  # Tango Python SDK
2
2
 
3
+ [![PyPI](https://img.shields.io/pypi/v/tango-python.svg)](https://pypi.org/project/tango-python/)
4
+ [![Python Versions](https://img.shields.io/pypi/pyversions/tango-python.svg)](https://pypi.org/project/tango-python/)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
6
+
3
7
  A modern Python SDK for the [Tango API](https://tango.makegov.com) by MakeGov, featuring dynamic response shaping and comprehensive type hints.
4
8
 
5
9
  ## Features
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "tango-python"
7
- version = "1.0.0"
7
+ version = "1.1.1"
8
8
  description = "Python SDK for the Tango API"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -37,10 +37,6 @@ dev = [
37
37
  "python-dotenv>=1.0.0",
38
38
  "pyyaml>=6.0",
39
39
  ]
40
- notebooks = [
41
- "jupyter>=1.0.0",
42
- "ipykernel>=6.25.0",
43
- ]
44
40
  webhooks = [
45
41
  "click>=8.1",
46
42
  ]
@@ -51,6 +51,7 @@ RESOURCE_TO_METHOD: dict[str, str] = {
51
51
  "naics": "list_naics",
52
52
  "gsa_elibrary_contracts": "list_gsa_elibrary_contracts",
53
53
  "itdashboard": "list_itdashboard_investments",
54
+ "budget_accounts": "list_budget_accounts",
54
55
  # Resources not yet implemented in SDK
55
56
  "offices": None,
56
57
  }
@@ -62,6 +63,7 @@ def get_shape_config_entries() -> list[tuple[str, str, type[Any]]]:
62
63
  IDV,
63
64
  OTA,
64
65
  OTIDV,
66
+ BudgetAccount,
65
67
  Contract,
66
68
  Entity,
67
69
  Forecast,
@@ -110,6 +112,7 @@ def get_shape_config_entries() -> list[tuple[str, str, type[Any]]]:
110
112
  ShapeConfig.ITDASHBOARD_INVESTMENTS_COMPREHENSIVE,
111
113
  ITDashboardInvestment,
112
114
  ),
115
+ ("BUDGET_ACCOUNTS_MINIMAL", ShapeConfig.BUDGET_ACCOUNTS_MINIMAL, BudgetAccount),
113
116
  ]
114
117
  for name, shape_str, model_cls in configs:
115
118
  entries.append((name, shape_str, model_cls))
@@ -9,6 +9,7 @@ from .exceptions import (
9
9
  TangoValidationError,
10
10
  )
11
11
  from .models import (
12
+ BudgetAccount,
12
13
  GsaElibraryContract,
13
14
  ITDashboardInvestment,
14
15
  PaginatedResponse,
@@ -43,7 +44,7 @@ from .webhooks import (
43
44
  )
44
45
  from .webhooks.receiver import Delivery, WebhookReceiver
45
46
 
46
- __version__ = "1.0.0"
47
+ __version__ = "1.1.1"
47
48
  __all__ = [
48
49
  "TangoClient",
49
50
  "TangoAPIError",
@@ -54,6 +55,7 @@ __all__ = [
54
55
  "RateLimitInfo",
55
56
  "ResolveCandidate",
56
57
  "ResolveResult",
58
+ "BudgetAccount",
57
59
  "GsaElibraryContract",
58
60
  "ITDashboardInvestment",
59
61
  "PaginatedResponse",