@@ -109,8 +109,9 @@ def __init__(
109
109
``token``. The ``local`` channel doesn't require authentication.
110
110
For non-local channels, it is recommended to always provide the relevant ``instance``
111
111
to minimize API calls. If an ``instance`` is not defined, the service will fetch all
112
- instances accessible within the
113
- account, filtered by ``region``, ``plans_preference``, and ``tags``.
112
+ instances accessible within the account, filtered by ``region``, ``plans_preference``,
113
+ and ``tags``. If ``plans_preference`` is not set, free and trial instances will be prioritized
114
+ over paid instances.
114
115
115
116
The service will attempt to load an account from file if (a) no explicit ``token``
116
117
was provided during instantiation or (b) a ``name`` is specified, even if an explicit
@@ -231,6 +232,37 @@ def __init__(
231
232
else :
232
233
self ._api_clients = {}
233
234
instance_backends = self ._resolve_cloud_instances (instance )
235
+ instance_names = [instance .get ("name" ) for instance in self ._backend_instance_groups ]
236
+ instance_plan_names = {
237
+ instance .get ("plan" ) for instance in self ._backend_instance_groups
238
+ }
239
+
240
+ tags_str = ", " .join (self ._tags ) if self ._tags else "None"
241
+ region_str = self ._region if self ._region else "us-east, eu-de"
242
+ if self ._plans_preference :
243
+ joined_preferences : str = ", " .join (self ._plans_preference )
244
+ plans_preference_str = f", plans_preference: { joined_preferences } )"
245
+ else :
246
+ joined_plan_names = ", " .join (instance_plan_names )
247
+ plans_preference_str = f"), and available plans: ({ joined_plan_names } )"
248
+
249
+ filters = f"(tags: { tags_str } , " f"region: { region_str } " f"{ plans_preference_str } "
250
+
251
+ logger .warning (
252
+ "Instance was not set at service instantiation. %s"
253
+ "Based on the following filters: %s, "
254
+ "the available account instances are: %s. "
255
+ "If you need a specific instance set it explicitly either by "
256
+ "using a saved account with a saved default instance or passing it "
257
+ "in directly to QiskitRuntimeService()." ,
258
+ (
259
+ ""
260
+ if self ._plans_preference
261
+ else "Free and trial plan instances will be prioritized. "
262
+ ),
263
+ filters ,
264
+ ", " .join (instance_names ),
265
+ )
234
266
for inst , _ in instance_backends :
235
267
self ._get_or_create_cloud_client (inst )
236
268
@@ -292,6 +324,13 @@ def _filter_instances_by_saved_preferences(self) -> None:
292
324
self ._backend_instance_groups = sorted (
293
325
filtered_groups , key = lambda d : plans .index (d ["plan" ])
294
326
)
327
+ else :
328
+ # if plans_preference is not set, prioritize free and trial plans
329
+ ordered_pricing_types = ["free" , "trial" , "paygo" , "paid" , "subscription" ]
330
+ self ._backend_instance_groups = sorted (
331
+ self ._backend_instance_groups ,
332
+ key = lambda d : ordered_pricing_types .index (d ["pricing_type" ]),
333
+ )
295
334
296
335
if not self ._backend_instance_groups :
297
336
error_string = ""
@@ -349,14 +388,28 @@ def _discover_account(
349
388
proxies = proxies ,
350
389
verify = verify_ ,
351
390
)
391
+ logger .warning (
392
+ "Loading account with the given token. A saved account will not be used."
393
+ )
352
394
else :
353
395
if url :
354
396
logger .warning ("Loading default %s account. Input 'url' is ignored." , channel )
355
397
account = AccountManager .get (filename = filename , name = name , channel = channel )
356
- elif any ([token , url ]):
357
- # Let's not infer based on these attributes as they may change in the future.
398
+ elif token :
399
+ account = Account .create_account (
400
+ channel = "ibm_quantum_platform" ,
401
+ token = token ,
402
+ url = url ,
403
+ instance = instance ,
404
+ proxies = proxies ,
405
+ verify = verify_ ,
406
+ )
407
+ logger .warning (
408
+ "Loading account with the given token. A saved account will not be used."
409
+ )
410
+ elif url :
358
411
raise ValueError (
359
- "'channel ' is required if 'token', or 'url' is specified but 'name' is not ."
412
+ "'url ' is not valid as a standalone parameter. Try also passing in 'token' or 'name' ."
360
413
)
361
414
362
415
# channel is not defined yet, get it from the AccountManager
@@ -525,9 +578,25 @@ def backends(
525
578
if name not in backends_available :
526
579
continue
527
580
backends_available = [name ]
581
+ else :
582
+ for inst_details in self ._backend_instance_groups :
583
+ if inst == inst_details ["crn" ]:
584
+ logger .warning (
585
+ "Loading instance: %s, plan: %s" ,
586
+ inst_details ["name" ],
587
+ inst_details ["plan" ],
588
+ )
528
589
for backend_name in backends_available :
529
590
if backend_name in unique_backends :
530
591
continue
592
+ if name :
593
+ for inst_details in self ._backend_instance_groups :
594
+ if inst == inst_details ["crn" ]:
595
+ logger .warning (
596
+ "Using instance: %s, plan: %s" ,
597
+ inst_details ["name" ],
598
+ inst_details ["plan" ],
599
+ )
531
600
unique_backends .add (backend_name )
532
601
self ._get_or_create_cloud_client (inst )
533
602
if backend := self ._create_backend_obj (
@@ -582,25 +651,20 @@ def _resolve_cloud_instances(self, instance: Optional[str]) -> List[Tuple[str, L
582
651
return [(default_crn , self ._discover_backends_from_instance (default_crn ))]
583
652
if not self ._all_instances :
584
653
self ._all_instances = self ._account .list_instances ()
585
- instance_names = [instance .get ("name" ) for instance in self ._all_instances ]
586
- logger .warning (
587
- "Instance was not set at service instantiation. A relevant instance from all available "
588
- "account instances will be selected based on the desired action. "
589
- "Available account instances are: %s. "
590
- "If you need the instance to be fixed, set it explicitly." ,
591
- ", " .join (instance_names ),
592
- )
593
654
if not self ._backend_instance_groups :
594
655
self ._backend_instance_groups = [
595
656
{
657
+ "name" : inst ["name" ],
596
658
"crn" : inst ["crn" ],
597
659
"plan" : inst ["plan" ],
598
660
"backends" : self ._discover_backends_from_instance (inst ["crn" ]),
599
661
"tags" : inst ["tags" ],
662
+ "pricing_type" : inst ["pricing_type" ],
600
663
}
601
664
for inst in self ._all_instances
602
665
]
603
666
self ._filter_instances_by_saved_preferences ()
667
+
604
668
return [(inst ["crn" ], inst ["backends" ]) for inst in self ._backend_instance_groups ]
605
669
606
670
def _get_or_create_cloud_client (self , instance : str ) -> None :
0 commit comments