Skip to content

Commit

Permalink
Merge pull request #41 from oracle/release_2018-01-11
Browse files Browse the repository at this point in the history
Releasing version 1.3.12
  • Loading branch information
benthamc authored Jan 11, 2018
2 parents 096a48d + 29a1cdf commit 090bcd5
Show file tree
Hide file tree
Showing 331 changed files with 8,387 additions and 1,005 deletions.
24 changes: 24 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,30 @@ All notable changes to this project will be documented in this file.

The format is based on `Keep a Changelog <http://keepachangelog.com/>`_.

====================
1.3.12 - 2018-01-11
====================

Added
-----
* Support for tagging:

* Support for creating, updating, retrieving and listing tags and tag namespaces (these operations can be found in Identity Service)
* Support for adding freeform and defined tags to resources in Core Services (Networking, Compute, and Block Volume) and Identity Service
* An example on using tagging can be found on `GitHub <https://github.com/oracle/oci-python-sdk/blob/master/examples/tagging.py>`_.

* Support for bringing your own custom image for emulation mode virtual machines in Compute Service
* Added the ``oci.pagination`` module, which contains convenience functions so that you don't have to manually deal with page tokens when using list operations. See the `documentation <https://oracle-cloud-infrastructure-python-sdk.readthedocs.io/en/latest/pagination.html>`_ for more information

Changed
-------
* Upgraded cryptography dependency to 2.1.3

* Added dependency on pyOpenSSL <= 17.4.0 as the minimum cryptography version for pyOpenSSL 17.5.0 is 2.1.4

* Upgraded six dependency to 1.11.0
* Ugraded requests dependency to 2.18.4

====================
1.3.11 - 2017-12-11
====================
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Contributing to the Oracle Cloud Infrastructure Python SDK
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

*Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.*
*Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.*

Pull requests can be made under
`The Oracle Contributor Agreement <https://www.oracle.com/technetwork/community/oca-486395.html>`_ (OCA).
Expand Down
6 changes: 3 additions & 3 deletions LICENSE.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.

This software is dual-licensed to you under the Universal Permissive License (UPL) and Apache License 2.0. See below for license terms. You may choose either license, or both.
____________________________
The Universal Permissive License (UPL), Version 1.0
Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.

Subject to the condition set forth below, permission is hereby granted to any person obtaining a copy of this software, associated documentation and/or data (collectively the "Software"), free of charge and under any and all copyright rights in the Software, and any and all patent rights owned or freely licensable by each licensor hereunder covering either (i) the unmodified Software as contributed to or provided by such licensor, or (ii) the Larger Works (as defined below), to deal in both

Expand All @@ -19,7 +19,7 @@ The above copyright notice and either this complete permission notice or at a mi
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.

The Apache Software License, Version 2.0
Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License"); You may not use this product except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. A copy of the license is also reproduced below. Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ __ https://github.com/oracle/oci-python-sdk
License
=======

Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.

This SDK and sample is dual licensed under the Universal Permissive License 1.0 and the Apache License 2.0.

Expand Down
11 changes: 11 additions & 0 deletions docs/api/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,17 @@ Load Balancer

.. autofunction:: wait_until

===========
Pagination
===========

.. module:: oci.pagination

.. autofunction:: list_call_get_all_results
.. autofunction:: list_call_get_up_to_limit
.. autofunction:: list_call_get_all_results_generator
.. autofunction:: list_call_get_up_to_limit_generator

=========
Request
=========
Expand Down
19 changes: 19 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import pkg_resources
import sphinx_rtd_theme

from sphinx.domains.python import PythonDomain

# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
Expand Down Expand Up @@ -236,3 +238,20 @@
# If true, do not generate a @detailmenu in the "Top" node's menu.
#
# texinfo_no_detailmenu = False

class PatchedPythonDomain(PythonDomain):
def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode):
if 'refspecific' in node and fromdocname == 'api/index':
# This for api/index.rst and defined tags. These have a data type of dict(str, dict(str, object)) but if
# Sphinx auto-linking tries to link "object" to the "object" property in CreateMultipartUploadDetails (which is
# incorrect).
#
# This prevents any non-explicit link (e.g. just plain "object") from being linked across, but if I was
# explicit like "oci.object_storage.models.CreateMultipartUploadDetails.object" that **should** still produce
# a link
if node['reftarget'] == 'object' and not node['refexplicit']:
del node['refspecific']
return super(PatchedPythonDomain, self).resolve_xref(env, fromdocname, builder, typ, target, node, contnode)

def setup(sphinx):
sphinx.override_domain(PatchedPythonDomain)
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ To get started, head over to the :ref:`installation instructions <install>` or s
upload-manager
raw-requests
waiters
pagination
api/index
contributions
notifications
Expand Down
2 changes: 1 addition & 1 deletion docs/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ The supported version of OpenSSL for the Python SDK is version 1.0.1 or newer.

If the version is lower than ``1.0.1``, run the following command to bypass the version issue::

pip install requests[security]==2.11.1
pip install requests[security]==2.18.4

This command instructs the `requests <https://pypi.python.org/pypi/requests>`_
library used by the Python SDK to use the version of OpenSSL that is bundled with the `cryptography <https://pypi.python.org/pypi/cryptography>`_
Expand Down
22 changes: 22 additions & 0 deletions docs/pagination.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.. raw:: html

<script type='text/javascript'>
var oldDocsHost = 'oracle-bare-metal-cloud-services-python-sdk';
if (window.location.href.indexOf(oldDocsHost) != -1) {
window.location.href = 'https://oracle-bare-metal-cloud-services-python-sdk.readthedocs.io/en/latest/deprecation-notice.html';
}
</script>

Pagination
~~~~~~~~~~~~
When you call a list operation (for example :py:func:`~oci.core.compute_client.ComputeClient.list_instances`) will retrieve a page of results. In order
to retrieve more data, you have to continue to make calls to the list operation, passing in the value of the most recent response's ``next_page`` attribute
as a parameter to the next list operation call.

As a convenience over manually writing pagination code, you can make use of the functions in the :py:mod:`~oci.pagination` module to:

* Eagerly load all possible results from a list call
* Eagerly load all results from a list call up to a given limit
* Lazily load results (either all results, or up to a given limit) from a list call via a generator. These generators can yield either values/models or the raw response from calling the list operation

For an example on how to use these functions, please check `GitHub <https://github.com/oracle/oci-python-sdk/blob/master/examples/pagination.py>`_.
18 changes: 18 additions & 0 deletions docs/waiters.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,24 @@ Sometimes you may need to wait until an attribute of a resource, such as an inst
# - The fourth parameter is the desired value. An equality (==) comparison is done
get_instance_response = oci.wait_until(client, client.get_instance(instance_ocid), 'lifecycle_state', 'RUNNING')
Instead of waiting for a single attribute to equal a given value, you can also provide a function reference (either a lambda or a reference to an already defined function) that
can be used to evaluate the response received from the service call. This function should return a truthy value if the waiter should stop waiting, and a falsey value if the waiter
should continue waiting.

For example, to wait until a volume backup reaches either the "AVAILABLE" or "FAULTY" state :

.. code-block:: python
oci.wait_until(client, client.get_volume_backup(vol_backup_id), evaluate_response=lambda r: r.data.lifecycle_state in ['AVAILABLE', 'FAULTY'])
Instead of using a lambda, an already defined function can be used:

.. code-block:: python
def should_stop_waiting_volume_backup(response):
return response.data.lifecycle_state in ['AVAILABLE', 'FAULTY']
oci.wait_until(client, client.get_volume_backup(vol_backup_id), evaluate_response=should_stop_waiting_volume_backup)
In addition to the base parameters shown above, the function can accept optional attributes to control the maximum amount of time it will wait for and the time between calls to the service. For more information on the optional parameters, see the documentation on the :py:func:`~oci.wait_until` function.

Expand Down
3 changes: 2 additions & 1 deletion examples/multipart_object_upload.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
# coding: utf-8
# Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.

from __future__ import print_function
import os
Expand Down
28 changes: 27 additions & 1 deletion examples/object_crud.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
# coding: utf-8
# Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.

import filecmp
import oci
from oci.object_storage.models import CreateBucketDetails

Expand Down Expand Up @@ -36,8 +38,32 @@
my_data, same_obj.data.content,
my_data == same_obj.data.content))

print('Uploading a file to object storage')

# First create a sample file
sample_content = b'a' * 1024 * 1024 * 5
with open('example_file', 'wb') as f:
f.write(sample_content)

# Then upload the file to Object Storage
example_file_object_name = 'example_file_obj'
with open('example_file', 'rb') as f:
obj = object_storage.put_object(namespace, bucket_name, example_file_object_name, f)

# Retrieve the file, streaming it into another file in 1 MiB chunks
print('Retrieving file from object storage')
get_obj = object_storage.get_object(namespace, bucket_name, example_file_object_name)
with open('example_file_retrieved', 'wb') as f:
for chunk in get_obj.data.raw.stream(1024 * 1024, decode_content=False):
f.write(chunk)

print('Uploaded and downloaded files are the same: {}'.format(filecmp.cmp('example_file', 'example_file_retrieved')))

print("Deleting object {}".format(object_name))
object_storage.delete_object(namespace, bucket_name, object_name)

print("Deleting object {}".format(example_file_object_name))
object_storage.delete_object(namespace, bucket_name, example_file_object_name)

print("Deleting bucket {}".format(bucket_name))
object_storage.delete_bucket(namespace, bucket_name)
88 changes: 66 additions & 22 deletions examples/pagination.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
# Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
# coding: utf-8
# Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.

# This script demonstrates different methods of pagination in the SDK via the oci.pagination module. This module supports:
#
# - Eagerly loading all possible results from a list call
# - Eagerly loading all results from a list call up to a given limit
# - Generators that can be used to lazily iterate over results from a list call. These generators can yield either values/models
# or the raw responses of the call

import oci

Expand All @@ -7,30 +15,66 @@
compartment_id = config["tenancy"]
identity = oci.identity.IdentityClient(config)

# This demonstrates the eager loading of all possible results. This will return an oci.response.Response whose data attribute contains
# a list of all results. The other attributes of the Response object come from the last response received from the service.
print('--------------------------------------------')
print('Eager load all results')
print('--------------------------------------------')
response = oci.pagination.list_call_get_all_results(identity.list_users, compartment_id)
for user in response.data:
print('User: {}'.format(user.name))

# operation-independent pagination function
def paginate(operation, *args, **kwargs):
"""Yields values from a list call, automatically following pagination tokens.
# This demonstrates the eager loading of all results up to a given limit. Note that we have to specify a record limit (20) and
# a page size (5)
#
# This will return an oci.response.Response whose data attribute contains a list of all results. The other attributes of the
# Response object come from the last response received from the service.
print('--------------------------------------------')
print('Eager load up to limit')
print('--------------------------------------------')
response = oci.pagination.list_call_get_up_to_limit(identity.list_users, 20, 5, compartment_id)
total_results = 0
for user in response.data:
total_results += 1
print('User: {}'.format(user.name))
print('Total results: {}'.format(total_results))

Metadata such as request_id, headers, and http status are not returned.
:param operation: a client list function such as identity.list_policies
"""
while True:
response = operation(*args, **kwargs)
for value in response.data:
yield value
kwargs["page"] = response.next_page
if not response.has_next_page:
break
# This demonstrates lazily loading, via a generator, all results. Here we use a generator which yields values/models via specifying
# the yield_mode as 'record'
print('--------------------------------------------')
print('Lazy load all results - yield values')
print('--------------------------------------------')
for user in oci.pagination.list_call_get_all_results_generator(identity.list_users, 'record', config["tenancy"]):
print('User: {}'.format(user.name))

# The below demonstrates lazily loading, via a generator, results up to a certain limit

for user in paginate(
identity.list_users,
compartment_id=compartment_id):
print("User: " + str(user))
print('--------------------------------------------')
print('Lazy load all results - yield raw responses')
print('--------------------------------------------')
response_num = 0
for response in oci.pagination.list_call_get_all_results_generator(identity.list_users, 'response', config["tenancy"]):
response_num += 1
for user in response.data:
print('Response: {}, User: {}'.format(response_num, user.name))

print('--------------------------------------------')
print('Lazy load up to limit - yield values')
print('--------------------------------------------')
total_results = 0
for user in oci.pagination.list_call_get_up_to_limit_generator(identity.list_users, 20, 10, 'record', config["tenancy"]):
total_results += 1
print('User: {}'.format(user.name))
print('Total results: {}'.format(total_results))

for group in paginate(
identity.list_groups,
compartment_id=compartment_id):
print("Group: " + str(group))
print('--------------------------------------------')
print('Lazy load up to limit - yield raw responses')
print('--------------------------------------------')
response_num = 0
total_results = 0
for response in oci.pagination.list_call_get_up_to_limit_generator(identity.list_users, 20, 10, 'response', config["tenancy"]):
response_num += 1
for user in response.data:
total_results += 1
print('Response: {}, User: {}'.format(response_num, user.name))
print('Total results: {}'.format(total_results))
5 changes: 3 additions & 2 deletions examples/parallel_upload_to_object_storage.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
#
# coding: utf-8
# Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.

# Uploads all files from a local directory to an object storage bucket
# using multiple processes so that the uploads are done in parallel.
#
Expand Down
3 changes: 2 additions & 1 deletion examples/raw_request.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
# coding: utf-8
# Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.

import requests
from oci.config import from_file
Expand Down
Loading

0 comments on commit 090bcd5

Please sign in to comment.