Subscribe

Share

Application Development

Developers: Create Autonomous Databases

Create an Oracle Autonomous Transaction Processing instance with the Python SDK for Oracle Cloud Infrastructure.

By Blaine Carter

July/August 2019

You’ve been working with Oracle Autonomous Transaction Processing, using the web dashboard, and now you’re ready to automate the process. This article demonstrates how to create a new Oracle Autonomous Transaction Processing instance in your Python application, using the Python SDK for Oracle Cloud Infrastructure. (You can refer to the documentation for more information about the SDK.)

Prerequisites

Before you create your new instance, confirm that

  • You are able to create an Oracle Autonomous Transaction Processing instance, using the Oracle Cloud Autonomous Database web dashboard.
  • You have successfully installed and configured the command-line interface for Oracle Cloud Infrastructure.
  • You have installed Python and have a basic understanding of Python programming. Python 2.7+ and 3.5+ are supported.
I will be using Python 3 for the article examples, and I will be running them on a Linux system. You may need to alter some system commands if you’re using a different operating system.

Installation

To start the SDK installation, first create and change into a directory for your project.

$ mkdir ~/ociPythonSdkExample
$ cd ~/ociPythonSdkExample

Python setup. To isolate your Python environments, it’s a good idea to use the virtualenv Python virtual environment. Follow the steps for your operating system if you’re new to virtualenv.

On my Linux system, I use the following commands to install virtualenv (virtualenv) and create a new environment (env).

$ python3 -m pip install --user virtualenv
$ python3 -m venv env

This will create a new directory called env.

Now I activate the new environment and check that it is active.

$ source env/bin/activate
$ which python

For your vitualenv setup, you should see something similar to this result when you activate the environment and check it:

/home/bcarter/ociPythonSdkExample/env/bin/python
(env) [bcarter ociPythonSdkExample]$

Now that you’re safely working in the virtualenv Python virtual environment, install the Python SDK for Oracle Cloud Infrastructure.

$ pip install oci

Verify that it is installed and configured correctly.

$ python3
Type "help", "copyright", "credits" or "license" for more information.
>>> import oci
>>> # Load the configuration file
... config = oci.config.from_file("~/.oci/config", "DEFAULT")
>>> # Create a service client
... identity = oci.identity.IdentityClient(config)
>>> # Get the current user
... user = identity.get_user(config["user"]).data
>>> print(user)
{
 "capabilities": {
   "can_use_api_keys": true,
   "can_use_auth_tokens": true,
   "can_use_console_password": true,
   "can_use_customer_secret_keys": true,
   "can_use_smtp_credentials": true
 },
 "compartment_id": "ocid1.tenancy.oc1..aBigLongGuidString",
 "defined_tags": {},
 "description": "me",
 "email": "blaine.carter@oracle.com",
 "external_identifier": null,
 "freeform_tags": {},
 "id": "ocid1.user.oc1..aBigLongGuidString ",
 "identity_provider_id": null,
 "inactive_status": null,
 "is_mfa_activated": false,
 "lifecycle_state": "ACTIVE",
 "name": "BlaineCarter",
 "time_created": "2019-03-21T18:58:06.069000+00:00"
}
>>> quit()

If you receive an error message when you’re verifying the installation and configuration of Python SDK for Oracle Cloud Infrastructure, make sure the command-line interface for Oracle Cloud Infrastructure is also installed and configured correctly.

Oracle Cloud Infrastructure compartment. It’s a good idea to work inside an Oracle Cloud Infrastructure compartment so you don’t accidentally affect the cloud objects of other users.

If you’d like to use a specific compartment, you’ll first need to get its Oracle Cloud ID (OCID).

To get the OCID in your Oracle Cloud Infrastructure dashboard,

  1. Expand the menu.
  2. Click Identity/Compartments.
  3. Find your compartment in the list.
  4. Click the OCID value.
  5. Click Copy in the pop-up.

Now create an environment variable with this OCID value:

$ export OCI_COMPARTMENT='ocid1.compartment.oc1..aBigLongGuidString'

The example code will look for this value or default to the root compartment if you don’t set it.

Python Code

The oci_atp.py utility module will include the methods that will create a new Oracle Autonomous Transaction Processing instance. The module will include three methods, and each method will accept an oci.database.DatabaseClient object.

create_atp(db_client, atp_details). The create_atp method in oci_atp.py also accepts an oci.database.models.CreateAutonomousDatabaseDetails object. The atp_details object defines the properties of the new Oracle Autonomous Transaction Processing instance. The properties I will be passing into the create_atp method are

  • atp_details.admin_password
  • atp_details.compartment_id
  • atp_details.db_name
  • atp_details.display_name
  • atp_details.cpu_core_count
  • atp_details.data_storage_size_in_tbs
  • atp_details.license_model

The create_atp method calls create_autonomous_database, passing in the details object. It stores the response in the atp_response variable. The response object contains detailed information about the newly provisioned Oracle Autonomous Transaction Processing instance, but I’m going to use only the atp_id value. The atp_id is the OCID for the new Oracle Autonomous Transaction Processing instance.

def create_atp(db_client, atp_details):
   # Provision a new ATP Database
   atp_response = db_client.create_autonomous_database(
       create_autonomous_database_details=atp_details)
 
   # Get the OCID for the new ATP Database, print and return the ID
   atp_id = atp_response.data.id
   print("Created Automated Transaction Processing Database: {}".format(atp_ID))
 
   return atp_id

delete_atp(db_client, atp_id). The delete_atp method in oci_atp.py accepts the Oracle Autonomous Transaction Processing OCID, which is passed into delete_autonomous_database. This method will terminate the Oracle Autonomous Transaction Processing instance. Be careful with this command—there is no undo.

def delete_atp(db_client, atp_id):
   # TERMINATE the automated transaction processing database
   db_client.delete_autonomous_database(atp_id)
   print("TERMINATED Automated Transaction Processing Database: {}".format(atp_id))

get_wallet(db_client, atp_id, password, fileName). In a previous article (“Getting Started with Autonomous”), I explained that you will need an Oracle wallet to access your new Oracle Autonomous Transaction Processing instance and I walked through the steps to manually download it through the Oracle Cloud dashboard.

Instead of using the dashboard to get the wallet this time, I’ll use the get_wallet method in oci_atp.py to generate and download a wallet.

The get_wallet method accepts the database_client object, the OCID of the Oracle Autonomous Transaction Processing instance, a password for the .zip file, and the path/filename to use when creating the .zip file. After generating and downloading the new wallet, the get_wallet method will create a .zip file, using the response data.

def get_wallet(db_client, atp_id, password, fileName):

   # Create a wallet details object
   atp_wallet = oci.database.models.GenerateAutonomousDatabaseWalletDetails()
 
   # Set the password
   atp_wallet.password = password
 
   # Generate the wallet and store the response object
   atp_wallet_response = db_client.generate_autonomous_database_wallet(
       autonomous_database_id = atp_id,
       generate_autonomous_database_wallet_details = atp_wallet,
   )
   
   # Create the new .zip file using the response data
   with open(fileName, "wb") as f:
       for data in atp_wallet_response.data:
           f.write(data)
 
   print("Wallet Downloaded \x1b[31m***Keep this fileName secure. It can be used to access your Database!***\x1b[0m")

 

The complete oci_atp.py module. Here are the methods just described—create_atp, delete_atp, and get_wallet—in the complete oci_atp.py utility module.

import oci
 
def create_atp(db_client, atp_details):
   # Provision a new ATP Database
   atp_response = db_client.create_autonomous_database(
       create_autonomous_database_details=atp_details)
 
   # Get the OCID for the new ATP Database, print and return the ID
   atp_id = atp_response.data.id
   print("Created Automated Transaction Processing Database: {}".format(atp_id))
 
   return atp_id
 
def delete_atp(db_client, atp_id):
   # TERMINATE the automated transaction processing database
   db_client.delete_autonomous_database(atp_id)
   print("TERMINATED automated transaction processing database: {}".format(atp_id))
 
def get_wallet(db_client, atp_id, password, fileName):
   # Create a wallet details object
   atp_wallet = oci.database.models.GenerateAutonomousDatabaseWalletDetails()
 
   # Set the password
   atp_wallet.password = password
 
   # Generate the wallet and store the response object
   atp_wallet_response = db_client.generate_autonomous_database_wallet(
       autonomous_database_id = atp_id,
       generate_autonomous_database_wallet_details = atp_wallet,
   )
   
   # Create the new .zip file using the atp_wallet_response data
   with open(fileName, "wb") as f:
       for data in atp_wallet_response.data:
           f.write(data)
 
   print("Wallet Downloaded \x1b[31m***Keep this fileName secure. It can be used to access your Database!***\x1b[0m")

Using the oci_atp.py Module

To access the oci_atp.py module, you first need to create an oci.database.DatabaseClient, db_client.

The db_client is created with the configuration details you included when you set up the command-line interface for Oracle Cloud Infrastructure.

You can load the default configuration.

config = oci.config.from_file()

Or, if you want to use a different file or configuration, you can load the details, as I did when I verified the SDK above.

config = oci.config.from_file("~/.oci/config", "DEFAULT")

You can now create the database client, using the config object.

# Initialize the client
db_client = oci.database.DatabaseClient(config)

Next you need to create and populate the atp_details object you will use to define the new Oracle Autonomous Transaction Processing instance.

   # Create the CreateAutonomousDatabaseDetails object
   atp_details = oci.database.models.CreateAutonomousDatabaseDetails()
 
   # Populate the details used to create the ATP Database
   atp_details.admin_password = "Welcome1!SDK" # ****(Remember to change this to a good password)*****
   atp_details.compartment_id = os.getenv("OCI_COMPARTMENT") or config["tenancy"] # Use a specific compartment or default to the Root compartment
   atp_details.db_name = "PySdkAtpTemp"
   atp_details.display_name = "Python SDK ATP Example"
   atp_details.cpu_core_count = 1
   atp_details.data_storage_size_in_tbs = 1
   atp_details.license_model = atp_details.LICENSE_MODEL_BRING_YOUR_OWN_LICENSE

Finally, provision the new Oracle Autonomous Transaction Processing instance, using the create_atp method.

   # Provision the ATP Database
   atp_id = oci_atp.create_atp(db_client, atp_details)

It will take a few minutes for the database to be fully provisioned and available.

Rather than manually watching the status on the Oracle Cloud dashboard, I use the wait_until method. This method will watch the new Oracle Autonomous Transaction Processing instance until the lifecycle_state value is AVAILABLE. By default, the method will check the status at an interval of max_interval_seconds=30, but I’ve changed it to 60 seconds. Also by default, the wait_until method will wait for only 12,000 seconds, but I’ve changed it to wait for three hours.

   # Wait for the new ATP Database to become available
   get_atp_response = oci.wait_until(
       db_client,
       db_client.get_autonomous_database(atp_id),
       'lifecycle_state',
       'AVAILABLE',
       max_interval_seconds=60,
       max_wait_seconds=21600,
       wait_callback = wait_callback
   )

The use of wait_callback is optional, but I like to have the visual it provides, so I know that the instance creation is still working. I use this method to print the status if it changes or a “.” if not.

atp_status = "NONE"
 
def wait_callback(attempts, results):
   global atp_status
   if atp_status != results.data.lifecycle_state:
       atp_status = results.data.lifecycle_state
       print(atp_status, end='', flush=True)
   else:
       print('.', end='', flush=True)
 
print("AVAILABLE")

The output should look like this:

PROVISIONING.......AVAILABLE

Once the database is available, you can download the wallet. The file will be a .zip file, so name it correctly. You can add a path to the filename value if you’d like to store the wallet in another location.

   # Wallet values
   walletPassword = "Wallet1!SDK" # CHANGE THE PASSWORD! - ****(Remember to change this to a good password)*****
   fileName = "{}_wallet.zip".format(atp_details.db_name)
 
   # Download the wallet
   oci_atp.get_wallet(db_client, atp_id, walletPassword, fileName)

The code for atp_example.py. The following atp_example.py example module calls the methods in the oci_atp.py utility module to create a new Oracle Autonomous Transaction Processing instance and download the .zip file.

import oci, os
import oci_atp
 
config = oci.config.from_file()
 
atp_status = "NONE"
 
def wait_callback(attempts, results):
   global atp_status
   if atp_status != results.data.lifecycle_state:
       atp_status = results.data.lifecycle_state
       print(atp_status, end='', flush=True)
   else:
       print('.', end='', flush=True)
 
if __name__ == "__main__":
   # Initialize the client
   db_client = oci.database.DatabaseClient(config)
 
   # Create the CreateAutonomousDatabaseDetails object
   atp_details = oci.database.models.CreateAutonomousDatabaseDetails()
 
   # Populate the details used to create the ATP Database
   atp_details.admin_password = "Welcome1!SDK" # ****(Remember to change this to a good password)*****
   atp_details.compartment_id = os.getenv("OCI_COMPARTMENT") or config["tenancy"] # Use a specific compartment or default to the Root compartment
   atp_details.db_name = "PySdkAtpTemp"
   atp_details.display_name = "Python SDK ATP Example"
   atp_details.cpu_core_count = 1
   atp_details.data_storage_size_in_tbs = 1
   atp_details.license_model = atp_details.LICENSE_MODEL_BRING_YOUR_OWN_LICENSE
 
   # Provision the ATP Database
   atp_id = oci_atp.create_atp(db_client, atp_details)
 
   # Wait for the new ATP Database to become available
   get_atp_response = oci.wait_until(
       db_client,
       db_client.get_autonomous_database(atp_id),
       'lifecycle_state',
       'AVAILABLE',
       max_interval_seconds=60,
       max_wait_seconds=21600,
       wait_callback = wait_callback
   )
 
   print("AVAILABLE")
 
   # Wallet values
   walletPassword = "Wallet1!SDK" # CHANGE THE PASSWORD! - ****(Remember to change this to a good password)*****
   fileName = "{}_wallet.zip".format(atp_details.db_name)
 
   # Download the wallet
   oci_atp.get_wallet(db_client, atp_id, walletPassword, fileName)

Test. Delete. More. After creating your new Oracle Autonomous Transaction Processing instance, you can test your connection by following the steps in the “Getting Started with Autonomous” article mentioned above.

I did not include a call to the delete_atp method, but it could be called like this:

oci_atp.delete_atp(db_client, "ocid1.autonomousdatabase.oc1.phx. aBigLongGuidString")

With the Python SDK for Oracle Cloud Infrastructure, you can create, configure, and delete almost all of your Oracle Cloud objects, and this article should get you started on using the SDK for those operations with Oracle Autonomous Transaction Processing. You can find some other examples on GitHub. If you run into problems with these examples, please reach out to me and I will do my best to help.

Next Steps

LEARN more about Oracle Autonomous Transaction Processing.

TRY Oracle Autonomous Transaction Processing.

Illustration by Wes Rowell