quapp-common 0.0.11.dev1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. quapp_common-0.0.11.dev1/LICENSE +8 -0
  2. quapp_common-0.0.11.dev1/PKG-INFO +41 -0
  3. quapp_common-0.0.11.dev1/README.md +7 -0
  4. quapp_common-0.0.11.dev1/pyproject.toml +31 -0
  5. quapp_common-0.0.11.dev1/qapp_common/__init__.py +0 -0
  6. quapp_common-0.0.11.dev1/qapp_common/async_tasks/__init__.py +0 -0
  7. quapp_common-0.0.11.dev1/qapp_common/async_tasks/async_task.py +11 -0
  8. quapp_common-0.0.11.dev1/qapp_common/async_tasks/export_circuit_task.py +119 -0
  9. quapp_common-0.0.11.dev1/qapp_common/async_tasks/post_processing_task.py +59 -0
  10. quapp_common-0.0.11.dev1/qapp_common/component/__init__.py +0 -0
  11. quapp_common-0.0.11.dev1/qapp_common/component/backend/__init__.py +0 -0
  12. quapp_common-0.0.11.dev1/qapp_common/component/backend/invocation.py +255 -0
  13. quapp_common-0.0.11.dev1/qapp_common/component/backend/job_fetching.py +247 -0
  14. quapp_common-0.0.11.dev1/qapp_common/component/callback/__init__.py +0 -0
  15. quapp_common-0.0.11.dev1/qapp_common/component/callback/update_job_metadata.py +39 -0
  16. quapp_common-0.0.11.dev1/qapp_common/component/device/__init__.py +0 -0
  17. quapp_common-0.0.11.dev1/qapp_common/component/device/device_selection.py +81 -0
  18. quapp_common-0.0.11.dev1/qapp_common/config/__init__.py +0 -0
  19. quapp_common-0.0.11.dev1/qapp_common/config/logging_config.py +8 -0
  20. quapp_common-0.0.11.dev1/qapp_common/config/thread_config.py +10 -0
  21. quapp_common-0.0.11.dev1/qapp_common/data/__init__.py +0 -0
  22. quapp_common-0.0.11.dev1/qapp_common/data/async_task/__init__.py +0 -0
  23. quapp_common-0.0.11.dev1/qapp_common/data/async_task/circuit_export/__init__.py +0 -0
  24. quapp_common-0.0.11.dev1/qapp_common/data/async_task/circuit_export/backend_holder.py +12 -0
  25. quapp_common-0.0.11.dev1/qapp_common/data/async_task/circuit_export/circuit_holder.py +11 -0
  26. quapp_common-0.0.11.dev1/qapp_common/data/backend/__init__.py +0 -0
  27. quapp_common-0.0.11.dev1/qapp_common/data/backend/backend_information.py +14 -0
  28. quapp_common-0.0.11.dev1/qapp_common/data/callback/__init__.py +0 -0
  29. quapp_common-0.0.11.dev1/qapp_common/data/callback/callback_url.py +10 -0
  30. quapp_common-0.0.11.dev1/qapp_common/data/device/__init__.py +0 -0
  31. quapp_common-0.0.11.dev1/qapp_common/data/device/circuit_running_option.py +16 -0
  32. quapp_common-0.0.11.dev1/qapp_common/data/promise/__init__.py +0 -0
  33. quapp_common-0.0.11.dev1/qapp_common/data/promise/post_processing_promise.py +18 -0
  34. quapp_common-0.0.11.dev1/qapp_common/data/promise/promise.py +11 -0
  35. quapp_common-0.0.11.dev1/qapp_common/data/request/__init__.py +0 -0
  36. quapp_common-0.0.11.dev1/qapp_common/data/request/invocation_request.py +24 -0
  37. quapp_common-0.0.11.dev1/qapp_common/data/request/job_fetching_request.py +11 -0
  38. quapp_common-0.0.11.dev1/qapp_common/data/request/request.py +23 -0
  39. quapp_common-0.0.11.dev1/qapp_common/data/response/__init__.py +0 -0
  40. quapp_common-0.0.11.dev1/qapp_common/data/response/authentication.py +9 -0
  41. quapp_common-0.0.11.dev1/qapp_common/data/response/job_response.py +32 -0
  42. quapp_common-0.0.11.dev1/qapp_common/data/response/project_header.py +9 -0
  43. quapp_common-0.0.11.dev1/qapp_common/enum/__init__.py +0 -0
  44. quapp_common-0.0.11.dev1/qapp_common/enum/base_enum.py +16 -0
  45. quapp_common-0.0.11.dev1/qapp_common/enum/http_header.py +10 -0
  46. quapp_common-0.0.11.dev1/qapp_common/enum/invocation_step.py +13 -0
  47. quapp_common-0.0.11.dev1/qapp_common/enum/media_type.py +12 -0
  48. quapp_common-0.0.11.dev1/qapp_common/enum/processing_unit.py +10 -0
  49. quapp_common-0.0.11.dev1/qapp_common/enum/provider_tag.py +22 -0
  50. quapp_common-0.0.11.dev1/qapp_common/enum/sdk.py +22 -0
  51. quapp_common-0.0.11.dev1/qapp_common/enum/status/__init__.py +0 -0
  52. quapp_common-0.0.11.dev1/qapp_common/enum/status/job_status.py +10 -0
  53. quapp_common-0.0.11.dev1/qapp_common/enum/status/status_code.py +10 -0
  54. quapp_common-0.0.11.dev1/qapp_common/enum/token_type.py +8 -0
  55. quapp_common-0.0.11.dev1/qapp_common/factory/__init__.py +0 -0
  56. quapp_common-0.0.11.dev1/qapp_common/factory/device_factory.py +22 -0
  57. quapp_common-0.0.11.dev1/qapp_common/factory/handler_factory.py +20 -0
  58. quapp_common-0.0.11.dev1/qapp_common/factory/provider_factory.py +22 -0
  59. quapp_common-0.0.11.dev1/qapp_common/handler/__init__.py +0 -0
  60. quapp_common-0.0.11.dev1/qapp_common/handler/handler.py +20 -0
  61. quapp_common-0.0.11.dev1/qapp_common/model/__init__.py +0 -0
  62. quapp_common-0.0.11.dev1/qapp_common/model/device/__init__.py +0 -0
  63. quapp_common-0.0.11.dev1/qapp_common/model/device/custom_device.py +87 -0
  64. quapp_common-0.0.11.dev1/qapp_common/model/device/device.py +257 -0
  65. quapp_common-0.0.11.dev1/qapp_common/model/provider/__init__.py +0 -0
  66. quapp_common-0.0.11.dev1/qapp_common/model/provider/provider.py +34 -0
  67. quapp_common-0.0.11.dev1/qapp_common/util/__init__.py +0 -0
  68. quapp_common-0.0.11.dev1/qapp_common/util/file_utils.py +23 -0
  69. quapp_common-0.0.11.dev1/qapp_common/util/http_utils.py +37 -0
  70. quapp_common-0.0.11.dev1/qapp_common/util/json_parser_utils.py +75 -0
  71. quapp_common-0.0.11.dev1/qapp_common/util/response_utils.py +36 -0
  72. quapp_common-0.0.11.dev1/quapp_common.egg-info/PKG-INFO +41 -0
  73. quapp_common-0.0.11.dev1/quapp_common.egg-info/SOURCES.txt +75 -0
  74. quapp_common-0.0.11.dev1/quapp_common.egg-info/dependency_links.txt +1 -0
  75. quapp_common-0.0.11.dev1/quapp_common.egg-info/requires.txt +12 -0
  76. quapp_common-0.0.11.dev1/quapp_common.egg-info/top_level.txt +1 -0
  77. quapp_common-0.0.11.dev1/setup.cfg +4 -0
@@ -0,0 +1,8 @@
1
+ The MIT License (MIT)
2
+ Copyright © CITYNOW Co. Ltd. All rights reserved.
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
5
+
6
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7
+
8
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,41 @@
1
+ Metadata-Version: 2.4
2
+ Name: quapp-common
3
+ Version: 0.0.11.dev1
4
+ Summary: Quapp common library supporting Quapp Platform for Quantum Computing
5
+ Author-email: "CITYNOW Co. Ltd. " <corp@citynow.vn>
6
+ License: The MIT License (MIT)
7
+ Copyright © CITYNOW Co. Ltd. All rights reserved.
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
14
+ Project-URL: Homepage, https://citynow.asia/
15
+ Keywords: quapp,quapp-common,quantum
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Programming Language :: Python
18
+ Classifier: Programming Language :: Python :: 3
19
+ Requires-Python: >=3.7
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: loguru
23
+ Requires-Dist: requests
24
+ Requires-Dist: numpy
25
+ Requires-Dist: matplotlib
26
+ Requires-Dist: pylatexenc
27
+ Provides-Extra: dev
28
+ Requires-Dist: black; extra == "dev"
29
+ Requires-Dist: bumpver; extra == "dev"
30
+ Requires-Dist: isort; extra == "dev"
31
+ Requires-Dist: pip-tools; extra == "dev"
32
+ Requires-Dist: pytest; extra == "dev"
33
+ Dynamic: license-file
34
+
35
+ # qapp-common
36
+
37
+ # changes
38
+ - Add pennylane in enum sdk
39
+ - Change function in `device.py` to protected to override in pennylane sdk
40
+
41
+
@@ -0,0 +1,7 @@
1
+ # qapp-common
2
+
3
+ # changes
4
+ - Add pennylane in enum sdk
5
+ - Change function in `device.py` to protected to override in pennylane sdk
6
+
7
+
@@ -0,0 +1,31 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "quapp-common"
7
+ version = "0.0.11.dev1"
8
+ description = "Quapp common library supporting Quapp Platform for Quantum Computing"
9
+ readme = "README.md"
10
+ authors = [{ name = "CITYNOW Co. Ltd. ", email = "corp@citynow.vn" }]
11
+ license = { file = "LICENSE" }
12
+ classifiers = [
13
+ "License :: OSI Approved :: MIT License",
14
+ "Programming Language :: Python",
15
+ "Programming Language :: Python :: 3",
16
+ ]
17
+ keywords = ["quapp", "quapp-common", "quantum"]
18
+ dependencies = [
19
+ "loguru",
20
+ "requests",
21
+ "numpy",
22
+ "matplotlib",
23
+ "pylatexenc"
24
+ ]
25
+ requires-python = ">=3.7"
26
+
27
+ [project.optional-dependencies]
28
+ dev = ["black", "bumpver", "isort", "pip-tools", "pytest"]
29
+
30
+ [project.urls]
31
+ Homepage = "https://citynow.asia/"
File without changes
@@ -0,0 +1,11 @@
1
+ """
2
+ QApp Platform Project async_task.py Copyright © CITYNOW Co. Ltd. All rights reserved.
3
+ """
4
+ from abc import abstractmethod
5
+
6
+
7
+ class AsyncTask:
8
+
9
+ @abstractmethod
10
+ def do(self):
11
+ pass
@@ -0,0 +1,119 @@
1
+ """
2
+ QApp Platform Project export_circuit.py Copyright © CITYNOW Co. Ltd. All rights reserved.
3
+ """
4
+ from io import BytesIO
5
+
6
+ import requests
7
+
8
+ from .async_task import AsyncTask
9
+ from ..data.async_task.circuit_export.backend_holder import BackendDataHolder
10
+ from ..data.async_task.circuit_export.circuit_holder import CircuitDataHolder
11
+ from ..config.logging_config import logger
12
+ from ..enum.media_type import MediaType
13
+ from ..util.file_utils import FileUtils
14
+ from ..util.http_utils import HttpUtils
15
+
16
+
17
+ class CircuitExportTask(AsyncTask):
18
+ MAX_CIRCUIT_IMAGE_SIZE = 5 * (1024 ** 2)
19
+
20
+ def __init__(self,
21
+ circuit_data_holder: CircuitDataHolder,
22
+ backend_data_holder: BackendDataHolder):
23
+ super().__init__()
24
+ self.circuit_data_holder = circuit_data_holder
25
+ self.backend_data_holder = backend_data_holder
26
+
27
+ def do(self):
28
+ """
29
+ Export circuit to svg file then send to QuaO server for saving
30
+ """
31
+ logger.debug("[Circuit export] Start")
32
+
33
+ circuit_export_url = self.circuit_data_holder.export_url
34
+
35
+ if circuit_export_url is None or len(circuit_export_url) < 1:
36
+ return
37
+
38
+ figure_buffer = self.__convert()
39
+
40
+ io_buffer_value, content_type = self.__determine_zip(figure_buffer=figure_buffer)
41
+
42
+ self.__send(io_buffer_value=io_buffer_value,
43
+ content_type=content_type)
44
+
45
+ def __convert(self):
46
+ """
47
+
48
+ @return:
49
+ """
50
+ logger.debug("[Circuit export] Preparing circuit figure...")
51
+ transpiled_circuit = self._transpile_circuit()
52
+ circuit_figure = transpiled_circuit.draw(output='mpl', fold=-1)
53
+
54
+ logger.debug("[Circuit export] Converting circuit figure to svg file...")
55
+ figure_buffer = BytesIO()
56
+ circuit_figure.savefig(figure_buffer, format='svg', bbox_inches='tight')
57
+
58
+ return figure_buffer
59
+
60
+ @staticmethod
61
+ def __determine_zip(figure_buffer):
62
+ """
63
+
64
+ @param figure_buffer:
65
+ @return:
66
+ """
67
+ buffer_value = figure_buffer.getvalue()
68
+ content_type = MediaType.SVG_XML
69
+
70
+ logger.debug("[Circuit export] Checking max file size")
71
+ estimated_file_size = len(buffer_value)
72
+
73
+ if estimated_file_size > CircuitExportTask.MAX_CIRCUIT_IMAGE_SIZE:
74
+ logger.debug("[Circuit export] Zip file")
75
+ zip_file_buffer = FileUtils.zip(io_buffer_value=buffer_value,
76
+ file_name="circuit_image.svg")
77
+
78
+ buffer_value = zip_file_buffer.getvalue()
79
+ content_type = MediaType.APPLICATION_ZIP
80
+
81
+ return buffer_value, content_type
82
+
83
+ def __send(self, io_buffer_value, content_type: MediaType):
84
+ """
85
+
86
+ @param io_buffer_value:
87
+ @param content_type:
88
+ """
89
+ url = self.circuit_data_holder.export_url
90
+
91
+ logger.debug(
92
+ "[Circuit export] Sending circuit svg image to [{0}] with POST method ...".format(
93
+ url))
94
+
95
+ payload = {'circuit': (
96
+ 'circuit_image.svg',
97
+ io_buffer_value,
98
+ content_type.value)}
99
+
100
+ response = requests.post(
101
+ url=url,
102
+ headers=HttpUtils.create_bearer_header(self.backend_data_holder.user_token),
103
+ files=payload)
104
+
105
+ if response.ok:
106
+ logger.debug("Sending request to QuaO backend successfully!")
107
+ else:
108
+ logger.debug("Sending request to QuaO backend failed with status {0}!".format(
109
+ response.status_code))
110
+
111
+ logger.debug("[Circuit export] Finish")
112
+
113
+ def _transpile_circuit(self):
114
+ """
115
+
116
+ @return: Transpiled circuit
117
+ """
118
+
119
+ raise NotImplemented('[CircuitExportTask] __transpile_circuit() method must be implemented')
@@ -0,0 +1,59 @@
1
+ """
2
+ QApp Platform Project post_processing_task.py Copyright © CITYNOW Co. Ltd. All rights reserved.
3
+ """
4
+ from .async_task import AsyncTask
5
+ from ..component.callback.update_job_metadata import update_job_metadata
6
+ from ..config.logging_config import logger
7
+ from ..data.promise.post_processing_promise import PostProcessingPromise
8
+ from ..data.response.job_response import JobResponse
9
+ from ..enum.media_type import MediaType
10
+ from ..enum.status.job_status import JobStatus
11
+ from ..enum.status.status_code import StatusCode
12
+ from ..util.json_parser_utils import JsonParserUtils
13
+
14
+
15
+ class PostProcessingTask(AsyncTask):
16
+ def __init__(self,
17
+ post_processing_fn,
18
+ promise: PostProcessingPromise):
19
+ self.post_processing_fn = post_processing_fn
20
+ self.promise = promise
21
+
22
+ def do(self):
23
+ """
24
+ Execute post_processing and send to backend
25
+ """
26
+
27
+ job_response = JobResponse(
28
+ authentication=self.promise.authentication,
29
+ project_header=self.promise.project_header,
30
+ job_status=JobStatus.DONE.value,
31
+ status_code=StatusCode.DONE)
32
+
33
+ update_job_metadata(job_response=job_response,
34
+ callback_url=self.promise.callback_url.on_start)
35
+
36
+ job_response.content_type = MediaType.APPLICATION_JSON
37
+
38
+ try:
39
+
40
+ logger.info("Execute post_processing ...")
41
+ job_result_post_processing = self.post_processing_fn(self.promise.job_result)
42
+
43
+ logger.debug("Parsing job result....")
44
+ print(job_result_post_processing)
45
+ job_response.job_result = JsonParserUtils.parse(job_result_post_processing)
46
+
47
+ update_job_metadata(job_response=job_response,
48
+ callback_url=self.promise.callback_url.on_done)
49
+
50
+ except Exception as exception:
51
+ job_response.job_result = {
52
+ "error": "Error when execute post_processing(): ",
53
+ "exception": str(exception),
54
+ }
55
+ job_response.status_code = StatusCode.ERROR
56
+ job_response.job_status = JobStatus.ERROR.value
57
+
58
+ update_job_metadata(job_response=job_response,
59
+ callback_url=self.promise.callback_url.on_error)
@@ -0,0 +1,255 @@
1
+ """
2
+ QApp Platform Project backend.py Copyright © CITYNOW Co. Ltd. All rights reserved.
3
+ """
4
+ from abc import abstractmethod, ABC
5
+
6
+ from ..callback.update_job_metadata import update_job_metadata
7
+ from ...component.device.device_selection import DeviceSelection
8
+ from ...config.logging_config import logger
9
+ from ...config.thread_config import circuit_running_pool
10
+ from ...data.backend.backend_information import BackendInformation
11
+ from ...data.device.circuit_running_option import CircuitRunningOption
12
+ from ...data.request.invocation_request import InvocationRequest
13
+ from ...data.response.authentication import Authentication
14
+ from ...data.response.job_response import JobResponse
15
+ from ...data.response.project_header import ProjectHeader
16
+ from ...enum.invocation_step import InvocationStep
17
+ from ...enum.media_type import MediaType
18
+ from ...enum.sdk import Sdk
19
+ from ...enum.status.job_status import JobStatus
20
+ from ...enum.status.status_code import StatusCode
21
+ from ...model.provider.provider import Provider
22
+
23
+ EXPORT_CIRCUIT_SDK = {Sdk.QISKIT, Sdk.BRAKET}
24
+
25
+
26
+ class Invocation(ABC):
27
+ def __init__(self, request_data: InvocationRequest):
28
+ self.sdk: Sdk = Sdk.resolve(request_data.sdk)
29
+ self.input = request_data.input
30
+ self.device_id = request_data.device_id
31
+ self.backend_information: BackendInformation
32
+ self.authentication: Authentication = request_data.authentication
33
+ self.project_header: ProjectHeader = request_data.project_header
34
+ self.options = CircuitRunningOption(
35
+ shots=request_data.shots,
36
+ processing_unit=request_data.processing_unit,
37
+ executor=circuit_running_pool,
38
+ max_job_size=1,
39
+ )
40
+ self.device_selection_url: str = request_data.device_selection_url
41
+ self.circuit_export_url: str = request_data.circuit_export_url
42
+ self.callback_dict: dict = {
43
+ InvocationStep.PREPARATION: request_data.preparation,
44
+ InvocationStep.EXECUTION: request_data.execution,
45
+ InvocationStep.ANALYSIS: request_data.analysis,
46
+ InvocationStep.FINALIZATION: request_data.finalization,
47
+ }
48
+ self.invoke_authentication = request_data.invoke_authentication
49
+
50
+ def submit_job(self, circuit_preparation_fn, post_processing_fn):
51
+ """
52
+
53
+ @param post_processing_fn: Post-processing function
54
+ @param circuit_preparation_fn: Circuit-preparation function
55
+ @return: Job result
56
+ """
57
+ logger.debug("[Invocation] Invoke job")
58
+
59
+ circuit = self.__pre_execute(circuit_preparation_fn)
60
+
61
+ if circuit is None:
62
+ return
63
+
64
+ self.__execute(circuit, post_processing_fn)
65
+
66
+ def __pre_execute(self, circuit_preparation_fn):
67
+ """
68
+
69
+ @param circuit_preparation_fn: Circuit preparation function
70
+ """
71
+ circuit = self.__prepare_circuit(circuit_preparation_fn)
72
+
73
+ if circuit is None:
74
+ return None
75
+
76
+ try:
77
+ self.__prepare_backend_data(circuit)
78
+
79
+ except Exception as exception:
80
+ job_response = JobResponse(
81
+ status_code=StatusCode.ERROR,
82
+ authentication=self.authentication,
83
+ project_header=self.project_header,
84
+ job_result={"error": str(exception)},
85
+ content_type=MediaType.APPLICATION_JSON,
86
+ job_status=JobStatus.ERROR.value,
87
+ )
88
+
89
+ update_job_metadata(
90
+ job_response=job_response,
91
+ callback_url=self.callback_dict.get(
92
+ InvocationStep.PREPARATION
93
+ ).on_error,
94
+ )
95
+
96
+ self._export_circuit(circuit)
97
+
98
+ return circuit
99
+
100
+ def __execute(self, circuit, post_processing_fn):
101
+ """
102
+
103
+ @param circuit: Circuit was run
104
+ @param post_processing_fn: Post-processing function
105
+ @return: Job response
106
+ """
107
+
108
+ logger.debug("[Invocation] Execute job")
109
+
110
+ try:
111
+ if self.backend_information is None:
112
+ raise Exception("Backend is not found")
113
+
114
+ device_name = self.backend_information.device_name
115
+ provider_tag = self.backend_information.provider_tag
116
+ backend_authentication = self.backend_information.authentication
117
+
118
+ logger.debug(
119
+ "[Invocation] Execute job with provider tag: {0}".format(
120
+ provider_tag.value
121
+ )
122
+ )
123
+
124
+ provider = self._create_provider()
125
+
126
+ logger.debug(
127
+ "[Invocation] Execute job with device name: {0}".format(device_name)
128
+ )
129
+ device = self._create_device(provider)
130
+
131
+ except Exception as exception:
132
+ job_response = JobResponse(
133
+ job_status=JobStatus.ERROR.value,
134
+ content_type=MediaType.APPLICATION_JSON,
135
+ status_code=StatusCode.ERROR,
136
+ authentication=self.authentication,
137
+ project_header=self.project_header,
138
+ job_result={"error": str(exception)},
139
+ )
140
+ update_job_metadata(
141
+ job_response=job_response,
142
+ callback_url=self.callback_dict.get(InvocationStep.EXECUTION).on_error,
143
+ )
144
+
145
+ return
146
+
147
+ device.run_circuit(
148
+ circuit=circuit,
149
+ post_processing_fn=post_processing_fn,
150
+ options=self.options,
151
+ callback_dict=self.callback_dict,
152
+ authentication=self.authentication,
153
+ project_header=self.project_header,
154
+ )
155
+
156
+ def __prepare_circuit(self, circuit_preparation_fn):
157
+ """
158
+
159
+ @param circuit_preparation_fn: Circuit preparation function
160
+ @return: circuit
161
+ """
162
+ logger.debug("[Invocation] Prepare circuit")
163
+
164
+ job_response = JobResponse(
165
+ status_code=StatusCode.DONE,
166
+ authentication=self.authentication,
167
+ project_header=self.project_header,
168
+ )
169
+ update_job_metadata(
170
+ job_response=job_response,
171
+ callback_url=self.callback_dict.get(InvocationStep.PREPARATION).on_start,
172
+ )
173
+
174
+ try:
175
+ circuit = circuit_preparation_fn(self.input)
176
+
177
+ if circuit is None:
178
+ raise Exception("Invalid circuit")
179
+
180
+ update_job_metadata(
181
+ job_response=job_response,
182
+ callback_url=self.callback_dict.get(InvocationStep.PREPARATION).on_done,
183
+ )
184
+
185
+ return circuit
186
+
187
+ except Exception as exception:
188
+ job_response.job_status = JobStatus.ERROR.value
189
+ job_response.content_type = MediaType.APPLICATION_JSON
190
+ job_response.status_code = StatusCode.ERROR
191
+ job_response.job_result = {"error": str(exception)}
192
+
193
+ update_job_metadata(
194
+ job_response=job_response,
195
+ callback_url=self.callback_dict.get(
196
+ InvocationStep.PREPARATION
197
+ ).on_error,
198
+ )
199
+
200
+ return None
201
+
202
+ def __prepare_backend_data(self, circuit):
203
+ """
204
+
205
+ @param circuit: Circuit was run
206
+ """
207
+
208
+ required_qubit_amount = self._get_qubit_amount(circuit)
209
+
210
+ device_selection = DeviceSelection(
211
+ required_qubit_amount,
212
+ self.device_id,
213
+ self.authentication.user_token,
214
+ self.device_selection_url,
215
+ )
216
+
217
+ self.backend_information = device_selection.select()
218
+ logger.info("before")
219
+ logger.info(self.backend_information.authentication)
220
+ self.backend_information.authentication = self.invoke_authentication
221
+ logger.info("after")
222
+ logger.info(self.backend_information.authentication)
223
+
224
+ @abstractmethod
225
+ def _export_circuit(self, circuit):
226
+ """
227
+
228
+ @param circuit: Circuit was exported
229
+ """
230
+
231
+ raise NotImplemented('[Invocation] _export_circuit() method must be implemented')
232
+
233
+ @abstractmethod
234
+ def _create_provider(self, ):
235
+ """
236
+ Create provider with ProviderFactory
237
+ """
238
+
239
+ raise NotImplemented('[Invocation] _create_provider() method must be implemented')
240
+
241
+ @abstractmethod
242
+ def _create_device(self, provider: Provider):
243
+ """
244
+ Create device with DeviceFactory
245
+ """
246
+
247
+ raise NotImplemented('[Invocation] _create_device() method must be implemented')
248
+
249
+ @abstractmethod
250
+ def _get_qubit_amount(self, circuit):
251
+ """
252
+ Get number qubit of circuit
253
+ """
254
+
255
+ raise NotImplemented('[Invocation] _get_qubit_amount() method must be implemented')