

# Working with AWS Boto3
<a name="braket-using-boto3"></a>

Boto3 is the AWS SDK for Python. With Boto3, Python developers can create, configure, and manage AWS services, such as Amazon Braket. Boto3 provides an object-oriented API, as well as low-level access to Amazon Braket.

Follow the instructions in the [Boto3 Quickstart guide](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/quickstart.html) to learn how to install and configure Boto3.

Boto3 provides the core functionality that works along with the Amazon Braket Python SDK to help you configure and run your quantum tasks. Python customers always need to install Boto3, because that is the core implementation. If you want to make use of additional helper methods, you also need to install the Amazon Braket SDK.

For example, when you call `CreateQuantumTask`, the Amazon Braket SDK submits the request to Boto3, which then calls the AWS API.

**Topics**
+ [Turn on the Amazon Braket Boto3 client](braket-using-boto3-client.md)
+ [Configure AWS CLI profiles for Boto3 and the Braket SDK](braket-using-boto3-profiles.md)

# Turn on the Amazon Braket Boto3 client
<a name="braket-using-boto3-client"></a>

To use Boto3 with Amazon Braket, you must import Boto3 and then define a client that you use to connect to the Amazon Braket API. In the following example, the Boto3 client is named `braket`.

```
import boto3
import botocore

braket = boto3.client("braket")
```

**Note**  
[Braket supports IPv6](https://docs.aws.amazon.com/vpc/latest/userguide/aws-ipv6-support.html). If you are using an IPv6-only network or wish to ensure your workload uses IPv6 traffic, use the dual-stack endpoints as outlined in the [Dual-stack and FIPS endpoints](https://docs.aws.amazon.com/sdkref/latest/guide/feature-endpoints.html) guide.

Now that you have a `braket` client established, you can make requests and process responses from the Amazon Braket service. You can get more detail on request and response data in the [API Reference](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/braket.html).

**Topics**
+ [Search for devices](#braket-using-boto3-example-search-devices)
+ [Retrieve a device](#braket-using-boto3-example-retrieve-devices)
+ [Create a quantum task](#braket-using-boto3-example-create-task)
+ [Retrieve a quantum task](#braket-using-boto3-example-retrieve-task)
+ [Search for quantum tasks](#braket-using-boto3-example-search-tasks)
+ [Cancel quantum task](#braket-using-boto3-example-cancel-task)

## Search for devices
<a name="braket-using-boto3-example-search-devices"></a>
+  `search_devices(**kwargs)` 

Search for devices using the specified filters.

```
# Pass search filters and optional parameters when sending the
# request and capture the response
response = braket.search_devices(filters=[{
    'name': 'deviceArn',
    'values': ['arn:aws:braket:::device/quantum-simulator/amazon/sv1']
}], maxResults=10)

print(f"Found {len(response['devices'])} devices")

for i in range(len(response['devices'])):
    device = response['devices'][i]
    print(device['deviceArn'])
```

## Retrieve a device
<a name="braket-using-boto3-example-retrieve-devices"></a>
+  `get_device(deviceArn)` 

Retrieve the devices available in Amazon Braket.

```
# Pass the device ARN when sending the request and capture the repsonse
response = braket.get_device(deviceArn='arn:aws:braket:::device/quantum-simulator/amazon/sv1')

print(f"Device {response['deviceName']} is {response['deviceStatus']}")
```

## Create a quantum task
<a name="braket-using-boto3-example-create-task"></a>
+  `create_quantum_task(**kwargs)` 

Create a quantum task.

```
# Create parameters to pass into create_quantum_task()
kwargs = {
    # Create a Bell pair
    'action': '{"braketSchemaHeader": {"name": "braket.ir.jaqcd.program", "version": "1"}, "results": [], "basis_rotation_instructions": [], "instructions": [{"type": "h", "target": 0}, {"type": "cnot", "control": 0, "target": 1}]}',
    # Specify the SV1 Device ARN
    'deviceArn': 'arn:aws:braket:::device/quantum-simulator/amazon/sv1',
    # Specify 2 qubits for the Bell pair
    'deviceParameters': '{"braketSchemaHeader": {"name": "braket.device_schema.simulators.gate_model_simulator_device_parameters", "version": "1"}, "paradigmParameters": {"braketSchemaHeader": {"name": "braket.device_schema.gate_model_parameters", "version": "1"}, "qubitCount": 2}}',
    # Specify where results should be placed when the quantum task completes.
    # You must ensure the S3 Bucket exists before calling create_quantum_task()
    'outputS3Bucket': 'amazon-braket-examples',
    'outputS3KeyPrefix': 'boto-examples',
    # Specify number of shots for the quantum task
    'shots': 100
}

# Send the request and capture the response
response = braket.create_quantum_task(**kwargs)

print(f"Quantum task {response['quantumTaskArn']} created")
```

## Retrieve a quantum task
<a name="braket-using-boto3-example-retrieve-task"></a>
+  `get_quantum_task(quantumTaskArn)` 

Retrieve the specified quantum task.

```
# Pass the quantum task ARN when sending the request and capture the response
response = braket.get_quantum_task(quantumTaskArn='arn:aws:braket:us-west-1:123456789012:quantum-task/ce78c429-cef5-45f2-88da-123456789012')

print(response['status'])
```

## Search for quantum tasks
<a name="braket-using-boto3-example-search-tasks"></a>
+  `search_quantum_tasks(**kwargs)` 

Search for quantum tasks that match the specified filter values.

```
# Pass search filters and optional parameters when sending the
# request and capture the response
response = braket.search_quantum_tasks(filters=[{
    'name': 'deviceArn',
    'operator': 'EQUAL',
    'values': ['arn:aws:braket:::device/quantum-simulator/amazon/sv1']
}], maxResults=25)

print(f"Found {len(response['quantumTasks'])} quantum tasks")

for n in range(len(response['quantumTasks'])):
    task = response['quantumTasks'][n]
    print(f"Quantum task {task['quantumTaskArn']} for {task['deviceArn']} is {task['status']}")
```

## Cancel quantum task
<a name="braket-using-boto3-example-cancel-task"></a>
+  `cancel_quantum_task(quantumTaskArn)` 

Cancel the specified quantum task.

```
# Pass the quantum task ARN when sending the request and capture the response
response = braket.cancel_quantum_task(quantumTaskArn='arn:aws:braket:us-west-1:123456789012:quantum-task/ce78c429-cef5-45f2-88da-123456789012')

print(f"Quantum task {response['quantumTaskArn']} is {response['cancellationStatus']}")
```

# Configure AWS CLI profiles for Boto3 and the Braket SDK
<a name="braket-using-boto3-profiles"></a>

The Amazon Braket SDK relies upon the default AWS CLI credentials, unless you explicitly specify otherwise. We recommend that you keep the default when you run on a managed Amazon Braket notebook because you must provide an IAM role that has permissions to launch the notebook instance.

Optionally, if you run your code locally (on an Amazon EC2 instance, for example), you can establish named AWS CLI profiles. You can give each profile a different permission set, rather than regularly overwriting the default profile.

This section provides a brief explanation of how to configure such a CLI `profile` and how to incorporate that profile into Amazon Braket so that API calls are made with the permissions from that profile.

**Topics**
+ [Step 1: Configure a local AWS CLI `profile`](#braket-using-boto3-profiles-step-1)
+ [Step 2: Establish a Boto3 session object](#braket-using-boto3-profiles-step-2)
+ [Step 3: Incorporate the Boto3 session into the Braket AwsSession](#braket-using-boto3-profiles-step-3)

## Step 1: Configure a local AWS CLI `profile`
<a name="braket-using-boto3-profiles-step-1"></a>

It is beyond the scope of this document to explain how to create a user and how to configure a non-default profile. For information on these topics, see:
+  [Getting started](https://docs.aws.amazon.com/singlesignon/latest/userguide/getting-started.html) 
+  [Configuring the AWS CLI to use AWS IAM Identity Center](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html) 

To use Amazon Braket, you must provide this user — and the associated CLI `profile` — with the necessary Braket permissions. For instance, you can attach the **AmazonBraketFullAccess** policy.

## Step 2: Establish a Boto3 session object
<a name="braket-using-boto3-profiles-step-2"></a>

In order to establish a Boto3 session object, utilize the following code example.

```
from boto3 import Session

# Insert CLI profile name here
boto_sess = Session(profile_name=`profile`)
```

**Note**  
If the expected API calls have Region-based restrictions that are not aligned with your `profile` default Region, you can specify a Region for the Boto3 session as shown in the following example.

```
# Insert CLI profile name _and_ region
boto_sess = Session(profile_name=`profile`, region_name=`region`)
```

For the argument designated as `region`, substitute a value that corresponds to one of the AWS Regions in which Amazon Braket is available such as `us-east-1`, `us-west-1`, and so forth.

## Step 3: Incorporate the Boto3 session into the Braket AwsSession
<a name="braket-using-boto3-profiles-step-3"></a>

The following example shows how to initialize a Boto3 Braket session and instantiate a device in that session.

```
from braket.aws import AwsSession, AwsDevice

# Initialize Braket session with Boto3 Session credentials
aws_session = AwsSession(boto_session=boto_sess)

# Instantiate any Braket QPU device with the previously initiated AwsSession
sim_arn = 'arn:aws:braket:::device/quantum-simulator/amazon/sv1'
device = AwsDevice(sim_arn, aws_session=aws_session)
```

After this setup is complete, you can submit quantum tasks to that instantiated `AwsDevice` object (by calling the `device.run(…​)` command for example). All API calls made by that device can use the IAM credentials associated with the CLI profile that you previously designated as `profile`.