From 57211d70fb9cefb7b68627191cc03b412ef4f0b5 Mon Sep 17 00:00:00 2001 From: qitia Date: Tue, 13 Mar 2018 07:20:45 +0000 Subject: [PATCH] update to version 11.5.9 --- HISTORY.rst | 5 + README.rst | 17 +- bingads/authorization.py | 60 ++-- bingads/manifest.py | 2 +- .../proxies/campaign_management_service.xml | 292 +++++++++++++++++- setup.py | 2 +- 6 files changed, 345 insertions(+), 33 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index 20726218..cf9c40ab 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -1,6 +1,11 @@ .. :changelog: Release History +--------------- +11.5.9(2018-03-12) ++++++++++++++++++++ +*Updated to support [Microsoft Account authentication in sandbox](https://docs.microsoft.com/en-us/bingads/guides/sandbox.md#access). + --------------- 11.5.8(2018-01-12) +++++++++++++++++++ diff --git a/README.rst b/README.rst index 344e2b58..9ac70da7 100644 --- a/README.rst +++ b/README.rst @@ -6,14 +6,19 @@ Bing Ads Python SDK :target: https://pypi.python.org/pypi/bingads -The Bing Ads Python Software Development Kit (SDK) Version 11.5 enhances the experience of developing Bing Ads applications with the Python programming language. - -The SDK includes proxy classes for all Bing Ads API web services and abstracts the low level details of authentication with OAuth. You can also read and write bulk files with the SDK BulkFileReader and BulkFileWriter, and use the high level BulkServiceManager interface to abstract and execute operations in the low level Bulk API. For more information, see `Bing Ads Client Libraries`_. +The Bing Ads Python Software Development Kit (SDK) Version 11.5 enhances the experience of developing Bing Ads applications +with the Python programming language. +The SDK includes proxy classes for all Bing Ads API web services and abstracts the low level details of authentication with OAuth. +You can also read and write bulk files with the SDK BulkFileReader and BulkFileWriter, +and use the high level BulkServiceManager interface to abstract and execute operations in the low level Bulk API. +For more information, see `Bing Ads Client Libraries`_ on MSDN. Getting Started --------------- -To get started developing Bing Ads applications with Python, install the SDK and either start with the `examples`_ or follow one of the application walkthroughs. For more information, see `Get Started Using Python with Bing Ads Services`_. +To get started developing Bing Ads applications with Python, +install the SDK and either start with the `examples`_ or follow one of the application walkthroughs on MSDN. +For more information, see `Getting Started Using Python with Bing Ads Services`_. External Dependencies --------------------- @@ -24,9 +29,9 @@ External Dependencies - `six`_ - `enum34`_ -.. _Bing Ads Client Libraries: https://docs.microsoft.com/en-us/bingads/guides/client-libraries +.. _Bing Ads Client Libraries: https://msdn.microsoft.com/en-US/library/bing-ads-client-libraries.aspx .. _examples: https://github.com/BingAds/BingAds-Python-SDK/tree/master/examples -.. _Get Started Using Python with Bing Ads Services: https://docs.microsoft.com/en-us/bingads/guides/get-started-python +.. _Getting Started Using Python with Bing Ads Services: https://msdn.microsoft.com/en-US/library/bing-ads-overview-getting-started-python-with-web-services.aspx .. _suds-jurko: http://pypi.python.org/pypi/suds-jurko .. _requests: http://pypi.python.org/pypi/requests diff --git a/bingads/authorization.py b/bingads/authorization.py index 013e8937..5e388013 100644 --- a/bingads/authorization.py +++ b/bingads/authorization.py @@ -9,6 +9,8 @@ from .exceptions import OAuthTokenRequestException +PRODUCTION='production' +SANDBOX='sandbox' class AuthorizationData: """ Represents a user who intends to access the corresponding customer and account. @@ -250,7 +252,7 @@ class OAuthAuthorization(Authentication): * :class:`.OAuthWebAuthCodeGrant` """ - def __init__(self, client_id, oauth_tokens=None): + def __init__(self, client_id, oauth_tokens=None, env=PRODUCTION): """ Initializes a new instance of the OAuthAuthorization class. :param client_id: The client identifier corresponding to your registered application. @@ -265,6 +267,7 @@ def __init__(self, client_id, oauth_tokens=None): self._client_id = client_id self._oauth_tokens = oauth_tokens self._state = None + self.environment=env @property def client_id(self): @@ -272,7 +275,7 @@ def client_id(self): For more information about using a client identifier for authentication, see the Client Password Authentication section of the OAuth 2.0 spec at - http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-3.1 + https://tools.ietf.org/html/rfc6749#section-4.1 :rtype: str """ @@ -335,11 +338,11 @@ class OAuthWithAuthorizationCode(OAuthAuthorization): Implement an extension of this class in compliance with the authorization code grant flow for Managing User Authentication with OAuth documented at http://go.microsoft.com/fwlink/?LinkID=511609. This is a standard OAuth 2.0 flow and is defined in detail in the Authorization Code Grant section of the OAuth 2.0 spec at - http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-4.1. + https://tools.ietf.org/html/rfc6749#section-4.1. For more information about registering a Bing Ads application, see http://go.microsoft.com/fwlink/?LinkID=511607. """ - def __init__(self, client_id, client_secret, redirection_uri, token_refreshed_callback=None, oauth_tokens=None): + def __init__(self, client_id, client_secret, redirection_uri, token_refreshed_callback=None, oauth_tokens=None, env=PRODUCTION): """ Initialize a new instance of this class. :param client_id: The client identifier corresponding to your registered application. @@ -356,7 +359,7 @@ def __init__(self, client_id, client_secret, redirection_uri, token_refreshed_ca :return: """ - super(OAuthWithAuthorizationCode, self).__init__(client_id, oauth_tokens=oauth_tokens) + super(OAuthWithAuthorizationCode, self).__init__(client_id, oauth_tokens=oauth_tokens, env=env) self._client_secret = client_secret self._redirection_uri = redirection_uri self._token_refreshed_callback = token_refreshed_callback @@ -368,7 +371,7 @@ def get_authorization_endpoint(self): :rtype: str """ endpoint = str.format( - 'https://login.live.com/oauth20_authorize.srf?client_id={0}&scope=bingads.manage&response_type={1}&redirect_uri={2}', + _UriOAuthService.AUTHORIZE_URI[self.environment], self._client_id, 'code', quote_plus(self._redirection_uri) @@ -380,7 +383,7 @@ def request_oauth_tokens_by_response_uri(self, response_uri): Using the specified authorization response redirection uri. For more information, see the Authorization Response section in the OAuth 2.0 spec - at http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-4.1.2. + at https://tools.ietf.org/html/rfc6749#section-4.1. :param response_uri: The response redirection uri. :type response_uri: str @@ -396,11 +399,12 @@ def request_oauth_tokens_by_response_uri(self, response_uri): ) code = parameters['code'][0] - self._oauth_tokens = _LiveComOAuthService.get_access_token( + self._oauth_tokens = _UriOAuthService.get_access_token( client_id=self.client_id, client_secret=self.client_secret, redirect_uri=self.redirection_uri, grant_type='authorization_code', + environment=self.environment, code=code, ) if self.token_refreshed_callback is not None: @@ -412,7 +416,7 @@ def request_oauth_tokens_by_refresh_token(self, refresh_token): Using the specified refresh token. For more information, see the Refreshing an Access Token section in the OAuth 2.0 spec - at http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-6. + at https://tools.ietf.org/html/rfc6749#section-6. :param refresh_token: The refresh token used to request new access and refresh tokens. :type refresh_token: str @@ -420,12 +424,13 @@ def request_oauth_tokens_by_refresh_token(self, refresh_token): :rtype: OAuthTokens """ - self._oauth_tokens = _LiveComOAuthService.get_access_token( + self._oauth_tokens = _UriOAuthService.get_access_token( client_id=self.client_id, client_secret=self.client_secret, redirect_uri=self.redirection_uri, grant_type='refresh_token', refresh_token=refresh_token, + environment=self.environment, ) if self.token_refreshed_callback is not None: self.token_refreshed_callback(self.oauth_tokens) # invoke the callback when token refreshed. @@ -482,11 +487,11 @@ class OAuthDesktopMobileAuthCodeGrant(OAuthWithAuthorizationCode): This class implements the authorization code grant flow for Managing User Authentication with OAuth documented at http://go.microsoft.com/fwlink/?LinkID=511609. This is a standard OAuth 2.0 flow and is defined in detail in the - Authorization Code Grant section of the OAuth 2.0 spec at http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-4.1. + Authorization Code Grant section of the OAuth 2.0 spec at https://tools.ietf.org/html/rfc6749#section-4.1. For more information about registering a Bing Ads application, see http://go.microsoft.com/fwlink/?LinkID=511607. """ - def __init__(self, client_id, oauth_tokens=None): + def __init__(self, client_id, oauth_tokens=None, env=PRODUCTION): """ Initializes a new instance of the this class with the specified client id. :param client_id: The client identifier corresponding to your registered application. @@ -498,8 +503,9 @@ def __init__(self, client_id, oauth_tokens=None): super(OAuthDesktopMobileAuthCodeGrant, self).__init__( client_id, None, - _LiveComOAuthService.DESKTOP_REDIRECTION_URI, + _UriOAuthService.REDIRECTION_URI[env], oauth_tokens=oauth_tokens, + env=env ) @@ -512,7 +518,7 @@ class OAuthWebAuthCodeGrant(OAuthWithAuthorizationCode): This class implements the authorization code grant flow for Managing User Authentication with OAuth documented at http://go.microsoft.com/fwlink/?LinkID=511609. This is a standard OAuth 2.0 flow and is defined in detail in the - Authorization Code Grant section of the OAuth 2.0 spec at http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-4.1. + Authorization Code Grant section of the OAuth 2.0 spec at https://tools.ietf.org/html/rfc6749#section-4.1. For more information about registering a Bing Ads application, see http://go.microsoft.com/fwlink/?LinkID=511607. """ @@ -528,11 +534,12 @@ class OAuthDesktopMobileImplicitGrant(OAuthAuthorization): This class implements the implicit grant flow for Managing User Authentication with OAuth documented at http://go.microsoft.com/fwlink/?LinkID=511608. This is a standard OAuth 2.0 flow and is defined in detail in the - Authorization Code Grant section of the OAuth 2.0 spec at http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-4.1. + Authorization Code Grant section of the OAuth 2.0 spec at https://tools.ietf.org/html/rfc6749#section-4.1. For more information about registering a Bing Ads application, see http://go.microsoft.com/fwlink/?LinkID=511607. """ + - def __init__(self, client_id, oauth_tokens=None): + def __init__(self, client_id, oauth_tokens=None, env=PRODUCTION): """ Initializes a new instance of the this class with the specified client id. :param client_id: The client identifier corresponding to your registered application. @@ -541,7 +548,9 @@ def __init__(self, client_id, oauth_tokens=None): :type oauth_tokens: OAuthTokens """ - super(OAuthDesktopMobileImplicitGrant, self).__init__(client_id, oauth_tokens=oauth_tokens) + super(OAuthDesktopMobileImplicitGrant, self).__init__(client_id, oauth_tokens=oauth_tokens, env=env) + + def get_authorization_endpoint(self): """ Gets the Microsoft Account authorization endpoint where the user should be navigated to give his or her consent. @@ -551,10 +560,10 @@ def get_authorization_endpoint(self): """ endpoint = str.format( - 'https://login.live.com/oauth20_authorize.srf?client_id={0}&scope=bingads.manage&response_type={1}&redirect_uri={2}', + _UriOAuthService.AUTHORIZE_URI[self.environment], self.client_id, 'token', - _LiveComOAuthService.DESKTOP_REDIRECTION_URI, + _UriOAuthService.REDIRECTION_URI[self.environment], ) return endpoint if self.state is None else endpoint + '&state=' + self.state @@ -583,16 +592,21 @@ def extract_access_token_from_uri(self, redirection_uri): @property def redirection_uri(self): - return _LiveComOAuthService.DESKTOP_REDIRECTION_URI + return _UriOAuthService.REDIRECTION_URI[self.environment] -class _LiveComOAuthService: +class _UriOAuthService: """ Provides method for getting OAuth tokens from the live.com authorization server.""" def __init__(self): pass - DESKTOP_REDIRECTION_URI = 'https://login.live.com/oauth20_desktop.srf' + REDIRECTION_URI={PRODUCTION:'https://login.live.com/oauth20_desktop.srf', + SANDBOX:'https://login.live-int.com/oauth20_desktop.srf'} + AUTH_TOKEN_URI={PRODUCTION:'https://login.live.com/oauth20_token.srf', + SANDBOX:'https://login.live-int.com/oauth20_token.srf'} + AUTHORIZE_URI={PRODUCTION:'https://login.live.com/oauth20_authorize.srf?client_id={0}&scope=bingads.manage&response_type={1}&redirect_uri={2}', + SANDBOX:'https://login.live-int.com/oauth20_authorize.srf?client_id={0}&scope=bingads.manage&response_type={1}&redirect_uri={2}&prompt=login'} @staticmethod def get_access_token(**kwargs): @@ -606,7 +620,7 @@ def get_access_token(**kwargs): if 'client_secret' in kwargs and kwargs['client_secret'] is None: del kwargs['client_secret'] - r = requests.post('https://login.live.com/oauth20_token.srf', kwargs, verify=True) + r = requests.post(_UriOAuthService.AUTH_TOKEN_URI[kwargs['environment']], kwargs, verify=True) try: r.raise_for_status() except Exception: diff --git a/bingads/manifest.py b/bingads/manifest.py index 6da1edc2..155ae8df 100644 --- a/bingads/manifest.py +++ b/bingads/manifest.py @@ -1,5 +1,5 @@ import sys -VERSION = '11.5.8' +VERSION = '11.5.9' BULK_FORMAT_VERSION_5 = '5.0' WORKING_NAME = 'BingAdsSDKPython' USER_AGENT = '{0} {1} {2}'.format(WORKING_NAME, VERSION, sys.version_info[0:3]) diff --git a/bingads/v11/proxies/campaign_management_service.xml b/bingads/v11/proxies/campaign_management_service.xml index 3a245560..0db08f07 100644 --- a/bingads/v11/proxies/campaign_management_service.xml +++ b/bingads/v11/proxies/campaign_management_service.xml @@ -71,9 +71,9 @@ + - @@ -130,6 +130,7 @@ + @@ -183,6 +184,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -318,6 +363,7 @@ + @@ -359,6 +405,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + 5 + + + + + + + 6 + + + + + + + + + + + + @@ -594,6 +716,13 @@ + + + + + + + @@ -643,6 +772,7 @@ + @@ -653,6 +783,15 @@ + + + + + + + + + @@ -706,6 +845,8 @@ + + @@ -2098,6 +2239,7 @@ + @@ -2205,6 +2347,7 @@ + @@ -2312,6 +2455,27 @@ + + + + 32768 + + + + + + + 65536 + + + + + + + 131072 + + + @@ -2422,6 +2586,7 @@ + @@ -2469,6 +2634,7 @@ + @@ -2577,6 +2743,47 @@ + + + + + + + + + + + + + + + + + + + 0 + + + + + + + 1 + + + + + + + 2 + + + + + + + + @@ -2777,6 +2984,17 @@ + + + + + + 1 + + + + + @@ -4036,6 +4254,23 @@ + + + + + + + + + + + + + + + + + @@ -6717,6 +6952,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -7312,6 +7571,12 @@ + + + + + + @@ -9593,10 +9858,33 @@ + + + + + + + + + + + + + + + + + + + + + + + - + diff --git a/setup.py b/setup.py index 9b0ccae7..a1f74805 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ except ImportError: from distutils.core import setup -VERSION = '11.5.8' +VERSION = '11.5.9' with open('README.rst', 'r') as f: readme = f.read()