QPU Tokens

Luna integrates with various quantum hardware providers, enabling seamless algorithm execution. To streamline your workflow, Luna securely stores your tokens, allowing you to reuse them across services. This lets you set your token once without needing to provide it for each individual run. Alternatively, you can provide an inline token for each call to quantum hardware if preferred.

Upon completing this tutorial, you will be able to:

  1. Distinguish between personal, organization-level, and inline tokens.
  2. Set your QPU tokens in Luna once for consistent reuse.
  3. Manage, modify, and remove your QPU tokens.
  4. 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 credentials
ls = LunaSolve(email="YOUREMAIL", password="YOURPASSWORD")

Personal vs. Organization vs. Inline Token

Personal Token

By storing your personal QPU token in Luna, you can seamlessly reuse it across different runs while running algorithms on quantum hardware. As a regular user, you can only set tokens for your personal account.

Here is an example of creating a personal IBM token:

# Set your personal token to access IBMs hardware
personal_token = ls.qpu_token.create(
    name="My Personal IBM Token",
    provider="ibm",
    token="<TOKEN>",
    token_type="personal"
)

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.

Organization-Level Token

At the organizational level, you have the flexibility to assign quantum hardware access tokens, enabling users to utilize the hardware while preventing unauthorized viewing, modification, or deletion of the tokens. To associate your account with an organization and gain administrative privileges, please contact us. Once you secure administrative access, you can start adding organization-level QPU tokens.

Here is an example of creating a organization-level IBM Token:


# As an administrator you can also set your organization token to access IBMs hardware
organization_token = ls.qpu_token.create(
    name="My Organization IBM Token",
    provider="ibm",
    token="<TOKEN>",
    token_type="organization"
)

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 only need to call it when you are creating a solution.

Here is an example of creating a job via LunaSolve and providing an inline token:

job = ls.solution.create(
    optimization_id=optimization.id,
    solver_name="QAOA",
    provider="ibm",
    qpu_tokens=TokenProvider(
        ibm=QpuToken(
            source="inline",
            token="<TOKEN>"
        )
    ),
    solver_parameters={"backend": "least_busy"}
)

However, if you don't want to specify your inline token each time and have it shown 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_FUJITSU_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_IBM_TOKEN="<IBM TOKEN>"

Linux/MacOS

export LUNA_IBM_TOKEN="<IBM TOKEN>"

Python

import os
os.environ["LUNA_IBM_TOKEN"] = "<IBM 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_IBM_TOKEN with the value <IBM 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_IBM_TOKEN="<IBM 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_IBM_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="QAOA",
    provider="ibm",
    solver_parameters={"backend": "least_busy"}
)

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 organization-level tokens.

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

print(personal_token)

# Retrieve an organization token (only for admins)
organization_token = ls.qpu_token.get(
    qpu_token_id=organization_token.id,
    token_type="organization"
)

print(organization_token)

Output:

id='664dfdd8acaf90d0a917a4e0' name='My Personal IBM Token' provider='ibm'
id='664dfdd8acaf90d0a917a4e1' name='My Organization IBM Token' provider='ibm'
# 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 IBM Token', provider='ibm')
    ],
<QpuTokenTypeEnum.ORGANIZATION: 'organization'>:
    [
        QpuToken(id='664dfdd8acaf90d0a917a4e1', name='My Organization IBM Token', provider='ibm')
    ]
}
# Rename a QPU Token
renamed_token = ls.qpu_token.update(
    qpu_token_id=personal_token.id,
    name="My Updated Personal Token"
)

print(renamed_token)

Output:

id='664c62c9da248277ca4cfb6f' name='My Updated Personal Token' provider='ibm'
# Delete a personal QPU Token
ls.qpu_token.delete(
    qpu_token_id=renamed_token.id
)

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

Using QPU Tokens to Access Quantum Hardware

To access quantum hardware, you'll need a QPU token specific to the corresponding provider. By storing your QPU token in Luna, you only need to specify which token to use for hardware access.

from luna_sdk.schemas.qpu_token import QpuToken, TokenProvider

# As an example, define a QUBO matrix
qubo_matrix = [
    [4, 0, 0, 0, -2],
    [0, -2, 0, 0, 0],
    [0, 0, 6, -3, 0],
    [0, 0, -3, 2, 0],
    [-2, 0, 0, 0, 5]
]

# Upload your QUBO to LunaSolve
optimization = ls.optimization.create_from_qubo(name="My QUBO", matrix=qubo_matrix)

# Solve the QUBO using QAOA and the least busy backend from IBM
job = ls.solution.create(
    optimization_id=optimization.id,
    solver_name="QAOA",
    provider="ibm",
    qpu_tokens=TokenProvider(
        ibm=QpuToken(
            source="personal",
            name="My IBM Token"
        )
    ),
    solver_parameters={"backend": "least_busy"}
)

Note here, that you only have to specify the type of token that you are using as well as the name of the token. If you are using a token of the type inline token, you can find more information on how to use this here.

Was this page helpful?