QPU Tokens

Luna integrates with various quantum hardware providers, enabling seamless execution of algorithms across different platforms. To streamline your workflow, Luna offers secure storage for your QPU (Quantum Processing Unit) tokens, allowing you to set the token once and reuse it across services without needing to re-enter it for each individual run. You can also configure tokens at the group level, granting access to specific users within the group. Alternatively, if preferred, you can provide an inline token for each call to quantum hardware without storing your token with us.

Upon completing this tutorial, you will be able to:

  1. Distinguish between personal, group and inline tokens.
  2. Set your QPU tokens in Luna once for consistent reuse.
  3. Set your tokens as environment variables.
  4. Manage, modify, and remove your QPU tokens.
  5. Use QPU tokens to run algorithms on quantum hardware.

First, you'll need to import the necessary packages and initiate your session with Luna. You can use both a LunaSolve and a LunaQ session, as the tokens are shared by both services. In this example, we will use LunaSolve.

# Load the Luna package
from luna_sdk import LunaSolve

# Initialize LunaSolve with your API key
ls = LunaSolve(api_key="<LUNA_API_KEY>")

In this tutorial, we’ll be working with tokens for D-Wave's quantum annealers. The setup process is the same for all other quantum backends accessible through Luna. For code snippets and examples on using tokens with various backends, please refer to our Solvers & Algorithms section.

Personal vs. Group vs. Inline Token

Before diving into the details, let's start by creating a simple optimization example to work with:

from luna_sdk.schemas.qpu_token import QpuToken, TokenProvider

qubo_matrix = [
    [4, 0, 0, 0, -2],
    [0, -2, 0, 1, 0],
    [0, 0, 6, -3, 0],
    [0, 1, -3, 2, 0],
    [-2, 0, 0, 0, 5]
]

optimization = ls.optimization.create_from_qubo(name="My QUBO", matrix=qubo_matrix)

Personal Token

By storing your personal QPU token in Luna, you can easily reuse it across multiple runs when executing algorithms on quantum hardware. As a regular user, you have the ability to set tokens for your personal account.

Here is an example of creating a personal D-Wave token:

# Set your personal token to access DWaves hardware
personal_token = ls.qpu_token.create(
    name="My Personal D-Wave Token",
    provider="dwave",
    token="<TOKEN>",
    token_type="personal"
)

Afterward, you can use your personal token to create a solution as shown below:

# Create a solution using your personal token
job = ls.solution.create(
    optimization_id=optimization.id,
    solver_name="QA",
    provider="dwave",
    qpu_tokens=TokenProvider(
        dwave=QpuToken(
            source="personal",
            name="My Personal D-Wave Token"
        )
    )
)

Group-Level Token

At the group level, you can make QPU tokens available to the selected users within your group. This setup allows authorized users to access the hardware securely, while ensuring that the tokens remain protected from unauthorized viewing, modification, or deletion.

To create groups within your organization and gain administrative privileges, please contact us. Once you secure administrative access, you can start adding QPU tokens to your group. You can find more information on groups in our guide on Organization Management.

Here is an example of creating a group-level DWave Token:

# As a group admin, you can set your group's token to access D-Wave
group_token = ls.qpu_token.create(
    name="My Group D-Wave Token",
    provider="dwave",
    token="<TOKEN>",
    token_type="group"
)

Afterward, you and your group users can use your group token to create a solution as shown below:

# Create a solution using your group token
job = ls.solution.create(
    optimization_id=optimization.id,
    solver_name="QA",
    provider="dwave",
    qpu_tokens=TokenProvider(
        dwave=QpuToken(
            source="group",
            name="My Group D-Wave Token"
        )
    )
)

Refer to the QPU Tokens to Access Quantum Hardware section below to see how you can use this token when creating a solution with LunaSolve.

Inline Token

Alternatively, you can provide an inline token. Setting your token as an inline token means that Luna does not store your token information in its database. You will then need to provide it when you are creating a solution using a quantum backend.

Here is an example of creating a solution via LunaSolve while providing an inline token:

# Create a solution using an inline token
job = ls.solution.create(
    optimization_id=optimization.id,
    solver_name="QA",
    provider="dwave",
    qpu_tokens=TokenProvider(
        dwave=QpuToken(
            source="inline",
            token="<TOKEN>"
        )
    )
)

Note: For IBM, QPU tokens currently cannot be stored due to specific usage guidelines. Therefore, when using IBM hardware, you have to work with token_type=inline.

If you don't want to specify your inline token each time and have it displayed in your code, you can also use environment variables for inline tokens. To do this, you need to set the appropriate environment variables. Below are the currently supported environment variables:

  • LUNA_IBM_TOKEN
  • LUNA_DWAVE_TOKEN
  • LUNA_QCTRL_TOKEN
  • LUNA_AWS_ACCESS_KEY
  • LUNA_AWS_SECRET_ACCESS_KEY

You can set environment variables using the command line, terminal, or directly in your Python code. Below are examples of how to set these environment variables. Note that variables set this way are only available for the current session of the terminal, command line, or Python program.

Windows

set LUNA_DWAVE_TOKEN="<DWAVE TOKEN>"

Linux/MacOS

export LUNA_DWAVE_TOKEN="<DWAVE TOKEN>"

Python

import os
os.environ["LUNA_DWAVE_TOKEN"] = "<DWAVE TOKEN>"

Alternatively, you can set persistent environment variables that are stored and available for any program or script in any terminal session without needing to be configured again.

Here are the instructions for setting persistent environment variables: Windows

  1. Open the System Control Panel.
  2. Select "System".
  3. Select "Advanced System Settings".
  4. Go to the "Advanced" tab.
  5. Select "Environment Variables..."
  6. Create a new entry named LUNA_DWAVE_TOKEN with the value <DWAVE Token>.
  7. Save your changes.

Linux/MacOS

  1. Open your shell-specific initialization files. This could be ~/.bashrc for bash or ~/.zshrc for zsh.
  2. At the end of the file, add the following line with the variable name and value:
export LUNA_DWAVE_TOKEN="<DWAVE TOKEN>"
  1. Save your changes.
  2. Apply the changes by either restarting the terminal window or running:
source ~/.bashrc

Please note that these steps need to be repeated for each QPU token you want to set.

Once you set the LUNA_DWAVE_TOKEN environment variable as shown in the code above, you can omit the qpu_tokens parameter in your operations. The token from your environment variable will be used automatically.

job = ls.solution.create(
    optimization_id=optimization.id,
    solver_name="QA",
    provider="dwave",
)

Note that when using the qpu_tokens parameter, this parameter will be prioritized over QPU tokens stored in environment variables. Also, if for some reason you happen to have more than one token key from the same provider, you can currently set only one key as an environment variable.

Managing Your QPU Tokens

Luna makes it easy to manage all your stored QPU tokens. You can retrieve, edit, and delete your tokens. Note that only admins can perform these actions for group-level tokens.

# Retrieve a personal token
personal_token = ls.qpu_token.get(
    qpu_token_id=personal_token.id,
    token_type="personal"
)

print(personal_token)

# Retrieve a group token (only for admins)
group_token = ls.qpu_token.get(
    qpu_token_id=group_token.id,
    token_type="group"
)

print(group_token)

Output:

id='664dfdd8acaf90d0a917a4e0' name='My Personal D-Wave Token' provider='dwave' token_type=<QpuTokenTypeEnum.PERSONAL: 'personal'>
id='664dfdd8acaf90d0a917a4e1' name='My Group D-Wave Token' provider='dwave' token_type=<QpuTokenTypeEnum.GROUP: 'group'>
# Retrieve all tokens that are available to you
all_tokens = ls.qpu_token.get_all()

print(all_tokens)

Output:

{
<QpuTokenTypeEnum.PERSONAL: 'personal'>:
    [
        QpuToken(id='664dfdd8acaf90d0a917a4e0', name='My Personal D-Wave Token', provider='dwave', token_type=<QpuTokenTypeEnum.PERSONAL: 'personal'>)
    ],
<QpuTokenTypeEnum.GROUP: 'group'>:
    [
        QpuToken(id='664dfdd8acaf90d0a917a4e1', name='My Group D-Wave Token', provider='dwave', token_type=<QpuTokenTypeEnum.GROUP: 'group'>)
    ]
}
# Rename a QPU Token
renamed_token = ls.qpu_token.update(
    qpu_token_id=personal_token.id,
    name="My Updated Personal Token",
    token_type="personal"
)

print(renamed_token)

Output:

id='664c62c9da248277ca4cfb6f' name='My Updated Personal Token' provider='dwave' token_type=<QpuTokenTypeEnum.PERSONAL: 'personal'>
# Delete a personal QPU Token
ls.qpu_token.delete(
    qpu_token_id=renamed_token.id,
    token_type="personal"
)

# Delete an group QPU Token (only for admins)
ls.qpu_token.delete(
    qpu_token_id=group_token.id,
    token_type="group"
)

Was this page helpful?