198 строки
7.2 KiB
Python
198 строки
7.2 KiB
Python
# --------------------------------------------------------------------------
|
|
#
|
|
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
#
|
|
# The MIT License (MIT)
|
|
#
|
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
# of this software and associated documentation files (the ""Software""), to
|
|
# deal in the Software without restriction, including without limitation the
|
|
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
# sell copies of the Software, and to permit persons to whom the Software is
|
|
# furnished to do so, subject to the following conditions:
|
|
#
|
|
# The above copyright notice and this permission notice shall be included in
|
|
# all copies or substantial portions of the Software.
|
|
#
|
|
# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
# IN THE SOFTWARE.
|
|
#
|
|
# --------------------------------------------------------------------------
|
|
|
|
|
|
try:
|
|
import configparser
|
|
from configparser import NoOptionError
|
|
except ImportError:
|
|
import ConfigParser as configparser
|
|
from ConfigParser import NoOptionError
|
|
import platform
|
|
|
|
import requests
|
|
|
|
from .exceptions import raise_with_traceback
|
|
from .pipeline import (
|
|
ClientRetryPolicy,
|
|
ClientRedirectPolicy,
|
|
ClientProxies,
|
|
ClientConnection)
|
|
from .version import msrest_version
|
|
|
|
|
|
def default_session_configuration_callback(session, global_config, local_config, **kwargs):
|
|
"""Configuration callback if you need to change default session configuration.
|
|
|
|
:param requests.Session session: The session.
|
|
:param Configuration global_config: The global configuration.
|
|
:param dict local_config: The on-the-fly configuration passed on the call.
|
|
:param dict kwargs: The current computed values for session.request method.
|
|
:return: Must return kwargs, to be passed to session.request. If None is return, initial kwargs will be used.
|
|
:rtype: dict
|
|
"""
|
|
return kwargs
|
|
|
|
|
|
class Configuration(object):
|
|
"""Client configuration.
|
|
|
|
:param str baseurl: REST API base URL.
|
|
:param str filepath: Path to existing config file (optional).
|
|
"""
|
|
|
|
def __init__(self, base_url, filepath=None):
|
|
# Service
|
|
self.base_url = base_url
|
|
|
|
# Communication configuration
|
|
self.connection = ClientConnection()
|
|
|
|
# ProxyConfiguration
|
|
self.proxies = ClientProxies()
|
|
|
|
# Retry configuration
|
|
self.retry_policy = ClientRetryPolicy()
|
|
|
|
# Redirect configuration
|
|
self.redirect_policy = ClientRedirectPolicy()
|
|
|
|
# User-Agent Header
|
|
self._user_agent = "python/{} ({}) requests/{} msrest/{}".format(
|
|
platform.python_version(),
|
|
platform.platform(),
|
|
requests.__version__,
|
|
msrest_version)
|
|
|
|
# Requests hooks. Must respect requests hook callback signature
|
|
# Note that we will inject the following parameters:
|
|
# - kwargs['msrest']['session'] with the current session
|
|
self.hooks = []
|
|
|
|
self.session_configuration_callback = default_session_configuration_callback
|
|
|
|
self._config = configparser.ConfigParser()
|
|
self._config.optionxform = str
|
|
|
|
if filepath:
|
|
self.load(filepath)
|
|
|
|
@property
|
|
def user_agent(self):
|
|
return self._user_agent
|
|
|
|
def add_user_agent(self, value):
|
|
self._user_agent = "{} {}".format(self._user_agent, value)
|
|
|
|
def _clear_config(self):
|
|
"""Clearout config object in memory."""
|
|
for section in self._config.sections():
|
|
self._config.remove_section(section)
|
|
|
|
def save(self, filepath):
|
|
"""Save current configuration to file.
|
|
|
|
:param str filepath: Path to file where settings will be saved.
|
|
:raises: ValueError if supplied filepath cannot be written to.
|
|
:rtype: None
|
|
"""
|
|
sections = [
|
|
"Connection",
|
|
"Proxies",
|
|
"RetryPolicy",
|
|
"RedirectPolicy"]
|
|
for section in sections:
|
|
self._config.add_section(section)
|
|
|
|
self._config.set("Connection", "base_url", self.base_url)
|
|
self._config.set("Connection", "timeout", self.connection.timeout)
|
|
self._config.set("Connection", "verify", self.connection.verify)
|
|
self._config.set("Connection", "cert", self.connection.cert)
|
|
|
|
self._config.set("Proxies", "proxies", self.proxies.proxies)
|
|
self._config.set("Proxies", "env_settings",
|
|
self.proxies.use_env_settings)
|
|
|
|
self._config.set("RetryPolicy", "retries", self.retry_policy.retries)
|
|
self._config.set("RetryPolicy", "backoff_factor",
|
|
self.retry_policy.backoff_factor)
|
|
self._config.set("RetryPolicy", "max_backoff",
|
|
self.retry_policy.max_backoff)
|
|
|
|
self._config.set("RedirectPolicy", "allow", self.redirect_policy.allow)
|
|
self._config.set("RedirectPolicy", "max_redirects",
|
|
self.redirect_policy.max_redirects)
|
|
try:
|
|
with open(filepath, 'w') as configfile:
|
|
self._config.write(configfile)
|
|
except (KeyError, EnvironmentError):
|
|
error = "Supplied config filepath invalid."
|
|
raise_with_traceback(ValueError, error)
|
|
finally:
|
|
self._clear_config()
|
|
|
|
def load(self, filepath):
|
|
"""Load configuration from existing file.
|
|
|
|
:param str filepath: Path to existing config file.
|
|
:raises: ValueError if supplied config file is invalid.
|
|
:rtype: None
|
|
"""
|
|
try:
|
|
self._config.read(filepath)
|
|
|
|
self.base_url = \
|
|
self._config.get("Connection", "base_url")
|
|
self.connection.timeout = \
|
|
self._config.getint("Connection", "timeout")
|
|
self.connection.verify = \
|
|
self._config.getboolean("Connection", "verify")
|
|
self.connection.cert = \
|
|
self._config.get("Connection", "cert")
|
|
|
|
self.proxies.proxies = \
|
|
eval(self._config.get("Proxies", "proxies"))
|
|
self.proxies.use_env_settings = \
|
|
self._config.getboolean("Proxies", "env_settings")
|
|
|
|
self.retry_policy.retries = \
|
|
self._config.getint("RetryPolicy", "retries")
|
|
self.retry_policy.backoff_factor = \
|
|
self._config.getfloat("RetryPolicy", "backoff_factor")
|
|
self.retry_policy.max_backoff = \
|
|
self._config.getint("RetryPolicy", "max_backoff")
|
|
|
|
self.redirect_policy.allow = \
|
|
self._config.getboolean("RedirectPolicy", "allow")
|
|
self.redirect_policy.max_redirects = \
|
|
self._config.set("RedirectPolicy", "max_redirects")
|
|
|
|
except (ValueError, EnvironmentError, NoOptionError):
|
|
error = "Supplied config file incompatible."
|
|
raise_with_traceback(ValueError, error)
|
|
finally:
|
|
self._clear_config()
|