用于python的Microsoft azure核心库
azure-core的Python项目详细描述
azure核心库
管道
azure核心管道是对msrest 0.6.0中引入的msrest管道的重新构造。 有关msrest实现的进一步讨论,请参见msrest wiki
azure核心管道是链接策略的实现,如azure sdk指南中所述。
管道的python实现有一些特定于python的机制。这是因为必须独立地支持管道的同步和异步实现。
当构建一个sdk时,开发人员可能会像这样使用管道:
fromazure.coreimportConfiguration,Pipelinefromazure.core.transportimportRequestsTransport,HttpRequestfromazure.core.pipeline.policiesimport(UserAgentPolicy,HeadersPolicy,RetryPolicy,RedirectPolicy,BearerTokenCredentialPolicy,ContentDecodePolicy,NetworkTraceLoggingPolicy,ProxyPolicy)classFooServiceClient:@staticmethoddef_create_config(credential,scopes,**kwargs):# Here the SDK developer would define the default# config to interact with the serviceconfig=Configuration(**kwargs)config.headers_policy=kwargs.get('headers_policy',HeadersPolicy({"CustomHeader":"Value"},**kwargs))config.user_agent_policy=kwargs.get('user_agent_policy',UserAgentPolicy("ServiceUserAgentValue",**kwargs))config.authentication_policy=kwargs.get('authentication_policy',BearerTokenCredentialPolicy(credential,scopes,**kwargs))config.retry_policy=kwargs.get('retry_policy',RetryPolicy(**kwargs))config.redirect_policy=kwargs.get('redirect_policy',RedirectPolicy(**kwargs))config.logging_policy=kwargs.get('logging_policy',NetworkTraceLoggingPolicy(**kwargs))config.proxy_policy=kwargs.get('proxy_policy',ProxyPolicy(**kwargs))returnconfigdef__init__(self,**kwargs):transport=kwargs.get('transport',RequestsTransport(**kwargs))config=FooServiceClient._create_config(**kwargs)policies=[config.user_agent_policy,config.headers_policy,config.authentication_policy,ContentDecodePolicy(),config.proxy_policy,config.redirect_policy,config.retry_policy,config.logging_policy,]self._pipeline=Pipeline(transport,policies=policies)defget_foo_properties(self,**kwargs)# Create a generic HTTP Request. This is not specific to any particular transport# or pipeline configuration.new_request=HttpRequest("GET","/")response=self._pipeline.run(new_request,**kwargs)returndeserialize_data(response.http_response)
使用此sdk的最终用户可能会编写如下代码:
fromazure.core.credentialsimportFooCredentialsfromazure.fooimportFooServiceClientcreds=FooCredentials("api-key")endpoint="http://service.azure.net# Scenario using entirely default configuration# We use the SDK-developer defined configuration.client=FooServiceClient(endpoint,creds)response=client.get_foo_properties()# Scenario where user wishes to tweak a couple of settings# In this case the configurable options can be passed directly into the client constructor.client=FooServiceClient(endpoint,creds,logging_enable=True,retries_total=5)response=client.get_foo_properties()# Scenario where user wishes to tweak settings for only a specific request# All the options available on construction are available as per-request overrides.# These can also be specified by the SDK developer - and it will be up to them to resolve# conflicts with user-defined parameters.client=FooServiceClient(endpoint,creds)response=client.get_foo_properties(redirects_max=0)# Scenario where user wishes to fully customize the policies.# All configuration options are passed through kwargsclient=FooServiceClient(endpoint,creds,retry_policy=CustomRetryPolicy()redirect_max=5,logging_enable=True)response=client.get_foo_properties()
配置
配置对象是管道中所有可配置策略的宿主。 新的配置对象不提供默认策略。 由sdk开发人员根据服务的需要指定每个策略默认值。
配置不应作为生成的sdk的公共api的一部分公开。
这可以在上面的代码示例中看到,它是在客户机类的staticmethod中实现的。 配置对象未指定将策略添加到管道的顺序。 sdk开发人员需要使用配置中的策略来正确地构造管道。 插入任何未公开/不可配置的策略。
transport=RequestsTransport(**kwargs)# SDK developer needs to build the policy order for the pipeline.config=FooServiceClient._create_config(**kwargs)policies=[config.headers_policy,config.user_agent_policy,config.authentication_policy,# Authentication policy needs to be inserted after all request mutation to accommodate signing.ContentDecodePolicy(),config.redirect_policy,config.retry_policy,config.logging_policy,# Logger should come last to accurately record the request/response as they are on the wire]self._pipeline=Pipeline(transport,policies=policies)
当前应在配置对象上定义的策略如下:
-Configuration.headers_policy# HeadersPolicy-Configuration.retry_policy# RetryPolicy-Configuration.redirect_policy# RedirectPolicy-Configuration.logging_policy# NetworkTraceLoggingPolicy-Configuration.user_agent_policy# UserAgentPolicy-Configuration.proxy_policy# While this is a ProxyPolicy object, current implementation is transport configuration.-Configuration.authentication_policy# BearerTokenCredentialPolicy
运输
sync/async http库的各种组合以及可选的事件循环实现都是可用的。因此,为了支持最广泛的客户场景,我们必须允许客户轻松地将http传输层交换到受支持的层中。
传输是管道中的最后一个节点,与管道中的任何策略都遵循相同的基本API。
当前唯一可用的同步管道传输使用请求
库:
fromazure.core.pipeline.transportimportRequestsTransportsynchronous_transport=RequestsTransport()
对于异步管道,有两个传输选项可用。根据用户是否安装了各种第三方依赖项(即aiohttp或trio)以及用户
应该能够很容易地指定他们选择的传输。sdk开发人员应该使用aiohttp
传输作为异步管道的默认传输,在异步管道中,用户没有指定替代方案。
fromazure.foo.aioimportFooServiceClientfromazure.core.pipeline.transportimport(# Identical implementation as the synchronous RequestsTransport wrapped in an asynchronous using the# built-in asyncio event loop.AsyncioRequestsTransport,# Identical implementation as the synchronous RequestsTransport wrapped in an asynchronous using the# third party trio event loop.TrioRequestsTransport,# Fully asynchronous implementation using the aiohttp library, using the built-in asyncio event loop.AioHttpTransport,)client=FooServiceClient(endpoint,creds,transport=AioHttpTransport())response=awaitclient.get_foo_properties()
可以在所有传输上配置一些公共属性。必须通过 在构建传输实例时作为kwargs参数。这些属性包括以下属性:
transport=AioHttpTransport(# The connect and read timeout value. Defaults to 100 seconds.connection_timeout=100,# SSL certificate verification. Enabled by default. Set to False to disable,# alternatively can be set to the path to a CA_BUNDLE file or directory with# certificates of trusted CAs.connection_verify=True,# Client-side certificates. You can specify a local cert to use as client side# certificate, as a single file (containing the private key and the certificate)# or as a # tuple of both files' paths.connection_cert=None,# The block size of data sent over the connection. Defaults to 4096 bytes.connection_data_block_size=4096)
httprequest和httpresponse
http request和http response对象表示http请求和响应构造的一般概念,与特定的传输或http库没有任何关系。
httprequest具有以下api。不同的运输方式不会有所不同:
classHttpRequest(object):def__init__(self,method,url,headers=None,files=None,data=None):self.method=methodself.url=urlself.headers=CaseInsensitiveDict(headers)self.files=filesself.data=data@propertydefbody(self):returnself.data@body.setterdefbody(self,value):self.data=valuedefformat_parameters(self,params):"""Format parameters into a valid query string. It's assumed all parameters have already been quoted as valid URL strings."""defset_xml_body(self,data):"""Set an XML element tree as the body of the request."""defset_json_body(self,data):"""Set a JSON-friendly object as the body of the request."""defset_multipart_body(self,data=None):"""Set form-encoded data as the body of the request. Supported content-types are: - application/x-www-form-urlencoded - multipart/form-data """defset_bytes_body(self,data):"""Set generic bytes as the body of the request."""
另一方面,httpresponse对象通常具有传输特定的派生。 这是为了适应如何为http库返回的对象提取数据。 还有一种异步风格:AsynchttpResponse。这是为了允许 来自响应的数据。 例如:
fromazure.core.pipeline.transportimport(RequestsTransportResponse,# HttpResponseAioHttpTransportResponse,# AsyncHttpResponseTrioRequestsTransportResponse,# AsyncHttpResponseAsyncioRequestsTransportResponse,# AsyncHttpResponse)
每个响应类型的api都是相同的,因此响应的使用者不必知道这些 特殊类型。
httpresponse具有以下api。不同的运输方式不会有所不同:
fromazure.coreimportConfiguration,Pipelinefromazure.core.transportimportRequestsTransport,HttpRequestfromazure.core.pipeline.policiesimport(UserAgentPolicy,HeadersPolicy,RetryPolicy,RedirectPolicy,BearerTokenCredentialPolicy,ContentDecodePolicy,NetworkTraceLoggingPolicy,ProxyPolicy)classFooServiceClient:@staticmethoddef_create_config(credential,scopes,**kwargs):# Here the SDK developer would define the default# config to interact with the serviceconfig=Configuration(**kwargs)config.headers_policy=kwargs.get('headers_policy',HeadersPolicy({"CustomHeader":"Value"},**kwargs))config.user_agent_policy=kwargs.get('user_agent_policy',UserAgentPolicy("ServiceUserAgentValue",**kwargs))config.authentication_policy=kwargs.get('authentication_policy',BearerTokenCredentialPolicy(credential,scopes,**kwargs))config.retry_policy=kwargs.get('retry_policy',RetryPolicy(**kwargs))config.redirect_policy=kwargs.get('redirect_policy',RedirectPolicy(**kwargs))config.logging_policy=kwargs.get('logging_policy',NetworkTraceLoggingPolicy(**kwargs))config.proxy_policy=kwargs.get('proxy_policy',ProxyPolicy(**kwargs))returnconfigdef__init__(self,**kwargs):transport=kwargs.get('transport',RequestsTransport(**kwargs))config=FooServiceClient._create_config(**kwargs)policies=[config.user_agent_policy,config.headers_policy,config.authentication_policy,ContentDecodePolicy(),config.proxy_policy,config.redirect_policy,config.retry_policy,config.logging_policy,]self._pipeline=Pipeline(transport,policies=policies)defget_foo_properties(self,**kwargs)# Create a generic HTTP Request. This is not specific to any particular transport# or pipeline configuration.new_request=HttpRequest("GET","/")response=self._pipeline.run(new_request,**kwargs)returndeserialize_data(response.http_response)0
管道请求和管道响应
这些对象提供了用于在管道中移动httprequest和httpresponse的容器。
WH如果sdk开发人员不显式地构造pipelinerequest,他们将处理pipelineresponse
从pipeline.run()返回的对象
这些对象是所有传输的通用对象,包括同步传输和异步传输。
管道请求和响应容器还负责承载上下文
对象。这是
传输特定,可以包含管道请求之间持久化的数据(例如重用打开的连接
池或"会话"),以及由sdk开发人员用于通过管道传输任意数据。
pipelinerequest和pipelineresponse的api如下:
fromazure.coreimportConfiguration,Pipelinefromazure.core.transportimportRequestsTransport,HttpRequestfromazure.core.pipeline.policiesimport(UserAgentPolicy,HeadersPolicy,RetryPolicy,RedirectPolicy,BearerTokenCredentialPolicy,ContentDecodePolicy,NetworkTraceLoggingPolicy,ProxyPolicy)classFooServiceClient:@staticmethoddef_create_config(credential,scopes,**kwargs):# Here the SDK developer would define the default# config to interact with the serviceconfig=Configuration(**kwargs)config.headers_policy=kwargs.get('headers_policy',HeadersPolicy({"CustomHeader":"Value"},**kwargs))config.user_agent_policy=kwargs.get('user_agent_policy',UserAgentPolicy("ServiceUserAgentValue",**kwargs))config.authentication_policy=kwargs.get('authentication_policy',BearerTokenCredentialPolicy(credential,scopes,**kwargs))config.retry_policy=kwargs.get('retry_policy',RetryPolicy(**kwargs))config.redirect_policy=kwargs.get('redirect_policy',RedirectPolicy(**kwargs))config.logging_policy=kwargs.get('logging_policy',NetworkTraceLoggingPolicy(**kwargs))config.proxy_policy=kwargs.get('proxy_policy',ProxyPolicy(**kwargs))returnconfigdef__init__(self,**kwargs):transport=kwargs.get('transport',RequestsTransport(**kwargs))config=FooServiceClient._create_config(**kwargs)policies=[config.user_agent_policy,config.headers_policy,config.authentication_policy,ContentDecodePolicy(),config.proxy_policy,config.redirect_policy,config.retry_policy,config.logging_policy,]self._pipeline=Pipeline(transport,policies=policies)defget_foo_properties(self,**kwargs)# Create a generic HTTP Request. This is not specific to any particular transport# or pipeline configuration.new_request=HttpRequest("GET","/")response=self._pipeline.run(new_request,**kwargs)returndeserialize_data(response.http_response)1
政策
python管道实现提供了两种策略。这些策略称为HttpPolicy和SansioHttpPolicy。
Sansiohttp政策
如果策略只是根据http规范修改或注释请求,那么它就是sansiohttpppolicy的一个子类,将在管道或异步管道上下文中工作。 这是一个简单的抽象类,可以在请求完成之前或之后执行操作。例如:
- 在请求中设置标题
- 记录请求和/或响应
sansiohttp策略应实现以下一种或多种方法:
fromazure.coreimportConfiguration,Pipelinefromazure.core.transportimportRequestsTransport,HttpRequestfromazure.core.pipeline.policiesimport(UserAgentPolicy,HeadersPolicy,RetryPolicy,RedirectPolicy,BearerTokenCredentialPolicy,ContentDecodePolicy,NetworkTraceLoggingPolicy,ProxyPolicy)classFooServiceClient:@staticmethoddef_create_config(credential,scopes,**kwargs):# Here the SDK developer would define the default# config to interact with the serviceconfig=Configuration(**kwargs)config.headers_policy=kwargs.get('headers_policy',HeadersPolicy({"CustomHeader":"Value"},**kwargs))config.user_agent_policy=kwargs.get('user_agent_policy',UserAgentPolicy("ServiceUserAgentValue",**kwargs))config.authentication_policy=kwargs.get('authentication_policy',BearerTokenCredentialPolicy(credential,scopes,**kwargs))config.retry_policy=kwargs.get('retry_policy',RetryPolicy(**kwargs))config.redirect_policy=kwargs.get('redirect_policy',RedirectPolicy(**kwargs))config.logging_policy=kwargs.get('logging_policy',NetworkTraceLoggingPolicy(**kwargs))config.proxy_policy=kwargs.get('proxy_policy',ProxyPolicy(**kwargs))returnconfigdef__init__(self,**kwargs):transport=kwargs.get('transport',RequestsTransport(**kwargs))config=FooServiceClient._create_config(**kwargs)policies=[config.user_agent_policy,config.headers_policy,config.authentication_policy,ContentDecodePolicy(),config.proxy_policy,config.redirect_policy,config.retry_policy,config.logging_policy,]self._pipeline=Pipeline(transport,policies=policies)defget_foo_properties(self,**kwargs)# Create a generic HTTP Request. This is not specific to any particular transport# or pipeline configuration.new_request=HttpRequest("GET","/")response=self._pipeline.run(new_request,**kwargs)returndeserialize_data(response.http_response)2
当前提供的SAN IO策略包括:
fromazure.coreimportConfiguration,Pipelinefromazure.core.transportimportRequestsTransport,HttpRequestfromazure.core.pipeline.policiesimport(UserAgentPolicy,HeadersPolicy,RetryPolicy,RedirectPolicy,BearerTokenCredentialPolicy,ContentDecodePolicy,NetworkTraceLoggingPolicy,ProxyPolicy)classFooServiceClient:@staticmethoddef_create_config(credential,scopes,**kwargs):# Here the SDK developer would define the default# config to interact with the serviceconfig=Configuration(**kwargs)config.headers_policy=kwargs.get('headers_policy',HeadersPolicy({"CustomHeader":"Value"},**kwargs))config.user_agent_policy=kwargs.get('user_agent_policy',UserAgentPolicy("ServiceUserAgentValue",**kwargs))config.authentication_policy=kwargs.get('authentication_policy',BearerTokenCredentialPolicy(credential,scopes,**kwargs))config.retry_policy=kwargs.get('retry_policy',RetryPolicy(**kwargs))config.redirect_policy=kwargs.get('redirect_policy',RedirectPolicy(**kwargs))config.logging_policy=kwargs.get('logging_policy',NetworkTraceLoggingPolicy(**kwargs))config.proxy_policy=kwargs.get('proxy_policy',ProxyPolicy(**kwargs))returnconfigdef__init__(self,**kwargs):transport=kwargs.get('transport',RequestsTransport(**kwargs))config=FooServiceClient._create_config(**kwargs)policies=[config.user_agent_policy,config.headers_policy,config.authentication_policy,ContentDecodePolicy(),config.proxy_policy,config.redirect_policy,config.retry_policy,config.logging_policy,]self._pipeline=Pipeline(transport,policies=policies)defget_foo_properties(self,**kwargs)# Create a generic HTTP Request. This is not specific to any particular transport# or pipeline configuration.new_request=HttpRequest("GET","/")response=self._pipeline.run(new_request,**kwargs)returndeserialize_data(response.http_response)3
HttpPolicy和AsynchttpPolicy
有些策略更复杂,比如重试策略,需要控制http工作流。 在当前版本中,它们是httppolicy或asynchtppolicy的子类,只能使用它们相应的同步或异步管道类型。
httppolicy或asynchtppolicy必须实现send
方法,并且此实现必须包含一个调用以处理管道中的下一个策略:
fromazure.coreimportConfiguration,Pipelinefromazure.core.transportimportRequestsTransport,HttpRequestfromazure.core.pipeline.policiesimport(UserAgentPolicy,HeadersPolicy,RetryPolicy,RedirectPolicy,BearerTokenCredentialPolicy,ContentDecodePolicy,NetworkTraceLoggingPolicy,ProxyPolicy)classFooServiceClient:@staticmethoddef_create_config(credential,scopes,**kwargs):# Here the SDK developer would define the default# config to interact with the serviceconfig=Configuration(**kwargs)config.headers_policy=kwargs.get('headers_policy',HeadersPolicy({"CustomHeader":"Value"},**kwargs))config.user_agent_policy=kwargs.get('user_agent_policy',UserAgentPolicy("ServiceUserAgentValue",**kwargs))config.authentication_policy=kwargs.get('authentication_policy',BearerTokenCredentialPolicy(credential,scopes,**kwargs))config.retry_policy=kwargs.get('retry_policy',RetryPolicy(**kwargs))config.redirect_policy=kwargs.get('redirect_policy',RedirectPolicy(**kwargs))config.logging_policy=kwargs.get('logging_policy',NetworkTraceLoggingPolicy(**kwargs))config.proxy_policy=kwargs.get('proxy_policy',ProxyPolicy(**kwargs))returnconfigdef__init__(self,**kwargs):transport=kwargs.get('transport',RequestsTransport(**kwargs))config=FooServiceClient._create_config(**kwargs)policies=[config.user_agent_policy,config.headers_policy,config.authentication_policy,ContentDecodePolicy(),config.proxy_policy,config.redirect_policy,config.retry_policy,config.logging_policy,]self._pipeline=Pipeline(transport,policies=policies)defget_foo_properties(self,**kwargs)# Create a generic HTTP Request. This is not specific to any particular transport# or pipeline configuration.new_request=HttpRequest("GET","/")response=self._pipeline.run(new_request,**kwargs)returndeserialize_data(response.http_response)4
当前提供的http策略包括:
fromazure.coreimportConfiguration,Pipelinefromazure.core.transportimportRequestsTransport,HttpRequestfromazure.core.pipeline.policiesimport(UserAgentPolicy,HeadersPolicy,RetryPolicy,RedirectPolicy,BearerTokenCredentialPolicy,ContentDecodePolicy,NetworkTraceLoggingPolicy,ProxyPolicy)classFooServiceClient:@staticmethoddef_create_config(credential,scopes,**kwargs):# Here the SDK developer would define the default# config to interact with the serviceconfig=Configuration(**kwargs)config.headers_policy=kwargs.get('headers_policy',HeadersPolicy({"CustomHeader":"Value"},**kwargs))config.user_agent_policy=kwargs.get('user_agent_policy',UserAgentPolicy("ServiceUserAgentValue",**kwargs))config.authentication_policy=kwargs.get('authentication_policy',BearerTokenCredentialPolicy(credential,scopes,**kwargs))config.retry_policy=kwargs.get('retry_policy',RetryPolicy(**kwargs))config.redirect_policy=kwargs.get('redirect_policy',RedirectPolicy(**kwargs))config.logging_policy=kwargs.get('logging_policy',NetworkTraceLoggingPolicy(**kwargs))config.proxy_policy=kwargs.get('proxy_policy',ProxyPolicy(**kwargs))returnconfigdef__init__(self,**kwargs):transport=kwargs.get('transport',RequestsTransport(**kwargs))config=FooServiceClient._create_config(**kwargs)policies=[config.user_agent_policy,config.headers_policy,config.authentication_policy,ContentDecodePolicy(),config.proxy_policy,config.redirect_policy,config.retry_policy,config.logging_policy,]self._pipeline=Pipeline(transport,policies=policies)defget_foo_properties(self,**kwargs)# Create a generic HTTP Request. This is not specific to any particular transport# or pipeline configuration.new_request=HttpRequest("GET","/")response=self._pipeline.run(new_request,**kwargs)returndeserialize_data(response.http_response)5
管道
管道本身表示一个策略链,其中链中的最后一个节点是http传输。 管道可以是同步的,也可以是异步的。 管道不公开策略链,因此单个策略不能/不应该更进一步 在实例化管道后进行配置。
管道有一个公开的操作:run(request)
它将向下发送一个新的httprequest对象
管道。此操作返回一个管道响应对象。
fromazure.coreimportConfiguration,Pipelinefromazure.core.transportimportRequestsTransport,HttpRequestfromazure.core.pipeline.policiesimport(UserAgentPolicy,HeadersPolicy,RetryPolicy,RedirectPolicy,BearerTokenCredentialPolicy,ContentDecodePolicy,NetworkTraceLoggingPolicy,ProxyPolicy)classFooServiceClient:@staticmethoddef_create_config(credential,scopes,**kwargs):# Here the SDK developer would define the default# config to interact with the serviceconfig=Configuration(**kwargs)config.headers_policy=kwargs.get('headers_policy',HeadersPolicy({"CustomHeader":"Value"},**kwargs))config.user_agent_policy=kwargs.get('user_agent_policy',UserAgentPolicy("ServiceUserAgentValue",**kwargs))config.authentication_policy=kwargs.get('authentication_policy',BearerTokenCredentialPolicy(credential,scopes,**kwargs))config.retry_policy=kwargs.get('retry_policy',RetryPolicy(**kwargs))config.redirect_policy=kwargs.get('redirect_policy',RedirectPolicy(**kwargs))config.logging_policy=kwargs.get('logging_policy',NetworkTraceLoggingPolicy(**kwargs))config.proxy_policy=kwargs.get('proxy_policy',ProxyPolicy(**kwargs))returnconfigdef__init__(self,**kwargs):transport=kwargs.get('transport',RequestsTransport(**kwargs))config=FooServiceClient._create_config(**kwargs)policies=[config.user_agent_policy,config.headers_policy,config.authentication_policy,ContentDecodePolicy(),config.proxy_policy,config.redirect_policy,config.retry_policy,config.logging_policy,]self._pipeline=Pipeline(transport,policies=policies)defget_foo_properties(self,**kwargs)# Create a generic HTTP Request. This is not specific to any particular transport# or pipeline configuration.new_request=HttpRequest("GET","/")response=self._pipeline.run(new_request,**kwargs)returndeserialize_data(response.http_response)6
发布历史记录
2019-08-xx版本1.0.0b2
中断更改
- 传输类不再采用
config
参数(改用kwargs)6372 azure.core.paging
已经完全重构了6420- httpresponse.content_type属性现在是一个字符串(以前是一个列表)6490
- 对于
streamdownloadgenerator
子类,响应现在是
httpresponse
,而不是像aiohttp.clientresponse
或requests.response
这样的传输响应。传输响应在内部响应
属性6490中可用
错误修复
- 导入异步管道类6496时不需要aiohttp
asynciorequieststrasport.sleep
现在如预期的那样是一个协作程序6490requeststrasport
与proxypolicy
实现细节不再紧密相关6372aiohttpttransport
不会在意外的Kwargs 6355上引发
功能
- 新的分页基类,支持
continuation\u token
和by\u page()
\6420 - 代理支持
aiohttpttransport
6372
2019-06-26版本1.0.0b1
- 预览1版本