Skip to content

Commit 2c25cfa

Browse files
dfana01dfana
andauthored
fix: update generated client, fix tests and improve organic data (#133)
* fix: update generated client, fix tests and improve organic data * fix lint * fix: unit test * fix: remove _targeting_template_ids from campaigns --------- Co-authored-by: dfana <{ID}+{username}@users.noreply.github.com>
1 parent 813fc8d commit 2c25cfa

12 files changed

Lines changed: 238 additions & 32 deletions

File tree

integration_tests/ads/test_ad_groups.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,7 @@ def test_update_success(self):
6363
)
6464

6565
new_name = "SDK_AD_GROUP_NEW_NAME"
66-
new_spec = {
67-
"GENDER": ["male"]
68-
}
66+
new_spec = {"gender": ["male"]}
6967

7068
ad_group.update_fields(
7169
name=new_name,
@@ -74,7 +72,7 @@ def test_update_success(self):
7472

7573
assert ad_group
7674
assert getattr(ad_group, "_name") == new_name
77-
assert getattr(ad_group,"_targeting_spec") == new_spec
75+
assert str(getattr(ad_group,"_targeting_spec")) == str(new_spec)
7876

7977
def test_update_fail_with_invalid_tracking_urls(self):
8078
"""

integration_tests/ads/test_conversion_events.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,17 @@
22
Test Conversion Model
33
"""
44
import os as _os
5+
from datetime import datetime
6+
57
from integration_tests.base_test import BaseTestCase
68
from integration_tests.config import DEFAULT_AD_ACCOUNT_ID
9+
from openapi_generated.pinterest_client import ApiException
710

811
from pinterest.client import PinterestSDKClient
912
from pinterest.ads.conversion_events import Conversion
1013

14+
_get_event_time = lambda: int(datetime.now().timestamp())
15+
1116
class TestSendConversionEvent(BaseTestCase):
1217
"""
1318
Test send Conversion Event
@@ -21,15 +26,15 @@ def test_send_conversion_success(self):
2126

2227
NUMBER_OF_CONVERSION_EVENTS = 2
2328
raw_user_data = dict(
24-
em = ["964bbaf162703657e787eb4455197c8b35c18940c75980b0285619fe9b8acec8"] #random hash256
29+
em = ["f660ab912ec121d1b1e928a0bb4bc61b15f5ad44d5efdc4e1c92a25e99b8e44a"] #random hash256
2530
)
2631
raw_custom_data = dict()
2732

2833
conversion_events = [
2934
Conversion.create_conversion_event(
3035
event_name = "add_to_cart",
3136
action_source = "app_ios",
32-
event_time = 1670026573,
37+
event_time = _get_event_time(),
3338
event_id = "eventId0001",
3439
user_data = raw_user_data,
3540
custom_data= raw_custom_data,
@@ -71,25 +76,20 @@ def test_send_conversion_fail(self):
7176
Conversion.create_conversion_event(
7277
event_name = "add_to_cart",
7378
action_source = "app_ios",
74-
event_time = 1670026573,
79+
event_time = _get_event_time(),
7580
event_id = "eventId0001",
7681
user_data = raw_user_data,
7782
custom_data = raw_custom_data,
7883
)
7984
for _ in range(NUMBER_OF_CONVERSION_EVENTS)
8085
]
8186

82-
response = Conversion.send_conversion_events(
83-
client = client,
84-
ad_account_id = DEFAULT_AD_ACCOUNT_ID,
85-
conversion_events = conversion_events,
86-
test = True,
87-
)
88-
89-
assert response
90-
assert response.num_events_received == 2
91-
assert response.num_events_processed == 0
92-
assert len(response.events) == 2
93-
94-
assert 'hashed format' in response.events[0].error_message
95-
assert 'hashed format' in response.events[0].error_message
87+
try:
88+
Conversion.send_conversion_events(
89+
client = client,
90+
ad_account_id = DEFAULT_AD_ACCOUNT_ID,
91+
conversion_events = conversion_events,
92+
test = True,
93+
)
94+
except ApiException as e:
95+
assert e.status == 422

integration_tests/clean_organic_data.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
"""
44

55
from pinterest.organic.boards import Board
6-
from integration_tests.config import DEFAULT_BOARD_ID
6+
from pinterest.organic.pins import Pin
7+
from integration_tests.config import DEFAULT_BOARD_ID, DEFAULT_PIN_ID
78

89
def test_delete_organic_data():
910
"""
@@ -14,5 +15,11 @@ def test_delete_organic_data():
1415
if board.id == DEFAULT_BOARD_ID:
1516
continue
1617
Board.delete(board_id=board.id)
17-
1818
assert len(Board.get_all()[0]) == 1
19+
20+
all_pins, _ = Pin.get_all()
21+
for pin in all_pins:
22+
if pin.id == DEFAULT_PIN_ID:
23+
continue
24+
Pin.delete(pin_id=pin.id)
25+
assert len(Pin.get_all()[0]) == 1

integration_tests/utils/organic_utils.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ def create_new_board(self, **kwargs):
4747
return Board.create(**_merge_default_params_with_params(self.get_default_params(), kwargs))
4848

4949
def delete_board(self, board_id):
50+
if board_id == DEFAULT_BOARD_ID:
51+
return
5052
return Board.delete(board_id=board_id, client=self.test_client)
5153

5254

@@ -79,4 +81,6 @@ def create_new_pin(self, **kwargs):
7981
return Pin.create(**_merge_default_params_with_params(self.get_default_params(), kwargs))
8082

8183
def delete_pin(self, pin_id):
84+
if pin_id == DEFAULT_PIN_ID:
85+
return
8286
return Pin.delete(pin_id=pin_id, client=self.test_client)

pinterest/ads/ad_groups.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from openapi_generated.pinterest_client.model.ad_group_response import AdGroupResponse
1111
from openapi_generated.pinterest_client.model.ad_group_create_request import AdGroupCreateRequest
1212
from openapi_generated.pinterest_client.model.ad_group_update_request import AdGroupUpdateRequest
13+
from openapi_generated.pinterest_client.model.targeting_spec import TargetingSpec
1314

1415
from pinterest.client import PinterestSDKClient
1516
from pinterest.utils.base_model import PinterestBaseModel
@@ -64,6 +65,7 @@ def __init__(
6465
self._feed_profile_id = None
6566
self._dca_assets = None
6667
self._optimization_goal_metadata = None
68+
self._targeting_template_ids = None
6769

6870
PinterestBaseModel.__init__(
6971
self,
@@ -207,6 +209,11 @@ def optimization_goal_metadata(self):
207209
#pylint: disable=missing-function-docstring
208210
return self._optimization_goal_metadata
209211

212+
@property
213+
def targeting_template_ids(self):
214+
#pylint: disable=missing-function-docstring
215+
return self._targeting_template_ids
216+
210217

211218
@classmethod
212219
def create(
@@ -351,6 +358,9 @@ def update_fields(self, **kwargs) -> bool:
351358
kwargs["billable_event"] = ActionType(kwargs["billable_event"])
352359
if "budget_type" in kwargs:
353360
kwargs["budget_type"] = BudgetType(kwargs["budget_type"])
361+
if "targeting_spec" in kwargs:
362+
kwargs["targeting_spec"] = TargetingSpec(**kwargs["targeting_spec"])
363+
354364
return self._update(
355365
params={
356366
"ad_account_id": self._ad_account_id,

pinterest/ads/ads.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818

1919
class Ad(PinterestBaseModel):
20-
# pylint: disable=R0903,duplicate-code
20+
# pylint: disable=R0903,duplicate-code,R0902
2121
"""
2222
Ad model used to view, create, update its attributes
2323
"""
@@ -63,6 +63,11 @@ def __init__(
6363
self._type = None
6464
self._updated_time = None
6565
self._summary_status = None
66+
self._grid_click_type = None
67+
self._customizable_cta_type = None
68+
self._lead_form_id = None
69+
self._quiz_pin_data = None
70+
6671
PinterestBaseModel.__init__(
6772
self,
6873
_id=str(ad_id),
@@ -210,6 +215,25 @@ def summary_status(self) -> str:
210215
# pylint: disable=missing-function-docstring
211216
return self._summary_status
212217

218+
@property
219+
def grid_click_type(self) -> str:
220+
# pylint: disable=missing-function-docstring
221+
return self._grid_click_type
222+
223+
@property
224+
def customizable_cta_type(self) -> str:
225+
# pylint: disable=missing-function-docstring
226+
return self._customizable_cta_type
227+
228+
@property
229+
def lead_form_id(self) -> str:
230+
# pylint: disable=missing-function-docstring
231+
return self._lead_form_id
232+
233+
@property
234+
def quiz_pin_data(self) -> str:
235+
# pylint: disable=missing-function-docstring
236+
return self._quiz_pin_data
213237

214238
@classmethod
215239
def create(cls,

pinterest/client/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,8 @@ def _get_config(cls, access_token: str,
141141
api_uri: str = config.PINTEREST_API_URI,
142142
debug: str = config.PINTEREST_DEBUG,
143143
log_file: str = config.PINTEREST_LOG_FILE,
144-
logger_format: str = config.PINTEREST_LOGGER_FORMAT):
144+
logger_format: str = config.PINTEREST_LOGGER_FORMAT,
145+
disabled_client_side_validations: str = config.PINTEREST_DISABLED_CLIENT_SIDE_VALIDATIONS):
145146
_config = Configuration(
146147
access_token=access_token,
147148
host=api_uri,
@@ -150,6 +151,7 @@ def _get_config(cls, access_token: str,
150151
_config.debug = debug
151152
_config.logger_file = log_file
152153
_config.logger_format = logger_format
154+
_config.disabled_client_side_validations = disabled_client_side_validations
153155
return _config
154156

155157
@classmethod

pinterest/config.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,15 @@
2525
PINTEREST_REFRESH_ACCESS_TOKEN = _os.environ.get('PINTEREST_REFRESH_ACCESS_TOKEN')
2626
PINTEREST_API_URI = _os.environ.get('PINTEREST_API_URI', 'https://api.pinterest.com/v5')
2727
PINTEREST_LOG_FILE = _os.environ.get('PINTEREST_LOG_FILE', None)
28-
PINTEREST_DISABLED_CLIENT_SIDE_VALIDATIONS = _os.environ.get('PINTEREST_DISABLED_CLIENT_SIDE_VALIDATIONS', None)
28+
DEFAULT_DISABLE_VALIDATIONS = ",".join([
29+
'multipleOf', 'maximum', 'exclusiveMaximum',
30+
'minimum', 'exclusiveMinimum', 'maxLength',
31+
'minLength', 'pattern', 'maxItems', 'minItems',
32+
])
33+
PINTEREST_DISABLED_CLIENT_SIDE_VALIDATIONS = _os.environ.get(
34+
'PINTEREST_DISABLED_CLIENT_SIDE_VALIDATIONS',
35+
DEFAULT_DISABLE_VALIDATIONS
36+
)
2937
PINTEREST_LOGGER_FORMAT = _os.environ.get('PINTEREST_LOGGER_FORMAT', '%(asctime)s %(levelname)s %(message)s')
3038
PINTEREST_SDK_VERSION = __version__
3139
PINTEREST_USER_AGENT = f'pins-sdk/python/v{PINTEREST_SDK_VERSION}'

pinterest/organic/boards.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
"""
44
from __future__ import annotations
55

6+
from datetime import datetime
7+
68
from openapi_generated.pinterest_client.api.boards_api import BoardsApi
79
from openapi_generated.pinterest_client.model.board import Board as GeneratedBoard
810
from openapi_generated.pinterest_client.model.board_update import BoardUpdate
@@ -209,6 +211,12 @@ def __init__(
209211
self._description = None
210212
self._owner = None
211213
self._privacy = None
214+
self._board_pins_modified_at = None
215+
self._pin_count = None
216+
self._created_at = None
217+
self._media = None
218+
self._collaborator_count = None
219+
self._follower_count = None
212220

213221
PinterestBaseModel.__init__(
214222
self,
@@ -247,6 +255,36 @@ def privacy(self) -> str:
247255
# pylint: disable=missing-function-docstring
248256
return self._privacy
249257

258+
@property
259+
def board_pins_modified_at(self) -> datetime:
260+
# pylint: disable=missing-function-docstring
261+
return self._board_pins_modified_at
262+
263+
@property
264+
def pin_count(self) -> int:
265+
# pylint: disable=missing-function-docstring
266+
return self._pin_count
267+
268+
@property
269+
def created_at(self) -> datetime:
270+
# pylint: disable=missing-function-docstring
271+
return self._created_at
272+
273+
@property
274+
def media(self) -> str:
275+
# pylint: disable=missing-function-docstring
276+
return self._media
277+
278+
@property
279+
def collaborator_count(self) -> int:
280+
# pylint: disable=missing-function-docstring
281+
return self._collaborator_count
282+
283+
@property
284+
def follower_count(self) -> int:
285+
# pylint: disable=missing-function-docstring
286+
return self._follower_count
287+
250288
def __repr__(self):
251289
return f"{self.__class__.__name__}(board_id={self._id})"
252290

0 commit comments

Comments
 (0)