استخدام IBM Cloud Resource Controller API لإدارة النسخ
يمكنك استخدام IBM Cloud® Resource Controller REST API لجلب النسخ وإنشائها وتحديثها برمجياً.
تتطلب جميع نقاط نهاية Resource Controller المصادقة عبر تمرير رأس يُسمى Authorization يحتوي على رمز الحامل (bearer token). راجع دليل إعداد REST API.
الحصول على نسخة
استخدم نقطة النهاية GET /v2/resource_instances/{crn} للحصول على معلومات حول نسخة معينة. يجب ترميز CRN لعنوان URL في المسار.
بالإضافة إلى حقول Resource Controller القياسية، تتضمن الاستجابة حقولاً خاصة بالحوسبة الكمية في كل من parameters وextensions. يخزّن extensions البيانات الوصفية الموحدة للنسخة، بينما يخزّن parameters فقط أحدث طلب لتعديل النسخة. لذلك، ينبغي أن تقرأ من extensions بدلاً من parameters.
يتضمن الكائن extensions هذه الحقول:
-
instance_limit_seconds— عدد صحيح، أوnull. حد وقت الاستخدام للنسخة. راجع تعيين حدود تخصيص النسخة. -
usage_allocation_seconds— عدد صحيح، أوnull. الوقت المخصص لهذه النسخة، يستخدمه مُجدوِل المشاركة العادلة لتحديد أولوية قائمة الانتظار. راجع تعيين حدود تخصيص النسخة. -
backends— مصفوفة من السلاسل النصية. القائمة المسموح بها لأسماء الـ backends المتاحة لهذه النسخة.["ANY"]تعني أن جميع الـ backends في الخطة متاحة (القيمة الافتراضية).[]تعني عدم توفر أي backend.
قد يكون الحقل backends في الكائن extensions قديماً. يمكن أن يحدث ذلك عندما يغيّر دعم IBM Quantum حسابك بطريقة تؤثر على النسخ. على سبيل المثال، عند إزالة backend من حساب، سيتم تحديث backends الخاصة بالنسخة، لكن هذا التغيير لا ينعكس حالياً بعد في Resource Controller API.
بدلاً من ذلك، الحل البديل الحالي هو استخدام IBM Quantum Compute Service REST API مع نقطة النهاية GET /v1/backends. (تأكد من تعيين الرأس Service-CRN إلى CRN الخاص بنسختك.)
- cURL
- Python
يجب ترميز CRN بترميز URL (URL-encoding) داخل المسار. استبدل كل : بـ %3A وكل / بـ %2F. على سبيل المثال، تصبح crn:v1:bluemix:... هي crn%3Av1%3Abluemix%3A....
curl \
--request GET \
--url 'https://resource-controller.cloud.ibm.com/v2/resource_instances/<YOUR_INSTANCE_CRN_URL_ENCODED>' \
--header 'Authorization: Bearer <YOUR_BEARER_TOKEN>'
import urllib.parse
import requests
crn = "<YOUR_INSTANCE_CRN>"
# We use urllib.parse.quote to URL-encode the CRN.
url = (
"https://resource-controller.cloud.ibm.com/v2/resource_instances/"
+ urllib.parse.quote(crn, safe="")
)
resp = requests.get(
url,
headers={"Authorization": f"Bearer {token}"},
timeout=30,
)
resp.raise_for_status()
print(resp.json())
الحصول على قائمة بجميع النسخ
استخدم نقطة النهاية GET /v2/resource_instances للحصول على قائمة بجميع نسخك. عيّن معامل الاستعلام resource_id إلى b6049020-80f4-11eb-a0f7-e35ec9b4054f للتصفية إلى نسخ IBM Quantum®.
إذا كان حسابك يحتوي على خطط متعددة وتريد التصفية حسب الخطة، عيّن معامل الاستعلام resource_plan_id إلى إحدى القيم التالية:
| الخطة | resource_plan_id |
|---|---|
| Premium | 7f666d17-7893-47d8-bf9d-2b2389fc4dfc |
| Flex | 53bde9d3-cdbb-46f5-a98f-60ebcadf7260 |
| Pay-As-You-Go | 5304b575-3cff-4455-90dc-ae4367762093 |
| Open | 850b21a7-71de-4e53-9441-1abdd202f35d |
تتضمن كل نتيجة نفس الحقل extensions الموصوف في الحصول على نسخة.
- cURL
- Python
curl \
--request GET \
--url 'https://resource-controller.cloud.ibm.com/v2/resource_instances?resource_id=b6049020-80f4-11eb-a0f7-e35ec9b4054f' \
--header 'Authorization: Bearer <YOUR_BEARER_TOKEN>'
import requests
resp = requests.get(
"https://resource-controller.cloud.ibm.com/v2/resource_instances?resource_id=b6049020-80f4-11eb-a0f7-e35ec9b4054f",
headers={"Authorization": f"Bearer {token}"},
timeout=30,
)
resp.raise_for_status()
print(resp.json())
تحديث نسخة
استخدم نقطة النهاية PATCH /v2/resource_instances/{crn} لتحديث الحد والتخصيص والـ backends المسموح بها لنسخة. يجب ترميز CRN لعنوان URL في المسار.
مرّر كائن JSON باسم parameters في نص الطلب يحتوي على الحقول التي تريد تغييرها، مع الرأس "Content-Type: application/json". تبقى الحقول المحذوفة دون تغيير.
-
instance_limit_seconds— عدد صحيح، أوnull. حد وقت الاستخدام للنسخة. راجع تعيين حدود تخصيص النسخة. -
usage_allocation_seconds— عدد صحيح، أوnull. الوقت المخصص لهذه النسخة، يستخدمه مُجدوِل المشاركة العادلة لتحديد أولوية قائمة الانتظار. راجع تعيين حدود تخصيص النسخة. لا ينطبق على نسخ Pay-As-You-Go. -
backends— مصفوفة من السلاسل النصية. القائمة المسموح بها لأسماء الـ backends المتاحة لهذه النسخة.["ANY"]تعني أن جميع الـ backends في الخطة متاحة.[]تعني عدم توفر أي backend.
تتجاهل واجهة برمجة التطبيقات الطلب بصمت إذا كانت parameters مطابقة للطلب السابق. في الكائن parameters، ضمّن دائماً حقل timestamp مضبوطاً على الوقت الحالي حتى تتم معاملة كل طلب بوصفه فريداً.
استجابة نقطة النهاية مشابهة لـ الحصول على نسخة، بما في ذلك طريقة تعاملها مع الكائن extensions.
- cURL
- Python
يجب ترميز CRN بترميز URL (URL-encoding) داخل المسار. استبدل كل : بـ %3A وكل / بـ %2F. على سبيل المثال، تصبح crn:v1:bluemix:... هي crn%3Av1%3Abluemix%3A....
curl \
--request PATCH \
--url 'https://resource-controller.cloud.ibm.com/v2/resource_instances/<YOUR_INSTANCE_CRN_URL_ENCODED>' \
--header 'Authorization: Bearer <YOUR_BEARER_TOKEN>' \
--header 'Content-Type: application/json' \
--data "{
\"parameters\": {
\"timestamp\": \"$(date -u +"%Y-%m-%dT%H:%M:%SZ")\",
\"usage_allocation_seconds\": 220
}
}"
import urllib.parse
import datetime
import requests
crn = "<YOUR_INSTANCE_CRN>"
# We use urllib.parse.quote to URL-encode the CRN.
url = (
"https://resource-controller.cloud.ibm.com/v2/resource_instances/"
+ urllib.parse.quote(crn, safe="")
)
timestamp = datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
body = {
"parameters": {
"timestamp": timestamp,
"usage_allocation_seconds": 220,
}
}
resp = requests.patch(
url,
headers={
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
},
json=body,
timeout=30,
)
resp.raise_for_status()
print(resp.json())
إنشاء نسخة جديدة
استخدم نقطة النهاية POST /v2/resource_instances لإنشاء (تزويد) نسخة جديدة. مرّر نص JSON مع الرأس "Content-Type: application/json".
الحقول المطلوبة:
-
name— اسم وصفي مقروء للنسخة. -
target— المنطقة، مثلus-eastأوeu-de. -
resource_plan_id— الخطة لهذه النسخة. راجع جدول معرّفات الخطط. -
resource_group— مجموعة الموارد التي ستُستخدم.
يمكنك أيضاً تضمين كائن parameters لتعيين قيم خاصة بالحوسبة الكمية:
-
instance_limit_seconds— عدد صحيح، أوnull. حد وقت الاستخدام للنسخة. راجع تعيين حدود تخصيص النسخة. -
usage_allocation_seconds— عدد صحيح، أوnull. الوقت المخصص لهذه النسخة، يستخدمه مُجدوِل المشاركة العادلة لتحديد أولوية قائمة الانتظار. راجع تعيين حدود تخصيص النسخة. لا ينطبق على نسخ Pay-As-You-Go. -
backends— مصفوفة من السلاسل النصية. القائمة المسموح بها لأسماء الـ backends المتاحة لهذه النسخة.["ANY"]تعني أن جميع الـ backends في الخطة متاحة.[]تعني عدم توفر أي backend.
- cURL
- Python
curl \
--request POST \
--url 'https://resource-controller.cloud.ibm.com/v2/resource_instances' \
--header 'Authorization: Bearer <YOUR_BEARER_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"name": "my-new-instance",
"target": "us-east",
"resource_plan_id": "7f666d17-7893-47d8-bf9d-2b2389fc4dfc",
"resource_group": "<YOUR_RESOURCE_GROUP_ID>",
"parameters": {
"instance_limit_seconds": 300,
"usage_allocation_seconds": 220
}
}'
import requests
body = {
"name": "my-new-instance",
"target": "us-east",
"resource_plan_id": "7f666d17-7893-47d8-bf9d-2b2389fc4dfc",
"resource_group": "<YOUR_RESOURCE_GROUP_ID>",
"parameters": {
"instance_limit_seconds": 300,
"usage_allocation_seconds": 220,
},
}
resp = requests.post(
"https://resource-controller.cloud.ibm.com/v2/resource_instances",
headers={
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
},
json=body,
timeout=30,
)
resp.raise_for_status()
print(resp.json())
تكوين الوصول إلى Qiskit Functions على نسخة
استخدم هذه التعليمات لتكوين الوصول إلى Qiskit Functions على نسخة IBM Quantum Compute Service موجودة باستخدام IBM Cloud Resource Controller API. اتبع التعليمات بالترتيب، حيث تبني الأوامر على بعضها البعض. فمثلاً، تُعيَّن متغيرات مثل الرمز وعنوان URL في خطوة واحدة ويُعاد استخدامها في الخطوات اللاحقة.
المتطلبات الأساسية
-
مفتاح IBM Cloud API (يُسمى أيضاً رمزاً). إذا لزم الأمر، أنشئ مفتاح API الخاص بك على لوحة التحكم.
-
CRN الخاص بالنسخة التي تريد تكوينها. تظهر CRN الخاصة بالنسخة على صفحة النسخ الخاصة بك.
الخطوة 1: الحصول على رمز حامل
استبدل مفتاح API الخاص بك برمز حامل. ستمرر هذا الرمز في رأس التخويل لجميع طلبات وحدة تحكم الموارد. شغّل الشيفرة التالية لإنشاء رمز حامل:
- cURL
- Python
curl --request POST \
--url 'https://iam.cloud.ibm.com/identity/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data 'apikey=<YOUR_API_KEY>&grant_type=urn%3Aibm%3Aparams%3Aoauth%3Agrant-type%3Aapikey'
--silent | jq .
import requests
api_key = "<YOUR_API_KEY>"
resp = requests.post(
"https://iam.cloud.ibm.com/identity/token",
headers={"Content-Type": "application/x-www-form-urlencoded"},
params={
"apikey": api_key,
"grant_type": "urn:ibm:params:oauth:grant-type:apikey",
},
timeout=30,
)
resp.raise_for_status()
token = resp.json()["access_token"]
print(token)
تتضمن الاستجابة حقل access_token، وهو رمز الحامل الخاص بك. انسخ هذه القيمة.
الخطوة 2: التحقق من الوصول
قبل إجراء أي تغييرات، تأكد من أن رمزك يعمل وافحص تكوين النسخة الحالي.
- cURL
- Python
يجب ترميز CRN يدوياً لعنوان URL في المسار. استبدل كل : بـ %3A وكل / بـ %2F. على سبيل المثال، تصبح crn:v1:bluemix:... هي crn%3Av1%3Abluemix%3A....
curl --request GET \
--url 'https://resource-controller.cloud.ibm.com/v2/resource_instances/<YOUR_INSTANCE_CRN_URL_ENCODED>' \
--header 'Authorization: Bearer <YOUR_BEARER_TOKEN>'
import urllib.parse
crn = "<YOUR_INSTANCE_CRN>"
# سيتم ترميز CRN لعنوان URL في المسار.
instance_url = (
"https://resource-controller.cloud.ibm.com/v2/resource_instances/"
+ urllib.parse.quote(crn, safe="")
)
headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
resp = requests.get(instance_url, headers=headers, timeout=30)
resp.raise_for_status()
print(resp.json()["extensions"])
تؤكد الاستجابة 200 OK أن رمزك صالح. تكوين النسخة الحالي موجود في حقل extensions من الاستجابة. استخدم هذا بدلاً من parameters، والتي قد تكون قديمة.
الخطوة 3: البحث عن تكوين الدوال على مستوى الحساب
لا يمكن منح نسخة الوصول إلا لما يستحقه الحساب. قبل تكوين النسخة، ابحث عن تكوين الحساب حتى تعرف الدوال ونماذج الأعمال والأذونات المتاحة للمنح. هذا هو المرجع المعتمد للقيم التي سترسلها في الخطوة 4.
استدعِ GET /accounts/{id} على Qiskit Runtime API باستخدام مفتاح API الخاص بك. {id} هو معرّف حسابك بدون بادئة a/. يمكنك إيجاده من CRN الخاص بالنسخة (crn:v1:bluemix:public:quantum-computing:...:a/<ACCOUNT_ID>:...).
- cURL
- Python
curl --request GET \
--url 'https://quantum.cloud.ibm.com/api/v1/accounts/<ACCOUNT_ID>' \
--header 'Authorization: apikey <YOUR_API_KEY>'
account_id = "<ACCOUNT_ID>" # from the CRN: crn:...:a/<ACCOUNT_ID>:...
resp = requests.get(
f"https://quantum.cloud.ibm.com/api/v1/accounts/{account_id}",
headers={"Authorization": f"apikey {api_key}"},
timeout=30,
)
resp.raise_for_status()
for plan in resp.json()["plans"]:
print(plan["plan_id"], plan.get("functions"), plan.get("custom_functions"))
تتضمن كل خطة في الاستجابة مصفوفة functions وكائن custom_functions إن كان مُكوَّناً. تسرد هذه القيم الاسم الدقيق والمزود ونموذج الأعمال والأذونات التي يمكنك منحها لنسخة تحت تلك الخطة.
توضح GET /accounts/{id} ما هو متاح للمنح على مستوى الحساب. توضح GET /functions (انظر التحقق من النتيجة) ما تم منحه بالفعل لنسخة معيّنة. استخدم نقطة النهاية account لاكتشاف القيم الصالحة، ونقطة النهاية functions للتأكد من النتيجة.
الخطوة 4: تكوين الوصول إلى الدوال
حدّث النسخة لمنح الوصول إلى Catalog Functions وCustom Functions.
- يجب أن تطابق قيم
nameوproviderوbusiness_modelفي functions تماماً الإدخالات المكوَّنة على مستوى الحساب (راجع الخطوة السابقة). يجب أن تكون الأذونات مجموعة جزئية غير فارغة من أذونات الحساب لتلك الدالة. وبالمثل، يجب أن تكونcustom_functions.permissionsمجموعة جزئية غير فارغة من أذوناتcustom_functionsالخاصة بالحساب. - ضمّن طابعاً زمنياً في parameters في كل عملية PATCH. يزيل Resource Controller التكرار في طلبات PATCH عن طريق مقارنة parameters الواردة بآخر قيمة قام بتخزينها. إذا تطابقت، يُسقط الطلب بصمت مع
200 OKدون الوصول إلى الخدمة. ضمّن قيمة طابع زمني متغيرة لمنع ذلك.
- cURL
- Python
curl --request PATCH \
--url 'https://resource-controller.cloud.ibm.com/v2/resource_instances/<YOUR_INSTANCE_CRN_URL_ENCODED>' \
--header 'Authorization: Bearer <YOUR_BEARER_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"parameters": {
"timestamp": "2026-06-30T00:00:00Z",
"functions": [
{
"name": "<FUNCTION_NAME>",
"provider": "<PROVIDER>",
"business_model": "<BUSINESS_MODEL>",
"permissions": [
"function.read",
"function.run",
"function-files.read",
"function-files.write"
]
}
],
"custom_functions": {
"permissions": [
"function-custom.write",
"function-custom.run"
]
}
}
}'
from datetime import datetime, timezone
# يمنع الطابع الزمني المتغير Resource Controller من إزالة تكرار الطلب.
_now = datetime.now(timezone.utc)
timestamp = _now.strftime("%Y-%m-%dT%H:%M:%S.") + f"{_now.microsecond:06d}000Z"
body = {
"parameters": {
"timestamp": timestamp,
"functions": [
{
"name": "<FUNCTION_NAME>",
"provider": "<PROVIDER>",
"business_model": "<BUSINESS_MODEL>",
"permissions": [
"function.read",
"function.run",
"function-files.read",
"function-files.write",
],
}
],
"custom_functions": {
"permissions": ["function-custom.write", "function-custom.run"],
},
}
}
resp = requests.patch(instance_url, headers=headers, json=body, timeout=30)
resp.raise_for_status()
print(resp.json()["extensions"])
تشير الاستجابة 200 OK إلى النجاح. يظهر التكوين المحدَّث في حقل extensions من الاستجابة.
إزالة الوصول إلى الدوال
Catalog Functions
لإزالة Catalog Functions من نسخة، أرسل PATCH مع "functions": null:
- cURL
- Python
--data '{
"parameters": {
"timestamp": "2026-06-30T00:00:01Z",
"functions": null
}
}'
body = {"parameters": {"timestamp": timestamp, "functions": None}}
resp = requests.patch(instance_url, headers=headers, json=body, timeout=30)
resp.raise_for_status()
يؤدي تعيين "functions": [] (مصفوفة فارغة) إلى مسح Catalog Functions بشكل مكافئ. null هي الصيغة القياسية.
Custom Functions
لإزالة Custom Functions من نسخة، أرسل PATCH مع "custom_functions": null:
- cURL
- Python
--data '{
"parameters": {
"timestamp": "2026-06-30T00:00:02Z",
"custom_functions": null
}
}'
body = {"parameters": {"timestamp": timestamp, "custom_functions": None}}
resp = requests.patch(instance_url, headers=headers, json=body, timeout=30)
resp.raise_for_status()
يؤدي تعيين "custom_functions": {"permissions": []} إلى مسح custom functions بشكل مكافئ. null هي الصيغة القياسية.
التحقق من النتيجة
للتأكد من أن النسخة تملك التكوين الصحيح لـ Qiskit Functions، استخدم GET /functions من Qiskit Runtime API بدلاً من Resource Controller. قد تكون الحالة المخزَّنة لدى Resource Controller قديمة إذا حدّثت تغييرات على مستوى الحساب النسخة خارج Resource Controller.
- cURL
- Python
curl --request GET \
--url 'https://quantum.cloud.ibm.com/api/v1/functions' \
--header 'Authorization: apikey <YOUR_API_KEY>' \
--header 'Service-CRN: <YOUR_INSTANCE_CRN>'
# يأخذ رأس Service-CRN القيمة الخام لـ CRN، وليس الصيغة المرمَّزة لعنوان URL.
resp = requests.get(
"https://quantum.cloud.ibm.com/api/v1/functions",
headers={"Authorization": f"apikey {api_key}", "Service-CRN": crn},
timeout=30,
)
resp.raise_for_status()
print(resp.json())
تسرد الاستجابة الدوال التي تملك النسخة حالياً حق الوصول إليها.