tango-python 0.4.4__tar.gz → 0.5.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.
Files changed (182) hide show
  1. {tango_python-0.4.4 → tango_python-0.5.0}/CHANGELOG.md +5 -0
  2. {tango_python-0.4.4 → tango_python-0.5.0}/PKG-INFO +1 -1
  3. {tango_python-0.4.4 → tango_python-0.5.0}/pyproject.toml +1 -1
  4. {tango_python-0.4.4 → tango_python-0.5.0}/scripts/check_filter_shape_conformance.py +12 -0
  5. {tango_python-0.4.4 → tango_python-0.5.0}/tango/__init__.py +3 -1
  6. {tango_python-0.4.4 → tango_python-0.5.0}/tango/client.py +107 -0
  7. {tango_python-0.4.4 → tango_python-0.5.0}/tango/models.py +54 -0
  8. {tango_python-0.4.4 → tango_python-0.5.0}/tango/shapes/explicit_schemas.py +63 -0
  9. tango_python-0.5.0/tests/cassettes/TestITDashboardIntegration.test_filter_by_agency_code +95 -0
  10. tango_python-0.5.0/tests/cassettes/TestITDashboardIntegration.test_filter_by_agency_name_text +93 -0
  11. tango_python-0.5.0/tests/cassettes/TestITDashboardIntegration.test_filter_by_cio_rating +94 -0
  12. tango_python-0.5.0/tests/cassettes/TestITDashboardIntegration.test_filter_by_cio_rating_max +93 -0
  13. tango_python-0.5.0/tests/cassettes/TestITDashboardIntegration.test_filter_by_performance_risk +94 -0
  14. tango_python-0.5.0/tests/cassettes/TestITDashboardIntegration.test_filter_by_type_of_investment +94 -0
  15. tango_python-0.5.0/tests/cassettes/TestITDashboardIntegration.test_filter_by_updated_time_range +93 -0
  16. tango_python-0.5.0/tests/cassettes/TestITDashboardIntegration.test_funding_and_cio_evaluation_expansions +88 -0
  17. tango_python-0.5.0/tests/cassettes/TestITDashboardIntegration.test_get_itdashboard_investment_by_uii +314 -0
  18. tango_python-0.5.0/tests/cassettes/TestITDashboardIntegration.test_itdashboard_pagination +364 -0
  19. tango_python-0.5.0/tests/cassettes/TestITDashboardIntegration.test_list_itdashboard_investments_with_search +182 -0
  20. tango_python-0.5.0/tests/cassettes/TestITDashboardIntegration.test_list_itdashboard_investments_with_shapes[custom-uii,agency_name,investment_title,updated_time] +164 -0
  21. tango_python-0.5.0/tests/cassettes/TestITDashboardIntegration.test_list_itdashboard_investments_with_shapes[default-None] +184 -0
  22. tango_python-0.5.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] +184 -0
  23. tango_python-0.5.0/tests/integration/test_itdashboard_integration.py +302 -0
  24. {tango_python-0.4.4 → tango_python-0.5.0}/tests/test_client.py +143 -0
  25. {tango_python-0.4.4 → tango_python-0.5.0}/uv.lock +1 -1
  26. {tango_python-0.4.4 → tango_python-0.5.0}/.env.example +0 -0
  27. {tango_python-0.4.4 → tango_python-0.5.0}/.github/workflows/lint.yml +0 -0
  28. {tango_python-0.4.4 → tango_python-0.5.0}/.github/workflows/publish.yml +0 -0
  29. {tango_python-0.4.4 → tango_python-0.5.0}/.github/workflows/test.yml +0 -0
  30. {tango_python-0.4.4 → tango_python-0.5.0}/.gitignore +0 -0
  31. {tango_python-0.4.4 → tango_python-0.5.0}/LICENSE +0 -0
  32. {tango_python-0.4.4 → tango_python-0.5.0}/README.md +0 -0
  33. {tango_python-0.4.4 → tango_python-0.5.0}/ROADMAP.md +0 -0
  34. {tango_python-0.4.4 → tango_python-0.5.0}/docs/API_REFERENCE.md +0 -0
  35. {tango_python-0.4.4 → tango_python-0.5.0}/docs/DEVELOPERS.md +0 -0
  36. {tango_python-0.4.4 → tango_python-0.5.0}/docs/SHAPES.md +0 -0
  37. {tango_python-0.4.4 → tango_python-0.5.0}/docs/quick_start.ipynb +0 -0
  38. {tango_python-0.4.4 → tango_python-0.5.0}/scripts/README.md +0 -0
  39. {tango_python-0.4.4 → tango_python-0.5.0}/scripts/fetch_api_schema.py +0 -0
  40. {tango_python-0.4.4 → tango_python-0.5.0}/scripts/generate_schemas_from_api.py +0 -0
  41. {tango_python-0.4.4 → tango_python-0.5.0}/scripts/pr_review.py +0 -0
  42. {tango_python-0.4.4 → tango_python-0.5.0}/scripts/test_production.py +0 -0
  43. {tango_python-0.4.4 → tango_python-0.5.0}/tango/exceptions.py +0 -0
  44. {tango_python-0.4.4 → tango_python-0.5.0}/tango/shapes/__init__.py +0 -0
  45. {tango_python-0.4.4 → tango_python-0.5.0}/tango/shapes/factory.py +0 -0
  46. {tango_python-0.4.4 → tango_python-0.5.0}/tango/shapes/generator.py +0 -0
  47. {tango_python-0.4.4 → tango_python-0.5.0}/tango/shapes/models.py +0 -0
  48. {tango_python-0.4.4 → tango_python-0.5.0}/tango/shapes/parser.py +0 -0
  49. {tango_python-0.4.4 → tango_python-0.5.0}/tango/shapes/schema.py +0 -0
  50. {tango_python-0.4.4 → tango_python-0.5.0}/tango/shapes/types.py +0 -0
  51. {tango_python-0.4.4 → tango_python-0.5.0}/tests/__init__.py +0 -0
  52. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestAgenciesIntegration.test_get_agency +0 -0
  53. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestAgenciesIntegration.test_list_agencies +0 -0
  54. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestBusinessTypesIntegration.test_business_type_field_type_validation +0 -0
  55. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestBusinessTypesIntegration.test_business_type_parsing_consistency +0 -0
  56. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestBusinessTypesIntegration.test_list_business_types +0 -0
  57. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestContractsIntegration.test_combined_filters_work_together +0 -0
  58. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestContractsIntegration.test_contract_cursor_pagination +0 -0
  59. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestContractsIntegration.test_contract_data_object_parsing +0 -0
  60. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestContractsIntegration.test_contract_field_types +0 -0
  61. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestContractsIntegration.test_filter_parameter_mappings[keyword-software] +0 -0
  62. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestContractsIntegration.test_filter_parameter_mappings[psc_code-R425] +0 -0
  63. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestContractsIntegration.test_list_contracts_with_awarding_agency_filter +0 -0
  64. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestContractsIntegration.test_list_contracts_with_date_range_filter +0 -0
  65. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestContractsIntegration.test_list_contracts_with_flat +0 -0
  66. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestContractsIntegration.test_list_contracts_with_naics_code_filter +0 -0
  67. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestContractsIntegration.test_list_contracts_with_shapes[custom-key,piid,recipient(display_name),total_contract_value,award_date] +0 -0
  68. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestContractsIntegration.test_list_contracts_with_shapes[default-None] +0 -0
  69. {tango_python-0.4.4 → tango_python-0.5.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
  70. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestContractsIntegration.test_list_contracts_with_shapes[minimal-key,piid,award_date,recipient(display_name),description,total_contract_value] +0 -0
  71. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestContractsIntegration.test_new_expiring_filters +0 -0
  72. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestContractsIntegration.test_new_fiscal_year_range_filters +0 -0
  73. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestContractsIntegration.test_new_identifier_filters +0 -0
  74. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestContractsIntegration.test_search_contracts_with_filters +0 -0
  75. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestContractsIntegration.test_search_filters_object_with_new_parameters +0 -0
  76. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestContractsIntegration.test_sort_and_order_mapped_to_ordering[asc-] +0 -0
  77. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestContractsIntegration.test_sort_and_order_mapped_to_ordering[desc--] +0 -0
  78. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestEdgeCasesIntegration.test_api_schema_stability_detection_contracts +0 -0
  79. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestEdgeCasesIntegration.test_api_schema_stability_detection_entities +0 -0
  80. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestEdgeCasesIntegration.test_date_field_parsing_edge_cases +0 -0
  81. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestEdgeCasesIntegration.test_decimal_field_parsing_edge_cases +0 -0
  82. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestEdgeCasesIntegration.test_empty_list_responses +0 -0
  83. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestEdgeCasesIntegration.test_entity_parsing_with_various_address_formats +0 -0
  84. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestEdgeCasesIntegration.test_flattened_responses_with_flat_lists +0 -0
  85. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestEdgeCasesIntegration.test_list_field_parsing_consistency +0 -0
  86. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestEdgeCasesIntegration.test_parsing_nested_objects_with_missing_data +0 -0
  87. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestEdgeCasesIntegration.test_parsing_null_missing_fields_in_contracts +0 -0
  88. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestEdgeCasesIntegration.test_parsing_with_minimal_shape_sparse_data +0 -0
  89. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestEntitiesIntegration.test_entity_field_types +0 -0
  90. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestEntitiesIntegration.test_entity_location_parsing +0 -0
  91. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestEntitiesIntegration.test_entity_parsing_with_business_types +0 -0
  92. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestEntitiesIntegration.test_entity_with_various_identifiers +0 -0
  93. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestEntitiesIntegration.test_get_entity_by_uei +0 -0
  94. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestEntitiesIntegration.test_list_entities_with_flat +0 -0
  95. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestEntitiesIntegration.test_list_entities_with_search +0 -0
  96. {tango_python-0.4.4 → tango_python-0.5.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
  97. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestEntitiesIntegration.test_list_entities_with_shapes[custom-uei,legal_business_name,cage_code] +0 -0
  98. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestEntitiesIntegration.test_list_entities_with_shapes[minimal-uei,legal_business_name,cage_code,business_types] +0 -0
  99. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestEntitiesIntegration.test_list_entities_with_shapes[with_address-uei,legal_business_name,cage_code,business_types,physical_address] +0 -0
  100. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestForecastsIntegration.test_forecast_field_types +0 -0
  101. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestForecastsIntegration.test_list_forecasts_with_shapes[custom-id,title,anticipated_award_date] +0 -0
  102. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestForecastsIntegration.test_list_forecasts_with_shapes[default-None] +0 -0
  103. {tango_python-0.4.4 → tango_python-0.5.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
  104. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestForecastsIntegration.test_list_forecasts_with_shapes[minimal-id,title,anticipated_award_date,fiscal_year,naics_code,status] +0 -0
  105. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestGrantsIntegration.test_grant_field_types +0 -0
  106. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestGrantsIntegration.test_grant_pagination +0 -0
  107. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestGrantsIntegration.test_list_grants_with_shapes[custom-grant_id,title,opportunity_number] +0 -0
  108. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestGrantsIntegration.test_list_grants_with_shapes[default-None] +0 -0
  109. {tango_python-0.4.4 → tango_python-0.5.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
  110. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestGrantsIntegration.test_list_grants_with_shapes[minimal-grant_id,opportunity_number,title,status(-),agency_code] +0 -0
  111. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestIDVsIntegration.test_get_idv_uses_default_shape +0 -0
  112. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestIDVsIntegration.test_list_idv_awards_uses_default_shape +0 -0
  113. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestIDVsIntegration.test_list_idv_child_idvs_uses_default_shape +0 -0
  114. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestIDVsIntegration.test_list_idv_transactions +0 -0
  115. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestIDVsIntegration.test_list_idvs_uses_default_shape_and_keyset_params +0 -0
  116. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestNaicsIntegration.test_list_naics +0 -0
  117. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestNoticesIntegration.test_list_notices_with_shapes[custom-notice_id,title,solicitation_number] +0 -0
  118. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestNoticesIntegration.test_list_notices_with_shapes[default-None] +0 -0
  119. {tango_python-0.4.4 → tango_python-0.5.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
  120. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestNoticesIntegration.test_list_notices_with_shapes[minimal-notice_id,title,solicitation_number,posted_date] +0 -0
  121. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestNoticesIntegration.test_notice_field_types +0 -0
  122. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestNoticesIntegration.test_notice_pagination +0 -0
  123. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestNoticesIntegration.test_notice_with_meta_fields +0 -0
  124. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestOTAsIntegration.test_get_ota +0 -0
  125. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestOTAsIntegration.test_list_otas +0 -0
  126. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestOTIDVsIntegration.test_get_otidv +0 -0
  127. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestOTIDVsIntegration.test_list_otidvs +0 -0
  128. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestOfficesIntegration.test_get_office +0 -0
  129. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestOfficesIntegration.test_list_offices +0 -0
  130. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestOpportunitiesIntegration.test_list_opportunities_with_shapes[custom-opportunity_id,title,solicitation_number] +0 -0
  131. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestOpportunitiesIntegration.test_list_opportunities_with_shapes[default-None] +0 -0
  132. {tango_python-0.4.4 → tango_python-0.5.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
  133. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestOpportunitiesIntegration.test_list_opportunities_with_shapes[minimal-opportunity_id,title,solicitation_number,response_deadline,active] +0 -0
  134. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestOpportunitiesIntegration.test_opportunity_field_types +0 -0
  135. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestOrganizationsIntegration.test_get_organization +0 -0
  136. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestOrganizationsIntegration.test_list_organizations +0 -0
  137. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestProtestsIntegration.test_get_protest_by_case_id +0 -0
  138. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestProtestsIntegration.test_list_protests_with_filter +0 -0
  139. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestProtestsIntegration.test_list_protests_with_shapes[custom-case_id,title,source_system,outcome] +0 -0
  140. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestProtestsIntegration.test_list_protests_with_shapes[default-None] +0 -0
  141. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestProtestsIntegration.test_list_protests_with_shapes[minimal-case_id,case_number,title,source_system,outcome,filed_date] +0 -0
  142. {tango_python-0.4.4 → tango_python-0.5.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
  143. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestProtestsIntegration.test_protest_pagination +0 -0
  144. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestSubawardsIntegration.test_list_subawards +0 -0
  145. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestTypeHintsIntegration.test_contracts_dict_access[custom-key,piid,description] +0 -0
  146. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestTypeHintsIntegration.test_contracts_dict_access[minimal-key,piid,award_date,recipient(display_name),description,total_contract_value] +0 -0
  147. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestTypeHintsIntegration.test_contracts_dict_access[ultra_minimal-key,piid,recipient(display_name),total_contract_value] +0 -0
  148. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestTypeHintsIntegration.test_entities_dict_access[minimal-uei,legal_business_name,cage_code,business_types] +0 -0
  149. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestTypeHintsIntegration.test_entities_dict_access[with_address-uei,legal_business_name,cage_code,business_types,physical_address] +0 -0
  150. {tango_python-0.4.4 → tango_python-0.5.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
  151. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestTypeHintsIntegration.test_notices_dict_access[minimal-notice_id,title,solicitation_number,posted_date] +0 -0
  152. {tango_python-0.4.4 → tango_python-0.5.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
  153. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestTypeHintsIntegration.test_opportunities_dict_access[minimal-opportunity_id,title,solicitation_number,response_deadline,active] +0 -0
  154. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestVehiclesIntegration.test_get_vehicle_supports_joiner_and_flat_lists +0 -0
  155. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestVehiclesIntegration.test_list_vehicle_awardees_uses_default_shape +0 -0
  156. {tango_python-0.4.4 → tango_python-0.5.0}/tests/cassettes/TestVehiclesIntegration.test_list_vehicles_uses_default_shape_and_search +0 -0
  157. {tango_python-0.4.4 → tango_python-0.5.0}/tests/conftest.py +0 -0
  158. {tango_python-0.4.4 → tango_python-0.5.0}/tests/integration/README.md +0 -0
  159. {tango_python-0.4.4 → tango_python-0.5.0}/tests/integration/__init__.py +0 -0
  160. {tango_python-0.4.4 → tango_python-0.5.0}/tests/integration/conftest.py +0 -0
  161. {tango_python-0.4.4 → tango_python-0.5.0}/tests/integration/test_agencies_integration.py +0 -0
  162. {tango_python-0.4.4 → tango_python-0.5.0}/tests/integration/test_contracts_integration.py +0 -0
  163. {tango_python-0.4.4 → tango_python-0.5.0}/tests/integration/test_edge_cases_integration.py +0 -0
  164. {tango_python-0.4.4 → tango_python-0.5.0}/tests/integration/test_entities_integration.py +0 -0
  165. {tango_python-0.4.4 → tango_python-0.5.0}/tests/integration/test_forecasts_integration.py +0 -0
  166. {tango_python-0.4.4 → tango_python-0.5.0}/tests/integration/test_grants_integration.py +0 -0
  167. {tango_python-0.4.4 → tango_python-0.5.0}/tests/integration/test_naics_integration.py +0 -0
  168. {tango_python-0.4.4 → tango_python-0.5.0}/tests/integration/test_notices_integration.py +0 -0
  169. {tango_python-0.4.4 → tango_python-0.5.0}/tests/integration/test_offices_integration.py +0 -0
  170. {tango_python-0.4.4 → tango_python-0.5.0}/tests/integration/test_opportunities_integration.py +0 -0
  171. {tango_python-0.4.4 → tango_python-0.5.0}/tests/integration/test_organizations_integration.py +0 -0
  172. {tango_python-0.4.4 → tango_python-0.5.0}/tests/integration/test_otas_otidvs_integration.py +0 -0
  173. {tango_python-0.4.4 → tango_python-0.5.0}/tests/integration/test_protests_integration.py +0 -0
  174. {tango_python-0.4.4 → tango_python-0.5.0}/tests/integration/test_reference_data_integration.py +0 -0
  175. {tango_python-0.4.4 → tango_python-0.5.0}/tests/integration/test_subawards_integration.py +0 -0
  176. {tango_python-0.4.4 → tango_python-0.5.0}/tests/integration/test_vehicles_idvs_integration.py +0 -0
  177. {tango_python-0.4.4 → tango_python-0.5.0}/tests/integration/validation.py +0 -0
  178. {tango_python-0.4.4 → tango_python-0.5.0}/tests/production/__init__.py +0 -0
  179. {tango_python-0.4.4 → tango_python-0.5.0}/tests/production/conftest.py +0 -0
  180. {tango_python-0.4.4 → tango_python-0.5.0}/tests/production/test_production_smoke.py +0 -0
  181. {tango_python-0.4.4 → tango_python-0.5.0}/tests/test_models.py +0 -0
  182. {tango_python-0.4.4 → tango_python-0.5.0}/tests/test_shapes.py +0 -0
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.5.0] - 2026-04-08
11
+
12
+ ### Added
13
+ - IT Dashboard investments: `list_itdashboard_investments`, `get_itdashboard_investment` (`/api/itdashboard/`) with shaping and filter params (`search`, `agency_code`, `agency_name`, `type_of_investment`, `updated_time_after`, `updated_time_before`, `cio_rating`, `cio_rating_max`, `performance_risk`). Tier-gated by the API: free tier gets `search`, pro adds structured filters, business+ adds CIO/performance analytics. New `ITDashboardInvestment` model and `ShapeConfig.ITDASHBOARD_INVESTMENTS_MINIMAL` / `ITDASHBOARD_INVESTMENTS_COMPREHENSIVE` defaults.
14
+
10
15
  ## [0.4.4] - 2026-03-25
11
16
 
12
17
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tango-python
3
- Version: 0.4.4
3
+ Version: 0.5.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
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "tango-python"
7
- version = "0.4.4"
7
+ version = "0.5.0"
8
8
  description = "Python SDK for the Tango API"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -50,6 +50,7 @@ RESOURCE_TO_METHOD: dict[str, str] = {
50
50
  "agencies": "list_agencies",
51
51
  "naics": "list_naics",
52
52
  "gsa_elibrary_contracts": "list_gsa_elibrary_contracts",
53
+ "itdashboard": "list_itdashboard_investments",
53
54
  # Resources not yet implemented in SDK
54
55
  "offices": None,
55
56
  }
@@ -66,6 +67,7 @@ def get_shape_config_entries() -> list[tuple[str, str, type[Any]]]:
66
67
  Forecast,
67
68
  Grant,
68
69
  GsaElibraryContract,
70
+ ITDashboardInvestment,
69
71
  Notice,
70
72
  Opportunity,
71
73
  Organization,
@@ -98,6 +100,16 @@ def get_shape_config_entries() -> list[tuple[str, str, type[Any]]]:
98
100
  ShapeConfig.GSA_ELIBRARY_CONTRACTS_MINIMAL,
99
101
  GsaElibraryContract,
100
102
  ),
103
+ (
104
+ "ITDASHBOARD_INVESTMENTS_MINIMAL",
105
+ ShapeConfig.ITDASHBOARD_INVESTMENTS_MINIMAL,
106
+ ITDashboardInvestment,
107
+ ),
108
+ (
109
+ "ITDASHBOARD_INVESTMENTS_COMPREHENSIVE",
110
+ ShapeConfig.ITDASHBOARD_INVESTMENTS_COMPREHENSIVE,
111
+ ITDashboardInvestment,
112
+ ),
101
113
  ]
102
114
  for name, shape_str, model_cls in configs:
103
115
  entries.append((name, shape_str, model_cls))
@@ -10,6 +10,7 @@ from .exceptions import (
10
10
  )
11
11
  from .models import (
12
12
  GsaElibraryContract,
13
+ ITDashboardInvestment,
13
14
  PaginatedResponse,
14
15
  RateLimitInfo,
15
16
  SearchFilters,
@@ -28,7 +29,7 @@ from .shapes import (
28
29
  TypeGenerator,
29
30
  )
30
31
 
31
- __version__ = "0.4.3"
32
+ __version__ = "0.5.0"
32
33
  __all__ = [
33
34
  "TangoClient",
34
35
  "TangoAPIError",
@@ -38,6 +39,7 @@ __all__ = [
38
39
  "TangoRateLimitError",
39
40
  "RateLimitInfo",
40
41
  "GsaElibraryContract",
42
+ "ITDashboardInvestment",
41
43
  "PaginatedResponse",
42
44
  "SearchFilters",
43
45
  "ShapeConfig",
@@ -26,6 +26,7 @@ from tango.models import (
26
26
  Forecast,
27
27
  Grant,
28
28
  GsaElibraryContract,
29
+ ITDashboardInvestment,
29
30
  Location,
30
31
  Notice,
31
32
  Opportunity,
@@ -1336,6 +1337,112 @@ class TangoClient:
1336
1337
  data, shape, GsaElibraryContract, flat, flat_lists, joiner=joiner
1337
1338
  )
1338
1339
 
1340
+ # ============================================================================
1341
+ # IT Dashboard Investments
1342
+ # ============================================================================
1343
+
1344
+ def list_itdashboard_investments(
1345
+ self,
1346
+ page: int = 1,
1347
+ limit: int = 25,
1348
+ shape: str | None = None,
1349
+ flat: bool = False,
1350
+ flat_lists: bool = False,
1351
+ joiner: str = ".",
1352
+ search: str | None = None,
1353
+ agency_code: int | None = None,
1354
+ agency_name: str | None = None,
1355
+ type_of_investment: str | None = None,
1356
+ updated_time_after: str | date | datetime | None = None,
1357
+ updated_time_before: str | date | datetime | None = None,
1358
+ cio_rating: int | None = None,
1359
+ cio_rating_max: int | None = None,
1360
+ performance_risk: bool | None = None,
1361
+ ) -> PaginatedResponse:
1362
+ """List federal IT investments from the IT Dashboard (`/api/itdashboard/`).
1363
+
1364
+ Filters are tier-gated by the API:
1365
+
1366
+ - **Free**: ``search`` (full-text across UII, title, description, agency, bureau)
1367
+ - **Pro**: ``agency_code``, ``type_of_investment``,
1368
+ ``updated_time_after`` / ``updated_time_before``
1369
+ - **Business+**: ``agency_name`` (text), ``cio_rating``,
1370
+ ``cio_rating_max``, ``performance_risk``
1371
+
1372
+ Hitting a gated filter on a lower tier returns a 403 with upgrade info.
1373
+
1374
+ CIO ratings: 1=High Risk, 2=Moderately High, 3=Medium, 4=Moderately Low, 5=Low.
1375
+ ``performance_risk=True`` returns investments with at least one NOT MET metric.
1376
+ """
1377
+ params: dict[str, Any] = {"page": page, "limit": min(limit, 100)}
1378
+ if shape is None:
1379
+ shape = ShapeConfig.ITDASHBOARD_INVESTMENTS_MINIMAL
1380
+ if shape:
1381
+ params["shape"] = shape
1382
+ if flat:
1383
+ params["flat"] = "true"
1384
+ if joiner:
1385
+ params["joiner"] = joiner
1386
+ if flat_lists:
1387
+ params["flat_lists"] = "true"
1388
+ for k, val in (
1389
+ ("search", search),
1390
+ ("agency_code", agency_code),
1391
+ ("agency_name", agency_name),
1392
+ ("type_of_investment", type_of_investment),
1393
+ ("updated_time_after", updated_time_after),
1394
+ ("updated_time_before", updated_time_before),
1395
+ ("cio_rating", cio_rating),
1396
+ ("cio_rating_max", cio_rating_max),
1397
+ ("performance_risk", performance_risk),
1398
+ ):
1399
+ if val is None:
1400
+ continue
1401
+ if isinstance(val, bool):
1402
+ params[k] = "true" if val else "false"
1403
+ elif isinstance(val, (date, datetime)):
1404
+ params[k] = val.isoformat()
1405
+ else:
1406
+ params[k] = val
1407
+ data = self._get("/api/itdashboard/", params)
1408
+ results = [
1409
+ self._parse_response_with_shape(
1410
+ obj, shape, ITDashboardInvestment, flat, flat_lists, joiner=joiner
1411
+ )
1412
+ for obj in data.get("results", [])
1413
+ ]
1414
+ return PaginatedResponse(
1415
+ count=data.get("count", 0),
1416
+ next=data.get("next"),
1417
+ previous=data.get("previous"),
1418
+ results=results,
1419
+ )
1420
+
1421
+ def get_itdashboard_investment(
1422
+ self,
1423
+ uii: str,
1424
+ shape: str | None = None,
1425
+ flat: bool = False,
1426
+ flat_lists: bool = False,
1427
+ joiner: str = ".",
1428
+ ) -> Any:
1429
+ """Get a single IT Dashboard investment by UII (`/api/itdashboard/{uii}/`)."""
1430
+ params: dict[str, Any] = {}
1431
+ if shape is None:
1432
+ shape = ShapeConfig.ITDASHBOARD_INVESTMENTS_COMPREHENSIVE
1433
+ if shape:
1434
+ params["shape"] = shape
1435
+ if flat:
1436
+ params["flat"] = "true"
1437
+ if joiner:
1438
+ params["joiner"] = joiner
1439
+ if flat_lists:
1440
+ params["flat_lists"] = "true"
1441
+ data = self._get(f"/api/itdashboard/{uii}/", params)
1442
+ return self._parse_response_with_shape(
1443
+ data, shape, ITDashboardInvestment, flat, flat_lists, joiner=joiner
1444
+ )
1445
+
1339
1446
  # ============================================================================
1340
1447
  # Vehicles (Awards)
1341
1448
  # ============================================================================
@@ -367,6 +367,45 @@ class GsaElibraryContract:
367
367
  sins: list[str] | None = None
368
368
 
369
369
 
370
+ @dataclass
371
+ class ITDashboardInvestment:
372
+ """Schema definition for IT Dashboard Investment (not used for instances)
373
+
374
+ Federal IT investment from itdashboard.gov, exposed at /api/itdashboard/.
375
+ Identified by ``uii`` (Unique Investment Identifier).
376
+
377
+ Tier-gated shape expansions:
378
+ Free base fields only
379
+ Pro+ ``funding`` and ``details`` expansions
380
+ Business+ nested sub-tables (``cio_evaluation``, ``contracts``,
381
+ ``projects``, ``cost_pools_towers``, ``funding_sources``,
382
+ ``performance_metrics``, ``performance_actual``,
383
+ ``operational_analysis``) and ``business_case_html``
384
+ """
385
+
386
+ uii: str
387
+ agency_code: int | None = None
388
+ agency_name: str | None = None
389
+ bureau_code: int | None = None
390
+ bureau_name: str | None = None
391
+ investment_title: str | None = None
392
+ type_of_investment: str | None = None
393
+ part_of_it_portfolio: str | None = None
394
+ updated_time: datetime | None = None
395
+ url: str | None = None
396
+ business_case_html: str | None = None
397
+ funding: dict[str, Any] | None = None
398
+ details: dict[str, Any] | None = None
399
+ cio_evaluation: list[dict[str, Any]] | None = None
400
+ contracts: list[dict[str, Any]] | None = None
401
+ projects: list[dict[str, Any]] | None = None
402
+ cost_pools_towers: list[dict[str, Any]] | None = None
403
+ funding_sources: list[dict[str, Any]] | None = None
404
+ performance_metrics: list[dict[str, Any]] | None = None
405
+ performance_actual: list[dict[str, Any]] | None = None
406
+ operational_analysis: list[dict[str, Any]] | None = None
407
+
408
+
370
409
  @dataclass
371
410
  class Vehicle:
372
411
  """Schema definition for Vehicle (not used for instances)"""
@@ -687,3 +726,18 @@ class ShapeConfig:
687
726
  GSA_ELIBRARY_CONTRACTS_MINIMAL: Final = (
688
727
  "uuid,contract_number,schedule,recipient(display_name,uei),idv(key,award_date)"
689
728
  )
729
+
730
+ # Default for list_itdashboard_investments()
731
+ # Free-tier safe: matches the API's INVESTMENT_LIST_DEFAULT_SHAPE.
732
+ ITDASHBOARD_INVESTMENTS_MINIMAL: Final = (
733
+ "uii,agency_name,bureau_name,investment_title,"
734
+ "type_of_investment,part_of_it_portfolio,updated_time,url"
735
+ )
736
+
737
+ # Default for get_itdashboard_investment()
738
+ # Free-tier safe: matches the API's INVESTMENT_RETRIEVE_DEFAULT_SHAPE.
739
+ ITDASHBOARD_INVESTMENTS_COMPREHENSIVE: Final = (
740
+ "uii,agency_code,agency_name,bureau_code,bureau_name,"
741
+ "investment_title,type_of_investment,part_of_it_portfolio,"
742
+ "updated_time,url"
743
+ )
@@ -1132,6 +1132,67 @@ GSA_ELIBRARY_CONTRACT_SCHEMA: dict[str, FieldSchema] = {
1132
1132
  ),
1133
1133
  }
1134
1134
 
1135
+ # IT Dashboard Investment
1136
+ ITDASHBOARD_INVESTMENT_SCHEMA: dict[str, FieldSchema] = {
1137
+ "uii": FieldSchema(name="uii", type=str, is_optional=False, is_list=False),
1138
+ "agency_code": FieldSchema(
1139
+ name="agency_code", type=int, is_optional=True, is_list=False
1140
+ ),
1141
+ "agency_name": FieldSchema(
1142
+ name="agency_name", type=str, is_optional=True, is_list=False
1143
+ ),
1144
+ "bureau_code": FieldSchema(
1145
+ name="bureau_code", type=int, is_optional=True, is_list=False
1146
+ ),
1147
+ "bureau_name": FieldSchema(
1148
+ name="bureau_name", type=str, is_optional=True, is_list=False
1149
+ ),
1150
+ "investment_title": FieldSchema(
1151
+ name="investment_title", type=str, is_optional=True, is_list=False
1152
+ ),
1153
+ "type_of_investment": FieldSchema(
1154
+ name="type_of_investment", type=str, is_optional=True, is_list=False
1155
+ ),
1156
+ "part_of_it_portfolio": FieldSchema(
1157
+ name="part_of_it_portfolio", type=str, is_optional=True, is_list=False
1158
+ ),
1159
+ "updated_time": FieldSchema(
1160
+ name="updated_time", type=datetime, is_optional=True, is_list=False
1161
+ ),
1162
+ "url": FieldSchema(name="url", type=str, is_optional=True, is_list=False),
1163
+ "business_case_html": FieldSchema(
1164
+ name="business_case_html", type=str, is_optional=True, is_list=False
1165
+ ),
1166
+ # Expansions: dict (funding/details) and list-of-dict (nested sub-tables).
1167
+ # Modeled as opaque dict/list since their inner shapes are dynamic.
1168
+ "funding": FieldSchema(name="funding", type=dict, is_optional=True, is_list=False),
1169
+ "details": FieldSchema(name="details", type=dict, is_optional=True, is_list=False),
1170
+ "cio_evaluation": FieldSchema(
1171
+ name="cio_evaluation", type=list, is_optional=True, is_list=True
1172
+ ),
1173
+ "contracts": FieldSchema(
1174
+ name="contracts", type=list, is_optional=True, is_list=True
1175
+ ),
1176
+ "projects": FieldSchema(
1177
+ name="projects", type=list, is_optional=True, is_list=True
1178
+ ),
1179
+ "cost_pools_towers": FieldSchema(
1180
+ name="cost_pools_towers", type=list, is_optional=True, is_list=True
1181
+ ),
1182
+ "funding_sources": FieldSchema(
1183
+ name="funding_sources", type=list, is_optional=True, is_list=True
1184
+ ),
1185
+ "performance_metrics": FieldSchema(
1186
+ name="performance_metrics", type=list, is_optional=True, is_list=True
1187
+ ),
1188
+ "performance_actual": FieldSchema(
1189
+ name="performance_actual", type=list, is_optional=True, is_list=True
1190
+ ),
1191
+ "operational_analysis": FieldSchema(
1192
+ name="operational_analysis", type=list, is_optional=True, is_list=True
1193
+ ),
1194
+ }
1195
+
1135
1196
  # ============================================================================
1136
1197
  # SCHEMA REGISTRY MAPPING
1137
1198
  # ============================================================================
@@ -1176,6 +1237,8 @@ EXPLICIT_SCHEMAS: dict[str, dict[str, FieldSchema]] = {
1176
1237
  # GSA eLibrary
1177
1238
  "GsaElibraryContract": GSA_ELIBRARY_CONTRACT_SCHEMA,
1178
1239
  "GsaElibraryIdvRef": GSA_ELIBRARY_IDV_REF_SCHEMA,
1240
+ # IT Dashboard
1241
+ "ITDashboardInvestment": ITDASHBOARD_INVESTMENT_SCHEMA,
1179
1242
  }
1180
1243
 
1181
1244
 
@@ -0,0 +1,95 @@
1
+ interactions:
2
+ - request:
3
+ body: ''
4
+ headers:
5
+ accept:
6
+ - '*/*'
7
+ accept-encoding:
8
+ - gzip, deflate
9
+ connection:
10
+ - keep-alive
11
+ host:
12
+ - tango.makegov.com
13
+ user-agent:
14
+ - python-httpx/0.28.1
15
+ method: GET
16
+ uri: https://tango.makegov.com/api/itdashboard/?page=1&limit=5&shape=uii%2Cagency_name%2Cbureau_name%2Cinvestment_title%2Ctype_of_investment%2Cpart_of_it_portfolio%2Cupdated_time%2Curl&agency_code=21
17
+ response:
18
+ body:
19
+ string: '{"count":360,"next":"https://tango.makegov.com/api/itdashboard/?agency_code=21&limit=5&page=2&shape=uii%2Cagency_name%2Cbureau_name%2Cinvestment_title%2Ctype_of_investment%2Cpart_of_it_portfolio%2Cupdated_time%2Curl","previous":null,"results":[{"uii":"021-777552743","agency_name":"Department
20
+ of Transportation","bureau_name":"National Highway Traffic Safety Administration","investment_title":"NHTSA0020:
21
+ Artemis","type_of_investment":"Major IT Investments","part_of_it_portfolio":"Part
22
+ 1. IT Investments for Mission Delivery","updated_time":"2026-03-27T12:45:58+00:00","url":"https://www.itdashboard.gov/investment-details/021-777552743"},{"uii":"021-302996650","agency_name":"Department
23
+ of Transportation","bureau_name":"National Highway Traffic Safety Administration","investment_title":"NHTSA0347:
24
+ CDAN Version 2.0","type_of_investment":"Major IT Investments","part_of_it_portfolio":"Part
25
+ 1. IT Investments for Mission Delivery","updated_time":"2026-03-26T16:50:10+00:00","url":"https://www.itdashboard.gov/investment-details/021-302996650"},{"uii":"021-165719668","agency_name":"Department
26
+ of Transportation","bureau_name":"National Highway Traffic Safety Administration","investment_title":"NHTSA0301:
27
+ Teleprocessing and Timesharing Services for the NDR Program","type_of_investment":"Major
28
+ IT Investments","part_of_it_portfolio":"Part 1. IT Investments for Mission
29
+ Delivery","updated_time":"2026-03-26T16:49:35+00:00","url":"https://www.itdashboard.gov/investment-details/021-165719668"},{"uii":"021-700323071","agency_name":"Department
30
+ of Transportation","bureau_name":"Maritime Administration","investment_title":"MARAD0071:
31
+ National Security Multi-Mission Vessel (NSMV)","type_of_investment":"Major
32
+ IT Investments","part_of_it_portfolio":"Part 1. IT Investments for Mission
33
+ Delivery","updated_time":"2026-03-25T20:04:19+00:00","url":"https://www.itdashboard.gov/investment-details/021-700323071"},{"uii":"021-700323070","agency_name":"Department
34
+ of Transportation","bureau_name":"Maritime Administration","investment_title":"MARAD0070:
35
+ USMMA Campus Solutions (UCAS)","type_of_investment":"Major IT Investments","part_of_it_portfolio":"Part
36
+ 1. IT Investments for Mission Delivery","updated_time":"2026-03-25T20:01:19+00:00","url":"https://www.itdashboard.gov/investment-details/021-700323070"}]}'
37
+ headers:
38
+ CF-RAY:
39
+ - 9e91f5012a290a26-ORD
40
+ Connection:
41
+ - keep-alive
42
+ Content-Type:
43
+ - application/json
44
+ Date:
45
+ - Wed, 08 Apr 2026 14:28:11 GMT
46
+ Nel:
47
+ - '{"report_to":"cf-nel","success_fraction":0.0,"max_age":604800}'
48
+ Report-To:
49
+ - '{"group":"cf-nel","max_age":604800,"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v4?s=3I21M9xblZ6mvJlcfLRR%2BgHPPkc4av1Jh5BnY2zzrEEQYRrjfLQYZ4wTjxthr51w2nNIPM4ww3TdtKdPPM%2BaPRa4lwu7%2F7SO1IC%2FtbBfAEYkTD6KuUhLQTtsgw8tF%2BSst8l8wPVEBcI8NpySZKvr"}]}'
50
+ Server:
51
+ - cloudflare
52
+ Transfer-Encoding:
53
+ - chunked
54
+ allow:
55
+ - GET, HEAD, OPTIONS
56
+ cf-cache-status:
57
+ - DYNAMIC
58
+ content-length:
59
+ - '2305'
60
+ cross-origin-opener-policy:
61
+ - same-origin
62
+ referrer-policy:
63
+ - same-origin
64
+ vary:
65
+ - Accept, Cookie
66
+ x-content-type-options:
67
+ - nosniff
68
+ x-execution-time:
69
+ - 0.024s
70
+ x-frame-options:
71
+ - DENY
72
+ x-ratelimit-burst-limit:
73
+ - '1000'
74
+ x-ratelimit-burst-remaining:
75
+ - '991'
76
+ x-ratelimit-burst-reset:
77
+ - '54'
78
+ x-ratelimit-daily-limit:
79
+ - '2000000'
80
+ x-ratelimit-daily-remaining:
81
+ - '1999933'
82
+ x-ratelimit-daily-reset:
83
+ - '34308'
84
+ x-ratelimit-limit:
85
+ - '1000'
86
+ x-ratelimit-remaining:
87
+ - '991'
88
+ x-ratelimit-reset:
89
+ - '54'
90
+ x-results-counttype:
91
+ - exact
92
+ status:
93
+ code: 200
94
+ message: OK
95
+ version: 1
@@ -0,0 +1,93 @@
1
+ interactions:
2
+ - request:
3
+ body: ''
4
+ headers:
5
+ accept:
6
+ - '*/*'
7
+ accept-encoding:
8
+ - gzip, deflate
9
+ connection:
10
+ - keep-alive
11
+ host:
12
+ - tango.makegov.com
13
+ user-agent:
14
+ - python-httpx/0.28.1
15
+ method: GET
16
+ uri: https://tango.makegov.com/api/itdashboard/?page=1&limit=5&shape=uii%2Cagency_name%2Cbureau_name%2Cinvestment_title%2Ctype_of_investment%2Cpart_of_it_portfolio%2Cupdated_time%2Curl&agency_name=defense
17
+ response:
18
+ body:
19
+ string: '{"count":2655,"next":"https://tango.makegov.com/api/itdashboard/?agency_name=defense&limit=5&page=2&shape=uii%2Cagency_name%2Cbureau_name%2Cinvestment_title%2Ctype_of_investment%2Cpart_of_it_portfolio%2Cupdated_time%2Curl","previous":null,"results":[{"uii":"007-000103860","agency_name":"Department
20
+ of Defense","bureau_name":"Army","investment_title":"ENTERPRISE BUSINESS SYSTEMS-CONVERGENCE","type_of_investment":"Major
21
+ IT Investments","part_of_it_portfolio":"Part 2. IT Investments for Mission
22
+ Support Services","updated_time":"2026-02-24T15:47:57+00:00","url":"https://www.itdashboard.gov/investment-details/007-000103860"},{"uii":"007-000103486","agency_name":"Department
23
+ of Defense","bureau_name":"Navy, Marine Corps","investment_title":"Naval -
24
+ Maintenance, Repair, and Overhaul","type_of_investment":"Major IT Investments","part_of_it_portfolio":"Part
25
+ 2. IT Investments for Mission Support Services","updated_time":"2026-02-24T15:47:56+00:00","url":"https://www.itdashboard.gov/investment-details/007-000103486"},{"uii":"007-000103389","agency_name":"Department
26
+ of Defense","bureau_name":"Navy, Marine Corps","investment_title":"Navy Personnel
27
+ and Pay","type_of_investment":"Major IT Investments","part_of_it_portfolio":"Part
28
+ 2. IT Investments for Mission Support Services","updated_time":"2026-02-24T15:47:55+00:00","url":"https://www.itdashboard.gov/investment-details/007-000103389"},{"uii":"007-000101162","agency_name":"Department
29
+ of Defense","bureau_name":"Defense-wide","investment_title":"DEFENSE AGENCIES
30
+ INITIATIVE","type_of_investment":"Major IT Investments","part_of_it_portfolio":"Part
31
+ 2. IT Investments for Mission Support Services","updated_time":"2026-02-24T15:47:53+00:00","url":"https://www.itdashboard.gov/investment-details/007-000101162"},{"uii":"007-000101099","agency_name":"Department
32
+ of Defense","bureau_name":"Defense-wide","investment_title":"Advancing Analytics","type_of_investment":"Major
33
+ IT Investments","part_of_it_portfolio":"Part 2. IT Investments for Mission
34
+ Support Services","updated_time":"2026-02-24T15:47:52+00:00","url":"https://www.itdashboard.gov/investment-details/007-000101099"}]}'
35
+ headers:
36
+ CF-RAY:
37
+ - 9e91f50efa00eb60-ORD
38
+ Connection:
39
+ - keep-alive
40
+ Content-Type:
41
+ - application/json
42
+ Date:
43
+ - Wed, 08 Apr 2026 14:28:13 GMT
44
+ Nel:
45
+ - '{"report_to":"cf-nel","success_fraction":0.0,"max_age":604800}'
46
+ Report-To:
47
+ - '{"group":"cf-nel","max_age":604800,"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v4?s=sVGRzZBXm8exykIK%2FejvOiYFHW4PdBAjQzVz8kFHaHvTKCThUTCPOdvSEmryfb1TOd2h6HWHaT4KLsBDgJFFcRVZqkYNjm32asNjoEnEg0wBrzakieSIJwfowtZYZjmpTn8HD%2BUTJzKIKlf6QARk"}]}'
48
+ Server:
49
+ - cloudflare
50
+ Transfer-Encoding:
51
+ - chunked
52
+ allow:
53
+ - GET, HEAD, OPTIONS
54
+ cf-cache-status:
55
+ - DYNAMIC
56
+ content-length:
57
+ - '2133'
58
+ cross-origin-opener-policy:
59
+ - same-origin
60
+ referrer-policy:
61
+ - same-origin
62
+ vary:
63
+ - Accept, Cookie
64
+ x-content-type-options:
65
+ - nosniff
66
+ x-execution-time:
67
+ - 0.023s
68
+ x-frame-options:
69
+ - DENY
70
+ x-ratelimit-burst-limit:
71
+ - '1000'
72
+ x-ratelimit-burst-remaining:
73
+ - '988'
74
+ x-ratelimit-burst-reset:
75
+ - '52'
76
+ x-ratelimit-daily-limit:
77
+ - '2000000'
78
+ x-ratelimit-daily-remaining:
79
+ - '1999930'
80
+ x-ratelimit-daily-reset:
81
+ - '34306'
82
+ x-ratelimit-limit:
83
+ - '1000'
84
+ x-ratelimit-remaining:
85
+ - '988'
86
+ x-ratelimit-reset:
87
+ - '52'
88
+ x-results-counttype:
89
+ - exact
90
+ status:
91
+ code: 200
92
+ message: OK
93
+ version: 1
@@ -0,0 +1,94 @@
1
+ interactions:
2
+ - request:
3
+ body: ''
4
+ headers:
5
+ accept:
6
+ - '*/*'
7
+ accept-encoding:
8
+ - gzip, deflate
9
+ connection:
10
+ - keep-alive
11
+ host:
12
+ - tango.makegov.com
13
+ user-agent:
14
+ - python-httpx/0.28.1
15
+ method: GET
16
+ uri: https://tango.makegov.com/api/itdashboard/?page=1&limit=5&shape=uii%2Cagency_name%2Cbureau_name%2Cinvestment_title%2Ctype_of_investment%2Cpart_of_it_portfolio%2Cupdated_time%2Curl&cio_rating=1
17
+ response:
18
+ body:
19
+ string: '{"count":8,"next":"https://tango.makegov.com/api/itdashboard/?cio_rating=1&limit=5&page=2&shape=uii%2Cagency_name%2Cbureau_name%2Cinvestment_title%2Ctype_of_investment%2Cpart_of_it_portfolio%2Cupdated_time%2Curl","previous":null,"results":[{"uii":"014-000000534","agency_name":"Department
20
+ of State","bureau_name":"Department of State","investment_title":"GDI-IoT
21
+ Network","type_of_investment":"Standard IT Investments","part_of_it_portfolio":"Part
22
+ 3. IT Standard IT Investments","updated_time":"2026-04-06T19:27:40+00:00","url":"https://www.itdashboard.gov/investment-details/014-000000534"},{"uii":"014-000000533","agency_name":"Department
23
+ of State","bureau_name":"Department of State","investment_title":"COM Solutions
24
+ Modernization","type_of_investment":"Standard IT Investments","part_of_it_portfolio":"Part
25
+ 3. IT Standard IT Investments","updated_time":"2026-04-06T19:04:06+00:00","url":"https://www.itdashboard.gov/investment-details/014-000000533"},{"uii":"010-000002832","agency_name":"Department
26
+ of the Interior","bureau_name":"Departmental Offices","investment_title":"DOI
27
+ - IBC Time & Attendance","type_of_investment":"Major IT Investments","part_of_it_portfolio":"Part
28
+ 2. IT Investments for Mission Support Services","updated_time":"2026-03-16T20:38:44+00:00","url":"https://www.itdashboard.gov/investment-details/010-000002832"},{"uii":"007-000103389","agency_name":"Department
29
+ of Defense","bureau_name":"Navy, Marine Corps","investment_title":"Navy Personnel
30
+ and Pay","type_of_investment":"Major IT Investments","part_of_it_portfolio":"Part
31
+ 2. IT Investments for Mission Support Services","updated_time":"2026-02-24T15:47:55+00:00","url":"https://www.itdashboard.gov/investment-details/007-000103389"},{"uii":"021-130077684","agency_name":"Department
32
+ of Transportation","bureau_name":"Federal Aviation Administration","investment_title":"FAAXX711:
33
+ Data Communications NextGen Support (DataComm)","type_of_investment":"Major
34
+ IT Investments","part_of_it_portfolio":"Part 1. IT Investments for Mission
35
+ Delivery","updated_time":"2025-09-29T22:01:34+00:00","url":"https://www.itdashboard.gov/investment-details/021-130077684"}]}'
36
+ headers:
37
+ CF-RAY:
38
+ - 9e91f5139db7edc5-ORD
39
+ Connection:
40
+ - keep-alive
41
+ Content-Type:
42
+ - application/json
43
+ Date:
44
+ - Wed, 08 Apr 2026 14:28:14 GMT
45
+ Nel:
46
+ - '{"report_to":"cf-nel","success_fraction":0.0,"max_age":604800}'
47
+ Report-To:
48
+ - '{"group":"cf-nel","max_age":604800,"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v4?s=3EXlOC16cG9P2yLN7rz2YxwmMHyB%2BASRQmSjD9NXeULjtV6qNnAtcbGbdzJ7hPhSr0xZQq%2Bj%2BydDFN0%2Bmn3ZCkvoLrZnfyyPvQm9gn7orEs0JLPwvC4s7vAIzTgJ1kXRvnJt"}]}'
49
+ Server:
50
+ - cloudflare
51
+ Transfer-Encoding:
52
+ - chunked
53
+ allow:
54
+ - GET, HEAD, OPTIONS
55
+ cf-cache-status:
56
+ - DYNAMIC
57
+ content-length:
58
+ - '2137'
59
+ cross-origin-opener-policy:
60
+ - same-origin
61
+ referrer-policy:
62
+ - same-origin
63
+ vary:
64
+ - Accept, Cookie
65
+ x-content-type-options:
66
+ - nosniff
67
+ x-execution-time:
68
+ - 0.050s
69
+ x-frame-options:
70
+ - DENY
71
+ x-ratelimit-burst-limit:
72
+ - '1000'
73
+ x-ratelimit-burst-remaining:
74
+ - '987'
75
+ x-ratelimit-burst-reset:
76
+ - '51'
77
+ x-ratelimit-daily-limit:
78
+ - '2000000'
79
+ x-ratelimit-daily-remaining:
80
+ - '1999929'
81
+ x-ratelimit-daily-reset:
82
+ - '34305'
83
+ x-ratelimit-limit:
84
+ - '1000'
85
+ x-ratelimit-remaining:
86
+ - '987'
87
+ x-ratelimit-reset:
88
+ - '51'
89
+ x-results-counttype:
90
+ - exact
91
+ status:
92
+ code: 200
93
+ message: OK
94
+ version: 1