توفر مكتبة OpenAI Python وصولاً سهلاً إلى OpenAI REST API من أي تطبيق Python 3.8+. تتضمن المكتبة تعريفات النوع لجميع معلمات الطلب وحقول الاستجابة، وتوفر عملاء متزامنين وغير متزامنين مدعومين بواسطة httpx.
يتم إنشاؤه من مواصفات OpenAPI الخاصة بنا مع الفولاذ المقاوم للصدأ.
يمكن العثور على وثائق REST API على المنصة.openai.com. يمكن العثور على واجهة برمجة التطبيقات الكاملة لهذه المكتبة في api.md.
مهم
تمت إعادة كتابة حزمة تطوير البرامج (SDK) في الإصدار الأول، والذي تم إصداره في 6 نوفمبر 2023. راجع دليل الترحيل الإصدار الأول، الذي يتضمن نصوصًا برمجية لتحديث التعليمات البرمجية الخاصة بك تلقائيًا.
# install from PyPI
pip install openai
يمكن العثور على واجهة برمجة التطبيقات الكاملة لهذه المكتبة في api.md.
import os
from openai import OpenAI
client = OpenAI (
api_key = os . environ . get ( "OPENAI_API_KEY" ), # This is the default and can be omitted
)
chat_completion = client . chat . completions . create (
messages = [
{
"role" : "user" ,
"content" : "Say this is a test" ,
}
],
model = "gpt-4o" ,
)
بينما يمكنك توفير وسيطة الكلمة الرئيسية api_key
، نوصي باستخدام python-dotenv لإضافة OPENAI_API_KEY="My API Key"
إلى ملف .env
الخاص بك حتى لا يتم تخزين مفتاح API الخاص بك في التحكم بالمصادر.
مع صورة مستضافة:
response = client . chat . completions . create (
model = "gpt-4o-mini" ,
messages = [
{
"role" : "user" ,
"content" : [
{ "type" : "text" , "text" : prompt },
{
"type" : "image_url" ,
"image_url" : { "url" : f" { img_url } " },
},
],
}
],
)
مع الصورة كسلسلة مشفرة base64:
response = client . chat . completions . create (
model = "gpt-4o-mini" ,
messages = [
{
"role" : "user" ,
"content" : [
{ "type" : "text" , "text" : prompt },
{
"type" : "image_url" ,
"image_url" : { "url" : f"data: { img_type } ;base64, { img_b64_str } " },
},
],
}
],
)
عند التفاعل مع واجهة برمجة التطبيقات، تكون بعض الإجراءات مثل بدء التشغيل وإضافة الملفات إلى مخازن المتجهات غير متزامنة وتستغرق وقتًا حتى تكتمل. يتضمن SDK وظائف مساعدة تقوم باستقصاء الحالة حتى تصل إلى الحالة النهائية ثم تقوم بإرجاع الكائن الناتج. إذا نتج عن أسلوب واجهة برمجة التطبيقات (API) إجراء يمكن أن يستفيد من الاستقصاء، فسيكون هناك إصدار مناظر من الأسلوب ينتهي بـ "_and_poll".
على سبيل المثال، لإنشاء تشغيل واستقصاء حتى يصل إلى الحالة النهائية، يمكنك تشغيل:
run = client . beta . threads . runs . create_and_poll (
thread_id = thread . id ,
assistant_id = assistant . id ,
)
يمكن العثور على مزيد من المعلومات حول دورة حياة التشغيل في وثائق دورة حياة التشغيل
عند إنشاء مخازن المتجهات والتفاعل معها، يمكنك استخدام مساعدي الاستقصاء لمراقبة حالة العمليات. وللتسهيل عليك، نوفر أيضًا مساعد التحميل المجمع للسماح لك بتحميل عدة ملفات في وقت واحد في وقت واحد.
sample_files = [ Path ( "sample-paper.pdf" ), ...]
batch = await client . vector_stores . file_batches . upload_and_poll (
store . id ,
files = sample_files ,
)
يتضمن SDK أيضًا مساعدين لمعالجة التدفقات والتعامل مع الأحداث الواردة.
with client . beta . threads . runs . stream (
thread_id = thread . id ,
assistant_id = assistant . id ,
instructions = "Please address the user as Jane Doe. The user has a premium account." ,
) as stream :
for event in stream :
# Print the text from text delta events
if event . type == "thread.message.delta" and event . data . delta . content :
print ( event . data . delta . content [ 0 ]. text )
يمكن العثور على مزيد من المعلومات حول مساعدي البث في الوثائق المخصصة: helpers.md
ما عليك سوى استيراد AsyncOpenAI
بدلاً من OpenAI
واستخدام await
مع كل استدعاء لواجهة برمجة التطبيقات:
import os
import asyncio
from openai import AsyncOpenAI
client = AsyncOpenAI (
api_key = os . environ . get ( "OPENAI_API_KEY" ), # This is the default and can be omitted
)
async def main () -> None :
chat_completion = await client . chat . completions . create (
messages = [
{
"role" : "user" ,
"content" : "Say this is a test" ,
}
],
model = "gpt-4o" ,
)
asyncio . run ( main ())
الوظيفة بين العملاء المتزامنين وغير المتزامنين متطابقة.
نحن نقدم الدعم لتدفق الاستجابات باستخدام الأحداث الجانبية للخادم (SSE).
from openai import OpenAI
client = OpenAI ()
stream = client . chat . completions . create (
messages = [
{
"role" : "user" ,
"content" : "Say this is a test" ,
}
],
model = "gpt-4o" ,
stream = True ,
)
for chunk in stream :
print ( chunk . choices [ 0 ]. delta . content or "" , end = "" )
يستخدم العميل غير المتزامن نفس الواجهة بالضبط.
import asyncio
from openai import AsyncOpenAI
client = AsyncOpenAI ()
async def main ():
stream = await client . chat . completions . create (
model = "gpt-4" ,
messages = [{ "role" : "user" , "content" : "Say this is a test" }],
stream = True ,
)
async for chunk in stream :
print ( chunk . choices [ 0 ]. delta . content or "" , end = "" )
asyncio . run ( main ())
مهم
نوصي بشدة بإنشاء مثيلات العميل بدلاً من الاعتماد على العميل العالمي.
نكشف أيضًا عن مثيل عميل عالمي يمكن الوصول إليه بطريقة مشابهة للإصدارات السابقة للإصدار v1.
import openai
# optional; defaults to `os.environ['OPENAI_API_KEY']`
openai . api_key = '...'
# all client options can be configured just like the `OpenAI` instantiation counterpart
openai . base_url = "https://..."
openai . default_headers = { "x-foo" : "true" }
completion = openai . chat . completions . create (
model = "gpt-4o" ,
messages = [
{
"role" : "user" ,
"content" : "How do I output all files in a directory using Python?" ,
},
],
)
print ( completion . choices [ 0 ]. message . content )
واجهة برمجة التطبيقات (API) هي تمامًا نفس واجهة برمجة التطبيقات (API) المستندة إلى مثيل العميل القياسي.
تم تصميم هذا للاستخدام داخل REPLs أو دفاتر الملاحظات من أجل تكرار أسرع، وليس في كود التطبيق.
نوصيك دائمًا بإنشاء مثيل للعميل (على سبيل المثال، باستخدام client = OpenAI()
) في كود التطبيق للأسباب التالية:
معلمات الطلب المتداخلة هي TypedDicts. الردود هي نماذج Pydantic والتي توفر أيضًا طرقًا مساعدة لأشياء مثل:
model.to_json()
model.to_dict()
توفر الطلبات والاستجابات المكتوبة الإكمال التلقائي والوثائق داخل المحرر الخاص بك. إذا كنت ترغب في رؤية أخطاء الكتابة في VS Code للمساعدة في اكتشاف الأخطاء مسبقًا، فاضبط python.analysis.typeCheckingMode
على basic
.
يتم ترقيم صفحات طرق القائمة في OpenAI API.
توفر هذه المكتبة مكررات ترقيم الصفحات تلقائيًا مع كل استجابة قائمة، لذلك لا يتعين عليك طلب الصفحات المتعاقبة يدويًا:
from openai import OpenAI
client = OpenAI ()
all_jobs = []
# Automatically fetches more pages as needed.
for job in client . fine_tuning . jobs . list (
limit = 20 ,
):
# Do something with job here
all_jobs . append ( job )
print ( all_jobs )
أو بشكل غير متزامن:
import asyncio
from openai import AsyncOpenAI
client = AsyncOpenAI ()
async def main () -> None :
all_jobs = []
# Iterate through items across all pages, issuing requests as needed.
async for job in client . fine_tuning . jobs . list (
limit = 20 ,
):
all_jobs . append ( job )
print ( all_jobs )
asyncio . run ( main ())
بدلاً من ذلك، يمكنك استخدام الأساليب .has_next_page()
أو .next_page_info()
أو .get_next_page()
لمزيد من التحكم الدقيق في العمل مع الصفحات:
first_page = await client . fine_tuning . jobs . list (
limit = 20 ,
)
if first_page . has_next_page ():
print ( f"will fetch next page using these details: { first_page . next_page_info () } " )
next_page = await first_page . get_next_page ()
print ( f"number of items we just fetched: { len ( next_page . data ) } " )
# Remove `await` for non-async usage.
أو مجرد العمل مباشرة مع البيانات التي تم إرجاعها:
first_page = await client . fine_tuning . jobs . list (
limit = 20 ,
)
print ( f"next page cursor: { first_page . after } " ) # => "next page cursor: ..."
for job in first_page . data :
print ( job . id )
# Remove `await` for non-async usage.
المعلمات المتداخلة هي قواميس، يتم كتابتها باستخدام TypedDict
، على سبيل المثال:
from openai import OpenAI
client = OpenAI ()
completion = client . chat . completions . create (
messages = [
{
"role" : "user" ,
"content" : "Can you generate an example json object describing a fruit?" ,
}
],
model = "gpt-4o" ,
response_format = { "type" : "json_object" },
)
يمكن تمرير معلمات الطلب التي تتوافق مع تحميلات الملفات على هيئة bytes
أو مثيل PathLike
أو مجموعة من (filename, contents, media type)
.
from pathlib import Path
from openai import OpenAI
client = OpenAI ()
client . files . create (
file = Path ( "input.jsonl" ),
purpose = "fine-tune" ,
)
يستخدم العميل غير المتزامن نفس الواجهة بالضبط. إذا قمت بتمرير مثيل PathLike
، فسيتم قراءة محتويات الملف بشكل غير متزامن تلقائيًا.
عندما تكون المكتبة غير قادرة على الاتصال بواجهة برمجة التطبيقات (على سبيل المثال، بسبب مشاكل في الاتصال بالشبكة أو انتهاء المهلة)، يتم ظهور فئة فرعية من openai.APIConnectionError
.
عندما تقوم واجهة برمجة التطبيقات (API) بإرجاع رمز حالة غير ناجح (أي استجابة 4xx أو 5xx)، يتم رفع فئة فرعية من openai.APIStatusError
، تحتوي على status_code
وخصائص response
.
جميع الأخطاء ترث من openai.APIError
.
import openai
from openai import OpenAI
client = OpenAI ()
try :
client . fine_tuning . jobs . create (
model = "gpt-4o" ,
training_file = "file-abc123" ,
)
except openai . APIConnectionError as e :
print ( "The server could not be reached" )
print ( e . __cause__ ) # an underlying Exception, likely raised within httpx.
except openai . RateLimitError as e :
print ( "A 429 status code was received; we should back off a bit." )
except openai . APIStatusError as e :
print ( "Another non-200-range status code was received" )
print ( e . status_code )
print ( e . response )
رموز الخطأ هي كما يلي:
رمز الحالة | نوع الخطأ |
---|---|
400 | BadRequestError |
401 | AuthenticationError |
403 | PermissionDeniedError |
404 | NotFoundError |
422 | UnprocessableEntityError |
429 | RateLimitError |
>=500 | InternalServerError |
لا يوجد | APIConnectionError |
لمزيد من المعلومات حول طلبات تصحيح الأخطاء، راجع هذه المستندات
توفر جميع استجابات الكائنات في SDK خاصية _request_id
والتي تتم إضافتها من رأس استجابة x-request-id
بحيث يمكنك تسجيل الطلبات الفاشلة بسرعة والإبلاغ عنها مرة أخرى إلى OpenAI.
completion = await client . chat . completions . create (
messages = [{ "role" : "user" , "content" : "Say this is a test" }], model = "gpt-4"
)
print ( completion . _request_id ) # req_123
لاحظ أنه على عكس الخصائص الأخرى التي تستخدم البادئة _
، فإن الخاصية _request_id
عامة. ما لم يتم توثيق خلاف ذلك، فإن جميع خصائص وأساليب ووحدات البادئة _
الأخرى تكون خاصة .
تتم إعادة محاولة بعض الأخطاء تلقائيًا مرتين بشكل افتراضي، مع تراجع أسي قصير. تتم إعادة محاولة أخطاء الاتصال (على سبيل المثال، بسبب مشكلة في الاتصال بالشبكة)، و408 مهلة الطلب، وتعارض 409، وحد معدل 429، و>=500 الأخطاء الداخلية بشكل افتراضي.
يمكنك استخدام خيار max_retries
لتكوين إعدادات إعادة المحاولة أو تعطيلها:
from openai import OpenAI
# Configure the default for all requests:
client = OpenAI (
# default is 2
max_retries = 0 ,
)
# Or, configure per-request:
client . with_options ( max_retries = 5 ). chat . completions . create (
messages = [
{
"role" : "user" ,
"content" : "How can I get the name of the current day in JavaScript?" ,
}
],
model = "gpt-4o" ,
)
بشكل افتراضي، تنتهي مهلة الطلبات بعد 10 دقائق. يمكنك ضبط ذلك باستخدام خيار timeout
، الذي يقبل كائنًا عائمًا أو httpx.Timeout
:
from openai import OpenAI
# Configure the default for all requests:
client = OpenAI (
# 20 seconds (default is 10 minutes)
timeout = 20.0 ,
)
# More granular control:
client = OpenAI (
timeout = httpx . Timeout ( 60.0 , read = 5.0 , write = 10.0 , connect = 2.0 ),
)
# Override per-request:
client . with_options ( timeout = 5.0 ). chat . completions . create (
messages = [
{
"role" : "user" ,
"content" : "How can I list all files in a directory using Python?" ,
}
],
model = "gpt-4o" ,
)
عند انتهاء المهلة، يتم طرح خطأ APITimeoutError
.
لاحظ أنه تتم إعادة محاولة طلبات انتهاء المهلة مرتين بشكل افتراضي.
نحن نستخدم وحدة logging
المكتبة القياسية.
يمكنك تمكين التسجيل عن طريق ضبط متغير البيئة OPENAI_LOG
على info
.
$ export OPENAI_LOG=info
أو debug
المزيد من التسجيل المطول.
None
يعني أنه null
أو مفقود في استجابة واجهة برمجة التطبيقات (API)، قد يكون الحقل null
أو مفقودًا تمامًا؛ وفي كلتا الحالتين، قيمته هي None
في هذه المكتبة. يمكنك التمييز بين الحالتين باستخدام .model_fields_set
:
if response . my_field is None :
if 'my_field' not in response . model_fields_set :
print ( 'Got json like {}, without a "my_field" key present at all.' )
else :
print ( 'Got json like {"my_field": null}.' )
يمكن الوصول إلى كائن الاستجابة "الخام" عن طريق البادئة .with_raw_response.
إلى أي استدعاء أسلوب HTTP، على سبيل المثال،
from openai import OpenAI
client = OpenAI ()
response = client . chat . completions . with_raw_response . create (
messages = [{
"role" : "user" ,
"content" : "Say this is a test" ,
}],
model = "gpt-4o" ,
)
print ( response . headers . get ( 'X-My-Header' ))
completion = response . parse () # get the object that `chat.completions.create()` would have returned
print ( completion )
تقوم هذه الطرق بإرجاع كائن LegacyAPIResponse
. هذه فئة قديمة حيث نقوم بتغييرها قليلاً في الإصدار الرئيسي التالي.
بالنسبة لعميل المزامنة، سيكون هذا هو نفسه في الغالب باستثناء content
text
سيكون طرقًا بدلاً من الخصائص. في العميل غير المتزامن، ستكون كافة الأساليب غير متزامنة.
سيتم توفير برنامج نصي للترحيل ويجب أن تكون عملية الترحيل بشكل عام سلسة.
.with_streaming_response
تقرأ الواجهة أعلاه بفارغ الصبر نص الاستجابة الكامل عند تقديم الطلب، والذي قد لا يكون دائمًا ما تريده.
لبث نص الاستجابة، استخدم .with_streaming_response
بدلاً من ذلك، والذي يتطلب مدير سياق ويقرأ نص الاستجابة فقط بمجرد استدعاء .read()
, .text()
, .json()
, .iter_bytes()
, .iter_text()
, .iter_lines()
أو .parse()
. في العميل غير المتزامن، هذه هي طرق غير متزامنة.
على هذا النحو، تقوم أساليب .with_streaming_response
بإرجاع كائن APIResponse
مختلف، ويقوم العميل غير المتزامن بإرجاع كائن AsyncAPIResponse
.
with client . chat . completions . with_streaming_response . create (
messages = [
{
"role" : "user" ,
"content" : "Say this is a test" ,
}
],
model = "gpt-4o" ,
) as response :
print ( response . headers . get ( "X-My-Header" ))
for line in response . iter_lines ():
print ( line )
مطلوب مدير السياق حتى يتم إغلاق الاستجابة بشكل موثوق.
تم كتابة هذه المكتبة للوصول بسهولة إلى واجهة برمجة التطبيقات الموثقة.
إذا كنت بحاجة إلى الوصول إلى نقاط النهاية أو المعلمات أو خصائص الاستجابة غير الموثقة، فلا يزال من الممكن استخدام المكتبة.
لتقديم طلبات إلى نقاط نهاية غير موثقة، يمكنك تقديم طلبات باستخدام client.get
و client.post
وأفعال http الأخرى. سيتم احترام الخيارات المتاحة للعميل (مثل إعادة المحاولة) عند تقديم هذا الطلب.
import httpx
response = client . post (
"/foo" ,
cast_to = httpx . Response ,
body = { "my_param" : True },
)
print ( response . headers . get ( "x-foo" ))
إذا كنت تريد إرسال معلمة إضافية بشكل صريح، فيمكنك القيام بذلك باستخدام خيارات طلب extra_query
و extra_body
و extra_headers
.
للوصول إلى خصائص الاستجابة غير الموثقة، يمكنك الوصول إلى الحقول الإضافية مثل response.unknown_prop
. يمكنك أيضًا الحصول على جميع الحقول الإضافية في نموذج Pydantic كإملاء باستخدام response.model_extra
.
يمكنك تجاوز عميل httpx مباشرة لتخصيصه ليناسب حالة الاستخدام الخاصة بك، بما في ذلك:
from openai import OpenAI , DefaultHttpxClient
client = OpenAI (
# Or use the `OPENAI_BASE_URL` env var
base_url = "http://my.test.server.example.com:8083/v1" ,
http_client = DefaultHttpxClient (
proxies = "http://my.test.proxy.example.com" ,
transport = httpx . HTTPTransport ( local_address = "0.0.0.0" ),
),
)
يمكنك أيضًا تخصيص العميل على أساس كل طلب باستخدام with_options()
:
client . with_options ( http_client = DefaultHttpxClient (...))
بشكل افتراضي، تقوم المكتبة بإغلاق اتصالات HTTP الأساسية عندما يتم تجميع البيانات المهملة للعميل. يمكنك إغلاق العميل يدويًا باستخدام طريقة .close()
إذا رغبت في ذلك، أو باستخدام مدير السياق الذي يتم إغلاقه عند الخروج.
لاستخدام هذه المكتبة مع Azure OpenAI، استخدم فئة AzureOpenAI
بدلاً من فئة OpenAI
.
مهم
يختلف شكل Azure API عن شكل API الأساسي مما يعني أن الأنواع الثابتة للاستجابات/المعلمات لن تكون صحيحة دائمًا.
from openai import AzureOpenAI
# gets the API Key from environment variable AZURE_OPENAI_API_KEY
client = AzureOpenAI (
# https://learn.microsoft.com/azure/ai-services/openai/reference#rest-api-versioning
api_version = "2023-07-01-preview" ,
# https://learn.microsoft.com/azure/cognitive-services/openai/how-to/create-resource?pivots=web-portal#create-a-resource
azure_endpoint = "https://example-endpoint.openai.azure.com" ,
)
completion = client . chat . completions . create (
model = "deployment-name" , # e.g. gpt-35-instant
messages = [
{
"role" : "user" ,
"content" : "How do I output all files in a directory using Python?" ,
},
],
)
print ( completion . to_json ())
بالإضافة إلى الخيارات المتوفرة في عميل OpenAI
الأساسي، يتم توفير الخيارات التالية:
azure_endpoint
(أو متغير البيئة AZURE_OPENAI_ENDPOINT
)azure_deployment
api_version
(أو متغير البيئة OPENAI_API_VERSION
)azure_ad_token
(أو متغير البيئة AZURE_OPENAI_AD_TOKEN
)azure_ad_token_provider
يمكن العثور هنا على مثال لاستخدام العميل بمعرف Microsoft Entra (المعروف سابقًا باسم Azure Active Directory).
تتبع هذه الحزمة بشكل عام اصطلاحات SemVer، على الرغم من أنه قد يتم إصدار بعض التغييرات غير المتوافقة مع الإصدارات السابقة كإصدارات ثانوية:
نحن نأخذ التوافق مع الإصدارات السابقة على محمل الجد ونعمل جاهدين لضمان إمكانية الاعتماد على تجربة ترقية سلسة.
نحن حريصون على ملاحظاتك. يرجى فتح قضية مع الأسئلة، والأخطاء، أو الاقتراحات.
إذا قمت بالترقية إلى الإصدار الأحدث ولكنك لم تشاهد أي ميزات جديدة كنت تتوقعها، فمن المحتمل أن بيئة بايثون الخاصة بك لا تزال تستخدم إصدارًا أقدم.
يمكنك تحديد الإصدار الذي يتم استخدامه في وقت التشغيل باستخدام:
import openai
print ( openai . __version__ )
بايثون 3.8 أو أعلى.
انظر الوثائق المساهمة.