Skip to content

Commit

Permalink
fix: update generated client, fix tests and improve organic data (#133)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
dfana01 and dfana authored Aug 28, 2024
1 parent 813fc8d commit 2c25cfa
Show file tree
Hide file tree
Showing 12 changed files with 238 additions and 32 deletions.
6 changes: 2 additions & 4 deletions integration_tests/ads/test_ad_groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,7 @@ def test_update_success(self):
)

new_name = "SDK_AD_GROUP_NEW_NAME"
new_spec = {
"GENDER": ["male"]
}
new_spec = {"gender": ["male"]}

ad_group.update_fields(
name=new_name,
Expand All @@ -74,7 +72,7 @@ def test_update_success(self):

assert ad_group
assert getattr(ad_group, "_name") == new_name
assert getattr(ad_group,"_targeting_spec") == new_spec
assert str(getattr(ad_group,"_targeting_spec")) == str(new_spec)

def test_update_fail_with_invalid_tracking_urls(self):
"""
Expand Down
34 changes: 17 additions & 17 deletions integration_tests/ads/test_conversion_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@
Test Conversion Model
"""
import os as _os
from datetime import datetime

from integration_tests.base_test import BaseTestCase
from integration_tests.config import DEFAULT_AD_ACCOUNT_ID
from openapi_generated.pinterest_client import ApiException

from pinterest.client import PinterestSDKClient
from pinterest.ads.conversion_events import Conversion

_get_event_time = lambda: int(datetime.now().timestamp())

class TestSendConversionEvent(BaseTestCase):
"""
Test send Conversion Event
Expand All @@ -21,15 +26,15 @@ def test_send_conversion_success(self):

NUMBER_OF_CONVERSION_EVENTS = 2
raw_user_data = dict(
em = ["964bbaf162703657e787eb4455197c8b35c18940c75980b0285619fe9b8acec8"] #random hash256
em = ["f660ab912ec121d1b1e928a0bb4bc61b15f5ad44d5efdc4e1c92a25e99b8e44a"] #random hash256
)
raw_custom_data = dict()

conversion_events = [
Conversion.create_conversion_event(
event_name = "add_to_cart",
action_source = "app_ios",
event_time = 1670026573,
event_time = _get_event_time(),
event_id = "eventId0001",
user_data = raw_user_data,
custom_data= raw_custom_data,
Expand Down Expand Up @@ -71,25 +76,20 @@ def test_send_conversion_fail(self):
Conversion.create_conversion_event(
event_name = "add_to_cart",
action_source = "app_ios",
event_time = 1670026573,
event_time = _get_event_time(),
event_id = "eventId0001",
user_data = raw_user_data,
custom_data = raw_custom_data,
)
for _ in range(NUMBER_OF_CONVERSION_EVENTS)
]

response = Conversion.send_conversion_events(
client = client,
ad_account_id = DEFAULT_AD_ACCOUNT_ID,
conversion_events = conversion_events,
test = True,
)

assert response
assert response.num_events_received == 2
assert response.num_events_processed == 0
assert len(response.events) == 2

assert 'hashed format' in response.events[0].error_message
assert 'hashed format' in response.events[0].error_message
try:
Conversion.send_conversion_events(
client = client,
ad_account_id = DEFAULT_AD_ACCOUNT_ID,
conversion_events = conversion_events,
test = True,
)
except ApiException as e:
assert e.status == 422
11 changes: 9 additions & 2 deletions integration_tests/clean_organic_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
"""

from pinterest.organic.boards import Board
from integration_tests.config import DEFAULT_BOARD_ID
from pinterest.organic.pins import Pin
from integration_tests.config import DEFAULT_BOARD_ID, DEFAULT_PIN_ID

def test_delete_organic_data():
"""
Expand All @@ -14,5 +15,11 @@ def test_delete_organic_data():
if board.id == DEFAULT_BOARD_ID:
continue
Board.delete(board_id=board.id)

assert len(Board.get_all()[0]) == 1

all_pins, _ = Pin.get_all()
for pin in all_pins:
if pin.id == DEFAULT_PIN_ID:
continue
Pin.delete(pin_id=pin.id)
assert len(Pin.get_all()[0]) == 1
4 changes: 4 additions & 0 deletions integration_tests/utils/organic_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ def create_new_board(self, **kwargs):
return Board.create(**_merge_default_params_with_params(self.get_default_params(), kwargs))

def delete_board(self, board_id):
if board_id == DEFAULT_BOARD_ID:
return
return Board.delete(board_id=board_id, client=self.test_client)


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

def delete_pin(self, pin_id):
if pin_id == DEFAULT_PIN_ID:
return
return Pin.delete(pin_id=pin_id, client=self.test_client)
10 changes: 10 additions & 0 deletions pinterest/ads/ad_groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from openapi_generated.pinterest_client.model.ad_group_response import AdGroupResponse
from openapi_generated.pinterest_client.model.ad_group_create_request import AdGroupCreateRequest
from openapi_generated.pinterest_client.model.ad_group_update_request import AdGroupUpdateRequest
from openapi_generated.pinterest_client.model.targeting_spec import TargetingSpec

from pinterest.client import PinterestSDKClient
from pinterest.utils.base_model import PinterestBaseModel
Expand Down Expand Up @@ -64,6 +65,7 @@ def __init__(
self._feed_profile_id = None
self._dca_assets = None
self._optimization_goal_metadata = None
self._targeting_template_ids = None

PinterestBaseModel.__init__(
self,
Expand Down Expand Up @@ -207,6 +209,11 @@ def optimization_goal_metadata(self):
#pylint: disable=missing-function-docstring
return self._optimization_goal_metadata

@property
def targeting_template_ids(self):
#pylint: disable=missing-function-docstring
return self._targeting_template_ids


@classmethod
def create(
Expand Down Expand Up @@ -351,6 +358,9 @@ def update_fields(self, **kwargs) -> bool:
kwargs["billable_event"] = ActionType(kwargs["billable_event"])
if "budget_type" in kwargs:
kwargs["budget_type"] = BudgetType(kwargs["budget_type"])
if "targeting_spec" in kwargs:
kwargs["targeting_spec"] = TargetingSpec(**kwargs["targeting_spec"])

return self._update(
params={
"ad_account_id": self._ad_account_id,
Expand Down
26 changes: 25 additions & 1 deletion pinterest/ads/ads.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@


class Ad(PinterestBaseModel):
# pylint: disable=R0903,duplicate-code
# pylint: disable=R0903,duplicate-code,R0902
"""
Ad model used to view, create, update its attributes
"""
Expand Down Expand Up @@ -63,6 +63,11 @@ def __init__(
self._type = None
self._updated_time = None
self._summary_status = None
self._grid_click_type = None
self._customizable_cta_type = None
self._lead_form_id = None
self._quiz_pin_data = None

PinterestBaseModel.__init__(
self,
_id=str(ad_id),
Expand Down Expand Up @@ -210,6 +215,25 @@ def summary_status(self) -> str:
# pylint: disable=missing-function-docstring
return self._summary_status

@property
def grid_click_type(self) -> str:
# pylint: disable=missing-function-docstring
return self._grid_click_type

@property
def customizable_cta_type(self) -> str:
# pylint: disable=missing-function-docstring
return self._customizable_cta_type

@property
def lead_form_id(self) -> str:
# pylint: disable=missing-function-docstring
return self._lead_form_id

@property
def quiz_pin_data(self) -> str:
# pylint: disable=missing-function-docstring
return self._quiz_pin_data

@classmethod
def create(cls,
Expand Down
4 changes: 3 additions & 1 deletion pinterest/client/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ def _get_config(cls, access_token: str,
api_uri: str = config.PINTEREST_API_URI,
debug: str = config.PINTEREST_DEBUG,
log_file: str = config.PINTEREST_LOG_FILE,
logger_format: str = config.PINTEREST_LOGGER_FORMAT):
logger_format: str = config.PINTEREST_LOGGER_FORMAT,
disabled_client_side_validations: str = config.PINTEREST_DISABLED_CLIENT_SIDE_VALIDATIONS):
_config = Configuration(
access_token=access_token,
host=api_uri,
Expand All @@ -150,6 +151,7 @@ def _get_config(cls, access_token: str,
_config.debug = debug
_config.logger_file = log_file
_config.logger_format = logger_format
_config.disabled_client_side_validations = disabled_client_side_validations
return _config

@classmethod
Expand Down
10 changes: 9 additions & 1 deletion pinterest/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,15 @@
PINTEREST_REFRESH_ACCESS_TOKEN = _os.environ.get('PINTEREST_REFRESH_ACCESS_TOKEN')
PINTEREST_API_URI = _os.environ.get('PINTEREST_API_URI', 'https://api.pinterest.com/v5')
PINTEREST_LOG_FILE = _os.environ.get('PINTEREST_LOG_FILE', None)
PINTEREST_DISABLED_CLIENT_SIDE_VALIDATIONS = _os.environ.get('PINTEREST_DISABLED_CLIENT_SIDE_VALIDATIONS', None)
DEFAULT_DISABLE_VALIDATIONS = ",".join([
'multipleOf', 'maximum', 'exclusiveMaximum',
'minimum', 'exclusiveMinimum', 'maxLength',
'minLength', 'pattern', 'maxItems', 'minItems',
])
PINTEREST_DISABLED_CLIENT_SIDE_VALIDATIONS = _os.environ.get(
'PINTEREST_DISABLED_CLIENT_SIDE_VALIDATIONS',
DEFAULT_DISABLE_VALIDATIONS
)
PINTEREST_LOGGER_FORMAT = _os.environ.get('PINTEREST_LOGGER_FORMAT', '%(asctime)s %(levelname)s %(message)s')
PINTEREST_SDK_VERSION = __version__
PINTEREST_USER_AGENT = f'pins-sdk/python/v{PINTEREST_SDK_VERSION}'
38 changes: 38 additions & 0 deletions pinterest/organic/boards.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
"""
from __future__ import annotations

from datetime import datetime

from openapi_generated.pinterest_client.api.boards_api import BoardsApi
from openapi_generated.pinterest_client.model.board import Board as GeneratedBoard
from openapi_generated.pinterest_client.model.board_update import BoardUpdate
Expand Down Expand Up @@ -209,6 +211,12 @@ def __init__(
self._description = None
self._owner = None
self._privacy = None
self._board_pins_modified_at = None
self._pin_count = None
self._created_at = None
self._media = None
self._collaborator_count = None
self._follower_count = None

PinterestBaseModel.__init__(
self,
Expand Down Expand Up @@ -247,6 +255,36 @@ def privacy(self) -> str:
# pylint: disable=missing-function-docstring
return self._privacy

@property
def board_pins_modified_at(self) -> datetime:
# pylint: disable=missing-function-docstring
return self._board_pins_modified_at

@property
def pin_count(self) -> int:
# pylint: disable=missing-function-docstring
return self._pin_count

@property
def created_at(self) -> datetime:
# pylint: disable=missing-function-docstring
return self._created_at

@property
def media(self) -> str:
# pylint: disable=missing-function-docstring
return self._media

@property
def collaborator_count(self) -> int:
# pylint: disable=missing-function-docstring
return self._collaborator_count

@property
def follower_count(self) -> int:
# pylint: disable=missing-function-docstring
return self._follower_count

def __repr__(self):
return f"{self.__class__.__name__}(board_id={self._id})"

Expand Down
Loading

0 comments on commit 2c25cfa

Please sign in to comment.