Running a Qiskit Function as a function

In this tutorial, you’ll learn how to create and run a Qiskit Function using Qiskit Serverless. A Qiskit Function is a self-contained Python script that can execute quantum workloads remotely on serverless infrastructure. We’ll start by writing a simple function that:

  • Builds a two-qubit quantum circuit to create a Bell state.

  • Transpiles the circuit for a target backend.

  • Runs the circuit using the Sampler primitive.

  • Saves the results so they can be retrieved later.

Install dependencies

Before we begin, make sure the required packages are installed in your notebook environment:

[ ]:
%pip install qiskit qiskit-ibm-runtime qiskit-serverless

Prep Work

Writing the Qiskit Function

First, we need to write the function code and save it to a file called function.py. This function will contain the logic for our Qiskit Function. For this example, we will create a two-qubit quantum circuit that prepares a Bell state, measures the result, and saves the measured probability distribution.

The code for the function is shown below:

from qiskit import QuantumCircuit
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime import SamplerV2 as Sampler
from qiskit_ibm_runtime.fake_provider import FakeVigoV2
from qiskit_serverless import save_result

# all print statement will be available in job logs
print("Running function...")

# Step 1: Create a Bell-state circuit
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.measure_all()

# Step 2: Transpile for a fake backend (for demonstration)
backend = FakeVigoV2()
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(circuit)

# Step 3: Run the Sampler primitive
sampler = Sampler(backend)
quasi_dists = sampler.run([isa_circuit]).result()[0].data.meas.get_counts()


# Step 4: Save results so they can be retrieved later by calling `.result()`
save_result(quasi_dists)
print("Completed running function.")

Now that we’ve written our Qiskit Function, the next step is to deploy it to the serverless environment so it can run remotely.

Deploying the function

To run the function, we need to import the necessary classes and configure them. One of these classes is ServerlessClient, which is a client class for interacting with compute resources.

The client stores configuration information about our compute resources, such as where they are located and how to connect to them. In this example, we will use a provider that is connected to a local Docker Compose setup. In this case, it allows us to run the function locally on our machine. If you want to run the function elsewhere, you will need to provide the corresponding host and authentication details.

[1]:
from qiskit_serverless import ServerlessClient
import os

⚠ This provider is set up with default credentials to a test cluster intended to run on your machine. For information on setting up infrastructure on your local machine, check out the guide on local infrastructure setup.

[2]:
client = ServerlessClient(
    token=os.environ.get("GATEWAY_TOKEN", "awesome_token"),
    instance=os.environ.get("GATEWAY_INSTANCE", "an_awesome_crn"),
    host=os.environ.get("GATEWAY_HOST", "http://localhost:8000"),
    # If you are using the kubernetes approach the URL must be http://localhost
)

client
[2]:
<gateway-client>

Create a Qiskit Function object

A QiskitFunction represents the function you want to run. It includes:

  • title - name of the Qiskit Function. This name will be used to identify and retrieve the function from the service.

  • entrypoint - the name of the Python file that will be executed.

  • working_dir - directory where your script is located (directory size must be less than 50MB). This is optional parameter and will be current folder by default.

This tells the serverless system what code to run and what supporting files to include. Everything in working_dir will be packaged and shipped to the compute node.

⚠ All content of working_dir will be shipped to cluster for execution

[3]:
from qiskit_serverless import QiskitFunction

function = QiskitFunction(
    title="my-first-function",
    entrypoint="function.py",
    working_dir="./source_files/"
)
[3]:
QiskitFunction(my-first-function)

Upload the function

Once the function object is created, upload it to the gateway so it can be executed later:

⚠ Execution of upload function ships All content of working_dir. When the contents of working_dir is changed, the upload function must be called again to update the shipped directory contents.

[ ]:
client.upload(function)

Running the QiskitFunction

After deploying the QiskitFunction, we can he function by its title:

[4]:
my_first_function = client.get("my-first-function")
my_first_function
[4]:
QiskitFunction(my-first-function)

We can run any function by calling run method on function object. This will make the job run on the gateway:

[5]:
job = my_first_function.run()
job
[5]:
<Job | a8b0be5a-ff24-4132-b706-9bac096790ae>

A Job instances have a status() method to check status of the function execution. It will help us monitor the status of our job:

[6]:
job.status()
[6]:
'QUEUED'

We can retrieve the result by calling the result() method of an instanced Job object. The result() method will not return until the job is done running the function.

[7]:
job.result()
[7]:
{'11': 535, '00': 489}

To inspect the logs from a function for debugging or analysis, you can access them from the Job instance.

[8]:
print(job.logs())
2025-11-03 10:03:01,072 INFO job_manager.py:531 -- Runtime env is setting up.
Running function...
Completed running function.

ServerlessClient object has method .widget which renders Jupyter widget to see list of executed programs.

[ ]:
client.widget()