Skip to content

Commit 870c3f3

Browse files
author
Paul Duncan
committed
Introduce Saved_Locations support.
Deprecate OAUTH, & Accounts
1 parent 5e551ff commit 870c3f3

File tree

19 files changed

+23285
-2
lines changed

19 files changed

+23285
-2
lines changed

README.md

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,15 @@ If you are migrating to version 5.0.0 or above from an earlier version, please c
3535

3636
We support all the endpoints available in our API.
3737

38-
* `oauth2`
39-
* `accounts`
38+
* `oauth2` (deprecated, use `access_token` instead)
39+
* `accounts` (deprecated)
4040
* `broadcasts`
4141
* `events`
4242
* `features`
4343
* `places`
4444
* `radius`
4545
* `beam`
46+
* `saved_locations`
4647

4748
Please refer to our [API Documentation](https://docs.predicthq.com/) for a description of each endpoint.
4849

@@ -316,6 +317,31 @@ for event in phq.events.search(config={"verify_ssl": False}):
316317
```
317318

318319

320+
### Saved_Locations endpoints
321+
322+
Additional examples are available in [usecases/saved_locations.py](https://github.com/predicthq/sdk-py/tree/master/usecases/places.py) file.
323+
324+
The following example searches for the saved_locations according to the parameters defined:
325+
326+
```Python
327+
from predicthq import Client
328+
329+
phq = Client(access_token="abc123")
330+
331+
332+
for saved_location in phq.saved_locations.search(
333+
updated__gt="2016-03-01",
334+
updated__gte="2016-03-01",
335+
updated__lt="2016-04-01",
336+
updated__lte="2016-04-01",
337+
labels=["test", "retail"],
338+
user_id="user_id",
339+
subscription_valid_types=["events"],
340+
):
341+
print(saved_location.location_id, saved_location.create_dt, saved_location.status)
342+
```
343+
344+
319345
## Running Tests
320346

321347
```Shell

predicthq/client.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ def initialize_endpoints(self):
3636
self.places = endpoints.PlacesEndpoint(proxy(self))
3737
self.radius = endpoints.SuggestedRadiusEndpoint(proxy(self))
3838
self.beam = endpoints.BeamEndpoint(proxy(self))
39+
self.saved_locations = endpoints.SavedLocationsEndpoint(proxy(self))
3940

4041
def get_headers(self, headers):
4142
_headers = {

predicthq/endpoints/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from .v1.places import PlacesEndpoint
77
from .v1.radius import SuggestedRadiusEndpoint
88
from .v1.beam import BeamEndpoint
9+
from .v1.saved_locations import SavedLocationsEndpoint
910

1011

1112
__all__ = [
@@ -17,4 +18,5 @@
1718
"PlacesEndpoint",
1819
"SuggestedRadiusEndpoint",
1920
"BeamEndpoint",
21+
"SavedLocationsEndpoint",
2022
]

predicthq/endpoints/oauth2/endpoint.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,18 @@
22
from predicthq.endpoints.decorators import accepts, returns
33
from .decorators import preload_config_defaults
44
from .schemas import AccessToken
5+
from deprecated import deprecated
56

67

78
class OAuth2Endpoint(BaseEndpoint):
9+
10+
@deprecated(
11+
reason=(
12+
"OAuth2 endpoints in the SDK are deprecated and will be removed in future releases. "
13+
"Use TokenAuth (API Access Token) with Client(..., access_token=...)."
14+
),
15+
category=FutureWarning,
16+
)
817
@accepts()
918
@preload_config_defaults(["client_id", "client_secret", "scope", "grant_type"])
1019
@returns(AccessToken)
@@ -22,6 +31,14 @@ def get_token(self, client_id, client_secret, scope, grant_type, **kwargs):
2231
verify=verify_ssl,
2332
)
2433

34+
35+
@deprecated(
36+
reason=(
37+
"OAuth2 endpoints in the SDK are deprecated and will be removed in future releases. "
38+
"Use TokenAuth (API Access Token) with Client(..., access_token=...)."
39+
),
40+
category=FutureWarning,
41+
)
2542
@accepts()
2643
@preload_config_defaults(["client_id", "client_secret", "token_type_hint"])
2744
def revoke_token(self, client_id, client_secret, token, token_type_hint, **kwargs):
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
11
from predicthq.endpoints.base import BaseEndpoint
22
from predicthq.endpoints.decorators import returns
33
from .schemas import Account
4+
from deprecated import deprecated
45

56

67
class AccountsEndpoint(BaseEndpoint):
8+
9+
@deprecated(
10+
reason=(
11+
"The Accounts endpoint in the SDK is deprecated and will be removed in future releases. "
12+
"Account information can be managed via the PredictHQ dashboard."
13+
),
14+
category=FutureWarning,
15+
)
716
@returns(Account)
817
def self(self):
918
return self.client.get(self.build_url("v1", "accounts/self"))
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from .endpoint import SavedLocationsEndpoint
2+
from .schemas import SavedLocation
3+
4+
5+
__all__ = ["SavedLocationsEndpoint", "SavedLocation"]
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
from predicthq.endpoints.base import UserBaseEndpoint
2+
from predicthq.endpoints.base import BaseEndpoint
3+
from predicthq.endpoints.decorators import accepts, returns
4+
from typing import overload, List, Optional, TextIO, Union
5+
from pydantic import BaseModel
6+
from predicthq.endpoints.decorators import accepts, returns
7+
from .schemas import (
8+
SavedLocation,
9+
SavedLocationResultSet,
10+
CreateSavedLocationResponse,
11+
PostSharingEnableResponse,
12+
SuggestedRadiusResponse,Location
13+
)
14+
from ..events.schemas import EventResultSet
15+
16+
17+
from typing import Optional, List
18+
19+
# Python < 3.11 does not have StrEnum in the enum module
20+
import sys
21+
if sys.version_info < (3, 11):
22+
import enum
23+
24+
class StrEnum(str, enum.Enum):
25+
pass
26+
else:
27+
from enum import StrEnum
28+
29+
# Python < 3.9 does not have Annotated
30+
if sys.version_info < (3, 9):
31+
from typing_extensions import Annotated
32+
else:
33+
from typing import Annotated
34+
35+
# Python < 3.8 does not have Literal
36+
if sys.version_info < (3, 8):
37+
from typing_extensions import Literal
38+
else:
39+
from typing import Literal
40+
41+
42+
class SavedLocationsEndpoint(UserBaseEndpoint):
43+
44+
@overload
45+
def search(
46+
self,
47+
location_id: Optional[List[str]] = None,
48+
location_code: Optional[List[str]] = None,
49+
labels: Optional[List[str]] = None,
50+
user_id: Optional[List[str]] = None,
51+
subscription_valid_types: Optional[List[str]] = None,
52+
q: Optional[str] = None,
53+
sort: Optional[List[str]] = None,
54+
offset: Optional[int] = None,
55+
limit: Optional[int] = None,
56+
**params,
57+
): ...
58+
@accepts()
59+
@returns(SavedLocationResultSet)
60+
def search(self, **params):
61+
verify_ssl = params.pop("config.verify_ssl", True)
62+
result = self.client.get(
63+
self.build_url("v1", "saved-locations"),
64+
params=params,
65+
verify=verify_ssl,
66+
)
67+
return result
68+
69+
70+
@overload
71+
def create(
72+
self,
73+
name: str,
74+
geojson: dict,
75+
labels: Optional[List[str]] = None,
76+
location_code: Optional[str] = None,
77+
formatted_address: Optional[str] = None,
78+
description: Optional[str] = None,
79+
place_ids: Optional[List[str]] = None,
80+
**params,
81+
): ...
82+
@accepts(query_string=False)
83+
@returns(CreateSavedLocationResponse)
84+
def create(self, **params):
85+
verify_ssl = params.pop("config.verify_ssl", True)
86+
87+
result = self.client.post(
88+
f"{self.build_url('v1', 'saved-locations')}",
89+
json=params,
90+
verify=verify_ssl,
91+
)
92+
return result
93+
94+
95+
@accepts()
96+
@returns(SavedLocation)
97+
def get(self, location_id, **params):
98+
verify_ssl = params.pop("config.verify_ssl", True)
99+
return self.client.get(
100+
f"{self.build_url('v1', 'saved-locations')}{location_id}",
101+
params=params,
102+
verify=verify_ssl,
103+
)
104+
105+
106+
@overload
107+
def search_event_result_set(
108+
location_id : str,
109+
date_range_type : Optional[str] = None,
110+
offset : Optional[int] = None,
111+
limit : Optional[int] = None,
112+
**params,
113+
):...
114+
@returns(EventResultSet)
115+
def search_event_result_set(self, location_id, **params):
116+
"""
117+
Search for events for a saved location.
118+
119+
Args:
120+
location_id (str): The ID of the location.
121+
date_range_type (str, optional): The date range type filter.
122+
offset (int, optional): Pagination offset.
123+
limit (int, optional): Pagination limit.
124+
... (other query params)
125+
126+
Returns:
127+
EventResultSet: The result set of events.
128+
"""
129+
verify_ssl = params.pop("config.verify_ssl", True)
130+
url = f"{self.build_url('v1', 'saved-locations')}{location_id}/insights/events"
131+
response = self.client.get(
132+
url,
133+
params=params,
134+
verify=verify_ssl,
135+
)
136+
return response
137+
138+
139+
@accepts()
140+
def refresh_location_insights(self, location_id: str, **params):
141+
verify_ssl = params.pop("config.verify_ssl", True)
142+
return self.client.post(
143+
f"{self.build_url('v1', 'saved-locations')}{location_id}/insights/refresh/",
144+
params=params,
145+
verify=verify_ssl,
146+
)
147+
148+
149+
@overload
150+
def replace_location_data(
151+
self,
152+
location_id: str,
153+
name: str,
154+
geojson: dict,
155+
labels: Optional[List[str]] = None,
156+
location_code: Optional[str] = None,
157+
formatted_address: Optional[str] = None,
158+
description: Optional[str] = None,
159+
place_ids: Optional[List[str]] = None,
160+
external_id: Optional[str] = None,
161+
**params,
162+
):...
163+
@accepts(query_string=False)
164+
def replace_location_data(self, location_id: str, **params):
165+
verify_ssl = params.pop("config.verify_ssl", True)
166+
params.pop("location_id", None) # Remove location_id from payload
167+
response = self.client.put(
168+
f"{self.build_url('v1', 'saved-locations')}{location_id}",
169+
json=params,
170+
verify=verify_ssl,
171+
)
172+
return response
173+
174+
175+
@accepts()
176+
def delete_location(self, location_id: str, **params):
177+
verify_ssl = params.pop("config.verify_ssl", True)
178+
return self.client.delete(
179+
f"{self.build_url('v1', 'saved-locations')}{location_id}",
180+
params=params,
181+
verify=verify_ssl,
182+
)
183+
#
184+
#
185+
@accepts()
186+
@returns(PostSharingEnableResponse)
187+
def sharing_enable(self, location_id: str, **params):
188+
verify_ssl = params.pop("config.verify_ssl", True)
189+
return self.client.post(
190+
f"{self.build_url('v1', 'saved-locations')}{location_id}/sharing/enable",
191+
params=params,
192+
verify=verify_ssl,
193+
)
194+
195+
196+
@overload
197+
def suggested_radius(
198+
self,
199+
location_origin: Location,
200+
radius_unit: str,
201+
industry: str,
202+
**params,
203+
):...
204+
@accepts(query_string=False)
205+
@returns(SuggestedRadiusResponse)
206+
def suggested_radius(self, **params):
207+
verify_ssl = params.pop("config.verify_ssl", True)
208+
loc = params.pop("location_origin", None)
209+
if isinstance(loc, Location):
210+
params["location.origin"] = loc.as_geopoint()
211+
elif isinstance(loc, str):
212+
params["location.origin"] = loc
213+
return self.client.get(
214+
f"{self.build_url('v1', 'suggested-radius')}",
215+
params=params,
216+
verify=verify_ssl,
217+
)

0 commit comments

Comments
 (0)