def get_authorization(client, verb, resource_id_or_fullname, resource_type, headers): authorization = auth.GetAuthorizationHeader( cosmos_client_connection=client, verb=verb, path='', resource_id_or_fullname=resource_id_or_fullname, is_name_based=True, resource_type=resource_type, headers=headers) # urllib.quote throws when the input parameter is None if authorization: # -_.!~*'() are valid characters in url, and shouldn't be quoted. authorization = urllib_quote(authorization, '-_.!~*\'()') return authorization
def GetHeaders(cosmos_client, default_headers, verb, path, resource_id, resource_type, options, partition_key_range_id = None): """Gets HTTP request headers. :param cosmos_client.CosmosClient cosmos_client: :param dict default_headers: :param str verb: :param str path: :param str resource_id: :param str resource_type: :param dict options: :param str partition_key_range_id: :return: The HTTP request headers. :rtype: dict """ headers = dict(default_headers) options = options or {} if cosmos_client._useMultipleWriteLocations: headers[http_constants.HttpHeaders.AllowTentativeWrites] = "true" pre_trigger_include = options.get('preTriggerInclude') if pre_trigger_include: headers[http_constants.HttpHeaders.PreTriggerInclude] = ( pre_trigger_include if isinstance(pre_trigger_include, str) else (',').join(pre_trigger_include)) post_trigger_include = options.get('postTriggerInclude') if post_trigger_include: headers[http_constants.HttpHeaders.PostTriggerInclude] = ( post_trigger_include if isinstance(post_trigger_include, str) else (',').join(post_trigger_include)) if options.get('maxItemCount'): headers[http_constants.HttpHeaders.PageSize] = options['maxItemCount'] access_condition = options.get('accessCondition') if access_condition: if access_condition['type'] == 'IfMatch': headers[http_constants.HttpHeaders.IfMatch] = access_condition['condition'] else: headers[http_constants.HttpHeaders.IfNoneMatch] = access_condition['condition'] if options.get('indexingDirective'): headers[http_constants.HttpHeaders.IndexingDirective] = ( options['indexingDirective']) consistency_level = None ''' get default client consistency level''' default_client_consistency_level = headers.get(http_constants.HttpHeaders.ConsistencyLevel) ''' set consistency level. check if set via options, this will override the default ''' if options.get('consistencyLevel'): consistency_level = options['consistencyLevel'] headers[http_constants.HttpHeaders.ConsistencyLevel] = consistency_level elif default_client_consistency_level is not None: consistency_level = default_client_consistency_level headers[http_constants.HttpHeaders.ConsistencyLevel] = consistency_level # figure out if consistency level for this request is session is_session_consistency = (consistency_level == documents.ConsistencyLevel.Session) # set session token if required if is_session_consistency is True and not IsMasterResource(resource_type): # if there is a token set via option, then use it to override default if options.get('sessionToken'): headers[http_constants.HttpHeaders.SessionToken] = options['sessionToken'] else: # check if the client's default consistency is session (and request consistency level is same), # then update from session container if default_client_consistency_level == documents.ConsistencyLevel.Session: # populate session token from the client's session container headers[http_constants.HttpHeaders.SessionToken] = ( cosmos_client.session.get_session_token(path)) if options.get('enableScanInQuery'): headers[http_constants.HttpHeaders.EnableScanInQuery] = ( options['enableScanInQuery']) if options.get('resourceTokenExpirySeconds'): headers[http_constants.HttpHeaders.ResourceTokenExpiry] = ( options['resourceTokenExpirySeconds']) if options.get('offerType'): headers[http_constants.HttpHeaders.OfferType] = options['offerType'] if options.get('offerThroughput'): headers[http_constants.HttpHeaders.OfferThroughput] = options['offerThroughput'] if 'partitionKey' in options: # if partitionKey value is Undefined, serialize it as {} to be consistent with other SDKs if options.get('partitionKey') is documents.Undefined: headers[http_constants.HttpHeaders.PartitionKey] = [{}] # else serialize using json dumps method which apart from regular values will serialize None into null else: headers[http_constants.HttpHeaders.PartitionKey] = json.dumps([options['partitionKey']]) if options.get('enableCrossPartitionQuery'): headers[http_constants.HttpHeaders.EnableCrossPartitionQuery] = options['enableCrossPartitionQuery'] if options.get('populateQueryMetrics'): headers[http_constants.HttpHeaders.PopulateQueryMetrics] = options['populateQueryMetrics'] if cosmos_client.master_key: headers[http_constants.HttpHeaders.XDate] = ( datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')) if cosmos_client.master_key or cosmos_client.resource_tokens: authorization = auth.GetAuthorizationHeader(cosmos_client, verb, path, resource_id, IsNameBased(resource_id), resource_type, headers) # urllib.quote throws when the input parameter is None if authorization: # -_.!~*'() are valid characters in url, and shouldn't be quoted. authorization = urllib_quote(authorization, '-_.!~*\'()') headers[http_constants.HttpHeaders.Authorization] = authorization if verb == 'post' or verb == 'put': if not headers.get(http_constants.HttpHeaders.ContentType): headers[http_constants.HttpHeaders.ContentType] = runtime_constants.MediaTypes.Json if not headers.get(http_constants.HttpHeaders.Accept): headers[http_constants.HttpHeaders.Accept] = runtime_constants.MediaTypes.Json if partition_key_range_id is not None: headers[http_constants.HttpHeaders.PartitionKeyRangeID] = partition_key_range_id if options.get('enableScriptLogging'): headers[http_constants.HttpHeaders.EnableScriptLogging] = options['enableScriptLogging'] if options.get('offerEnableRUPerMinuteThroughput'): headers[http_constants.HttpHeaders.OfferIsRUPerMinuteThroughputEnabled] = options['offerEnableRUPerMinuteThroughput'] if options.get('disableRUPerMinuteUsage'): headers[http_constants.HttpHeaders.DisableRUPerMinuteUsage] = options['disableRUPerMinuteUsage'] if options.get('changeFeed') is True: # On REST level, change feed is using IfNoneMatch/ETag instead of continuation. if_none_match_value = None if options.get('continuation'): if_none_match_value = options['continuation'] elif options.get('isStartFromBeginning') and options['isStartFromBeginning'] == False: if_none_match_value = '*' if if_none_match_value: headers[http_constants.HttpHeaders.IfNoneMatch] = if_none_match_value headers[http_constants.HttpHeaders.AIM] = http_constants.HttpHeaders.IncrementalFeedHeaderValue else: if options.get('continuation'): headers[http_constants.HttpHeaders.Continuation] = (options['continuation']) if options.get('populatePartitionKeyRangeStatistics'): headers[http_constants.HttpHeaders.PopulatePartitionKeyRangeStatistics] = options['populatePartitionKeyRangeStatistics'] if options.get('populateQuotaInfo'): headers[http_constants.HttpHeaders.PopulateQuotaInfo] = options['populateQuotaInfo'] return headers