Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Releasing version 1.3.16 #50

Merged
merged 1 commit into from
Mar 8, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,26 @@ 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.16 - 2018-03-08
====================

Added
-----
* Added support for the Email Service

* An example on using the Email Service can be found on `GitHub <https://github.com/oracle/oci-python-sdk/blob/master/examples/email_service_example.py>`__.

* Added support for SMTP credentials in the Identity Service

* An example on managing SMTP credentials can be found on `GitHub <https://github.com/oracle/oci-python-sdk/blob/master/examples/email_service_example.py>`__.

* Added support for paravirtualized volume attachments in Core Services

* An example on using volume attachments can be found on `GitHub <https://github.com/oracle/oci-python-sdk/blob/master/examples/volume_attachment_example.py>`__.

* Added support for variable size boot volumes in Core Services

====================
1.3.15 - 2018-02-22
====================
Expand Down
22 changes: 22 additions & 0 deletions docs/api/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,28 @@ Virtual Network
:imported-members:
:inherited-members:

==========
Email
==========

--------
Client
--------

.. autoclass:: oci.email.email_client.EmailClient
:members:

--------
Models
--------

.. automodule:: oci.email.models
:special-members: __init__
:members:
:undoc-members:
:imported-members:
:inherited-members:

==============
File Storage
==============
Expand Down
3 changes: 1 addition & 2 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,13 @@ To get started, head over to the :ref:`installation instructions <install>` or s
backward-compatibility
quickstart
logging
parallel-ops
pass-explicit-null
upload-manager
raw-requests
waiters
pagination
api/index
customize_service_client/index
sdk_behaviors/index
contributions
notifications
license
Expand Down
20 changes: 20 additions & 0 deletions docs/sdk_behaviors/handle_naive_datetime.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
.. _handle-naive-datetime:

Handling naive datetimes
~~~~~~~~~~~~~~~~~~~~~~~~~~
For operations and models which accept a `datetime <https://docs.python.org/3.6/library/datetime.html>`__ object, if a naive
``datetime`` is passed (i.e. one without any ``tzinfo``) then the SDK will interpret the date and time as being UTC. This is
the equivalent of running the following code on the naive ``datetime``:

.. code-block:: pycon

>>> import datetime
>>> import pytz
>>> my_naive_datetime = datetime.datetime(2001, 1, 1, 12, 30)
>>> my_naive_datetime
datetime.datetime(2001, 1, 1, 12, 30)
>>> pytz.utc.localize(my_naive_datetime)
datetime.datetime(2001, 1, 1, 12, 30, tzinfo=<UTC>)


For aware ``datetime`` objects (i.e. those with a ``tzinfo``), their timezone information will be used as-is.
17 changes: 17 additions & 0 deletions docs/sdk_behaviors/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.. sdk-behaviors:

SDK Behaviors
~~~~~~~~~~~~~~
This section describes SDK-specific behaviors:

* :doc:`Handling naive datetimes </sdk_behaviors/handle_naive_datetime>`
* :doc:`Parallel operations </parallel-ops>`
* :doc:`Passing explicit null/None values </pass-explicit-null>`

.. toctree::
:hidden:
:maxdepth: 2

handle_naive_datetime
/parallel-ops
/pass-explicit-null
166 changes: 166 additions & 0 deletions examples/email_service_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
# coding: utf-8
# Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.

# This script provides a basic example of how to use the Email Service in the Python SDK. This script accepts two
# will demonstrate:
#
# * Creating, retrieving, listing and deleting email senders
# * Creating, retrieving, listing and deleting email suppressions
# * Obtaining SMTP credentials for your IAM user so that you can send emails.
# See https://docs.us-phoenix-1.oraclecloud.com/Content/Email/Tasks/configuresmtpconnection.htm for more
# information on sending emails
#
# This script accepts three arguments:
#
# * The compartment ID where email senders will be created
# * The address of the email sender
# * The address of the email suppression
#
# Note that email senders are created in the compartment which you specify, but the suppressions are always created at the tenancy
# level. The tenancy will be read from your configuration file.

import oci
import sys

# Default config file and profile
config = oci.config.from_file()
email_client = oci.email.EmailClient(config)
identity_client = oci.identity.IdentityClient(config)

if len(sys.argv) != 4:
raise RuntimeError('This script expects an argument of a compartment OCID, sender email address and suppression email address')

# The first argument is the name of the script, so start the index at 1
compartment_id = sys.argv[1]
sender_address = sys.argv[2]
suppression_address = sys.argv[3]

create_sender_response = email_client.create_sender(
oci.email.models.CreateSenderDetails(
compartment_id=compartment_id,
email_address=sender_address
)
)
print('Created sender:\n{}'.format(create_sender_response.data))
print('\n=========================\n')

# A sender has a lifecycle state, so we can wait for it to become available
get_sender_response = oci.wait_until(email_client, email_client.get_sender(create_sender_response.data.id), 'lifecycle_state', 'ACTIVE')
print('Waited for sender to become available:\n{}'.format(get_sender_response.data))
print('\n=========================\n')

# We can list all senders, and also provide optional filters and sorts. Here we'll list all
# senders sorted by their email address, and also demonstrate filtering by sender email
# address (an exact match filter)
#
# Listing senders is a paginated operation, so we can use the functions in oci.pagination
senders = oci.pagination.list_call_get_all_results(
email_client.list_senders,
compartment_id,
sort_by='EMAILADDRESS',
sort_order='ASC'
).data
print('Listing senders sorted by email address:')
for s in senders:
print(s)
print('\n=========================\n')

senders = oci.pagination.list_call_get_all_results(
email_client.list_senders,
compartment_id,
email_address='fake-{}'.format(sender_address)
).data
print('Listing senders filtered by email address - no data expected:')
for s in senders:
print(s)
print('\n=========================\n')

# Suppressions do not have a lifecycle state, so we don't have to wait on anything after creation
create_suppression_response = email_client.create_suppression(
oci.email.models.CreateSuppressionDetails(
compartment_id=config['tenancy'],
email_address=suppression_address
)
)
print('Created suppression:\n{}'.format(create_suppression_response.data))
print('\n=========================\n')

# We can list all suppressions, and also provide optional filters and sorts. Here we'll list all
# suppressions sorted by their time created, and also demonstrate filtering by suppression email
# address (an exact match filter)
#
# Listing senders is a paginated operation, so we can use the functions in oci.pagination
suppressions = oci.pagination.list_call_get_all_results(
email_client.list_suppressions,
config['tenancy'],
sort_by='TIMECREATED',
sort_order='DESC'
).data
print('Listing suppressions sorted by time created:')
for s in suppressions:
print(s)
print('\n=========================\n')

suppressions = oci.pagination.list_call_get_all_results(
email_client.list_suppressions,
config['tenancy'],
email_address='fake-{}'.format(suppression_address)
).data
print('Listing suppressions filtered by email address - no data expected:')
for s in suppressions:
print(s)
print('\n=========================\n')

# We can also delete a sender and then wait for it to be deleted. The sender may already be deleted
# by the time we call oci.wait_until, so pass the get_sender_response to the waiter. It is recommended that
# you have a get response prior to calling the delete, INSTEAD OF doing:
#
# oci.wait_until(email_client, email_client.get_sender(sender_id), ...)
#
# When deleting, since the resource may be gone, we set succeed_on_not_found on the waiter so that we consider
# receiving a 404 back from the service as a successful delete
email_client.delete_sender(get_sender_response.data.id)
oci.wait_until(email_client, get_sender_response, 'lifecycle_state', 'DELETED', succeed_on_not_found=True)
print('Deleted sender')

# Suppressions do not have a lifecycle state, so we don't have to wait on anything after deletion
email_client.delete_suppression(create_suppression_response.data.id)
print('Deleted suppression')

# In order to send email, we'll need to create an SMTP credential associated with an IAM user. More
# information on sending email can be found here:
# https://docs.us-phoenix-1.oraclecloud.com/Content/Email/Tasks/configuresmtpconnection.htm
#
# Note, also, that an IAM user can only have two active SMTP credentials at any time
#
# Also the password for the SMTP credential is ONLY available in the create response, so you
# should store/save this as it won't be retrievable later
create_smtp_credential_response = identity_client.create_smtp_credential(
oci.identity.models.CreateSmtpCredentialDetails(
description='new credential'
),
user_id=config['user']
)
print('Created SMTP credential:\n{}'.format(create_smtp_credential_response.data))
print('\n=========================\n')

# We can update the description of an SMTP credential
update_smtp_credential_response = identity_client.update_smtp_credential(
config['user'],
create_smtp_credential_response.data.id,
oci.identity.models.UpdateSmtpCredentialDetails(
description='updated credential description'
)
)
print('Updated SMTP credential:\n{}'.format(update_smtp_credential_response.data))
print('\n=========================\n')

# We can list the credentials for a user. Note that this is not a paginated operation
list_smtp_credentials_response = identity_client.list_smtp_credentials(config['user'])
print('SMTP credentials for user:\n{}'.format(list_smtp_credentials_response.data))
print('\n=========================\n')

identity_client.delete_smtp_credential(config['user'], create_smtp_credential_response.data.id)
print('Deleted SMTP credential')

print('\nScript Finished')
7 changes: 3 additions & 4 deletions examples/retrieve_audit_events.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#!/usr/bin/env python
# coding: utf-8
# Copyright (c) 2016, 2018, 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 retrieves all audit logs across an OCI Tenancy.
# for a timespan defined by start_time and end_time.
Expand Down Expand Up @@ -95,4 +94,4 @@ def get_audit_events(audit, compartment_ocids, start_time, end_time):

# Results for a region 'r' for each compartment.
if audit_events:
print audit_events
print(audit_events)
Loading