Release Notes¶
v0.30.0¶
Prelude¶
The main feature in this release is the major refactor in logs to differentiate between provider logs and user logs and optimize storage. The logs are now stored in COS while keeping backward compatibility.
New Features¶
The
qiskit-serverlessPython library added two new utilities,get_logger()andget_provider_logger(), available to Qiskit Function developers. Developers should use these functions within their source code to distinguish which logging information is relevant for users (get_logger()) or providers (get_provider_logger()) respectively. These functions create[PUBLIC]and[PRIVATE]prefixes under the hood to allow the service to filter the information appropriately. To keep intellectual property safe, only function users can access user logs, and only providers can access provider logs. For example:from qiskit_serverless import get_logger, get_provider_logger user_logger = get_logger() provider_logger = get_provider_logger() get_logger().info("User log") user_logger.info("User multiline\nlog") user_logger.warning("User log") user_logger.error("User log") get_provider_logger().info("Provider log") provider_logger.info("Provider multiline\nlog") provider_logger.warning("Provider log") provider_logger.error("Provider log")
The
ServerlessClientandJobclasses’logs()method will from now on only return user logs. To access provider logs, we have added a newprovider_logs()method. For example:runnable_function = serverless_client.function("my_function") job = runnable_function.run() print(job.logs()) # only users print(job.provider_logs()) # only providers
Uploaded files now should have a valid file type in order to be accepted by the platform.
The accepted MIME types for uploaded files are:
application/x-tar (.tar)
application/gzip (.gz, .tgz)
application/json (.json)
application/octet-stream (generic binary; may include .bin, .dat, .exe)
application/zip (.zip)
text/plain (.txt, .log)
text/csv (.csv)
Upgrade Notes¶
Added a new
versionfield to theProgramDjango model. This field is used to track the version of the program (function).
Added a new
JobEventstable to our database to improve metrics and provide a more flexible foundation for future event-tracking features. Each time a job changes state, a new event is now recorded in the database.- The new
JobEventstable includes: id: auto-generated UUIDjob: foreign key referencing the jobs tablecreated: timestamp automatically set at event creationevent_type: string describing the event type (currently"Status change")context: string indicating where the change originated (e.g., Scheduler, API)data: JSON payload containing event‑specific details
- The new
Added several quality of life improvements in testing.
The Scheduler is modified to upload logs to COS when a job transitions from running to a terminal state. At that moment, the logs will be filtered based on the prefixes, and the information will be saved in the corresponding folder inside COS.
The Gateway endpoint
/logshas been modified to only target user logs, and a new /provider_logs` has been added for provider logs. Both should return: 1. The COS log for finished jobs, if it exists. This was previously filtered in the Scheduler. 2. The Ray console logs if the job is running. This is filtered live. 3. As a fallback, logs from the database.
Four new exception classes have been added to the gateway API to better differentiate between different failure scenarios:
JobNotFoundException,ProviderNotFoundException,FunctionNotFoundExceptionandFileNotFoundExceptionthat inherit from an abstractNotFoundErrorbase class.
Added a new gateway setting to limit the number of active jobs per user. By setting the environment variable
LIMITS_ACTIVE_JOBS_PER_USER, you can restrict the total number of jobs a user can have acrossQUEUED,PENDING, andRUNNINGstates. The default limit is50.
Requests to run programs will now return an
HTTP 429 Too Many Requestsresponse if a user attempts to start a new job while they are at their active job limit.
The Scheduler and API code have been refactored to improve their maintainability and scalability. Most changes are internal and do not affect the user experience, but some additions have been made, for example, the scheduler can now respond to
SIGINTandSIGTERMsignals, and the API now accepts a dynamic configuration system that allows changing application settings at runtime.
Deprecation Notes¶
The
@distribute_qiskit_functiondecorator has been deprecated and will be removed in following releases. The decorator was designed for remote program execution, a functionality that is now provided through the different serverless clients through theuploadmethod.
Bug Fixes¶
Fixed a bug in the function versioning workflow where the version set upon function creation couldn’t be uploaded to the platform, stored in the database, or retrieved upon function retrieval. After the fix, the function version can be tracked through the whole life cycle. For example:
from qiskit_serverless import QiskitFunction my-func = QiskitFunction( title="my_func_title", entrypoint="my_func_entrypoint.py", working_dir="./source_files/", version="2.0.0", ) # this print outputs 2.0.0 print(my-func.version) serverless.upload(my-func) my-func-load = serverless.function("my_func_title") # this print now also outputs 2.0.0 (previously empty) print(my-func-load.version)
Fixed an issue that affected local testing when using custom functions packaged as Docker images. These custom functions are registered as “provider” functions, however, their data path was resolved to a “custom” function data path, resulting in a “File not found” error when trying to fetch function arguments. After the fix, the data paths are resolved correctly, and no error is raised:
For user functions:
DATA_PATH = \data\usernameFor provider functions:
DATA_PATH = \data\username\providername\imagename
v0.29.0¶
Upgrade Notes¶
Refactored storage service initialization to accept
Programmodel instances instead of individual parameters. TheFileStorageandArgumentsStorageclasses now accept afunctionparameter (Program model instance) rather than separateusername,function_title, andprovider_nameparameters. This change improves code cohesion by reducing the number of parameters passed between components and ensures consistent access to program metadata across storage services.
Removed unused
function_titleandprovider_nameparameters fromProgramViewSet.run()method’s call tojob_serializer.save()as these parameters are no longer used after the storage service refactoring.
Removed
LocalClientandRayClientclasses and their usages in the tests. For testing, one should useServerlessClientwith default values as indocs/deployment/example_custom_image_function.rst. In addition, updated tests and removed irrelevant comments.
The legacy IBM Quantum authentication channel (
ibm_quantum) has been removed. Users should migrate to using the IBM Quantum Platform channel (ibm_quantum_platform) for authentication. The authentication logic has been simplified to support onlyibm_cloudandibm_quantum_platformchannels. When no channel header is provided and a CRN is present, the system defaults toibm_quantum_platform.
Qiskit Serverless now supports the latest version of the
qiskit-ibm-runtimepackage:qiskit-ibm-runtime==0.45.
Bug Fixes¶
Fixed a bug in the json decoder that would crop the response details to the first character when gateway errors were raised. This utility now forwards the full error message to the raised
QiskitServerlessException.
Fixed error handling when a function is not found. Instead of providing a bare 404 error, the
QiskitServerlessExceptionnow contains a more meaningful error message:QiskitServerlessException: | Message: Http bad request. | Code: 404 | Details: User program 'my-program' was not found or you do not have permission to view it.
Fixes https://github.com/Qiskit/qiskit-serverless/issues/1773.
Fixed a bug in
FunctionRepository.get_user_function()where functions with providers could be incorrectly returned when searching for user functions without providers. The method now correctly filters byprovider=Noneto ensure only user-owned functions without providers are returned. This prevents incorrect storage path resolution when users have multiple functions with the same title.
v0.28.0¶
New Features¶
IBMServerlessClientnow supports custom gateway host URLs through thehostparameter. This allows for a more streamlined testing of the client connecting to non-production gateways.
Added a new
ProgramHistorymodel and database table to track when entities perform actions to add or remove an instance from a program. These allow to audit access changes for bothinstancesandtrial_instances.
v0.27.1¶
Upgrade Notes¶
The scheduling logic that was managing non GPU and GPU jobs was improved. Now the scheduler manages both type of jobs independently so you can adjust separately where each of these jobs are run.
Qiskit Serverless now supports the latest version of the
qiskit-ibm-runtimepackage:qiskit-ibm-runtime==0.43.
Bug Fixes¶
Fixed a bug in the scheduler that was preventing it from stopping jobs automatically after the timeout threshold specified with the environment variable
PROGRAM_TIMEOUT.
v0.27.0¶
New Features¶
A new utility
get_runtime_service()is now available to simplify the instantiation of aQiskitRuntimeServicewithin a function. It automatically pulls credentials from environment variables, reducing boilerplate code and improving usability for function developers.Example usage:
from qiskit_serverless import get_runtime_service service = get_runtime_service() backend = service.backend("ibm_fez")
This is equivalent to:
import os from qiskit_serverless import get_arguments, save_result from qiskit_ibm_runtime import QiskitRuntimeService service = QiskitRuntimeService( channel=os.environ["QISKIT_IBM_CHANNEL"], instance=os.environ["QISKIT_IBM_INSTANCE"], token=os.environ["QISKIT_IBM_TOKEN"], ) backend = service.backend("ibm_fez")
This function also enables automatic tracking of runtime job and session IDs created during function execution. It’s important to note that tracking will only be possible if the function runtime jobs are submitted through a service instantiated with this function.
On top of the default credentials, function developers can customize the call to
get_runtime_service()with custom input parameters, includingtoken,instance,channelandurl. For example:from qiskit_serverless import get_runtime_service service = get_runtime_service(channel="ibm_quantum_platform", token="staging_token", instance="staging_crn", url="staging_url") backend = service.backend("staging_backend")
When using
get_runtime_service()inside a serverless function, the resulting job object now supports two new methods:job.runtime_jobs()andjob.runtime_sessions(). These methods return lists of job/session IDs that can be used to fetch job objects from aQiskitRuntimeServiceor access IQP dashboards.job.runtime_jobs()accepts an optionalruntime_sessionparameter that allows to filter the returned jobs by associated session id. For example:job = function.run(...) runtime_ids = job.runtime_jobs() # out = ["job_id_1", "job_id_2", "job_id_3"...] runtime_sessions = job.runtime_sessions() # out = ["session_id_1", "session_id_2"] # a specific session id can be passed to the runtime_jobs() method to filter by session: session_id = job.runtime_sessions()[0] # out = "session_id_1" session_job_ids = job.runtime_jobs(session_id) # in this example, only job ids 1 and 3 correspond to session_id_1: # out = ["job_id_1", "job_id_3"]
Upgrade Notes¶
Added a new AccessPolicy for User model to be able to allow or not the access to the service by the
is_activeparameter.
Enhanced
job.cancel()behavior to use the newly introduced features.job.cancel()now attempts to instantiate aQiskitRuntimeServiceusing the credentials from theServerlessClient, allowing automatic canceling of associated runtime jobs. This works when the credentials used in the function match those in the client, which happens by default when usingget_runtime_service()with no additional inputs.To support local testing or non-standard runtime URLs (e.g., staging environments), where the
ServerlessClientdon’t match those in theQiskitRuntimeServiceused to submit the jobs,job.cancel()accepts a service parameter:service = QiskitRuntimeService( channel="ibm_quantum_platform", token="MY_TOKEN", instance="MY_CRN", url="my.staging.url.com" ) job.cancel(service)
The
ServerlessRuntimeServiceclass has been updated to support changes introduced inqiskit_ibm_runtime>=0.42, unlocking compatibility of the qiskit-serverless>=0.27.0 package withqiskit_ibm_runtime>=0.42. For older versions ofqiskit-serverless,qiskit_ibm_runtime<0.42will still be required.
The Scheduler will start to manage the size of the logs generated by the Qiskit Functions. The environment variable
FUNCTIONS_LOGS_SIZE_LIMITwill be in charge of the maximum size that the system will allow to store.
Enhanced
client.jobs()andfunction.jobs()behavior with new filters to improve the management of the different jobs. Now you can filter bystatusand bycreated_afterto retrieve those specific jobs. For example:# Filtering by status it will retrieve all the jobs with that status client.jobs(status="SUCCEEDED") # The same it will apply after a specific date time_filter = datetime.now(timezone.utc) client.jobs(created_after=time_filter) # And all these new filters can be combined with the Qiskit Function filter # to be able to return running jobs from the specific Qiskit Function function.jobs(status="RUNNING")