diff --git a/CHANGELOG.md b/CHANGELOG.md index c562710..a485161 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/docs/API_REFERENCE.md b/docs/API_REFERENCE.md index e7c7560..a93f1d8 100644 --- a/docs/API_REFERENCE.md +++ b/docs/API_REFERENCE.md @@ -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 diff --git a/tango/client.py b/tango/client.py index 29d9f1b..dbfbe9f 100644 --- a/tango/client.py +++ b/tango/client.py @@ -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 <= diff --git a/tests/test_client.py b/tests/test_client.py index 737c1b1..3ce0f1b 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -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.