-
Notifications
You must be signed in to change notification settings - Fork 283
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #51 from oracle/release_2018-03-26
Releasing version 1.3.17
- Loading branch information
Showing
353 changed files
with
4,182 additions
and
782 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
.. _exception-handling: | ||
|
||
Exception handling | ||
~~~~~~~~~~~~~~~~~~~~~~ | ||
When using the Python SDK, you should be prepared to handle the following exceptions: | ||
|
||
* Any response received by the SDK with a non-2xx HTTP status will be thrown as a :py:class:`~oci.exceptions.ServiceError` | ||
* A ``ValueError`` will be thrown if you provide invalid parameters to a method call or when setting an attribute. For example: | ||
|
||
* When setting an attribute on a model and that attribute has a constrained set of values, such as :py:attr:`~oci.core.models.CreatePublicIpDetails.lifetime` on ``CreatePublicIpDetails`` | ||
* When passing a blank string as the identifier for a ``get_`` operation, such as passing a nil ``instance_id`` to :py:meth:`~oci.core.compute_client.ComputeClient.get_instance` | ||
|
||
* :py:class:`~oci.exceptions.ClientError` and its subclasses. These exceptions are raised when there is an error with your configuration file or when using the :py:meth:`~oci.wait_until` function | ||
|
||
* :py:class:`~oci.exceptions.ConfigFileNotFound` | ||
* :py:class:`~oci.exceptions.InvalidConfig` | ||
* :py:class:`~oci.exceptions.InvalidPrivateKey` | ||
* :py:class:`~oci.exceptions.MissingPrivateKeyPassphrase` | ||
* :py:class:`~oci.exceptions.ProfileNotFound` | ||
* :py:class:`~oci.exceptions.WaitUntilNotSupported` | ||
* :py:class:`~oci.exceptions.MaximumWaitTimeExceeded` | ||
|
||
* If you use the :py:class:`~oci.object_storage.UploadManager` then you should also catch :py:class:`~oci.exceptions.MultipartUploadError` | ||
|
||
* The Python SDK uses the `Requests <http://docs.python-requests.org/en/master/>`_ library to make calls to OCI services but it does not mask or wrap any of the errors originating from this library, so you should also account for these in your code. The exception reference for Requests can be found `here <http://docs.python-requests.org/en/master/_modules/requests/exceptions/>`__ and `here <http://docs.python-requests.org/en/master/api/#exceptions>`__ | ||
|
||
Handling HTTP 3xx responses | ||
============================ | ||
As a result of the SDK treating responses with a non-2xx HTTP status as a :py:class:`~oci.exceptions.ServiceError` the SDK will throw a :py:class:`~oci.exceptions.ServiceError` on 3xx responses. This can impact operations which support conditional GETs, such as :py:meth:`~oci.object_storage.object_storage_client.ObjectStorageClient.get_object` and :py:meth:`~oci.object_storage.object_storage_client.ObjectStorageClient.head_object` methods as these can return responses with a HTTP status code of 304 if passed an ``if_none_match`` which corresponds to the curent etag of the object or bucket. | ||
|
||
In order to account for this, you should catch :py:class:`~oci.exceptions.ServiceError` and check its ``status`` attribute for the HTTP status code. For example: | ||
|
||
.. code-block:: python | ||
import oci | ||
config = oci.config.from_file() | ||
client = oci.object_storage.ObjectStorageClient(config) | ||
try: | ||
get_object_response = client.get_object('my_namespace', 'my_bucket', 'my_object', if_none_match='some_etag_value') | ||
except oci.exceptions.ServiceError as e: | ||
if e.status == 304: | ||
# Object exists but has not been modified (based on the etag value) | ||
pass | ||
else: | ||
raise |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,3 +30,9 @@ In order to modify the underlying Session object, you can do something similar t | |
The key parts are that the underlying Session object can be accessed via ``base_client.session`` and we can then modify the `proxies <http://docs.python-requests.org/en/master/api/#requests.Session.proxies>`_ | ||
dictionary to add any required proxies. | ||
|
||
If your proxy uses HTTP Basic Auth, then when setting ``base_client.session.proxies`` you can use the *http://user:password@host/* syntax to provide the username and password. For example: | ||
|
||
.. code-block:: python | ||
compute.base_client.session.proxies = { 'https': 'http://myuser:[email protected]:80' } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
.. _sdk-retries: | ||
|
||
Retries | ||
~~~~~~~~ | ||
By default, operations exposed in the SDK do not retry, but retries can be set in the SDK on a per-operation basis. Each operation accepts a | ||
``retry_strategy`` keyword argument which can be used to set the retry strategy for that operation. This retry stategy could be: | ||
|
||
* The default strategy vended by the SDK as :py:data:`~oci.retry.DEFAULT_RETRY_STRATEGY` | ||
* The :py:class:`~oci.retry.NoneRetryStrategy`. This will result in no retries being performed for the operation | ||
* A custom strategy produced via the :py:class:`~oci.retry.RetryStrategyBuilder` | ||
|
||
A sample on using retries, including the default strategy and a custom strategy, can be found on `GitHub <https://github.com/oracle/oci-python-sdk/blob/master/examples/retries.py>` | ||
|
||
Default Retry Strategy | ||
------------------------ | ||
The default retry strategy vended by the SDK has the following attributes: | ||
|
||
* 5 total attempts | ||
* Total allowed elapsed time for all requests of 300 seconds (5 minutes) | ||
* Exponential backoff with jitter, using: | ||
|
||
* The base time to use in retry calculations will be 1 second | ||
* An exponent of 2. When calculating the next retry time we will raise this to the power of the number of attempts | ||
* A maximum wait time between calls of 30 seconds | ||
|
||
* Exponential backoff with equal jitter is used for throttles as this guarantees some sleep time between attempts. The sleep time in this circumstance is calculated as: | ||
|
||
.. code-block:: none | ||
exponential_backoff_sleep_base = min(base_time * (exponent ** attempt_number), max_wait_time) | ||
sleep_time = (exponential_backoff_sleep_base / 2.0) + random(0, exponential_backoff_sleep_base / 2.0) | ||
* Exponential backoff with full jitter is used for other scenarios where we need to retry (e.g. timeouts, HTTP 5xx). The sleep time in this circumstance is calculated as: | ||
|
||
.. code-block:: none | ||
exponential_backoff_sleep_base = min(base_time * (exponent ** attempt_number), max_wait_time) | ||
sleep_time = random(0, exponential_backoff_sleep_base) | ||
* Retries on the following exception types: | ||
|
||
* Timeouts and connection errors | ||
* HTTP 429s (throttles) | ||
* HTTP 5xx (server errors) |
Oops, something went wrong.