Skip to content

Commit 6fffa70

Browse files
committed
fix(typing): resolve list-shadowing, ship py.typed cleanly; v0.5.1
- Qualify builtin list as builtins.list where a 'list' method shadows it (Locations/Reviews/Photos/ConnectedAccounts) so annotations stay checkable once py.typed ships (mypy 28 -> 0) - Fix README clone URL to github.com/listings-api/listingsapi-python-sdk - Bump version to 0.5.1
1 parent 980987b commit 6fffa70

9 files changed

Lines changed: 34 additions & 30 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,7 @@ client = listingsapi.ListingsAPI(
533533
Runnable scripts for every area live in [examples/](examples/), from a 10-line quickstart to a full FastAPI backend.
534534

535535
```bash
536-
git clone https://github.com/Listings-API/listingsapi-python-sdk.git
536+
git clone https://github.com/listings-api/listingsapi-python-sdk.git
537537
cd listingsapi-python-sdk
538538
pip install -e ".[dev]"
539539
pytest

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "listingsapi"
7-
version = "0.5.0"
7+
version = "0.5.1"
88
description = "Python SDK for listingsAPI — listings, reviews, posts, and analytics for local marketing"
99
readme = "README.md"
1010
requires-python = ">=3.9"

src/listingsapi/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
ValidationError,
2424
)
2525

26-
__version__ = "0.5.0"
26+
__version__ = "0.5.1"
2727

2828
__all__ = [
2929
# Client

src/listingsapi/resources/connected_accounts.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from __future__ import annotations
44

5+
import builtins
56
from typing import Any
67

78
from listingsapi._types import APIObject
@@ -43,7 +44,7 @@ def details(self, connected_account_id: str) -> APIObject:
4344
data = self._get(f"connected-accounts/{connected_account_id}/details")
4445
return APIObject(data.get("data", {}).get("connectedAccountDetails") or {})
4546

46-
def folders(self, connected_account_id: str, *, folder_name: str | None = None) -> list[APIObject]:
47+
def folders(self, connected_account_id: str, *, folder_name: str | None = None) -> builtins.list[APIObject]:
4748
"""Get folders under a connected Google account."""
4849
params: dict[str, str] = {}
4950
if folder_name is not None:
@@ -115,15 +116,15 @@ def disconnect_facebook(self, connected_account_id: str) -> APIObject:
115116
)
116117
return APIObject(data.get("data", {}).get("fbBulkDisconnect") or {})
117118

118-
def trigger_matches(self, connected_account_ids: list[str]) -> APIObject:
119+
def trigger_matches(self, connected_account_ids: builtins.list[str]) -> APIObject:
119120
"""Trigger matching of profiles to listingsAPI locations."""
120121
data = self._post(
121122
"connected-accounts/trigger-matches",
122123
{"input": {"connectedAccountIds": connected_account_ids}},
123124
)
124125
return APIObject(data.get("data", {}).get("connectedAccountsTriggerMatches") or {})
125126

126-
def confirm_matches(self, match_record_ids: list[str]) -> APIObject:
127+
def confirm_matches(self, match_record_ids: builtins.list[str]) -> APIObject:
127128
"""Confirm suggested matches between connected account listings and locations."""
128129
data = self._post(
129130
"connected-accounts/confirm-matches",

src/listingsapi/resources/locations.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from __future__ import annotations
44

5+
import builtins
56
import json
67
from typing import Any
78

@@ -78,7 +79,7 @@ def retrieve(self, location_id: str | int) -> APIObject:
7879
raise NotFoundError(f"Location {location_id} not found", status_code=404)
7980
return results[0]
8081

81-
def list_by_ids(self, location_ids: list[str | int]) -> list[APIObject]:
82+
def list_by_ids(self, location_ids: builtins.list[str | int]) -> builtins.list[APIObject]:
8283
"""Get locations by a list of IDs (numeric or base64)."""
8384
if not location_ids:
8485
return []
@@ -87,7 +88,7 @@ def list_by_ids(self, location_ids: list[str | int]) -> list[APIObject]:
8788
items = data.get("data", {}).get("getLocationsByIds") or []
8889
return [APIObject(item) for item in items]
8990

90-
def list_by_store_codes(self, store_codes: list[str]) -> list[APIObject]:
91+
def list_by_store_codes(self, store_codes: builtins.list[str]) -> builtins.list[APIObject]:
9192
"""Get locations matching the given store codes."""
9293
if not store_codes:
9394
return []
@@ -99,7 +100,7 @@ def search(
99100
self,
100101
query: str,
101102
*,
102-
fields: list[str] | None = None,
103+
fields: builtins.list[str] | None = None,
103104
first: int | None = None,
104105
after: str | None = None,
105106
before: str | None = None,
@@ -168,11 +169,11 @@ def add(
168169
website: str | None = None,
169170
store_id: str | None = None,
170171
hide_address: bool | None = None,
171-
business_hours: list[dict[str, Any]] | None = None,
172-
folder_ids: list[str] | None = None,
172+
business_hours: builtins.list[dict[str, Any]] | None = None,
173+
folder_ids: builtins.list[str] | None = None,
173174
service_area: dict[str, Any] | None = None,
174-
place_action_links: list[dict[str, Any]] | None = None,
175-
enabled_site_ids: list[int] | None = None,
175+
place_action_links: builtins.list[dict[str, Any]] | None = None,
176+
enabled_site_ids: builtins.list[int] | None = None,
176177
additional_fields: dict[str, Any] | None = None,
177178
) -> APIObject:
178179
"""Create a location in one call with every mandatory field as a keyword argument.
@@ -222,7 +223,7 @@ def add(
222223
)
223224
print(result.location.id)
224225
"""
225-
problems: list[str] = []
226+
problems: builtins.list[str] = []
226227
if not name or not (2 <= len(name.strip()) <= 150):
227228
problems.append("name must be 2-150 characters")
228229
if not description or len(description.strip()) < 200:
@@ -276,15 +277,15 @@ def update(self, input: dict[str, Any]) -> APIObject:
276277
data = self._post("locations/update", {"input": input})
277278
return APIObject(data.get("data", {}).get("updateLocation") or {})
278279

279-
def archive(self, location_ids: list[str | int]) -> APIObject:
280+
def archive(self, location_ids: builtins.list[str | int]) -> APIObject:
280281
"""Archive one or more locations."""
281282
encoded = [encode_location_id(lid) for lid in location_ids]
282283
data = self._post("locations/archive", {"input": {"locationIds": encoded}})
283284
return APIObject(data.get("data", {}).get("archiveLocations") or {})
284285

285286

286287
def cancel_archive(
287-
self, location_ids: list[str | int], selection_type: str, changed_by: str
288+
self, location_ids: builtins.list[str | int], selection_type: str, changed_by: str
288289
) -> APIObject:
289290
"""Cancel a scheduled archival."""
290291
encoded = [encode_location_id(lid) for lid in location_ids]

src/listingsapi/resources/photos.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from __future__ import annotations
44

5+
import builtins
56
from typing import Any
67

78
from listingsapi._types import APIObject
@@ -17,29 +18,29 @@ class Photos(APIResource):
1718
client.photos.add(16808, [{"photo": "https://example.com/img.jpg", "type": "ADDITIONAL"}])
1819
"""
1920

20-
def list(self, location_id: str | int) -> list[APIObject]:
21+
def list(self, location_id: str | int) -> builtins.list[APIObject]:
2122
"""Get photos attached to a location."""
2223
data = self._location_get(location_id, "photos")
2324
items = data.get("data", {}).get("mediaFilesOfLocation") or []
2425
return [APIObject(item) for item in items]
2526

26-
def add(self, location_id: str | int, photos: list[dict[str, Any]]) -> APIObject:
27+
def add(self, location_id: str | int, photos: builtins.list[dict[str, Any]]) -> APIObject:
2728
"""Add photos to a location. Each item needs 'photo' (URL) and 'type' (LOGO, COVER, ADDITIONAL)."""
2829
data = self._post(
2930
"locations/photos",
3031
{"input": {"locationId": encode_location_id(location_id), "photos": photos}},
3132
)
3233
return APIObject(data.get("data", {}).get("addLocationPhotos") or {})
3334

34-
def remove(self, location_id: str | int, photo_ids: list[str]) -> APIObject:
35+
def remove(self, location_id: str | int, photo_ids: builtins.list[str]) -> APIObject:
3536
"""Remove photos from a location."""
3637
data = self._post(
3738
"locations/photos/remove",
3839
{"input": {"locationId": encode_location_id(location_id), "photoIds": photo_ids}},
3940
)
4041
return APIObject(data.get("data", {}).get("removeLocationPhotos") or {})
4142

42-
def star(self, location_id: str | int, media_ids: list[str], *, starred: bool = True) -> APIObject:
43+
def star(self, location_id: str | int, media_ids: builtins.list[str], *, starred: bool = True) -> APIObject:
4344
"""Star or unstar photos. Max 4 starred photos per account."""
4445
data = self._post(
4546
"locations/photos/star",

src/listingsapi/resources/reviews.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from __future__ import annotations
44

5+
import builtins
56
import json
67
from typing import Any
78

@@ -79,11 +80,11 @@ def list(
7980
after: str | None = None,
8081
before: str | None = None,
8182
last: int | None = None,
82-
site_urls: list[str] | None = None,
83+
site_urls: builtins.list[str] | None = None,
8384
start_date: str | None = None,
8485
end_date: str | None = None,
8586
category: str | None = None,
86-
rating_filters: list[int] | None = None,
87+
rating_filters: builtins.list[int] | None = None,
8788
) -> SyncPage:
8889
"""List reviews for a location with optional filters."""
8990
params: dict[str, Any] = {}
@@ -155,15 +156,15 @@ def settings(self, location_id: str | int) -> APIObject:
155156
data = self._location_get(location_id, "reviews/settings")
156157
return APIObject(data.get("data", {}).get("interactionsSetting") or {})
157158

158-
def edit_settings(self, location_id: str | int, site_urls: list[dict[str, Any]]) -> APIObject:
159+
def edit_settings(self, location_id: str | int, site_urls: builtins.list[dict[str, Any]]) -> APIObject:
159160
"""Update review source URLs for a location."""
160161
data = self._post(
161162
"locations/reviews/settings/edit",
162163
{"locationId": encode_location_id(location_id), "siteUrls": site_urls},
163164
)
164165
return APIObject(data.get("data", {}).get("editInteractionsSetting") or {})
165166

166-
def details(self, interaction_ids: list[str]) -> APIObject:
167+
def details(self, interaction_ids: builtins.list[str]) -> APIObject:
167168
"""Get detailed info for specific reviews by ID."""
168169
if not interaction_ids:
169170
return APIObject({})
@@ -172,12 +173,12 @@ def details(self, interaction_ids: list[str]) -> APIObject:
172173

173174
def phrases(
174175
self,
175-
location_ids: list[str],
176+
location_ids: builtins.list[str],
176177
*,
177-
site_urls: list[str] | None = None,
178+
site_urls: builtins.list[str] | None = None,
178179
start_date: str | None = None,
179180
end_date: str | None = None,
180-
) -> list[APIObject]:
181+
) -> builtins.list[APIObject]:
181182
"""Get commonly mentioned phrases from reviews."""
182183
if not location_ids:
183184
return []
@@ -192,7 +193,7 @@ def phrases(
192193
items = data.get("data", {}).get("newReviewPhrases") or []
193194
return [APIObject(item) for item in items]
194195

195-
def site_config(self) -> list[APIObject]:
196+
def site_config(self) -> builtins.list[APIObject]:
196197
"""Get eligible review sites for the account."""
197198
data = self._get("reviews/site-config")
198199
items = data.get("data", {}).get("interactionSiteConfig") or []

src/listingsapi/resources/workflows.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ def weekly_reputation_report(
134134

135135
review_overview = reviews.analytics.overview(location_id, **date_params).to_dict()
136136

137-
review_page = reviews.list(location_id, first=50, **date_params)
137+
review_page = reviews.list(location_id, first=50, start_date=start_date, end_date=end_date)
138138
recent_reviews = [r.to_dict() for r in review_page]
139139

140140
google = analytics.google(location_id, from_date=start_date, to_date=end_date).to_dict()

tests/test_listingsapi.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ def test_analytics_google(client):
388388

389389

390390
def test_version():
391-
assert listingsapi.__version__ == "0.5.0"
391+
assert listingsapi.__version__ == "0.5.1"
392392

393393

394394
# --- locations.add (one-call create with validation) ---

0 commit comments

Comments
 (0)