Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Documentation
- Documented (and pinned with tests) the OR syntax `list_entities(socioeconomic=...)` has always supported: pipe-separated values match entities holding any of the listed designations, e.g. `socioeconomic="OY|A2"`; values are SAM business-type codes (e.g. `OY` Black American Owned, `A6` SBA-certified 8(a), `A2` Woman Owned), not set-aside codes.

## [1.5.0] - 2026-08-04

### Added
Expand Down
2 changes: 1 addition & 1 deletion docs/API_REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -713,7 +713,7 @@ entities = client.list_entities(
- `name` - Filter by entity name
- `psc` - Filter by PSC code
- `purpose_of_registration_code` - Filter by registration purpose
- `socioeconomic` - Filter by socioeconomic status
- `socioeconomic` - Filter by socioeconomic status; takes SAM business-type codes (e.g. `OY` Black American Owned, `A6` SBA-certified 8(a), `A2` Woman Owned — see `GET /api/business_types/`), not set-aside codes; accepts pipe-separated values for OR semantics, e.g. `socioeconomic="OY|A2"`
- `state` - Filter by state
- `total_awards_obligated_gte` / `total_awards_obligated_lte` - Obligation amount range
- `uei` - Filter by UEI
Expand Down
2 changes: 1 addition & 1 deletion tango/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2081,7 +2081,7 @@ def list_entities(
name: Entity name filter
psc: PSC code filter
purpose_of_registration_code: Purpose of registration code
socioeconomic: Socioeconomic status filter
socioeconomic: Socioeconomic status filter; takes SAM business-type codes (e.g. "OY" Black American Owned, "A6" SBA-certified 8(a), "A2" Woman Owned — see `GET /api/business_types/`), not set-aside codes, and accepts pipe-separated values for OR semantics, e.g. ``socioeconomic="OY|A2"``
state: State filter
total_awards_obligated_gte: Total awards obligated >=
total_awards_obligated_lte: Total awards obligated <=
Expand Down
16 changes: 16 additions & 0 deletions tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1992,6 +1992,22 @@ def test_list_psc_omits_unset_has_awards(self, mock_request):
assert "has_awards" not in mock_request.call_args[1]["params"]


class TestEntityFilters:
"""The server ORs pipe-separated `socioeconomic` values; the SDK's job is to forward the string verbatim."""

@patch("tango.client.httpx.Client.request")
def test_list_entities_forwards_pipe_separated_socioeconomic(self, mock_request):
_stub_empty_page(mock_request)
TangoClient(api_key="test-key").list_entities(socioeconomic="OY|A2")
assert mock_request.call_args[1]["params"]["socioeconomic"] == "OY|A2"

@patch("tango.client.httpx.Client.request")
def test_list_entities_omits_unset_socioeconomic(self, mock_request):
_stub_empty_page(mock_request)
TangoClient(api_key="test-key").list_entities()
assert "socioeconomic" not in mock_request.call_args[1]["params"]


class TestAgencyFilterDiagnostics:
"""`meta` from the API's agency-filter diagnostics.

Expand Down
Loading