tango-python 1.1.3__py3-none-any.whl → 1.2.0__py3-none-any.whl

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/__init__.py CHANGED
@@ -44,7 +44,7 @@ from .webhooks import (
44
44
  )
45
45
  from .webhooks.receiver import Delivery, WebhookReceiver
46
46
 
47
- __version__ = "1.1.3"
47
+ __version__ = "1.2.0"
48
48
  __all__ = [
49
49
  "TangoClient",
50
50
  "TangoAPIError",
tango/client.py CHANGED
@@ -2649,6 +2649,85 @@ class TangoClient:
2649
2649
  bea_category: str | None = None,
2650
2650
  on_off_budget: str | None = None,
2651
2651
  subfunction_code: str | None = None,
2652
+ # Range-numeric filters: each field also accepts ``__gte`` / ``__lte``.
2653
+ requested_ba: float | None = None,
2654
+ requested_ba_gte: float | None = None,
2655
+ requested_ba_lte: float | None = None,
2656
+ enacted_ba: float | None = None,
2657
+ enacted_ba_gte: float | None = None,
2658
+ enacted_ba_lte: float | None = None,
2659
+ apportioned: float | None = None,
2660
+ apportioned_gte: float | None = None,
2661
+ apportioned_lte: float | None = None,
2662
+ obligated_total: float | None = None,
2663
+ obligated_total_gte: float | None = None,
2664
+ obligated_total_lte: float | None = None,
2665
+ outlayed_total: float | None = None,
2666
+ outlayed_total_gte: float | None = None,
2667
+ outlayed_total_lte: float | None = None,
2668
+ unobligated_balance: float | None = None,
2669
+ unobligated_balance_gte: float | None = None,
2670
+ unobligated_balance_lte: float | None = None,
2671
+ contract_obligated: float | None = None,
2672
+ contract_obligated_gte: float | None = None,
2673
+ contract_obligated_lte: float | None = None,
2674
+ contract_outlayed: float | None = None,
2675
+ contract_outlayed_gte: float | None = None,
2676
+ contract_outlayed_lte: float | None = None,
2677
+ assistance_obligated: float | None = None,
2678
+ assistance_obligated_gte: float | None = None,
2679
+ assistance_obligated_lte: float | None = None,
2680
+ assistance_outlayed: float | None = None,
2681
+ assistance_outlayed_gte: float | None = None,
2682
+ assistance_outlayed_lte: float | None = None,
2683
+ contract_share_of_obligated_capped: float | None = None,
2684
+ contract_share_of_obligated_capped_gte: float | None = None,
2685
+ contract_share_of_obligated_capped_lte: float | None = None,
2686
+ obligated_to_apportioned_pct: float | None = None,
2687
+ obligated_to_apportioned_pct_gte: float | None = None,
2688
+ obligated_to_apportioned_pct_lte: float | None = None,
2689
+ obligated_to_apportioned_pct_capped: float | None = None,
2690
+ obligated_to_apportioned_pct_capped_gte: float | None = None,
2691
+ obligated_to_apportioned_pct_capped_lte: float | None = None,
2692
+ apportioned_to_enacted_pct: float | None = None,
2693
+ apportioned_to_enacted_pct_gte: float | None = None,
2694
+ apportioned_to_enacted_pct_lte: float | None = None,
2695
+ apportioned_to_enacted_pct_capped: float | None = None,
2696
+ apportioned_to_enacted_pct_capped_gte: float | None = None,
2697
+ apportioned_to_enacted_pct_capped_lte: float | None = None,
2698
+ obligated_to_enacted_pct: float | None = None,
2699
+ obligated_to_enacted_pct_gte: float | None = None,
2700
+ obligated_to_enacted_pct_lte: float | None = None,
2701
+ obligated_to_enacted_pct_capped: float | None = None,
2702
+ obligated_to_enacted_pct_capped_gte: float | None = None,
2703
+ obligated_to_enacted_pct_capped_lte: float | None = None,
2704
+ outlayed_to_obligated_pct: float | None = None,
2705
+ outlayed_to_obligated_pct_gte: float | None = None,
2706
+ outlayed_to_obligated_pct_lte: float | None = None,
2707
+ outlayed_to_obligated_pct_capped: float | None = None,
2708
+ outlayed_to_obligated_pct_capped_gte: float | None = None,
2709
+ outlayed_to_obligated_pct_capped_lte: float | None = None,
2710
+ unobligated_pct: float | None = None,
2711
+ unobligated_pct_gte: float | None = None,
2712
+ unobligated_pct_lte: float | None = None,
2713
+ enacted_ba_yoy_pct: float | None = None,
2714
+ enacted_ba_yoy_pct_gte: float | None = None,
2715
+ enacted_ba_yoy_pct_lte: float | None = None,
2716
+ obligated_yoy_pct: float | None = None,
2717
+ obligated_yoy_pct_gte: float | None = None,
2718
+ obligated_yoy_pct_lte: float | None = None,
2719
+ enacted_ba_5yr_cagr: float | None = None,
2720
+ enacted_ba_5yr_cagr_gte: float | None = None,
2721
+ enacted_ba_5yr_cagr_lte: float | None = None,
2722
+ ba_growth_next_year_pct: float | None = None,
2723
+ ba_growth_next_year_pct_gte: float | None = None,
2724
+ ba_growth_next_year_pct_lte: float | None = None,
2725
+ actual_vs_requested_contract: float | None = None,
2726
+ actual_vs_requested_contract_gte: float | None = None,
2727
+ actual_vs_requested_contract_lte: float | None = None,
2728
+ actual_vs_requested_contract_capped: float | None = None,
2729
+ actual_vs_requested_contract_capped_gte: float | None = None,
2730
+ actual_vs_requested_contract_capped_lte: float | None = None,
2652
2731
  search: str | None = None,
2653
2732
  ordering: str | None = None,
2654
2733
  ) -> PaginatedResponse:
@@ -2674,8 +2753,49 @@ class TangoClient:
2674
2753
  bea_category: BEA category (exact).
2675
2754
  on_off_budget: On/off budget flag (exact).
2676
2755
  subfunction_code: Subfunction code (exact).
2756
+ requested_ba: President's-budget requested BA (exact). Also
2757
+ ``requested_ba_gte`` / ``requested_ba_lte`` for range queries.
2758
+ enacted_ba: Enacted budget authority (exact / gte / lte).
2759
+ apportioned: Apportioned amount (exact / gte / lte).
2760
+ obligated_total: Total obligated (exact / gte / lte).
2761
+ outlayed_total: Total outlayed (exact / gte / lte).
2762
+ unobligated_balance: Apportioned minus obligated, in dollars
2763
+ (exact / gte / lte). Use ``__gte`` to surface accounts with
2764
+ appropriated headroom that hasn't yet hit contract.
2765
+ contract_obligated: Contract-only obligated (exact / gte / lte).
2766
+ contract_outlayed: Contract-only outlayed (exact / gte / lte).
2767
+ assistance_obligated: Assistance-only obligated (exact / gte / lte).
2768
+ assistance_outlayed: Assistance-only outlayed (exact / gte / lte).
2769
+ contract_share_of_obligated_capped: Contracts as share of
2770
+ obligated, capped at 1.0 (exact / gte / lte). Use ``__gte`` to
2771
+ filter to contract-heavy accounts.
2772
+ obligated_to_apportioned_pct: Burn ratio
2773
+ (obligated / apportioned). Also ``_capped`` variant capped at
2774
+ 1.0. Both expose exact / gte / lte.
2775
+ apportioned_to_enacted_pct: Apportionment ratio
2776
+ (apportioned / enacted). Also ``_capped`` variant. Exact / gte / lte.
2777
+ obligated_to_enacted_pct: Obligated-to-enacted ratio. Also
2778
+ ``_capped`` variant. Exact / gte / lte.
2779
+ outlayed_to_obligated_pct: Spendout ratio (outlayed / obligated).
2780
+ Also ``_capped`` variant. Exact / gte / lte.
2781
+ unobligated_pct: Unobligated share of apportioned (exact / gte / lte).
2782
+ enacted_ba_yoy_pct: Year-over-year enacted BA growth
2783
+ (exact / gte / lte).
2784
+ obligated_yoy_pct: Year-over-year obligated growth
2785
+ (exact / gte / lte).
2786
+ enacted_ba_5yr_cagr: 5-year compound annual growth of enacted BA
2787
+ (exact / gte / lte).
2788
+ ba_growth_next_year_pct: Next-year requested BA growth
2789
+ (exact / gte / lte). Use ``__gte`` for forward-looking
2790
+ pipeline discovery.
2791
+ actual_vs_requested_contract: Realization ratio of contract
2792
+ obligated against the prior-year request (exact / gte / lte).
2793
+ Also ``_capped`` variant.
2677
2794
  search: Full-text search over account_title/agency_name/bureau_name.
2678
- ordering: Sort field (prefix with '-' for descending).
2795
+ ordering: Sort field (prefix with '-' for descending). Any of the
2796
+ numeric fields above is a valid ordering target — e.g.
2797
+ ``ordering="-unobligated_balance"`` to rank by largest
2798
+ headroom first.
2679
2799
  """
2680
2800
  params: dict[str, Any] = {"page": page, "limit": min(limit, 100)}
2681
2801
  if shape is None:
@@ -2686,7 +2806,7 @@ class TangoClient:
2686
2806
  params["flat"] = "true"
2687
2807
  if flat_lists:
2688
2808
  params["flat_lists"] = "true"
2689
- for key, val in (
2809
+ scalar_filters: tuple[tuple[str, Any], ...] = (
2690
2810
  ("federal_account_symbol", federal_account_symbol),
2691
2811
  ("fiscal_year", fiscal_year),
2692
2812
  ("fiscal_year__gte", fiscal_year_gte),
@@ -2699,9 +2819,146 @@ class TangoClient:
2699
2819
  ("subfunction_code", subfunction_code),
2700
2820
  ("search", search),
2701
2821
  ("ordering", ordering),
2702
- ):
2822
+ )
2823
+ for key, val in scalar_filters:
2703
2824
  if val is not None:
2704
2825
  params[key] = val
2826
+ # Range-numeric filters: each field has exact / __gte / __lte forms.
2827
+ range_filters: tuple[tuple[str, float | None, float | None, float | None], ...] = (
2828
+ ("requested_ba", requested_ba, requested_ba_gte, requested_ba_lte),
2829
+ ("enacted_ba", enacted_ba, enacted_ba_gte, enacted_ba_lte),
2830
+ ("apportioned", apportioned, apportioned_gte, apportioned_lte),
2831
+ ("obligated_total", obligated_total, obligated_total_gte, obligated_total_lte),
2832
+ ("outlayed_total", outlayed_total, outlayed_total_gte, outlayed_total_lte),
2833
+ (
2834
+ "unobligated_balance",
2835
+ unobligated_balance,
2836
+ unobligated_balance_gte,
2837
+ unobligated_balance_lte,
2838
+ ),
2839
+ (
2840
+ "contract_obligated",
2841
+ contract_obligated,
2842
+ contract_obligated_gte,
2843
+ contract_obligated_lte,
2844
+ ),
2845
+ (
2846
+ "contract_outlayed",
2847
+ contract_outlayed,
2848
+ contract_outlayed_gte,
2849
+ contract_outlayed_lte,
2850
+ ),
2851
+ (
2852
+ "assistance_obligated",
2853
+ assistance_obligated,
2854
+ assistance_obligated_gte,
2855
+ assistance_obligated_lte,
2856
+ ),
2857
+ (
2858
+ "assistance_outlayed",
2859
+ assistance_outlayed,
2860
+ assistance_outlayed_gte,
2861
+ assistance_outlayed_lte,
2862
+ ),
2863
+ (
2864
+ "contract_share_of_obligated_capped",
2865
+ contract_share_of_obligated_capped,
2866
+ contract_share_of_obligated_capped_gte,
2867
+ contract_share_of_obligated_capped_lte,
2868
+ ),
2869
+ (
2870
+ "obligated_to_apportioned_pct",
2871
+ obligated_to_apportioned_pct,
2872
+ obligated_to_apportioned_pct_gte,
2873
+ obligated_to_apportioned_pct_lte,
2874
+ ),
2875
+ (
2876
+ "obligated_to_apportioned_pct_capped",
2877
+ obligated_to_apportioned_pct_capped,
2878
+ obligated_to_apportioned_pct_capped_gte,
2879
+ obligated_to_apportioned_pct_capped_lte,
2880
+ ),
2881
+ (
2882
+ "apportioned_to_enacted_pct",
2883
+ apportioned_to_enacted_pct,
2884
+ apportioned_to_enacted_pct_gte,
2885
+ apportioned_to_enacted_pct_lte,
2886
+ ),
2887
+ (
2888
+ "apportioned_to_enacted_pct_capped",
2889
+ apportioned_to_enacted_pct_capped,
2890
+ apportioned_to_enacted_pct_capped_gte,
2891
+ apportioned_to_enacted_pct_capped_lte,
2892
+ ),
2893
+ (
2894
+ "obligated_to_enacted_pct",
2895
+ obligated_to_enacted_pct,
2896
+ obligated_to_enacted_pct_gte,
2897
+ obligated_to_enacted_pct_lte,
2898
+ ),
2899
+ (
2900
+ "obligated_to_enacted_pct_capped",
2901
+ obligated_to_enacted_pct_capped,
2902
+ obligated_to_enacted_pct_capped_gte,
2903
+ obligated_to_enacted_pct_capped_lte,
2904
+ ),
2905
+ (
2906
+ "outlayed_to_obligated_pct",
2907
+ outlayed_to_obligated_pct,
2908
+ outlayed_to_obligated_pct_gte,
2909
+ outlayed_to_obligated_pct_lte,
2910
+ ),
2911
+ (
2912
+ "outlayed_to_obligated_pct_capped",
2913
+ outlayed_to_obligated_pct_capped,
2914
+ outlayed_to_obligated_pct_capped_gte,
2915
+ outlayed_to_obligated_pct_capped_lte,
2916
+ ),
2917
+ ("unobligated_pct", unobligated_pct, unobligated_pct_gte, unobligated_pct_lte),
2918
+ (
2919
+ "enacted_ba_yoy_pct",
2920
+ enacted_ba_yoy_pct,
2921
+ enacted_ba_yoy_pct_gte,
2922
+ enacted_ba_yoy_pct_lte,
2923
+ ),
2924
+ (
2925
+ "obligated_yoy_pct",
2926
+ obligated_yoy_pct,
2927
+ obligated_yoy_pct_gte,
2928
+ obligated_yoy_pct_lte,
2929
+ ),
2930
+ (
2931
+ "enacted_ba_5yr_cagr",
2932
+ enacted_ba_5yr_cagr,
2933
+ enacted_ba_5yr_cagr_gte,
2934
+ enacted_ba_5yr_cagr_lte,
2935
+ ),
2936
+ (
2937
+ "ba_growth_next_year_pct",
2938
+ ba_growth_next_year_pct,
2939
+ ba_growth_next_year_pct_gte,
2940
+ ba_growth_next_year_pct_lte,
2941
+ ),
2942
+ (
2943
+ "actual_vs_requested_contract",
2944
+ actual_vs_requested_contract,
2945
+ actual_vs_requested_contract_gte,
2946
+ actual_vs_requested_contract_lte,
2947
+ ),
2948
+ (
2949
+ "actual_vs_requested_contract_capped",
2950
+ actual_vs_requested_contract_capped,
2951
+ actual_vs_requested_contract_capped_gte,
2952
+ actual_vs_requested_contract_capped_lte,
2953
+ ),
2954
+ )
2955
+ for field, exact, gte, lte in range_filters:
2956
+ if exact is not None:
2957
+ params[field] = exact
2958
+ if gte is not None:
2959
+ params[f"{field}__gte"] = gte
2960
+ if lte is not None:
2961
+ params[f"{field}__lte"] = lte
2705
2962
  data = self._get("/api/budget/accounts/", params)
2706
2963
  results = [
2707
2964
  self._parse_response_with_shape(obj, shape, BudgetAccount, flat, flat_lists)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tango-python
3
- Version: 1.1.3
3
+ Version: 1.2.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
@@ -1,5 +1,5 @@
1
- tango/__init__.py,sha256=GFajAGv2H7jhE0yuU7wJk8qOqEARV7Mg2bFIelwsodE,1912
2
- tango/client.py,sha256=3rZO03j-it7X0BP1EDJSpj5MVOV8JXtnC7AL2pijobQ,148758
1
+ tango/__init__.py,sha256=5IJJ7dqh_g9VN5f59ajqEoWcDoaxuQNcGHezYN5DBr4,1912
2
+ tango/client.py,sha256=sauxEB6UQ7kb7F2BKGB9lBQEXuOjT37lbWXD6OJbiUc,161143
3
3
  tango/exceptions.py,sha256=aRvDm0dUCEtNDfRVYCX7SEDdd1WlIVVY6sN78Tzo-a0,3114
4
4
  tango/models.py,sha256=QqUPtO7HJJDUaJDAMUkzvqR7pj1YIr8BetbS4palxc0,34261
5
5
  tango/shapes/__init__.py,sha256=7ea1WU74jp4znhNw-gXruag6m6eyPZtbVgbDFmFUWro,1072
@@ -15,8 +15,8 @@ tango/webhooks/cli.py,sha256=f_vQbJ2AeSQjKnQo7MxHFyUB2SAKcgHYmGQULS0isqQ,13858
15
15
  tango/webhooks/receiver.py,sha256=5yhsVhlLyoxmOCGvmbynWAIlDB2OaCPVf1H4GA1SxmU,9279
16
16
  tango/webhooks/signing.py,sha256=92Ee-0B6PR7ZkvY3Np3gzl88-mtfKkh-I7lxqCe2lGw,2374
17
17
  tango/webhooks/simulate.py,sha256=g2Osa0FYU5mJuon07T2aUCtmkUoTEzsY261tlp76fF0,3165
18
- tango_python-1.1.3.dist-info/METADATA,sha256=dvg8fyZFIcwz6xkS1J40HFHjtAxtIAfsolxz0RIM3aw,20599
19
- tango_python-1.1.3.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
20
- tango_python-1.1.3.dist-info/entry_points.txt,sha256=kGLUbglUjuaAqEFvOZ1QuSW0vWb6VeSpCIFKaOFkKoQ,50
21
- tango_python-1.1.3.dist-info/licenses/LICENSE,sha256=j2kYVHMwTkoGn3ZNScnrdIueG0k2XzB_LCPFoyBc2wk,1064
22
- tango_python-1.1.3.dist-info/RECORD,,
18
+ tango_python-1.2.0.dist-info/METADATA,sha256=WSJqToZWI1-xEBAXHA89qpr4SUQC4UhmnZqWZhD8pyE,20599
19
+ tango_python-1.2.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
20
+ tango_python-1.2.0.dist-info/entry_points.txt,sha256=kGLUbglUjuaAqEFvOZ1QuSW0vWb6VeSpCIFKaOFkKoQ,50
21
+ tango_python-1.2.0.dist-info/licenses/LICENSE,sha256=j2kYVHMwTkoGn3ZNScnrdIueG0k2XzB_LCPFoyBc2wk,1064
22
+ tango_python-1.2.0.dist-info/RECORD,,