Skip to content

Commit

Permalink
Update clients to get bug fixes in python client (#640)
Browse files Browse the repository at this point in the history
* Update clients to get bug fixes in python client

* Cherry pick from de2a890#diff-bb5d1bd3a0ab3e6964890043bd3d1faf
  • Loading branch information
atbagga authored May 29, 2019
1 parent 3bc2102 commit 9a93b59
Show file tree
Hide file tree
Showing 36 changed files with 393 additions and 239 deletions.
2 changes: 1 addition & 1 deletion azure-devops/azext_devops/devops_sdk/_file_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def load(self):
try:
if os.path.isfile(self.file_name):
if self.max_age > 0 and os.stat(self.file_name).st_mtime + self.max_age < time.time():
logger.debug('Cache file expired: %s', file=self.file_name)
logger.debug('Cache file expired: %s', self.file_name)
os.remove(self.file_name)
else:
logger.debug('Loading cache file: %s', self.file_name)
Expand Down
19 changes: 12 additions & 7 deletions azure-devops/azext_devops/devops_sdk/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def add_user_agent(self, user_agent):
if user_agent is not None:
self.config.add_user_agent(user_agent)

def _send_request(self, request, headers=None, content=None, **operation_config):
def _send_request(self, request, headers=None, content=None, media_type=None, **operation_config):
"""Prepare and send request object according to configuration.
:param ClientRequest request: The request object to be sent.
:param dict headers: Any headers to add to the request.
Expand All @@ -57,16 +57,20 @@ def _send_request(self, request, headers=None, content=None, **operation_config)
or (TRACE_ENV_VAR_COMPAT in os.environ and os.environ[TRACE_ENV_VAR_COMPAT] == 'true'):
print(request.method + ' ' + request.url)
logger.debug('%s %s', request.method, request.url)
logger.debug('Request content: %s', content)
if media_type is not None and media_type == 'application/json':
logger.debug('Request content: %s', content)
response = self._client.send(request=request, headers=headers,
content=content, **operation_config)
logger.debug('Response content: %s', response.content)
if ('Content-Type' in response.headers
and response.headers['Content-Type'].startswith('application/json')):
logger.debug('Response content: %s', response.content)
if response.status_code < 200 or response.status_code >= 300:
self._handle_error(request, response)
return response

def _send(self, http_method, location_id, version, route_values=None,
query_parameters=None, content=None, media_type='application/json', accept_media_type='application/json', if_match=None):
query_parameters=None, content=None, media_type='application/json', accept_media_type='application/json',
additional_headers=None):
request = self._create_request_message(http_method=http_method,
location_id=location_id,
route_values=route_values,
Expand All @@ -85,8 +89,9 @@ def _send(self, http_method, location_id, version, route_values=None,
# Construct headers
headers = {'Content-Type': media_type + '; charset=utf-8',
'Accept': accept_media_type + ';api-version=' + negotiated_version}
if if_match:
headers['if-match'] = if_match
if additional_headers is not None:
for key in additional_headers:
headers[key] = str(additional_headers[key])
if self.config.additional_headers is not None:
for key in self.config.additional_headers:
headers[key] = self.config.additional_headers[key]
Expand All @@ -96,7 +101,7 @@ def _send(self, http_method, location_id, version, route_values=None,
headers['X-VSS-ForceMsaPassThrough'] = 'true'
if Client._session_header_key in Client._session_data and Client._session_header_key not in headers:
headers[Client._session_header_key] = Client._session_data[Client._session_header_key]
response = self._send_request(request=request, headers=headers, content=content)
response = self._send_request(request=request, headers=headers, content=content, media_type=media_type)
if Client._session_header_key in response.headers:
Client._session_data[Client._session_header_key] = response.headers[Client._session_header_key]
return response
Expand Down
33 changes: 32 additions & 1 deletion azure-devops/azext_devops/devops_sdk/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
from .v5_0.client_factory import ClientFactoryV5_0
from .v5_1.client_factory import ClientFactoryV5_1


logger = logging.getLogger(__name__)


Expand All @@ -24,6 +23,7 @@ class Connection(object):

def __init__(self, base_url=None, creds=None, user_agent=None):
self._config = ClientConfiguration(base_url)
self._config.credentials = creds
self._addition_user_agent = user_agent
if user_agent is not None:
self._config.add_user_agent(user_agent)
Expand All @@ -35,6 +35,7 @@ def __init__(self, base_url=None, creds=None, user_agent=None):
self.clients = ClientFactory(self)
self.clients_v5_0 = ClientFactoryV5_0(self)
self.clients_v5_1 = ClientFactoryV5_1(self)
self.use_fiddler = False

def get_client(self, client_type):
"""get_client.
Expand All @@ -57,6 +58,8 @@ def _get_client_instance(self, client_class):
url = self._get_url_for_client_instance(client_class)
client = client_class(url, self._creds)
client.add_user_agent(self._addition_user_agent)
if self.use_fiddler:
self._configure_client_for_fiddler(client)
return client

def _get_url_for_client_instance(self, client_class):
Expand All @@ -74,16 +77,35 @@ def _get_url_for_client_instance(self, client_class):
for resource_area in resource_areas:
if resource_area.id.lower() == resource_id.lower():
return resource_area.location_url

# Check SPS deployment level for the resource area
resource_area = self._get_deployment_resource_area_from_sps(resource_id)
if resource_area is not None:
return resource_area.location_url

raise AzureDevOpsClientRequestError(('Could not find information for resource area {id} '
+ 'from server: {url}').format(id=resource_id,
url=self.base_url))

def _get_deployment_resource_area_from_sps(self, resource_id):
resource_id = resource_id.lower()
if resource_id in _deployment_level_resource_areas:
return _deployment_level_resource_areas[resource_id]
location_client = LocationClient(sps_url, self._creds)
if self.use_fiddler:
self._configure_client_for_fiddler(location_client)
resource_area = location_client.get_resource_area(area_id=resource_id)
_deployment_level_resource_areas[resource_id] = resource_area
return resource_area

def authenticate(self):
self._get_resource_areas(force=True)

def _get_resource_areas(self, force=False):
if self._resource_areas is None or force:
location_client = LocationClient(self.base_url, self._creds)
if self.use_fiddler:
self._configure_client_for_fiddler(location_client)
if not force and RESOURCE_FILE_CACHE[location_client.normalized_url]:
try:
logger.debug('File cache hit for resources on: %s', location_client.normalized_url)
Expand All @@ -109,3 +131,12 @@ def _get_resource_areas(self, force=False):
@staticmethod
def _combine_url(part1, part2):
return part1.rstrip('/') + '/' + part2.strip('/')

@staticmethod
def _configure_client_for_fiddler(client):
client.config.connection.verify = False
client.config.proxies.add(protocol='https', proxy_url='https://127.0.0.1:8888')


_deployment_level_resource_areas = {}
sps_url = 'https://app.vssps.visualstudio.com'
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def __init__(self, base_url=None, creds=None):
self._serialize = Serializer(client_models)
self._deserialize = Deserializer(client_models)

resource_area_identifier = None
resource_area_identifier = '8ccfef3d-2b87-4e99-8ccb-66e343d2daa8'

def get_profile(self, id, details=None, with_attributes=None, partition=None, core_attributes=None, force_refresh=None):
"""GetProfile.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,16 @@ def create_or_update_page(self, parameters, project, wiki_identifier, path, vers
query_parameters['path'] = self._serialize.query('path', path, 'str')
if comment is not None:
query_parameters['comment'] = self._serialize.query('comment', comment, 'str')
additional_headers = {}
if version is not None:
additional_headers['If-Match'] = version
content = self._serialize.body(parameters, 'WikiPageCreateOrUpdateParameters')
response = self._send(http_method='PUT',
location_id='25d3fbc7-fe3d-46cb-b5a5-0b6f79caf27b',
version='5.0',
route_values=route_values,
query_parameters=query_parameters,
additional_headers=additional_headers,
content=content)
response_object = models.WikiPageResponse()
response_object.page = self._deserialize('WikiPage', response)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -347,10 +347,14 @@ def get_widgets(self, team_context, dashboard_id, eTag=None):
route_values['team'] = self._serialize.url('team', team, 'string')
if dashboard_id is not None:
route_values['dashboardId'] = self._serialize.url('dashboard_id', dashboard_id, 'str')
additional_headers = {}
if eTag is not None:
additional_headers['ETag'] = eTag
response = self._send(http_method='GET',
location_id='bdcff53a-8355-4172-a00a-40497ea23afc',
version='5.0-preview.2',
route_values=route_values)
route_values=route_values,
additional_headers=additional_headers)
response_object = models.WidgetsVersionedList()
response_object.widgets = self._deserialize('[Widget]', self._unwrap_collection(response))
response_object.eTag = response.headers.get('ETag')
Expand Down Expand Up @@ -422,11 +426,15 @@ def replace_widgets(self, widgets, team_context, dashboard_id, eTag=None):
route_values['team'] = self._serialize.url('team', team, 'string')
if dashboard_id is not None:
route_values['dashboardId'] = self._serialize.url('dashboard_id', dashboard_id, 'str')
additional_headers = {}
if eTag is not None:
additional_headers['ETag'] = eTag
content = self._serialize.body(widgets, '[Widget]')
response = self._send(http_method='PUT',
location_id='bdcff53a-8355-4172-a00a-40497ea23afc',
version='5.0-preview.2',
route_values=route_values,
additional_headers=additional_headers,
content=content)
response_object = models.WidgetsVersionedList()
response_object.widgets = self._deserialize('[Widget]', self._unwrap_collection(response))
Expand Down Expand Up @@ -499,11 +507,15 @@ def update_widgets(self, widgets, team_context, dashboard_id, eTag=None):
route_values['team'] = self._serialize.url('team', team, 'string')
if dashboard_id is not None:
route_values['dashboardId'] = self._serialize.url('dashboard_id', dashboard_id, 'str')
additional_headers = {}
if eTag is not None:
additional_headers['ETag'] = eTag
content = self._serialize.body(widgets, '[Widget]')
response = self._send(http_method='PATCH',
location_id='bdcff53a-8355-4172-a00a-40497ea23afc',
version='5.0-preview.2',
route_values=route_values,
additional_headers=additional_headers,
content=content)
response_object = models.WidgetsVersionedList()
response_object.widgets = self._deserialize('[Widget]', self._unwrap_collection(response))
Expand Down
Loading

0 comments on commit 9a93b59

Please sign in to comment.