tango-python 1.1.2__py3-none-any.whl → 1.1.3__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.2"
47
+ __version__ = "1.1.3"
48
48
  __all__ = [
49
49
  "TangoClient",
50
50
  "TangoAPIError",
tango/client.py CHANGED
@@ -1923,15 +1923,37 @@ class TangoClient:
1923
1923
  )
1924
1924
 
1925
1925
  # Business Types endpoints
1926
- def list_business_types(self, page: int = 1, limit: int = 25) -> PaginatedResponse:
1927
- """List business types"""
1928
- params = {"page": page, "limit": min(limit, 100)}
1926
+ def list_business_types(
1927
+ self,
1928
+ page: int = 1,
1929
+ limit: int = 25,
1930
+ shape: str | None = None,
1931
+ flat: bool = False,
1932
+ flat_lists: bool = False,
1933
+ ) -> PaginatedResponse:
1934
+ """List business types.
1935
+
1936
+ When ``shape`` is omitted the API applies its own default
1937
+ (``name,code``) and results are returned as :class:`BusinessType`
1938
+ instances. When ``shape`` is provided, raw dicts are returned so the
1939
+ caller can rely on the exact shape requested.
1940
+ """
1941
+ params: dict[str, Any] = {"page": page, "limit": min(limit, 100)}
1942
+ if shape:
1943
+ params["shape"] = shape
1944
+ if flat:
1945
+ params["flat"] = "true"
1946
+ if flat_lists:
1947
+ params["flat_lists"] = "true"
1929
1948
  data = self._get("/api/business_types/", params)
1949
+ results: list[Any] = (
1950
+ list(data["results"]) if shape else [BusinessType(**btype) for btype in data["results"]]
1951
+ )
1930
1952
  return PaginatedResponse(
1931
1953
  count=data["count"],
1932
1954
  next=data.get("next"),
1933
1955
  previous=data.get("previous"),
1934
- results=[BusinessType(**btype) for btype in data["results"]],
1956
+ results=results,
1935
1957
  )
1936
1958
 
1937
1959
  def list_naics(
@@ -1945,8 +1967,17 @@ class TangoClient:
1945
1967
  revenue_limit_gte: int | None = None,
1946
1968
  revenue_limit_lte: int | None = None,
1947
1969
  search: str | None = None,
1970
+ shape: str | None = None,
1971
+ flat: bool = False,
1972
+ flat_lists: bool = False,
1948
1973
  ) -> PaginatedResponse:
1949
- """List NAICS codes (`/api/naics/`)."""
1974
+ """List NAICS codes (`/api/naics/`).
1975
+
1976
+ When ``shape`` is omitted the API applies its own default. Passing any
1977
+ of the ``revenue_limit*`` / ``employee_limit*`` filters causes the API
1978
+ to widen the default shape to include ``size_standards`` and
1979
+ ``federal_obligations``.
1980
+ """
1950
1981
  params: dict[str, Any] = {"page": page, "limit": min(limit, 100)}
1951
1982
  if employee_limit is not None:
1952
1983
  params["employee_limit"] = employee_limit
@@ -1962,6 +1993,12 @@ class TangoClient:
1962
1993
  params["revenue_limit_lte"] = revenue_limit_lte
1963
1994
  if search is not None:
1964
1995
  params["search"] = search
1996
+ if shape:
1997
+ params["shape"] = shape
1998
+ if flat:
1999
+ params["flat"] = "true"
2000
+ if flat_lists:
2001
+ params["flat_lists"] = "true"
1965
2002
  data = self._get("/api/naics/", params)
1966
2003
  return PaginatedResponse(
1967
2004
  count=data.get("count", 0),
@@ -3344,9 +3381,22 @@ class TangoClient:
3344
3381
  raise TangoValidationError("Department code is required")
3345
3382
  return self._get(f"/api/departments/{code}/")
3346
3383
 
3347
- def list_psc(self, page: int = 1, limit: int = 25) -> PaginatedResponse[dict[str, Any]]:
3384
+ def list_psc(
3385
+ self,
3386
+ page: int = 1,
3387
+ limit: int = 25,
3388
+ shape: str | None = None,
3389
+ flat: bool = False,
3390
+ flat_lists: bool = False,
3391
+ ) -> PaginatedResponse[dict[str, Any]]:
3348
3392
  """List Product Service Codes (`/api/psc/`)."""
3349
3393
  params: dict[str, Any] = {"page": page, "limit": min(limit, 100)}
3394
+ if shape:
3395
+ params["shape"] = shape
3396
+ if flat:
3397
+ params["flat"] = "true"
3398
+ if flat_lists:
3399
+ params["flat_lists"] = "true"
3350
3400
  data = self._get("/api/psc/", params)
3351
3401
  return PaginatedResponse(
3352
3402
  count=int(data.get("count", 0)),
@@ -3355,11 +3405,24 @@ class TangoClient:
3355
3405
  results=list(data.get("results") or []),
3356
3406
  )
3357
3407
 
3358
- def get_psc(self, code: str) -> dict[str, Any]:
3408
+ def get_psc(
3409
+ self,
3410
+ code: str,
3411
+ shape: str | None = None,
3412
+ flat: bool = False,
3413
+ flat_lists: bool = False,
3414
+ ) -> dict[str, Any]:
3359
3415
  """Get a Product Service Code by code (`/api/psc/{code}/`)."""
3360
3416
  if not code:
3361
3417
  raise TangoValidationError("PSC code is required")
3362
- return self._get(f"/api/psc/{code}/")
3418
+ params: dict[str, Any] = {}
3419
+ if shape:
3420
+ params["shape"] = shape
3421
+ if flat:
3422
+ params["flat"] = "true"
3423
+ if flat_lists:
3424
+ params["flat_lists"] = "true"
3425
+ return self._get(f"/api/psc/{code}/", params)
3363
3426
 
3364
3427
  def get_psc_metrics(self, code: str, months: int, period_grouping: str) -> dict[str, Any]:
3365
3428
  """Get rolling PSC metrics (`/api/psc/{code}/metrics/{months}/{period_grouping}/`).
@@ -3374,11 +3437,24 @@ class TangoClient:
3374
3437
  raise TangoValidationError("PSC code is required")
3375
3438
  return self._get(f"/api/psc/{code}/metrics/{months}/{period_grouping}/")
3376
3439
 
3377
- def get_naics(self, code: str) -> dict[str, Any]:
3440
+ def get_naics(
3441
+ self,
3442
+ code: str,
3443
+ shape: str | None = None,
3444
+ flat: bool = False,
3445
+ flat_lists: bool = False,
3446
+ ) -> dict[str, Any]:
3378
3447
  """Get a NAICS code by code (`/api/naics/{code}/`)."""
3379
3448
  if not code:
3380
3449
  raise TangoValidationError("NAICS code is required")
3381
- return self._get(f"/api/naics/{code}/")
3450
+ params: dict[str, Any] = {}
3451
+ if shape:
3452
+ params["shape"] = shape
3453
+ if flat:
3454
+ params["flat"] = "true"
3455
+ if flat_lists:
3456
+ params["flat_lists"] = "true"
3457
+ return self._get(f"/api/naics/{code}/", params)
3382
3458
 
3383
3459
  def get_naics_metrics(self, code: str, months: int, period_grouping: str) -> dict[str, Any]:
3384
3460
  """Get rolling NAICS metrics (`/api/naics/{code}/metrics/{months}/{period_grouping}/`)."""
@@ -3386,17 +3462,41 @@ class TangoClient:
3386
3462
  raise TangoValidationError("NAICS code is required")
3387
3463
  return self._get(f"/api/naics/{code}/metrics/{months}/{period_grouping}/")
3388
3464
 
3389
- def get_business_type(self, code: str) -> dict[str, Any]:
3465
+ def get_business_type(
3466
+ self,
3467
+ code: str,
3468
+ shape: str | None = None,
3469
+ flat: bool = False,
3470
+ flat_lists: bool = False,
3471
+ ) -> dict[str, Any]:
3390
3472
  """Get a business type by code (`/api/business_types/{code}/`)."""
3391
3473
  if not code:
3392
3474
  raise TangoValidationError("Business type code is required")
3393
- return self._get(f"/api/business_types/{code}/")
3475
+ params: dict[str, Any] = {}
3476
+ if shape:
3477
+ params["shape"] = shape
3478
+ if flat:
3479
+ params["flat"] = "true"
3480
+ if flat_lists:
3481
+ params["flat_lists"] = "true"
3482
+ return self._get(f"/api/business_types/{code}/", params)
3394
3483
 
3395
3484
  def list_assistance_listings(
3396
- self, page: int = 1, limit: int = 25
3485
+ self,
3486
+ page: int = 1,
3487
+ limit: int = 25,
3488
+ shape: str | None = None,
3489
+ flat: bool = False,
3490
+ flat_lists: bool = False,
3397
3491
  ) -> PaginatedResponse[dict[str, Any]]:
3398
3492
  """List Assistance Listings (CFDA programs) (`/api/assistance_listings/`)."""
3399
3493
  params: dict[str, Any] = {"page": page, "limit": min(limit, 100)}
3494
+ if shape:
3495
+ params["shape"] = shape
3496
+ if flat:
3497
+ params["flat"] = "true"
3498
+ if flat_lists:
3499
+ params["flat_lists"] = "true"
3400
3500
  data = self._get("/api/assistance_listings/", params)
3401
3501
  return PaginatedResponse(
3402
3502
  count=int(data.get("count", 0)),
@@ -3405,22 +3505,44 @@ class TangoClient:
3405
3505
  results=list(data.get("results") or []),
3406
3506
  )
3407
3507
 
3408
- def get_assistance_listing(self, number: str) -> dict[str, Any]:
3508
+ def get_assistance_listing(
3509
+ self,
3510
+ number: str,
3511
+ shape: str | None = None,
3512
+ flat: bool = False,
3513
+ flat_lists: bool = False,
3514
+ ) -> dict[str, Any]:
3409
3515
  """Get an Assistance Listing by CFDA number (`/api/assistance_listings/{number}/`)."""
3410
3516
  if not number:
3411
3517
  raise TangoValidationError("Assistance listing number is required")
3412
- return self._get(f"/api/assistance_listings/{number}/")
3518
+ params: dict[str, Any] = {}
3519
+ if shape:
3520
+ params["shape"] = shape
3521
+ if flat:
3522
+ params["flat"] = "true"
3523
+ if flat_lists:
3524
+ params["flat_lists"] = "true"
3525
+ return self._get(f"/api/assistance_listings/{number}/", params)
3413
3526
 
3414
3527
  def list_mas_sins(
3415
3528
  self,
3416
3529
  page: int = 1,
3417
3530
  limit: int = 25,
3418
3531
  search: str | None = None,
3532
+ shape: str | None = None,
3533
+ flat: bool = False,
3534
+ flat_lists: bool = False,
3419
3535
  ) -> PaginatedResponse[dict[str, Any]]:
3420
3536
  """List GSA MAS SINs (`/api/mas_sins/`)."""
3421
3537
  params: dict[str, Any] = {"page": page, "limit": min(limit, 100)}
3422
3538
  if search is not None:
3423
3539
  params["search"] = search
3540
+ if shape:
3541
+ params["shape"] = shape
3542
+ if flat:
3543
+ params["flat"] = "true"
3544
+ if flat_lists:
3545
+ params["flat_lists"] = "true"
3424
3546
  data = self._get("/api/mas_sins/", params)
3425
3547
  return PaginatedResponse(
3426
3548
  count=int(data.get("count", 0)),
@@ -3429,11 +3551,24 @@ class TangoClient:
3429
3551
  results=list(data.get("results") or []),
3430
3552
  )
3431
3553
 
3432
- def get_mas_sin(self, sin: str) -> dict[str, Any]:
3554
+ def get_mas_sin(
3555
+ self,
3556
+ sin: str,
3557
+ shape: str | None = None,
3558
+ flat: bool = False,
3559
+ flat_lists: bool = False,
3560
+ ) -> dict[str, Any]:
3433
3561
  """Get a MAS SIN by code (`/api/mas_sins/{sin}/`)."""
3434
3562
  if not sin:
3435
3563
  raise TangoValidationError("MAS SIN is required")
3436
- return self._get(f"/api/mas_sins/{sin}/")
3564
+ params: dict[str, Any] = {}
3565
+ if shape:
3566
+ params["shape"] = shape
3567
+ if flat:
3568
+ params["flat"] = "true"
3569
+ if flat_lists:
3570
+ params["flat_lists"] = "true"
3571
+ return self._get(f"/api/mas_sins/{sin}/", params)
3437
3572
 
3438
3573
  # ============================================================================
3439
3574
  # Entity sub-resources
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tango-python
3
- Version: 1.1.2
3
+ Version: 1.1.3
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=gg4U46hFhUJwgvbGtOdP3vgooi8US-fLXvpBZ060_H8,1912
2
- tango/client.py,sha256=9-IfMZwerx4uRsPlDI38uQDv77TNl2qShCHVtP4t7EU,144839
1
+ tango/__init__.py,sha256=GFajAGv2H7jhE0yuU7wJk8qOqEARV7Mg2bFIelwsodE,1912
2
+ tango/client.py,sha256=3rZO03j-it7X0BP1EDJSpj5MVOV8JXtnC7AL2pijobQ,148758
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.2.dist-info/METADATA,sha256=-wGAubnmnT1ysNyUThjVuYWx3p9IjDPf-4FQrxy756U,20599
19
- tango_python-1.1.2.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
20
- tango_python-1.1.2.dist-info/entry_points.txt,sha256=kGLUbglUjuaAqEFvOZ1QuSW0vWb6VeSpCIFKaOFkKoQ,50
21
- tango_python-1.1.2.dist-info/licenses/LICENSE,sha256=j2kYVHMwTkoGn3ZNScnrdIueG0k2XzB_LCPFoyBc2wk,1064
22
- tango_python-1.1.2.dist-info/RECORD,,
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,,