Clients only require a valid config object:

>>> from oraclebmc.identity import IdentityClient
>>> identity = IdentityClient(config)

CRUD operations and Pagination

Creating entities

Let's create a new user and group, and add the user to the group. Then we'll list all users in the tenancy, and finally clean up the user and group we created.

First, we'll need to create a valid config object and service client. If you haven't set up a config file, head over to the Configuration section to create one. We'll use the default location ~/.oraclebmc/config and default profile name DEFAULT to create an Identity client. Since we'll be using the root compartment (or tenancy) for most operations, let's also extract that from the config object:

>>> import oraclebmc
>>> config = oraclebmc.config.from_file()
>>> identity = oraclebmc.identity.IdentityClient(config)
>>> compartment_id = config["tenancy"]

Next we'll need to populate an instance of the CreateGroupDetails model with our request, and then send it:

>>> from oraclebmc.identity.models import CreateGroupDetails
>>> request = CreateGroupDetails()
>>> request.compartment_id = compartment_id
>>> request.name = "my-test-group"
>>> request.description = "Created with the Python SDK"

>>> group = identity.create_group(request)
>>> print(group.data.id)
"id": "ocid1.group.oc1..aaaaaaaaikib..."

Creating a user is very similar:

>>> from oraclebmc.identity.models import CreateUserDetails
>>> request = CreateUserDetails()
>>> request.compartment_id = compartment_id
>>> request.name = "my-test-user"
>>> request.description = "Created with the Python SDK"
>>> user = identity.create_user(request)
>>> print(user.data.id)

Using the ids from the group and user above, we can add the user to the group:

>>> from oraclebmc.identity.models import AddUserToGroupDetails
>>> request = AddUserToGroupDetails()
>>> request.group_id = group.data.id
>>> request.user_id = user.data.id
>>> response = identity.add_user_to_group(request)
>>> print(response.status)

Listing with Pagination

List operations use pagination to limit the size of each response. The Python SDK exposes the pagination values through the has_next_page and next_page attributes on each response. For example, listing users in the root compartment:

>>> first_page = identity.list_users(compartment_id=compartment_id)
>>> len(first_page.data)
>>> first_page.has_next_page
>>> first_page.next_page

Even though a response includes a next page, there may not be more results. The last page will return an empty list, and will not have a next_page token.

Here's a very simple way to paginate a call:

def paginate(operation, *args, **kwargs):
    while True:
        response = operation(*args, **kwargs)
        for value in response.data:
            yield value
        kwargs["page"] = response.next_page
        if not response.has_next_page:

To iterate over all users, the call is now:

>>> for user in paginate(
...         identity.list_users,
...         compartment_id=compartment_id):
...     print(user)

This paginate function will work for any list call, but will not include the response metadata, such as headers, HTTP status code, or request id.

Deleting entities

Now to clean up the entities we created. Users can't be deleted if they're still part of a group, and groups can't be deleted if they still have users. So we need to use identity.remove_user_from_group, which takes a user_group_membership_id. Because users and groups can have any number of relationships, we'll use list_user_group_memberships and provide both optional parameters user_id and group_id to constrain the result set:

>>> memberships = identity.list_user_group_memberships(
...     compartment_id=compartment_id,
...     user_id=user.data.id,
...     group_id=group.data.id)
# There can never be more than one membership for a unique user/group combination
>>> assert len(memberships.data) == 1
>>> membership_id = memberships.data[0].id

Finally, we can remove the user from the group, and delete both resources. Here we're using response.status to make sure the delete responded with 204:

>>> identity.remove_user_from_group(
...     user_group_membership_id=membership_id).status
>>> identity.delete_user(user_id=user.data.id).status
>>> identity.delete_group(group_id=group.data.id).status

Working with Bytes

When using object storage, you'll need to provide a namespace, in addition to your compartment id:

>>> object_storage = oraclebmc.object_storage.ObjectStorageClient(config)
>>> namespace = object_storage.get_namespace().data

To upload an object, we'll create a bucket:

>>> from oraclebmc.object_storage.models import CreateBucketDetails
>>> request = CreateBucketDetails()
>>> request.compartment_id = compartment_id
>>> request.name = "MyTestBucket"
>>> bucket = object_storage.create_bucket(namespace, request)
>>> bucket.data.etag

Now we can upload arbitrary bytes:

>>> my_data = b"Hello, World!"
>>> obj = object_storage.put_object(
...     namespace,
...     bucket.data.name,
...     "my-object-name",
...     my_data)

And to get it back:

>>> same_obj = object_storage.get_object(
...     namespace,
...     bucket.data.name,
...     "my-object-name")
... same_obj.data
<Response [200]>
... same_obj.data.content
b'Hello, World!'

Next Steps

Next, head to the User Guides or jump right into the API Reference to explore the available operations for each service, and their parameters. Additional Python examples can be found on GitHub.


The Python SDK uses lowercase_with_underscores for operations and parameters. For example, the ListApiKeys operation is called with IdentityClient.list_api_keys and its parameter userId is translated to user_id.