diff --git a/client/quantum_serverless/__init__.py b/client/quantum_serverless/__init__.py index d63804110..1554f92d6 100644 --- a/client/quantum_serverless/__init__.py +++ b/client/quantum_serverless/__init__.py @@ -31,6 +31,7 @@ put, get_refs_by_status, Provider, + ServerlessProvider, IBMServerlessProvider, save_result, ) diff --git a/client/quantum_serverless/core/__init__.py b/client/quantum_serverless/core/__init__.py index cddbcf4c7..e41d9f985 100644 --- a/client/quantum_serverless/core/__init__.py +++ b/client/quantum_serverless/core/__init__.py @@ -27,6 +27,7 @@ :toctree: ../stubs/ Provider + ServerlessProvider IBMServerlessProvider BaseProvider ComputeResource @@ -50,7 +51,13 @@ """ -from .provider import BaseProvider, ComputeResource, Provider, IBMServerlessProvider +from .provider import ( + BaseProvider, + ComputeResource, + Provider, + ServerlessProvider, + IBMServerlessProvider, +) from .job import BaseJobClient, RayJobClient, GatewayJobClient, Job, save_result from .program import ( Program, diff --git a/client/quantum_serverless/core/decorators.py b/client/quantum_serverless/core/decorators.py index 89a8dbf33..a04fd374f 100644 --- a/client/quantum_serverless/core/decorators.py +++ b/client/quantum_serverless/core/decorators.py @@ -340,7 +340,7 @@ def distribute_program( """[Experimental] Program decorator to turn function into remotely executable program. Example: - >>> @distribute_program(provider=Provider(...), dependencies=[...]) + >>> @distribute_program(provider=ServerlessProvider(...), dependencies=[...]) >>> def my_program(): >>> print("Hola!") >>> @@ -357,13 +357,13 @@ def distribute_program( # pylint: disable=import-outside-toplevel,cyclic-import from quantum_serverless import QuantumServerlessException from quantum_serverless.core.program import Program - from quantum_serverless.core.provider import Provider + from quantum_serverless.core.provider import ServerlessProvider # create provider if provider is None: # try to create from env vars try: - provider = Provider() + provider = ServerlessProvider() except QuantumServerlessException as qs_error: raise QuantumServerlessException( "Set provider in arguments for `distribute_program` " diff --git a/client/quantum_serverless/core/provider.py b/client/quantum_serverless/core/provider.py index 56d77cbd5..2c8139dc8 100644 --- a/client/quantum_serverless/core/provider.py +++ b/client/quantum_serverless/core/provider.py @@ -24,9 +24,10 @@ :toctree: ../stubs/ ComputeResource - Provider + ServerlessProvider """ import logging +import warnings import os.path from dataclasses import dataclass from typing import Optional, List, Dict, Any @@ -147,7 +148,20 @@ def __repr__(self): class BaseProvider(JsonSerializable): - """Provider.""" + """ + A provider class for specifying custom compute resources. + + Example: + >>> provider = BaseProvider( + >>> name="", + >>> host="", + >>> token="", + >>> compute_resource=ComputeResource( + >>> name="", + >>> host="" + >>> ), + >>> ) + """ def __init__( self, @@ -157,18 +171,8 @@ def __init__( compute_resource: Optional[ComputeResource] = None, available_compute_resources: Optional[List[ComputeResource]] = None, ): - """Provider for serverless computation. - - Example: - >>> provider = Provider( - >>> name="", - >>> host="", - >>> token="", - >>> compute_resource=ComputeResource( - >>> name="", - >>> host="" - >>> ), - >>> ) + """ + Initialize a BaseProvider instance. Args: name: name of provider @@ -298,6 +302,7 @@ def download(self, file: str, download_location: str): def delete(self, file: str): """Deletes file uploaded or produced by the programs,""" + raise NotImplementedError def upload(self, file: str): """Upload file.""" @@ -308,8 +313,17 @@ def widget(self): return Widget(self).show() -class Provider(BaseProvider): - """Provider.""" +class ServerlessProvider(BaseProvider): + """ + A provider for connecting to a specified host. + + Example: + >>> provider = ServerlessProvider( + >>> name="", + >>> host="", + >>> token="", + >>> ) + """ def __init__( self, @@ -321,7 +335,8 @@ def __init__( token: Optional[str] = None, verbose: bool = False, ): - """Provider. + """ + Initializes the ServerlessProvider instance. Args: name: name of provider @@ -332,7 +347,6 @@ def __init__( token: authorization token """ name = name or "gateway-provider" - host = host or os.environ.get(ENV_GATEWAY_PROVIDER_HOST) if host is None: raise QuantumServerlessException("Please provide `host` of gateway.") @@ -422,11 +436,32 @@ def _verify_token(self, token: str): raise QuantumServerlessException("Cannot verify token.") from reason -class IBMServerlessProvider(Provider): - """IBMServerlessProvider.""" +class Provider(ServerlessProvider): + """ + [Deprecated since version 0.6.4] Use :class:`.ServerlessProvider` instead. + + A provider for connecting to a specified host. This class has been + renamed to :class:`.ServerlessProvider`. + """ + + def __init__(self, *args, **kwargs): + warnings.warn( + "The Provider class is deprecated. Use the identical ServerlessProvider class instead." + ) + super().__init__(*args, **kwargs) + + +class IBMServerlessProvider(ServerlessProvider): + """ + A provider for connecting to the IBM serverless host. + + Example: + >>> provider = IBMServerlessProvider(token="") + """ def __init__(self, token: str): - """Constructor for IBMServerlessProvider + """ + Initialize a provider with access to an IBMQ-provided remote cluster. Args: token: IBM quantum token diff --git a/docs/deployment/client_configuration.rst b/docs/deployment/client_configuration.rst index 043f6c461..f41a05571 100644 --- a/docs/deployment/client_configuration.rst +++ b/docs/deployment/client_configuration.rst @@ -15,7 +15,7 @@ To install the client library, run: Next, we need to configure the client to communicate with the provider. -This is done through the `Provider` configuration. +This can be done through the `BaseProvider` configuration. Before we can configure the client and provider, we need to know two things: the `username/password` @@ -33,9 +33,9 @@ you can start configuring the client: .. code-block:: - from quantum_serverless import QuantumServerless, Provider + from quantum_serverless import QuantumServerless, ServerlessProvider - provider = Provider( + provider = ServerlessProvider( username="", password="", host="", diff --git a/docs/examples/01_vqe.ipynb b/docs/examples/01_vqe.ipynb index a220bf5de..f87edefc7 100644 --- a/docs/examples/01_vqe.ipynb +++ b/docs/examples/01_vqe.ipynb @@ -179,7 +179,7 @@ "metadata": {}, "outputs": [], "source": [ - "from quantum_serverless import QuantumServerless, Provider\n", + "from quantum_serverless import QuantumServerless, ServerlessProvider\n", "import os" ] }, @@ -189,7 +189,7 @@ "metadata": {}, "outputs": [], "source": [ - "provider = Provider(\n", + "provider = ServerlessProvider(\n", " username=os.environ.get(\"GATEWAY_USER\", \"user\"),\n", " password=os.environ.get(\"GATEWAY_PASSWORD\", \"password123\"),\n", " # token=os.environ.get(\"GATEWAY_TOKEN\", \"\"), # token can be used instead of user/password combination\n", diff --git a/docs/examples/02_qaoa.ipynb b/docs/examples/02_qaoa.ipynb index d1d41cea1..f34282034 100644 --- a/docs/examples/02_qaoa.ipynb +++ b/docs/examples/02_qaoa.ipynb @@ -200,7 +200,7 @@ "metadata": {}, "outputs": [], "source": [ - "from quantum_serverless import QuantumServerless, Provider\n", + "from quantum_serverless import QuantumServerless, ServerlessProvider\n", "import os" ] }, @@ -221,7 +221,7 @@ } ], "source": [ - "provider = Provider(\n", + "provider = ServerlessProvider(\n", " username=os.environ.get(\"GATEWAY_USER\", \"user\"),\n", " password=os.environ.get(\"GATEWAY_PASSWORD\", \"password123\"),\n", " # token=os.environ.get(\"GATEWAY_TOKEN\", \"\"), # token can be used instead of user/password combination\n", diff --git a/docs/getting_started/basic/01_running_program.ipynb b/docs/getting_started/basic/01_running_program.ipynb index 6ed4011d3..652ff70c9 100644 --- a/docs/getting_started/basic/01_running_program.ipynb +++ b/docs/getting_started/basic/01_running_program.ipynb @@ -46,7 +46,7 @@ "\n", "To run the program, we need to import the necessary classes and configure them. One of these classes is QuantumServerless, which is a client class for interacting with compute resources.\n", "\n", - "QuantumServerless takes a Provider object as a constructor argument. The Provider object 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 program locally on our machine. If you want to run the program elsewhere, you will need to provide the corresponding host and authentication details." + "QuantumServerless takes a [BaseProvider](https://qiskit-extensions.github.io/quantum-serverless/stubs/quantum_serverless.core.BaseProvider.html) instance as a constructor argument. The provider 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 program locally on our machine. If you want to run the program elsewhere, you will need to provide the corresponding host and authentication details." ] }, { @@ -56,7 +56,7 @@ "metadata": {}, "outputs": [], "source": [ - "from quantum_serverless import QuantumServerless, Provider\n", + "from quantum_serverless import QuantumServerless, ServerlessProvider\n", "import os" ] }, @@ -86,7 +86,7 @@ } ], "source": [ - "provider = Provider(\n", + "provider = ServerlessProvider(\n", " username=os.environ.get(\"GATEWAY_USER\", \"user\"),\n", " password=os.environ.get(\"GATEWAY_PASSWORD\", \"password123\"),\n", " # token=os.environ.get(\"GATEWAY_TOKEN\", \"\"), # token can be used instead of user/password combination\n", diff --git a/docs/getting_started/basic/02_arguments_and_results.ipynb b/docs/getting_started/basic/02_arguments_and_results.ipynb index ccb71862c..64e91e653 100644 --- a/docs/getting_started/basic/02_arguments_and_results.ipynb +++ b/docs/getting_started/basic/02_arguments_and_results.ipynb @@ -138,10 +138,10 @@ } ], "source": [ - "from quantum_serverless import QuantumServerless, Provider\n", + "from quantum_serverless import QuantumServerless, ServerlessProvider\n", "import os\n", "\n", - "provider = Provider(\n", + "provider = ServerlessProvider(\n", " username=os.environ.get(\"GATEWAY_USER\", \"user\"),\n", " password=os.environ.get(\"GATEWAY_PASSWORD\", \"password123\"),\n", " # token=os.environ.get(\"GATEWAY_TOKEN\", \"\"), # token can be used instead of user/password combination\n", diff --git a/docs/getting_started/basic/03_dependencies.ipynb b/docs/getting_started/basic/03_dependencies.ipynb index c3b5fb3b5..98defdb5d 100644 --- a/docs/getting_started/basic/03_dependencies.ipynb +++ b/docs/getting_started/basic/03_dependencies.ipynb @@ -104,10 +104,10 @@ } ], "source": [ - "from quantum_serverless import QuantumServerless, Provider\n", + "from quantum_serverless import QuantumServerless, ServerlessProvider\n", "import os\n", "\n", - "provider = Provider(\n", + "provider = ServerlessProvider(\n", " username=os.environ.get(\"GATEWAY_USER\", \"user\"),\n", " password=os.environ.get(\"GATEWAY_PASSWORD\", \"password123\"),\n", " # token=os.environ.get(\"GATEWAY_TOKEN\", \"\"), # token can be used instead of user/password combination\n", diff --git a/docs/getting_started/basic/04_distributed_workloads.ipynb b/docs/getting_started/basic/04_distributed_workloads.ipynb index 395eca7a0..4a866d42c 100644 --- a/docs/getting_started/basic/04_distributed_workloads.ipynb +++ b/docs/getting_started/basic/04_distributed_workloads.ipynb @@ -87,10 +87,10 @@ } ], "source": [ - "from quantum_serverless import QuantumServerless, Provider\n", + "from quantum_serverless import QuantumServerless, ServerlessProvider\n", "import os\n", "\n", - "provider = Provider(\n", + "provider = ServerlessProvider(\n", " username=os.environ.get(\"GATEWAY_USER\", \"user\"),\n", " password=os.environ.get(\"GATEWAY_PASSWORD\", \"password123\"),\n", " # token=os.environ.get(\"GATEWAY_TOKEN\", \"\"), # token can be used instead of user/password combination\n", diff --git a/docs/getting_started/basic/05_retrieving_past_results.ipynb b/docs/getting_started/basic/05_retrieving_past_results.ipynb index be2704a76..cdb59cf28 100644 --- a/docs/getting_started/basic/05_retrieving_past_results.ipynb +++ b/docs/getting_started/basic/05_retrieving_past_results.ipynb @@ -15,7 +15,7 @@ "id": "37322958-a029-46bb-bc46-82b7ded329b5", "metadata": {}, "source": [ - "First, create [Provider](https://qiskit-extensions.github.io/quantum-serverless/stubs/quantum_serverless.core.Provider.html#quantum_serverless.core.Provider) and [QuantumServerless](https://qiskit-extensions.github.io/quantum-serverless/stubs/quantum_serverless.QuantumServerless.html#quantum_serverless.QuantumServerless) instances.\n", + "First, create [ServerlessProvider](https://qiskit-extensions.github.io/quantum-serverless/stubs/quantum_serverless.core.Provider.html#quantum_serverless.core.ServerlessProvider) and [QuantumServerless](https://qiskit-extensions.github.io/quantum-serverless/stubs/quantum_serverless.QuantumServerless.html#quantum_serverless.QuantumServerless) instances.\n", "\n", "> ⚠ 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](https://qiskit-extensions.github.io/quantum-serverless/deployment/local.html)." ] @@ -27,10 +27,10 @@ "metadata": {}, "outputs": [], "source": [ - "from quantum_serverless import QuantumServerless, Provider\n", + "from quantum_serverless import QuantumServerless, ServerlessProvider\n", "import os\n", "\n", - "provider = Provider(\n", + "provider = ServerlessProvider(\n", " username=os.environ.get(\"GATEWAY_USER\", \"user\"),\n", " password=os.environ.get(\"GATEWAY_PASSWORD\", \"password123\"),\n", " # token=os.environ.get(\"GATEWAY_TOKEN\", \"\"), # token can be used instead of user/password combination\n", diff --git a/docs/getting_started/experimental/file_download.ipynb b/docs/getting_started/experimental/file_download.ipynb index 05fb34c0a..30c80ad85 100644 --- a/docs/getting_started/experimental/file_download.ipynb +++ b/docs/getting_started/experimental/file_download.ipynb @@ -48,9 +48,9 @@ ], "source": [ "import os\n", - "from quantum_serverless import QuantumServerless, Provider, Program\n", + "from quantum_serverless import QuantumServerless, ServerlessProvider, Program\n", "\n", - "provider = Provider(\n", + "provider = ServerlessProvider(\n", " username=\"user\",\n", " password=\"password123\",\n", " host=os.environ.get(\"GATEWAY_HOST\", \"http://localhost:8000\"),\n", diff --git a/docs/getting_started/experimental/running_programs_using_decorators.ipynb b/docs/getting_started/experimental/running_programs_using_decorators.ipynb index 0689e403c..bece7d615 100644 --- a/docs/getting_started/experimental/running_programs_using_decorators.ipynb +++ b/docs/getting_started/experimental/running_programs_using_decorators.ipynb @@ -43,9 +43,9 @@ ], "source": [ "import os\n", - "from quantum_serverless import Provider\n", + "from quantum_serverless import ServerlessProvider\n", "\n", - "provider = Provider(\n", + "provider = ServerlessProvider(\n", " username=\"user\",\n", " password=\"password123\",\n", " host=os.environ.get(\"GATEWAY_HOST\", \"http://localhost:8000\"),\n", @@ -61,7 +61,7 @@ "## Hello, Qiskit!\n", "\n", "Let's create simpliest program by writing a funtion `hello_qiskit` and annotating it with `@distribute_program` decorator. \n", - "Decorator accepts `Provider` as one of the arguments. Other arguments are `dependencies` to specify extra packages to install during execution and `working_dir` to specify working directory that will be shiped for remote execution if needed." + "The ``distribute_program`` decorator accepts a [BaseProvider](https://qiskit-extensions.github.io/quantum-serverless/stubs/quantum_serverless.core.BaseProvider.html) instance for the ``provider`` argument. Other arguments are `dependencies` to specify extra packages to install during execution and `working_dir` to specify working directory that will be shiped for remote execution if needed." ] }, { diff --git a/docs/migration/migration_from_qiskit_runtime_programs.ipynb b/docs/migration/migration_from_qiskit_runtime_programs.ipynb index 687b073a2..782bed2a1 100644 --- a/docs/migration/migration_from_qiskit_runtime_programs.ipynb +++ b/docs/migration/migration_from_qiskit_runtime_programs.ipynb @@ -126,10 +126,10 @@ } ], "source": [ - "from quantum_serverless import QuantumServerless, Provider\n", + "from quantum_serverless import QuantumServerless, ServerlessProvider\n", "import os\n", "\n", - "provider = Provider(\n", + "provider = ServerlessProvider(\n", " username=os.environ.get(\"GATEWAY_USER\", \"user\"),\n", " password=os.environ.get(\"GATEWAY_PASSWORD\", \"password123\"),\n", " # token=os.environ.get(\"GATEWAY_TOKEN\", \"\"), # token can be used instead of user/password combination\n",