From e07537fe7862689aba04afd03b80202af34145c3 Mon Sep 17 00:00:00 2001 From: PhoenixCPH Date: Fri, 22 May 2026 02:26:10 +0800 Subject: [PATCH] docs: add multi-language README support Add Chinese, Spanish, French, Portuguese, Russian, and German README translations with a unified language switcher, aligned with common i18n documentation patterns for global SDK adoption. --- README-DE.md | 512 ++++++++++++++++++++++++++++++++++++++++++++++++++ README-ES.md | 512 ++++++++++++++++++++++++++++++++++++++++++++++++++ README-FR.md | 514 +++++++++++++++++++++++++++++++++++++++++++++++++++ README-PT.md | 512 ++++++++++++++++++++++++++++++++++++++++++++++++++ README-RU.md | 512 ++++++++++++++++++++++++++++++++++++++++++++++++++ README-ZH.md | 503 +++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 2 + 7 files changed, 3067 insertions(+) create mode 100644 README-DE.md create mode 100644 README-ES.md create mode 100644 README-FR.md create mode 100644 README-PT.md create mode 100644 README-RU.md create mode 100644 README-ZH.md diff --git a/README-DE.md b/README-DE.md new file mode 100644 index 0000000..33d2895 --- /dev/null +++ b/README-DE.md @@ -0,0 +1,512 @@ +# Perplexity Python-API-Bibliothek + +**Sprachen / Languages:** [English](./README.md) · [中文](./README-ZH.md) · [Español](./README-ES.md) · [Français](./README-FR.md) · [Português](./README-PT.md) · [Русский](./README-RU.md) · [Deutsch](./README-DE.md) + + +[![PyPI version](https://img.shields.io/pypi/v/perplexityai.svg?label=pypi%20(stable))](https://pypi.org/project/perplexityai/) + +Die Perplexity Python-Bibliothek bietet bequemen Zugriff auf die Perplexity REST API aus jeder Python-3.9+-Anwendung. Die Bibliothek enthält Typdefinitionen für alle Anfrageparameter und Antwortfelder und bietet sowohl synchrone als auch asynchrone Clients auf Basis von [httpx](https://github.com/encode/httpx). + +Sie wird mit [Stainless](https://www.stainless.com/) generiert. + +## Dokumentation + +Die REST-API-Dokumentation finden Sie unter [docs.perplexity.ai](https://docs.perplexity.ai/). Die vollständige API dieser Bibliothek finden Sie in [api.md](api.md). + +## Installation + +```sh +# install from PyPI +pip install perplexityai +``` + +## Search API + +Websuchergebnisse abrufen: + +```python +import os +from perplexity import Perplexity + +client = Perplexity( + api_key=os.environ.get("PERPLEXITY_API_KEY"), # This is the default and can be omitted +) + +search = client.search.create( + query="latest AI developments 2024", + max_results=5 +) + +for result in search.results: + print(f"{result.title}: {result.url}") +``` + +## Chat Completions + +Die vollständige API dieser Bibliothek finden Sie in [api.md](api.md). + +```python +import os +from perplexity import Perplexity + +client = Perplexity( + api_key=os.environ.get("PERPLEXITY_API_KEY"), # This is the default and can be omitted +) + +stream_chunk = client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "Tell me about the latest developments in AI", + } + ], + model="sonar", +) +print(stream_chunk.id) +``` + +Obwohl Sie ein `api_key`-Schlüsselwortargument übergeben können, +empfehlen wir die Verwendung von [python-dotenv](https://pypi.org/project/python-dotenv/), +um `PERPLEXITY_API_KEY="My API Key"` zu Ihrer `.env`-Datei hinzuzufügen, +damit Ihr API-Schlüssel nicht in der Versionskontrolle gespeichert wird. + +## Asynchrone Nutzung + +Importieren Sie einfach `AsyncPerplexity` anstelle von `Perplexity` und verwenden Sie `await` bei jedem API-Aufruf: + +```python +import os +import asyncio +from perplexity import AsyncPerplexity + +client = AsyncPerplexity( + api_key=os.environ.get("PERPLEXITY_API_KEY"), # This is the default and can be omitted +) + + +async def main() -> None: + stream_chunk = await client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "Tell me about the latest developments in AI", + } + ], + model="sonar", + ) + print(stream_chunk.id) + + +asyncio.run(main()) +``` + +Die Funktionalität zwischen den synchronen und asynchronen Clients ist ansonsten identisch. + +### Mit aiohttp + +Standardmäßig verwendet der asynchrone Client `httpx` für HTTP-Anfragen. Für bessere Concurrency-Leistung können Sie jedoch auch `aiohttp` als HTTP-Backend verwenden. + +Sie können dies aktivieren, indem Sie `aiohttp` installieren: + +```sh +# install from PyPI +pip install perplexityai[aiohttp] +``` + +Dann können Sie es aktivieren, indem Sie den Client mit `http_client=DefaultAioHttpClient()` instanziieren: + +```python +import os +import asyncio +from perplexity import DefaultAioHttpClient +from perplexity import AsyncPerplexity + + +async def main() -> None: + async with AsyncPerplexity( + api_key=os.environ.get("PERPLEXITY_API_KEY"), # This is the default and can be omitted + http_client=DefaultAioHttpClient(), + ) as client: + stream_chunk = await client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "Tell me about the latest developments in AI", + } + ], + model="sonar", + ) + print(stream_chunk.id) + + +asyncio.run(main()) +``` + +## Streaming-Antworten + +Wir unterstützen Streaming-Antworten mit Server Side Events (SSE). + +```python +from perplexity import Perplexity + +client = Perplexity() + +stream = client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "Tell me about the latest developments in AI", + } + ], + model="sonar", + stream=True, +) +for stream_chunk in stream: + print(stream_chunk.id) +``` + +Der asynchrone Client verwendet genau dieselbe Schnittstelle. + +```python +from perplexity import AsyncPerplexity + +client = AsyncPerplexity() + +stream = await client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "Tell me about the latest developments in AI", + } + ], + model="sonar", + stream=True, +) +async for stream_chunk in stream: + print(stream_chunk.id) +``` + +## Verwendung von Typen + +Verschachtelte Anfrageparameter sind [TypedDicts](https://docs.python.org/3/library/typing.html#typing.TypedDict). Antworten sind [Pydantic-Modelle](https://docs.pydantic.dev), die auch Hilfsmethoden für Dinge wie bereitstellen: + +- Serialisierung zurück in JSON, `model.to_json()` +- Konvertierung in ein Dictionary, `model.to_dict()` + +Typisierte Anfragen und Antworten bieten Autovervollständigung und Dokumentation in Ihrem Editor. Wenn Sie Typfehler in VS Code sehen möchten, um Fehler früher zu erkennen, setzen Sie `python.analysis.typeCheckingMode` auf `basic`. + +## Verschachtelte Parameter + +Verschachtelte Parameter sind Dictionaries, typisiert mit `TypedDict`, zum Beispiel: + +```python +from perplexity import Perplexity + +client = Perplexity() + +stream_chunk = client.chat.completions.create( + messages=[ + { + "content": "string", + "role": "system", + } + ], + model="model", + web_search_options={}, +) +print(stream_chunk.choices) +``` + +## Fehlerbehandlung + +Wenn die Bibliothek keine Verbindung zur API herstellen kann (z. B. aufgrund von Netzwerkverbindungsproblemen oder einem Timeout), wird eine Unterklasse von `perplexity.APIConnectionError` ausgelöst. + +Wenn die API einen Nicht-Erfolgs-Statuscode zurückgibt (d. h. 4xx- oder 5xx-Antwort), wird eine Unterklasse von `perplexity.APIStatusError` ausgelöst, die die Eigenschaften `status_code` und `response` enthält. + +Alle Fehler erben von `perplexity.APIError`. + +```python +import perplexity +from perplexity import Perplexity + +client = Perplexity() + +try: + client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "What is the capital of France?", + } + ], + model="sonar", + ) +except perplexity.APIConnectionError as e: + print("The server could not be reached") + print(e.__cause__) # an underlying Exception, likely raised within httpx. +except perplexity.RateLimitError as e: + print("A 429 status code was received; we should back off a bit.") +except perplexity.APIStatusError as e: + print("Another non-200-range status code was received") + print(e.status_code) + print(e.response) +``` + +Die Fehlercodes sind wie folgt: + +| Status Code | Error Type | +| ----------- | -------------------------- | +| 400 | `BadRequestError` | +| 401 | `AuthenticationError` | +| 403 | `PermissionDeniedError` | +| 404 | `NotFoundError` | +| 422 | `UnprocessableEntityError` | +| 429 | `RateLimitError` | +| >=500 | `InternalServerError` | +| N/A | `APIConnectionError` | + +### Wiederholungsversuche + +Bestimmte Fehler werden standardmäßig automatisch 2-mal wiederholt, mit einem kurzen exponentiellen Backoff. +Verbindungsfehler (z. B. aufgrund eines Netzwerkverbindungsproblems), 408 Request Timeout, 409 Conflict, +429 Rate Limit und >=500 Internal-Fehler werden standardmäßig alle wiederholt. + +Sie können die Option `max_retries` verwenden, um Wiederholungseinstellungen zu konfigurieren oder zu deaktivieren: + +```python +from perplexity import Perplexity + +# Configure the default for all requests: +client = Perplexity( + # default is 2 + max_retries=0, +) + +# Or, configure per-request: +client.with_options(max_retries=5).chat.completions.create( + messages=[ + { + "role": "user", + "content": "What is the capital of France?", + } + ], + model="sonar", +) +``` + +### Timeouts + +Standardmäßig laufen Anfragen nach 15 Minuten ab. Sie können dies mit der Option `timeout` konfigurieren, +die einen Float oder ein [`httpx.Timeout`](https://www.python-httpx.org/advanced/timeouts/#fine-tuning-the-configuration)-Objekt akzeptiert: + +```python +import httpx +from perplexity import Perplexity + +# Configure the default for all requests: +client = Perplexity( + # 20 seconds (default is 15 minutes) + timeout=20.0, +) + +# More granular control: +client = Perplexity( + 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": "What is the capital of France?", + } + ], + model="sonar", +) +``` + +Bei einem Timeout wird ein `APITimeoutError` ausgelöst. + +Beachten Sie, dass Anfragen, die ablaufen, [standardmäßig zweimal wiederholt werden](#wiederholungsversuche). + +## Erweitert + +### Logging + +Wir verwenden das Modul [`logging`](https://docs.python.org/3/library/logging.html) der Standardbibliothek. + +Sie können Logging aktivieren, indem Sie die Umgebungsvariable `PERPLEXITY_LOG` auf `info` setzen. + +```shell +$ export PERPLEXITY_LOG=info +``` + +Oder auf `debug` für ausführlicheres Logging. + +### Wie man erkennt, ob `None` `null` oder fehlend bedeutet + +In einer API-Antwort kann ein Feld explizit `null` sein oder vollständig fehlen; in beiden Fällen ist sein Wert in dieser Bibliothek `None`. Sie können die beiden Fälle mit `.model_fields_set` unterscheiden: + +```py +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}.') +``` + +### Zugriff auf Rohdaten der Antwort (z. B. Header) + +Auf das „Roh“-Response-Objekt kann zugegriffen werden, indem `.with_raw_response.` jedem HTTP-Methodenaufruf vorangestellt wird, z. B.: + +```py +from perplexity import Perplexity + +client = Perplexity() +response = client.chat.completions.with_raw_response.create( + messages=[{ + "role": "user", + "content": "What is the capital of France?", + }], + model="sonar", +) +print(response.headers.get('X-My-Header')) + +completion = response.parse() # get the object that `chat.completions.create()` would have returned +print(completion.id) +``` + +Diese Methoden geben ein [`APIResponse`](https://github.com/perplexityai/perplexity-py/tree/main/src/perplexity/_response.py)-Objekt zurück. + +Der asynchrone Client gibt ein [`AsyncAPIResponse`](https://github.com/perplexityai/perplexity-py/tree/main/src/perplexity/_response.py) mit derselben Struktur zurück; der einzige Unterschied sind `await`-fähige Methoden zum Lesen des Antwortinhalts. + +#### `.with_streaming_response` + +Die obige Schnittstelle liest den vollständigen Antwortbody beim Senden der Anfrage sofort ein, was nicht immer gewünscht ist. + +Um den Antwortbody zu streamen, verwenden Sie stattdessen `.with_streaming_response`, was einen Kontextmanager erfordert und den Antwortbody erst liest, wenn Sie `.read()`, `.text()`, `.json()`, `.iter_bytes()`, `.iter_text()`, `.iter_lines()` oder `.parse()` aufrufen. Im asynchronen Client sind dies asynchrone Methoden. + +```python +with client.chat.completions.with_streaming_response.create( + messages=[ + { + "role": "user", + "content": "What is the capital of France?", + } + ], + model="sonar", +) as response: + print(response.headers.get("X-My-Header")) + + for line in response.iter_lines(): + print(line) +``` + +Der Kontextmanager ist erforderlich, damit die Antwort zuverlässig geschlossen wird. + +### Benutzerdefinierte/undokumentierte Anfragen + +Diese Bibliothek ist typisiert für bequemen Zugriff auf die dokumentierte API. + +Wenn Sie auf undokumentierte Endpunkte, Parameter oder Antworteigenschaften zugreifen müssen, kann die Bibliothek dennoch verwendet werden. + +#### Undokumentierte Endpunkte + +Um Anfragen an undokumentierte Endpunkte zu senden, können Sie `client.get`, `client.post` und andere +HTTP-Verben verwenden. Client-Optionen werden bei dieser Anfrage berücksichtigt (z. B. Wiederholungsversuche). + +```py +import httpx + +response = client.post( + "/foo", + cast_to=httpx.Response, + body={"my_param": True}, +) + +print(response.headers.get("x-foo")) +``` + +#### Undokumentierte Anfrageparameter + +Wenn Sie explizit einen zusätzlichen Parameter senden möchten, können Sie dies mit den Anfrageoptionen `extra_query`, `extra_body` und `extra_headers` tun. + +#### Undokumentierte Antworteigenschaften + +Um auf undokumentierte Antworteigenschaften zuzugreifen, können Sie auf die zusätzlichen Felder wie `response.unknown_prop` zugreifen. Sie +können auch alle zusätzlichen Felder im Pydantic-Modell als Dictionary mit +[`response.model_extra`](https://docs.pydantic.dev/latest/api/base_model/#pydantic.BaseModel.model_extra) abrufen. + +### Konfiguration des HTTP-Clients + +Sie können den [httpx-Client](https://www.python-httpx.org/api/#client) direkt überschreiben, um ihn für Ihren Anwendungsfall anzupassen, einschließlich: + +- Unterstützung für [Proxies](https://www.python-httpx.org/advanced/proxies/) +- Benutzerdefinierte [Transports](https://www.python-httpx.org/advanced/transports/) +- Zusätzliche [erweiterte](https://www.python-httpx.org/advanced/clients/) Funktionalität + +```python +import httpx +from perplexity import Perplexity, DefaultHttpxClient + +client = Perplexity( + # Or use the `PERPLEXITY_BASE_URL` env var + base_url="http://my.test.server.example.com:8083", + http_client=DefaultHttpxClient( + proxy="http://my.test.proxy.example.com", + transport=httpx.HTTPTransport(local_address="0.0.0.0"), + ), +) +``` + +Sie können den Client auch pro Anfrage mit `with_options()` anpassen: + +```python +client.with_options(http_client=DefaultHttpxClient(...)) +``` + +### Verwaltung von HTTP-Ressourcen + +Standardmäßig schließt die Bibliothek die zugrunde liegenden HTTP-Verbindungen, wenn der Client [vom Garbage Collector freigegeben](https://docs.python.org/3/reference/datamodel.html#object.__del__) wird. Sie können den Client bei Bedarf manuell mit der Methode `.close()` schließen oder mit einem Kontextmanager, der beim Verlassen schließt. + +```py +from perplexity import Perplexity + +with Perplexity() as client: + # make requests here + ... + +# HTTP client is now closed +``` + +## Versionierung + +Dieses Paket folgt im Allgemeinen den [SemVer](https://semver.org/spec/v2.0.0.html)-Konventionen, obwohl bestimmte rückwärtsinkompatible Änderungen als Minor-Versionen veröffentlicht werden können: + +1. Änderungen, die nur statische Typen betreffen, ohne das Laufzeitverhalten zu beeinträchtigen. +2. Änderungen an Bibliotheksinterna, die technisch öffentlich sind, aber nicht für die externe Nutzung vorgesehen oder dokumentiert sind. _(Bitte öffnen Sie ein GitHub-Issue, wenn Sie auf solche Interna angewiesen sind.)_ +3. Änderungen, von denen wir nicht erwarten, dass sie die überwiegende Mehrheit der Benutzer in der Praxis betreffen. + +Wir nehmen Rückwärtskompatibilität ernst und arbeiten daran, Ihnen ein reibungsloses Upgrade-Erlebnis zu bieten. + +Wir freuen uns über Ihr Feedback; bitte öffnen Sie ein [Issue](https://www.github.com/perplexityai/perplexity-py/issues) mit Fragen, Fehlern oder Vorschlägen. + +### Ermittlung der installierten Version + +Wenn Sie auf die neueste Version aktualisiert haben, aber keine neuen Funktionen sehen, die Sie erwartet haben, verwendet Ihre Python-Umgebung wahrscheinlich noch eine ältere Version. + +Sie können die zur Laufzeit verwendete Version wie folgt ermitteln: + +```py +import perplexity +print(perplexity.__version__) +``` + +## Anforderungen + +Python 3.9 oder höher. + +## Mitwirken + +Siehe [die Mitwirkungsdokumentation](./CONTRIBUTING.md). diff --git a/README-ES.md b/README-ES.md new file mode 100644 index 0000000..58cf9c4 --- /dev/null +++ b/README-ES.md @@ -0,0 +1,512 @@ +# Biblioteca Python de la API de Perplexity + +**Idiomas / Languages:** [English](./README.md) · [中文](./README-ZH.md) · [Español](./README-ES.md) · [Français](./README-FR.md) · [Português](./README-PT.md) · [Русский](./README-RU.md) · [Deutsch](./README-DE.md) + + +[![PyPI version](https://img.shields.io/pypi/v/perplexityai.svg?label=pypi%20(stable))](https://pypi.org/project/perplexityai/) + +La biblioteca Python de Perplexity ofrece un acceso cómodo a la API REST de Perplexity desde cualquier aplicación Python 3.9 o superior. La biblioteca incluye definiciones de tipos para todos los parámetros de solicitud y campos de respuesta, y proporciona clientes síncronos y asíncronos basados en [httpx](https://github.com/encode/httpx). + +Está generada con [Stainless](https://www.stainless.com/). + +## Documentación + +La documentación de la API REST está disponible en [docs.perplexity.ai](https://docs.perplexity.ai/). La API completa de esta biblioteca se encuentra en [api.md](api.md). + +## Instalación + +```sh +# install from PyPI +pip install perplexityai +``` + +## API de búsqueda + +Obtenga resultados de búsqueda web: + +```python +import os +from perplexity import Perplexity + +client = Perplexity( + api_key=os.environ.get("PERPLEXITY_API_KEY"), # This is the default and can be omitted +) + +search = client.search.create( + query="latest AI developments 2024", + max_results=5 +) + +for result in search.results: + print(f"{result.title}: {result.url}") +``` + +## Completaciones de chat + +La API completa de esta biblioteca se encuentra en [api.md](api.md). + +```python +import os +from perplexity import Perplexity + +client = Perplexity( + api_key=os.environ.get("PERPLEXITY_API_KEY"), # This is the default and can be omitted +) + +stream_chunk = client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "Tell me about the latest developments in AI", + } + ], + model="sonar", +) +print(stream_chunk.id) +``` + +Aunque puede proporcionar un argumento con nombre `api_key`, +recomendamos usar [python-dotenv](https://pypi.org/project/python-dotenv/) +para añadir `PERPLEXITY_API_KEY="My API Key"` a su archivo `.env` +de modo que su clave de API no quede almacenada en el control de versiones. + +## Uso asíncrono + +Simplemente importe `AsyncPerplexity` en lugar de `Perplexity` y use `await` en cada llamada a la API: + +```python +import os +import asyncio +from perplexity import AsyncPerplexity + +client = AsyncPerplexity( + api_key=os.environ.get("PERPLEXITY_API_KEY"), # This is the default and can be omitted +) + + +async def main() -> None: + stream_chunk = await client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "Tell me about the latest developments in AI", + } + ], + model="sonar", + ) + print(stream_chunk.id) + + +asyncio.run(main()) +``` + +La funcionalidad entre los clientes síncrono y asíncrono es idéntica en lo demás. + +### Con aiohttp + +Por defecto, el cliente asíncrono usa `httpx` para las solicitudes HTTP. Sin embargo, para mejorar el rendimiento de concurrencia también puede usar `aiohttp` como backend HTTP. + +Puede habilitarlo instalando `aiohttp`: + +```sh +# install from PyPI +pip install perplexityai[aiohttp] +``` + +A continuación puede habilitarlo instanciando el cliente con `http_client=DefaultAioHttpClient()`: + +```python +import os +import asyncio +from perplexity import DefaultAioHttpClient +from perplexity import AsyncPerplexity + + +async def main() -> None: + async with AsyncPerplexity( + api_key=os.environ.get("PERPLEXITY_API_KEY"), # This is the default and can be omitted + http_client=DefaultAioHttpClient(), + ) as client: + stream_chunk = await client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "Tell me about the latest developments in AI", + } + ], + model="sonar", + ) + print(stream_chunk.id) + + +asyncio.run(main()) +``` + +## Respuestas en streaming + +Ofrecemos soporte para respuestas en streaming mediante Server Side Events (SSE). + +```python +from perplexity import Perplexity + +client = Perplexity() + +stream = client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "Tell me about the latest developments in AI", + } + ], + model="sonar", + stream=True, +) +for stream_chunk in stream: + print(stream_chunk.id) +``` + +El cliente asíncrono usa exactamente la misma interfaz. + +```python +from perplexity import AsyncPerplexity + +client = AsyncPerplexity() + +stream = await client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "Tell me about the latest developments in AI", + } + ], + model="sonar", + stream=True, +) +async for stream_chunk in stream: + print(stream_chunk.id) +``` + +## Uso de tipos + +Los parámetros de solicitud anidados son [TypedDicts](https://docs.python.org/3/library/typing.html#typing.TypedDict). Las respuestas son [modelos Pydantic](https://docs.pydantic.dev) que también ofrecen métodos auxiliares para cosas como: + +- Serializar de nuevo a JSON, `model.to_json()` +- Convertir a un diccionario, `model.to_dict()` + +Las solicitudes y respuestas tipadas proporcionan autocompletado y documentación dentro de su editor. Si desea ver errores de tipo en VS Code para detectar errores antes, configure `python.analysis.typeCheckingMode` en `basic`. + +## Parámetros anidados + +Los parámetros anidados son diccionarios, tipados con `TypedDict`, por ejemplo: + +```python +from perplexity import Perplexity + +client = Perplexity() + +stream_chunk = client.chat.completions.create( + messages=[ + { + "content": "string", + "role": "system", + } + ], + model="model", + web_search_options={}, +) +print(stream_chunk.choices) +``` + +## Manejo de errores + +Cuando la biblioteca no puede conectarse a la API (por ejemplo, debido a problemas de conexión de red o un tiempo de espera agotado), se lanza una subclase de `perplexity.APIConnectionError`. + +Cuando la API devuelve un código de estado distinto de éxito (es decir, respuesta 4xx o 5xx), se lanza una subclase de `perplexity.APIStatusError`, que contiene las propiedades `status_code` y `response`. + +Todos los errores heredan de `perplexity.APIError`. + +```python +import perplexity +from perplexity import Perplexity + +client = Perplexity() + +try: + client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "What is the capital of France?", + } + ], + model="sonar", + ) +except perplexity.APIConnectionError as e: + print("The server could not be reached") + print(e.__cause__) # an underlying Exception, likely raised within httpx. +except perplexity.RateLimitError as e: + print("A 429 status code was received; we should back off a bit.") +except perplexity.APIStatusError as e: + print("Another non-200-range status code was received") + print(e.status_code) + print(e.response) +``` + +Los códigos de error son los siguientes: + +| Status Code | Error Type | +| ----------- | -------------------------- | +| 400 | `BadRequestError` | +| 401 | `AuthenticationError` | +| 403 | `PermissionDeniedError` | +| 404 | `NotFoundError` | +| 422 | `UnprocessableEntityError` | +| 429 | `RateLimitError` | +| >=500 | `InternalServerError` | +| N/A | `APIConnectionError` | + +### Reintentos + +Ciertos errores se reintentan automáticamente 2 veces por defecto, con un breve retroceso exponencial. +Los errores de conexión (por ejemplo, debido a un problema de conectividad de red), 408 Request Timeout, 409 Conflict, +429 Rate Limit y errores internos >=500 se reintentan por defecto. + +Puede usar la opción `max_retries` para configurar o deshabilitar los ajustes de reintento: + +```python +from perplexity import Perplexity + +# Configure the default for all requests: +client = Perplexity( + # default is 2 + max_retries=0, +) + +# Or, configure per-request: +client.with_options(max_retries=5).chat.completions.create( + messages=[ + { + "role": "user", + "content": "What is the capital of France?", + } + ], + model="sonar", +) +``` + +### Tiempos de espera + +Por defecto, las solicitudes agotan el tiempo de espera tras 15 minutos. Puede configurarlo con la opción `timeout`, +que acepta un float o un objeto [`httpx.Timeout`](https://www.python-httpx.org/advanced/timeouts/#fine-tuning-the-configuration): + +```python +import httpx +from perplexity import Perplexity + +# Configure the default for all requests: +client = Perplexity( + # 20 seconds (default is 15 minutes) + timeout=20.0, +) + +# More granular control: +client = Perplexity( + 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": "What is the capital of France?", + } + ], + model="sonar", +) +``` + +Al agotarse el tiempo de espera, se lanza un `APITimeoutError`. + +Tenga en cuenta que las solicitudes que agotan el tiempo de espera se [reintentan dos veces por defecto](#reintentos). + +## Avanzado + +### Registro + +Usamos el módulo estándar [`logging`](https://docs.python.org/3/library/logging.html). + +Puede habilitar el registro estableciendo la variable de entorno `PERPLEXITY_LOG` en `info`. + +```shell +$ export PERPLEXITY_LOG=info +``` + +O en `debug` para un registro más detallado. + +### Cómo saber si `None` significa `null` o ausente + +En una respuesta de la API, un campo puede ser explícitamente `null` o estar completamente ausente; en cualquiera de los dos casos, su valor es `None` en esta biblioteca. Puede diferenciar ambos casos con `.model_fields_set`: + +```py +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}.') +``` + +### Acceso a datos de respuesta sin procesar (p. ej. cabeceras) + +Se puede acceder al objeto Response "sin procesar" anteponiendo `.with_raw_response.` a cualquier llamada a un método HTTP, p. ej., + +```py +from perplexity import Perplexity + +client = Perplexity() +response = client.chat.completions.with_raw_response.create( + messages=[{ + "role": "user", + "content": "What is the capital of France?", + }], + model="sonar", +) +print(response.headers.get('X-My-Header')) + +completion = response.parse() # get the object that `chat.completions.create()` would have returned +print(completion.id) +``` + +Estos métodos devuelven un objeto [`APIResponse`](https://github.com/perplexityai/perplexity-py/tree/main/src/perplexity/_response.py). + +El cliente asíncrono devuelve un [`AsyncAPIResponse`](https://github.com/perplexityai/perplexity-py/tree/main/src/perplexity/_response.py) con la misma estructura; la única diferencia son métodos que admiten `await` para leer el contenido de la respuesta. + +#### `.with_streaming_response` + +La interfaz anterior lee de forma anticipada el cuerpo completo de la respuesta cuando realiza la solicitud, lo cual puede no ser siempre lo que desea. + +Para transmitir el cuerpo de la respuesta en streaming, use `.with_streaming_response` en su lugar, lo cual requiere un administrador de contexto y solo lee el cuerpo de la respuesta cuando llama a `.read()`, `.text()`, `.json()`, `.iter_bytes()`, `.iter_text()`, `.iter_lines()` o `.parse()`. En el cliente asíncrono, estos son métodos async. + +```python +with client.chat.completions.with_streaming_response.create( + messages=[ + { + "role": "user", + "content": "What is the capital of France?", + } + ], + model="sonar", +) as response: + print(response.headers.get("X-My-Header")) + + for line in response.iter_lines(): + print(line) +``` + +El administrador de contexto es necesario para que la respuesta se cierre de forma fiable. + +### Realizar solicitudes personalizadas o no documentadas + +Esta biblioteca está tipada para un acceso cómodo a la API documentada. + +Si necesita acceder a endpoints, parámetros o propiedades de respuesta no documentados, la biblioteca sigue siendo utilizable. + +#### Endpoints no documentados + +Para realizar solicitudes a endpoints no documentados, puede usar `client.get`, `client.post` y otros +verbos HTTP. Las opciones del cliente se respetarán (como los reintentos) al hacer esta solicitud. + +```py +import httpx + +response = client.post( + "/foo", + cast_to=httpx.Response, + body={"my_param": True}, +) + +print(response.headers.get("x-foo")) +``` + +#### Parámetros de solicitud no documentados + +Si desea enviar explícitamente un parámetro adicional, puede hacerlo con las opciones de solicitud `extra_query`, `extra_body` y `extra_headers`. + +#### Propiedades de respuesta no documentadas + +Para acceder a propiedades de respuesta no documentadas, puede acceder a los campos adicionales como `response.unknown_prop`. También +puede obtener todos los campos adicionales del modelo Pydantic como un diccionario con +[`response.model_extra`](https://docs.pydantic.dev/latest/api/base_model/#pydantic.BaseModel.model_extra). + +### Configuración del cliente HTTP + +Puede sobrescribir directamente el [cliente httpx](https://www.python-httpx.org/api/#client) para personalizarlo según su caso de uso, incluyendo: + +- Soporte para [proxies](https://www.python-httpx.org/advanced/proxies/) +- [Transportes](https://www.python-httpx.org/advanced/transports/) personalizados +- Funcionalidad [avanzada](https://www.python-httpx.org/advanced/clients/) adicional + +```python +import httpx +from perplexity import Perplexity, DefaultHttpxClient + +client = Perplexity( + # Or use the `PERPLEXITY_BASE_URL` env var + base_url="http://my.test.server.example.com:8083", + http_client=DefaultHttpxClient( + proxy="http://my.test.proxy.example.com", + transport=httpx.HTTPTransport(local_address="0.0.0.0"), + ), +) +``` + +También puede personalizar el cliente por solicitud usando `with_options()`: + +```python +client.with_options(http_client=DefaultHttpxClient(...)) +``` + +### Gestión de recursos HTTP + +Por defecto, la biblioteca cierra las conexiones HTTP subyacentes cuando el cliente es [recogido por el recolector de basura](https://docs.python.org/3/reference/datamodel.html#object.__del__). Puede cerrar manualmente el cliente con el método `.close()` si lo desea, o con un administrador de contexto que cierra al salir. + +```py +from perplexity import Perplexity + +with Perplexity() as client: + # make requests here + ... + +# HTTP client is now closed +``` + +## Versionado + +Este paquete sigue en general las convenciones de [SemVer](https://semver.org/spec/v2.0.0.html), aunque ciertos cambios incompatibles con versiones anteriores pueden publicarse como versiones menores: + +1. Cambios que solo afectan a tipos estáticos, sin romper el comportamiento en tiempo de ejecución. +2. Cambios en los internos de la biblioteca que son técnicamente públicos pero no están destinados ni documentados para uso externo. _(Abra un issue en GitHub para informarnos si depende de dichos internos.)_ +3. Cambios que no esperamos que afecten en la práctica a la gran mayoría de usuarios. + +Nos tomamos en serio la compatibilidad hacia atrás y trabajamos para que pueda confiar en una experiencia de actualización fluida. + +Valoramos sus comentarios; abra un [issue](https://www.github.com/perplexityai/perplexity-py/issues) con preguntas, errores o sugerencias. + +### Determinar la versión instalada + +Si ha actualizado a la última versión pero no ve las funciones nuevas que esperaba, es probable que su entorno de Python siga usando una versión anterior. + +Puede determinar la versión que se usa en tiempo de ejecución con: + +```py +import perplexity +print(perplexity.__version__) +``` + +## Requisitos + +Python 3.9 o superior. + +## Contribuir + +Consulte [la documentación de contribución](./CONTRIBUTING.md). diff --git a/README-FR.md b/README-FR.md new file mode 100644 index 0000000..c7c9121 --- /dev/null +++ b/README-FR.md @@ -0,0 +1,514 @@ +# Bibliothèque Python de l'API Perplexity + +**Langues / Languages:** [English](./README.md) · [中文](./README-ZH.md) · [Español](./README-ES.md) · [Français](./README-FR.md) · [Português](./README-PT.md) · [Русский](./README-RU.md) · [Deutsch](./README-DE.md) + + +[![PyPI version](https://img.shields.io/pypi/v/perplexityai.svg?label=pypi%20(stable))](https://pypi.org/project/perplexityai/) + +La bibliothèque Python Perplexity offre un accès pratique à l'API REST Perplexity depuis toute application Python 3.9 ou supérieure. La bibliothèque inclut des définitions de types pour tous les paramètres de requête et les champs de réponse, +et propose des clients synchrones et asynchrones basés sur [httpx](https://github.com/encode/httpx). + +Elle est générée avec [Stainless](https://www.stainless.com/). + +## Documentation + +La documentation de l'API REST se trouve sur [docs.perplexity.ai](https://docs.perplexity.ai/). L'API complète de cette bibliothèque est décrite dans [api.md](api.md). + +## Installation + +```sh +# install from PyPI +pip install perplexityai +``` + +## API de recherche + +Obtenir des résultats de recherche web : + +```python +import os +from perplexity import Perplexity + +client = Perplexity( + api_key=os.environ.get("PERPLEXITY_API_KEY"), # This is the default and can be omitted +) + +search = client.search.create( + query="latest AI developments 2024", + max_results=5 +) + +for result in search.results: + print(f"{result.title}: {result.url}") +``` + +## Complétions de chat + +L'API complète de cette bibliothèque est décrite dans [api.md](api.md). + +```python +import os +from perplexity import Perplexity + +client = Perplexity( + api_key=os.environ.get("PERPLEXITY_API_KEY"), # This is the default and can be omitted +) + +stream_chunk = client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "Tell me about the latest developments in AI", + } + ], + model="sonar", +) +print(stream_chunk.id) +``` + +Bien que vous puissiez fournir un argument nommé `api_key`, +nous recommandons d'utiliser [python-dotenv](https://pypi.org/project/python-dotenv/) +pour ajouter `PERPLEXITY_API_KEY="My API Key"` à votre fichier `.env` +afin que votre clé API ne soit pas stockée dans le contrôle de version. + +## Utilisation asynchrone + +Importez simplement `AsyncPerplexity` au lieu de `Perplexity` et utilisez `await` avec chaque appel API : + +```python +import os +import asyncio +from perplexity import AsyncPerplexity + +client = AsyncPerplexity( + api_key=os.environ.get("PERPLEXITY_API_KEY"), # This is the default and can be omitted +) + + +async def main() -> None: + stream_chunk = await client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "Tell me about the latest developments in AI", + } + ], + model="sonar", + ) + print(stream_chunk.id) + + +asyncio.run(main()) +``` + +Les fonctionnalités des clients synchrones et asynchrones sont par ailleurs identiques. + +### Avec aiohttp + +Par défaut, le client asynchrone utilise `httpx` pour les requêtes HTTP. Cependant, pour de meilleures performances de concurrence, vous pouvez également utiliser `aiohttp` comme backend HTTP. + +Vous pouvez l'activer en installant `aiohttp` : + +```sh +# install from PyPI +pip install perplexityai[aiohttp] +``` + +Puis activez-le en instanciant le client avec `http_client=DefaultAioHttpClient()` : + +```python +import os +import asyncio +from perplexity import DefaultAioHttpClient +from perplexity import AsyncPerplexity + + +async def main() -> None: + async with AsyncPerplexity( + api_key=os.environ.get("PERPLEXITY_API_KEY"), # This is the default and can be omitted + http_client=DefaultAioHttpClient(), + ) as client: + stream_chunk = await client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "Tell me about the latest developments in AI", + } + ], + model="sonar", + ) + print(stream_chunk.id) + + +asyncio.run(main()) +``` + +## Réponses en streaming + +Nous prenons en charge les réponses en streaming via Server Side Events (SSE). + +```python +from perplexity import Perplexity + +client = Perplexity() + +stream = client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "Tell me about the latest developments in AI", + } + ], + model="sonar", + stream=True, +) +for stream_chunk in stream: + print(stream_chunk.id) +``` + +Le client asynchrone utilise exactement la même interface. + +```python +from perplexity import AsyncPerplexity + +client = AsyncPerplexity() + +stream = await client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "Tell me about the latest developments in AI", + } + ], + model="sonar", + stream=True, +) +async for stream_chunk in stream: + print(stream_chunk.id) +``` + +## Utilisation des types + +Les paramètres de requête imbriqués sont des [TypedDicts](https://docs.python.org/3/library/typing.html#typing.TypedDict). Les réponses sont des [modèles Pydantic](https://docs.pydantic.dev) qui fournissent également des méthodes utilitaires pour : + +- Sérialiser en JSON, `model.to_json()` +- Convertir en dictionnaire, `model.to_dict()` + +Les requêtes et réponses typées offrent l'autocomplétion et la documentation dans votre éditeur. Si vous souhaitez voir les erreurs de type dans VS Code pour détecter les bugs plus tôt, définissez `python.analysis.typeCheckingMode` sur `basic`. + +## Paramètres imbriqués + +Les paramètres imbriqués sont des dictionnaires, typés avec `TypedDict`, par exemple : + +```python +from perplexity import Perplexity + +client = Perplexity() + +stream_chunk = client.chat.completions.create( + messages=[ + { + "content": "string", + "role": "system", + } + ], + model="model", + web_search_options={}, +) +print(stream_chunk.choices) +``` + +## Gestion des erreurs + +Lorsque la bibliothèque ne parvient pas à se connecter à l'API (par exemple, en raison de problèmes de connexion réseau ou d'un délai d'attente dépassé), une sous-classe de `perplexity.APIConnectionError` est levée. + +Lorsque l'API renvoie un code d'état autre que le succès (c'est-à-dire une réponse 4xx ou 5xx), +une sous-classe de `perplexity.APIStatusError` est levée, contenant les propriétés `status_code` et `response`. + +Toutes les erreurs héritent de `perplexity.APIError`. + +```python +import perplexity +from perplexity import Perplexity + +client = Perplexity() + +try: + client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "What is the capital of France?", + } + ], + model="sonar", + ) +except perplexity.APIConnectionError as e: + print("The server could not be reached") + print(e.__cause__) # an underlying Exception, likely raised within httpx. +except perplexity.RateLimitError as e: + print("A 429 status code was received; we should back off a bit.") +except perplexity.APIStatusError as e: + print("Another non-200-range status code was received") + print(e.status_code) + print(e.response) +``` + +Les codes d'erreur sont les suivants : + +| Status Code | Error Type | +| ----------- | -------------------------- | +| 400 | `BadRequestError` | +| 401 | `AuthenticationError` | +| 403 | `PermissionDeniedError` | +| 404 | `NotFoundError` | +| 422 | `UnprocessableEntityError` | +| 429 | `RateLimitError` | +| >=500 | `InternalServerError` | +| N/A | `APIConnectionError` | + +### Nouvelles tentatives + +Certaines erreurs sont automatiquement réessayées 2 fois par défaut, avec un court backoff exponentiel. +Les erreurs de connexion (par exemple, dues à un problème de connectivité réseau), le délai d'attente 408 Request Timeout, le conflit 409 Conflict, +la limite de débit 429 Rate Limit et les erreurs internes >=500 sont toutes réessayées par défaut. + +Vous pouvez utiliser l'option `max_retries` pour configurer ou désactiver les paramètres de nouvelle tentative : + +```python +from perplexity import Perplexity + +# Configure the default for all requests: +client = Perplexity( + # default is 2 + max_retries=0, +) + +# Or, configure per-request: +client.with_options(max_retries=5).chat.completions.create( + messages=[ + { + "role": "user", + "content": "What is the capital of France?", + } + ], + model="sonar", +) +``` + +### Délais d'attente + +Par défaut, les requêtes expirent après 15 minutes. Vous pouvez configurer cela avec l'option `timeout`, +qui accepte un float ou un objet [`httpx.Timeout`](https://www.python-httpx.org/advanced/timeouts/#fine-tuning-the-configuration) : + +```python +import httpx +from perplexity import Perplexity + +# Configure the default for all requests: +client = Perplexity( + # 20 seconds (default is 15 minutes) + timeout=20.0, +) + +# More granular control: +client = Perplexity( + 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": "What is the capital of France?", + } + ], + model="sonar", +) +``` + +En cas de dépassement du délai, une `APITimeoutError` est levée. + +Notez que les requêtes qui expirent sont [réessayées deux fois par défaut](#nouvelles-tentatives). + +## Avancé + +### Journalisation + +Nous utilisons le module standard [`logging`](https://docs.python.org/3/library/logging.html). + +Vous pouvez activer la journalisation en définissant la variable d'environnement `PERPLEXITY_LOG` sur `info`. + +```shell +$ export PERPLEXITY_LOG=info +``` + +Ou sur `debug` pour une journalisation plus verbeuse. + +### Comment savoir si `None` signifie `null` ou absent + +Dans une réponse API, un champ peut être explicitement `null`, ou totalement absent ; dans les deux cas, sa valeur est `None` dans cette bibliothèque. Vous pouvez distinguer les deux cas avec `.model_fields_set` : + +```py +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}.') +``` + +### Accès aux données brutes de la réponse (p. ex. en-têtes) + +L'objet Response « brut » est accessible en préfixant `.with_raw_response.` à tout appel de méthode HTTP, par exemple : + +```py +from perplexity import Perplexity + +client = Perplexity() +response = client.chat.completions.with_raw_response.create( + messages=[{ + "role": "user", + "content": "What is the capital of France?", + }], + model="sonar", +) +print(response.headers.get('X-My-Header')) + +completion = response.parse() # get the object that `chat.completions.create()` would have returned +print(completion.id) +``` + +Ces méthodes renvoient un objet [`APIResponse`](https://github.com/perplexityai/perplexity-py/tree/main/src/perplexity/_response.py). + +Le client asynchrone renvoie un [`AsyncAPIResponse`](https://github.com/perplexityai/perplexity-py/tree/main/src/perplexity/_response.py) avec la même structure, la seule différence étant des méthodes `await` pour lire le contenu de la réponse. + +#### `.with_streaming_response` + +L'interface ci-dessus lit intégralement le corps de la réponse lors de la requête, ce qui n'est pas toujours souhaitable. + +Pour streamer le corps de la réponse, utilisez plutôt `.with_streaming_response`, qui nécessite un gestionnaire de contexte et ne lit le corps de la réponse qu'une fois que vous appelez `.read()`, `.text()`, `.json()`, `.iter_bytes()`, `.iter_text()`, `.iter_lines()` ou `.parse()`. Dans le client asynchrone, ce sont des méthodes async. + +```python +with client.chat.completions.with_streaming_response.create( + messages=[ + { + "role": "user", + "content": "What is the capital of France?", + } + ], + model="sonar", +) as response: + print(response.headers.get("X-My-Header")) + + for line in response.iter_lines(): + print(line) +``` + +Le gestionnaire de contexte est requis pour que la réponse soit fermée de manière fiable. + +### Requêtes personnalisées ou non documentées + +Cette bibliothèque est typée pour un accès pratique à l'API documentée. + +Si vous devez accéder à des points de terminaison, paramètres ou propriétés de réponse non documentés, la bibliothèque reste utilisable. + +#### Points de terminaison non documentés + +Pour faire des requêtes vers des points de terminaison non documentés, vous pouvez utiliser `client.get`, `client.post` et d'autres +verbes HTTP. Les options du client seront respectées (comme les nouvelles tentatives) lors de cette requête. + +```py +import httpx + +response = client.post( + "/foo", + cast_to=httpx.Response, + body={"my_param": True}, +) + +print(response.headers.get("x-foo")) +``` + +#### Paramètres de requête non documentés + +Si vous souhaitez envoyer explicitement un paramètre supplémentaire, vous pouvez le faire avec les options de requête `extra_query`, `extra_body` et `extra_headers`. + +#### Propriétés de réponse non documentées + +Pour accéder aux propriétés de réponse non documentées, vous pouvez accéder aux champs supplémentaires comme `response.unknown_prop`. Vous +pouvez également obtenir tous les champs supplémentaires du modèle Pydantic sous forme de dictionnaire avec +[`response.model_extra`](https://docs.pydantic.dev/latest/api/base_model/#pydantic.BaseModel.model_extra). + +### Configuration du client HTTP + +Vous pouvez directement remplacer le [client httpx](https://www.python-httpx.org/api/#client) pour l'adapter à votre cas d'usage, notamment : + +- Prise en charge des [proxies](https://www.python-httpx.org/advanced/proxies/) +- [Transports](https://www.python-httpx.org/advanced/transports/) personnalisés +- Fonctionnalités [avancées](https://www.python-httpx.org/advanced/clients/) supplémentaires + +```python +import httpx +from perplexity import Perplexity, DefaultHttpxClient + +client = Perplexity( + # Or use the `PERPLEXITY_BASE_URL` env var + base_url="http://my.test.server.example.com:8083", + http_client=DefaultHttpxClient( + proxy="http://my.test.proxy.example.com", + transport=httpx.HTTPTransport(local_address="0.0.0.0"), + ), +) +``` + +Vous pouvez également personnaliser le client par requête avec `with_options()` : + +```python +client.with_options(http_client=DefaultHttpxClient(...)) +``` + +### Gestion des ressources HTTP + +Par défaut, la bibliothèque ferme les connexions HTTP sous-jacentes lorsque le client est [collecté par le ramasse-miettes](https://docs.python.org/3/reference/datamodel.html#object.__del__). Vous pouvez fermer manuellement le client avec la méthode `.close()` si vous le souhaitez, ou avec un gestionnaire de contexte qui ferme à la sortie. + +```py +from perplexity import Perplexity + +with Perplexity() as client: + # make requests here + ... + +# HTTP client is now closed +``` + +## Versionnement + +Ce package suit généralement les conventions [SemVer](https://semver.org/spec/v2.0.0.html), bien que certains changements rétro-incompatibles puissent être publiés en versions mineures : + +1. Changements qui n'affectent que les types statiques, sans casser le comportement à l'exécution. +2. Changements aux internes de la bibliothèque qui sont techniquement publics mais non destinés ni documentés pour un usage externe. _(Veuillez ouvrir une issue GitHub pour nous indiquer si vous vous appuyez sur ces internes.)_ +3. Changements que nous n'attendons pas impacter la grande majorité des utilisateurs en pratique. + +Nous prenons la rétrocompatibilité au sérieux et travaillons dur pour que vous puissiez compter sur une mise à niveau fluide. + +Vos retours nous intéressent ; ouvrez une [issue](https://www.github.com/perplexityai/perplexity-py/issues) pour des questions, des bugs ou des suggestions. + +### Déterminer la version installée + +Si vous avez mis à jour vers la dernière version mais ne voyez pas les nouvelles fonctionnalités attendues, votre environnement Python utilise probablement encore une version plus ancienne. + +Vous pouvez déterminer la version utilisée à l'exécution avec : + +```py +import perplexity +print(perplexity.__version__) +``` + +## Prérequis + +Python 3.9 ou supérieur. + +## Contribution + +Voir [la documentation de contribution](./CONTRIBUTING.md). diff --git a/README-PT.md b/README-PT.md new file mode 100644 index 0000000..74efb85 --- /dev/null +++ b/README-PT.md @@ -0,0 +1,512 @@ +# Biblioteca Python da API Perplexity + +**Idiomas / Languages:** [English](./README.md) · [中文](./README-ZH.md) · [Español](./README-ES.md) · [Français](./README-FR.md) · [Português](./README-PT.md) · [Русский](./README-RU.md) · [Deutsch](./README-DE.md) + + +[![PyPI version](https://img.shields.io/pypi/v/perplexityai.svg?label=pypi%20(stable))](https://pypi.org/project/perplexityai/) + +A biblioteca Python Perplexity oferece acesso conveniente à API REST Perplexity a partir de qualquer aplicação Python 3.9+. A biblioteca inclui definições de tipos para todos os parâmetros de solicitação e campos de resposta, e oferece clientes síncronos e assíncronos com tecnologia [httpx](https://github.com/encode/httpx). + +Ela é gerada com [Stainless](https://www.stainless.com/). + +## Documentação + +A documentação da API REST pode ser encontrada em [docs.perplexity.ai](https://docs.perplexity.ai/). A API completa desta biblioteca pode ser encontrada em [api.md](api.md). + +## Instalação + +```sh +# install from PyPI +pip install perplexityai +``` + +## Search API + +Obtenha resultados de pesquisa na web: + +```python +import os +from perplexity import Perplexity + +client = Perplexity( + api_key=os.environ.get("PERPLEXITY_API_KEY"), # This is the default and can be omitted +) + +search = client.search.create( + query="latest AI developments 2024", + max_results=5 +) + +for result in search.results: + print(f"{result.title}: {result.url}") +``` + +## Chat Completions + +A API completa desta biblioteca pode ser encontrada em [api.md](api.md). + +```python +import os +from perplexity import Perplexity + +client = Perplexity( + api_key=os.environ.get("PERPLEXITY_API_KEY"), # This is the default and can be omitted +) + +stream_chunk = client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "Tell me about the latest developments in AI", + } + ], + model="sonar", +) +print(stream_chunk.id) +``` + +Embora você possa fornecer um argumento de palavra-chave `api_key`, +recomendamos usar [python-dotenv](https://pypi.org/project/python-dotenv/) +para adicionar `PERPLEXITY_API_KEY="My API Key"` ao seu arquivo `.env`, +de modo que sua chave de API não fique armazenada no controle de versão. + +## Uso assíncrono + +Basta importar `AsyncPerplexity` em vez de `Perplexity` e usar `await` em cada chamada à API: + +```python +import os +import asyncio +from perplexity import AsyncPerplexity + +client = AsyncPerplexity( + api_key=os.environ.get("PERPLEXITY_API_KEY"), # This is the default and can be omitted +) + + +async def main() -> None: + stream_chunk = await client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "Tell me about the latest developments in AI", + } + ], + model="sonar", + ) + print(stream_chunk.id) + + +asyncio.run(main()) +``` + +A funcionalidade entre os clientes síncronos e assíncronos é, de resto, idêntica. + +### Com aiohttp + +Por padrão, o cliente assíncrono usa `httpx` para solicitações HTTP. No entanto, para melhor desempenho de concorrência, você também pode usar `aiohttp` como backend HTTP. + +Você pode habilitar isso instalando `aiohttp`: + +```sh +# install from PyPI +pip install perplexityai[aiohttp] +``` + +Em seguida, você pode habilitá-lo instanciando o cliente com `http_client=DefaultAioHttpClient()`: + +```python +import os +import asyncio +from perplexity import DefaultAioHttpClient +from perplexity import AsyncPerplexity + + +async def main() -> None: + async with AsyncPerplexity( + api_key=os.environ.get("PERPLEXITY_API_KEY"), # This is the default and can be omitted + http_client=DefaultAioHttpClient(), + ) as client: + stream_chunk = await client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "Tell me about the latest developments in AI", + } + ], + model="sonar", + ) + print(stream_chunk.id) + + +asyncio.run(main()) +``` + +## Respostas em streaming + +Oferecemos suporte a respostas em streaming usando Server Side Events (SSE). + +```python +from perplexity import Perplexity + +client = Perplexity() + +stream = client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "Tell me about the latest developments in AI", + } + ], + model="sonar", + stream=True, +) +for stream_chunk in stream: + print(stream_chunk.id) +``` + +O cliente assíncrono usa exatamente a mesma interface. + +```python +from perplexity import AsyncPerplexity + +client = AsyncPerplexity() + +stream = await client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "Tell me about the latest developments in AI", + } + ], + model="sonar", + stream=True, +) +async for stream_chunk in stream: + print(stream_chunk.id) +``` + +## Uso de tipos + +Parâmetros de solicitação aninhados são [TypedDicts](https://docs.python.org/3/library/typing.html#typing.TypedDict). As respostas são [modelos Pydantic](https://docs.pydantic.dev), que também fornecem métodos auxiliares para coisas como: + +- Serializar de volta para JSON, `model.to_json()` +- Converter para um dicionário, `model.to_dict()` + +Solicitações e respostas tipadas fornecem autocompletar e documentação no seu editor. Se quiser ver erros de tipo no VS Code para ajudar a detectar bugs mais cedo, defina `python.analysis.typeCheckingMode` como `basic`. + +## Parâmetros aninhados + +Parâmetros aninhados são dicionários, tipados com `TypedDict`, por exemplo: + +```python +from perplexity import Perplexity + +client = Perplexity() + +stream_chunk = client.chat.completions.create( + messages=[ + { + "content": "string", + "role": "system", + } + ], + model="model", + web_search_options={}, +) +print(stream_chunk.choices) +``` + +## Tratamento de erros + +Quando a biblioteca não consegue se conectar à API (por exemplo, devido a problemas de conexão de rede ou timeout), uma subclasse de `perplexity.APIConnectionError` é lançada. + +Quando a API retorna um código de status de falha (ou seja, resposta 4xx ou 5xx), uma subclasse de `perplexity.APIStatusError` é lançada, contendo as propriedades `status_code` e `response`. + +Todos os erros herdam de `perplexity.APIError`. + +```python +import perplexity +from perplexity import Perplexity + +client = Perplexity() + +try: + client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "What is the capital of France?", + } + ], + model="sonar", + ) +except perplexity.APIConnectionError as e: + print("The server could not be reached") + print(e.__cause__) # an underlying Exception, likely raised within httpx. +except perplexity.RateLimitError as e: + print("A 429 status code was received; we should back off a bit.") +except perplexity.APIStatusError as e: + print("Another non-200-range status code was received") + print(e.status_code) + print(e.response) +``` + +Os códigos de erro são os seguintes: + +| Status Code | Error Type | +| ----------- | -------------------------- | +| 400 | `BadRequestError` | +| 401 | `AuthenticationError` | +| 403 | `PermissionDeniedError` | +| 404 | `NotFoundError` | +| 422 | `UnprocessableEntityError` | +| 429 | `RateLimitError` | +| >=500 | `InternalServerError` | +| N/A | `APIConnectionError` | + +### Tentativas novamente + +Certos erros são automaticamente repetidos 2 vezes por padrão, com um backoff exponencial curto. +Erros de conexão (por exemplo, devido a um problema de conectividade de rede), 408 Request Timeout, 409 Conflict, +429 Rate Limit e erros internos >=500 são todos repetidos por padrão. + +Você pode usar a opção `max_retries` para configurar ou desabilitar as configurações de repetição: + +```python +from perplexity import Perplexity + +# Configure the default for all requests: +client = Perplexity( + # default is 2 + max_retries=0, +) + +# Or, configure per-request: +client.with_options(max_retries=5).chat.completions.create( + messages=[ + { + "role": "user", + "content": "What is the capital of France?", + } + ], + model="sonar", +) +``` + +### Timeouts + +Por padrão, as solicitações expiram após 15 minutos. Você pode configurar isso com a opção `timeout`, +que aceita um float ou um objeto [`httpx.Timeout`](https://www.python-httpx.org/advanced/timeouts/#fine-tuning-the-configuration): + +```python +import httpx +from perplexity import Perplexity + +# Configure the default for all requests: +client = Perplexity( + # 20 seconds (default is 15 minutes) + timeout=20.0, +) + +# More granular control: +client = Perplexity( + 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": "What is the capital of France?", + } + ], + model="sonar", +) +``` + +Em caso de timeout, um `APITimeoutError` é lançado. + +Observe que solicitações que expiram são [repetidas duas vezes por padrão](#tentativas-novamente). + +## Avançado + +### Logging + +Usamos o módulo [`logging`](https://docs.python.org/3/library/logging.html) da biblioteca padrão. + +Você pode habilitar o logging definindo a variável de ambiente `PERPLEXITY_LOG` como `info`. + +```shell +$ export PERPLEXITY_LOG=info +``` + +Ou como `debug` para logging mais detalhado. + +### Como saber se `None` significa `null` ou ausente + +Em uma resposta da API, um campo pode ser explicitamente `null` ou estar totalmente ausente; em ambos os casos, seu valor é `None` nesta biblioteca. Você pode diferenciar os dois casos com `.model_fields_set`: + +```py +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}.') +``` + +### Acessando dados brutos da resposta (por exemplo, cabeçalhos) + +O objeto Response "bruto" pode ser acessado prefixando `.with_raw_response.` a qualquer chamada de método HTTP, por exemplo, + +```py +from perplexity import Perplexity + +client = Perplexity() +response = client.chat.completions.with_raw_response.create( + messages=[{ + "role": "user", + "content": "What is the capital of France?", + }], + model="sonar", +) +print(response.headers.get('X-My-Header')) + +completion = response.parse() # get the object that `chat.completions.create()` would have returned +print(completion.id) +``` + +Esses métodos retornam um objeto [`APIResponse`](https://github.com/perplexityai/perplexity-py/tree/main/src/perplexity/_response.py). + +O cliente assíncrono retorna um [`AsyncAPIResponse`](https://github.com/perplexityai/perplexity-py/tree/main/src/perplexity/_response.py) com a mesma estrutura; a única diferença são métodos com `await` para ler o conteúdo da resposta. + +#### `.with_streaming_response` + +A interface acima lê avidamente o corpo completo da resposta quando você faz a solicitação, o que nem sempre é o desejado. + +Para fazer streaming do corpo da resposta, use `.with_streaming_response` em vez disso, o que requer um gerenciador de contexto e só lê o corpo da resposta quando você chama `.read()`, `.text()`, `.json()`, `.iter_bytes()`, `.iter_text()`, `.iter_lines()` ou `.parse()`. No cliente assíncrono, estes são métodos assíncronos. + +```python +with client.chat.completions.with_streaming_response.create( + messages=[ + { + "role": "user", + "content": "What is the capital of France?", + } + ], + model="sonar", +) as response: + print(response.headers.get("X-My-Header")) + + for line in response.iter_lines(): + print(line) +``` + +O gerenciador de contexto é necessário para que a resposta seja fechada de forma confiável. + +### Fazendo solicitações personalizadas/não documentadas + +Esta biblioteca é tipada para acesso conveniente à API documentada. + +Se precisar acessar endpoints, parâmetros ou propriedades de resposta não documentados, a biblioteca ainda pode ser usada. + +#### Endpoints não documentados + +Para fazer solicitações a endpoints não documentados, você pode usar `client.get`, `client.post` e outros +verbos HTTP. As opções do cliente serão respeitadas (como repetições) ao fazer esta solicitação. + +```py +import httpx + +response = client.post( + "/foo", + cast_to=httpx.Response, + body={"my_param": True}, +) + +print(response.headers.get("x-foo")) +``` + +#### Parâmetros de solicitação não documentados + +Se quiser enviar explicitamente um parâmetro extra, você pode fazê-lo com as opções de solicitação `extra_query`, `extra_body` e `extra_headers`. + +#### Propriedades de resposta não documentadas + +Para acessar propriedades de resposta não documentadas, você pode acessar os campos extras como `response.unknown_prop`. Você +também pode obter todos os campos extras no modelo Pydantic como um dicionário com +[`response.model_extra`](https://docs.pydantic.dev/latest/api/base_model/#pydantic.BaseModel.model_extra). + +### Configurando o cliente HTTP + +Você pode substituir diretamente o [cliente httpx](https://www.python-httpx.org/api/#client) para personalizá-lo para o seu caso de uso, incluindo: + +- Suporte a [proxies](https://www.python-httpx.org/advanced/proxies/) +- [Transports](https://www.python-httpx.org/advanced/transports/) personalizados +- Funcionalidade [avançada](https://www.python-httpx.org/advanced/clients/) adicional + +```python +import httpx +from perplexity import Perplexity, DefaultHttpxClient + +client = Perplexity( + # Or use the `PERPLEXITY_BASE_URL` env var + base_url="http://my.test.server.example.com:8083", + http_client=DefaultHttpxClient( + proxy="http://my.test.proxy.example.com", + transport=httpx.HTTPTransport(local_address="0.0.0.0"), + ), +) +``` + +Você também pode personalizar o cliente por solicitação usando `with_options()`: + +```python +client.with_options(http_client=DefaultHttpxClient(...)) +``` + +### Gerenciando recursos HTTP + +Por padrão, a biblioteca fecha as conexões HTTP subjacentes sempre que o cliente é [coletado pelo garbage collector](https://docs.python.org/3/reference/datamodel.html#object.__del__). Você pode fechar manualmente o cliente usando o método `.close()` se desejar, ou com um gerenciador de contexto que fecha ao sair. + +```py +from perplexity import Perplexity + +with Perplexity() as client: + # make requests here + ... + +# HTTP client is now closed +``` + +## Versionamento + +Este pacote geralmente segue as convenções [SemVer](https://semver.org/spec/v2.0.0.html), embora certas alterações incompatíveis com versões anteriores possam ser lançadas como versões menores: + +1. Alterações que afetam apenas tipos estáticos, sem quebrar o comportamento em tempo de execução. +2. Alterações nos internals da biblioteca que são tecnicamente públicos, mas não destinados ou documentados para uso externo. _(Por favor, abra uma issue no GitHub para nos informar se você depende de tais internals.)_ +3. Alterações que não esperamos impactar a vasta maioria dos usuários na prática. + +Levamos a compatibilidade com versões anteriores a sério e trabalhamos para garantir que você possa contar com uma experiência de atualização tranquila. + +Estamos interessados no seu feedback; por favor, abra uma [issue](https://www.github.com/perplexityai/perplexity-py/issues) com perguntas, bugs ou sugestões. + +### Determinando a versão instalada + +Se você atualizou para a versão mais recente, mas não está vendo os novos recursos que esperava, é provável que seu ambiente Python ainda esteja usando uma versão mais antiga. + +Você pode determinar a versão usada em tempo de execução com: + +```py +import perplexity +print(perplexity.__version__) +``` + +## Requisitos + +Python 3.9 ou superior. + +## Contribuindo + +Consulte [a documentação de contribuição](./CONTRIBUTING.md). diff --git a/README-RU.md b/README-RU.md new file mode 100644 index 0000000..e283603 --- /dev/null +++ b/README-RU.md @@ -0,0 +1,512 @@ +# Python-библиотека API Perplexity + +**Языки / Languages:** [English](./README.md) · [中文](./README-ZH.md) · [Español](./README-ES.md) · [Français](./README-FR.md) · [Português](./README-PT.md) · [Русский](./README-RU.md) · [Deutsch](./README-DE.md) + + +[![PyPI version](https://img.shields.io/pypi/v/perplexityai.svg?label=pypi%20(stable))](https://pypi.org/project/perplexityai/) + +Python-библиотека Perplexity обеспечивает удобный доступ к REST API Perplexity из любого приложения на Python 3.9+. Библиотека включает определения типов для всех параметров запросов и полей ответов, а также предоставляет синхронные и асинхронные клиенты на базе [httpx](https://github.com/encode/httpx). + +Она сгенерирована с помощью [Stainless](https://www.stainless.com/). + +## Документация + +Документация REST API доступна на [docs.perplexity.ai](https://docs.perplexity.ai/). Полный API этой библиотеки можно найти в [api.md](api.md). + +## Установка + +```sh +# install from PyPI +pip install perplexityai +``` + +## Search API + +Получите результаты веб-поиска: + +```python +import os +from perplexity import Perplexity + +client = Perplexity( + api_key=os.environ.get("PERPLEXITY_API_KEY"), # This is the default and can be omitted +) + +search = client.search.create( + query="latest AI developments 2024", + max_results=5 +) + +for result in search.results: + print(f"{result.title}: {result.url}") +``` + +## Chat Completions + +Полный API этой библиотеки можно найти в [api.md](api.md). + +```python +import os +from perplexity import Perplexity + +client = Perplexity( + api_key=os.environ.get("PERPLEXITY_API_KEY"), # This is the default and can be omitted +) + +stream_chunk = client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "Tell me about the latest developments in AI", + } + ], + model="sonar", +) +print(stream_chunk.id) +``` + +Хотя вы можете передать ключевой аргумент `api_key`, +мы рекомендуем использовать [python-dotenv](https://pypi.org/project/python-dotenv/) +и добавить `PERPLEXITY_API_KEY="My API Key"` в ваш файл `.env`, +чтобы API-ключ не хранился в системе контроля версий. + +## Асинхронное использование + +Просто импортируйте `AsyncPerplexity` вместо `Perplexity` и используйте `await` с каждым вызовом API: + +```python +import os +import asyncio +from perplexity import AsyncPerplexity + +client = AsyncPerplexity( + api_key=os.environ.get("PERPLEXITY_API_KEY"), # This is the default and can be omitted +) + + +async def main() -> None: + stream_chunk = await client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "Tell me about the latest developments in AI", + } + ], + model="sonar", + ) + print(stream_chunk.id) + + +asyncio.run(main()) +``` + +Функциональность синхронного и асинхронного клиентов в остальном идентична. + +### С aiohttp + +По умолчанию асинхронный клиент использует `httpx` для HTTP-запросов. Однако для повышения производительности при конкурентном доступе вы также можете использовать `aiohttp` в качестве HTTP-бэкенда. + +Вы можете включить это, установив `aiohttp`: + +```sh +# install from PyPI +pip install perplexityai[aiohttp] +``` + +Затем вы можете включить это, создав экземпляр клиента с `http_client=DefaultAioHttpClient()`: + +```python +import os +import asyncio +from perplexity import DefaultAioHttpClient +from perplexity import AsyncPerplexity + + +async def main() -> None: + async with AsyncPerplexity( + api_key=os.environ.get("PERPLEXITY_API_KEY"), # This is the default and can be omitted + http_client=DefaultAioHttpClient(), + ) as client: + stream_chunk = await client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "Tell me about the latest developments in AI", + } + ], + model="sonar", + ) + print(stream_chunk.id) + + +asyncio.run(main()) +``` + +## Потоковые ответы + +Мы поддерживаем потоковые ответы с использованием Server Side Events (SSE). + +```python +from perplexity import Perplexity + +client = Perplexity() + +stream = client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "Tell me about the latest developments in AI", + } + ], + model="sonar", + stream=True, +) +for stream_chunk in stream: + print(stream_chunk.id) +``` + +Асинхронный клиент использует точно такой же интерфейс. + +```python +from perplexity import AsyncPerplexity + +client = AsyncPerplexity() + +stream = await client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "Tell me about the latest developments in AI", + } + ], + model="sonar", + stream=True, +) +async for stream_chunk in stream: + print(stream_chunk.id) +``` + +## Использование типов + +Вложенные параметры запросов — это [TypedDicts](https://docs.python.org/3/library/typing.html#typing.TypedDict). Ответы — это [модели Pydantic](https://docs.pydantic.dev), которые также предоставляют вспомогательные методы для таких операций, как: + +- Сериализация обратно в JSON, `model.to_json()` +- Преобразование в словарь, `model.to_dict()` + +Типизированные запросы и ответы обеспечивают автодополнение и документацию в вашем редакторе. Если вы хотите видеть ошибки типов в VS Code, чтобы раньше обнаруживать ошибки, установите `python.analysis.typeCheckingMode` в `basic`. + +## Вложенные параметры + +Вложенные параметры — это словари, типизированные с помощью `TypedDict`, например: + +```python +from perplexity import Perplexity + +client = Perplexity() + +stream_chunk = client.chat.completions.create( + messages=[ + { + "content": "string", + "role": "system", + } + ], + model="model", + web_search_options={}, +) +print(stream_chunk.choices) +``` + +## Обработка ошибок + +Когда библиотека не может подключиться к API (например, из-за проблем с сетевым подключением или таймаута), выбрасывается подкласс `perplexity.APIConnectionError`. + +Когда API возвращает код статуса неуспешного ответа (то есть 4xx или 5xx), выбрасывается подкласс `perplexity.APIStatusError`, содержащий свойства `status_code` и `response`. + +Все ошибки наследуются от `perplexity.APIError`. + +```python +import perplexity +from perplexity import Perplexity + +client = Perplexity() + +try: + client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "What is the capital of France?", + } + ], + model="sonar", + ) +except perplexity.APIConnectionError as e: + print("The server could not be reached") + print(e.__cause__) # an underlying Exception, likely raised within httpx. +except perplexity.RateLimitError as e: + print("A 429 status code was received; we should back off a bit.") +except perplexity.APIStatusError as e: + print("Another non-200-range status code was received") + print(e.status_code) + print(e.response) +``` + +Коды ошибок следующие: + +| Status Code | Error Type | +| ----------- | -------------------------- | +| 400 | `BadRequestError` | +| 401 | `AuthenticationError` | +| 403 | `PermissionDeniedError` | +| 404 | `NotFoundError` | +| 422 | `UnprocessableEntityError` | +| 429 | `RateLimitError` | +| >=500 | `InternalServerError` | +| N/A | `APIConnectionError` | + +### Повторные попытки + +Некоторые ошибки автоматически повторяются 2 раза по умолчанию с короткой экспоненциальной задержкой. +Ошибки подключения (например, из-за проблем с сетевым подключением), 408 Request Timeout, 409 Conflict, +429 Rate Limit и внутренние ошибки >=500 по умолчанию повторяются. + +Вы можете использовать опцию `max_retries` для настройки или отключения параметров повторных попыток: + +```python +from perplexity import Perplexity + +# Configure the default for all requests: +client = Perplexity( + # default is 2 + max_retries=0, +) + +# Or, configure per-request: +client.with_options(max_retries=5).chat.completions.create( + messages=[ + { + "role": "user", + "content": "What is the capital of France?", + } + ], + model="sonar", +) +``` + +### Таймауты + +По умолчанию запросы завершаются по таймауту через 15 минут. Вы можете настроить это с помощью опции `timeout`, +которая принимает float или объект [`httpx.Timeout`](https://www.python-httpx.org/advanced/timeouts/#fine-tuning-the-configuration): + +```python +import httpx +from perplexity import Perplexity + +# Configure the default for all requests: +client = Perplexity( + # 20 seconds (default is 15 minutes) + timeout=20.0, +) + +# More granular control: +client = Perplexity( + 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": "What is the capital of France?", + } + ], + model="sonar", +) +``` + +При таймауте выбрасывается `APITimeoutError`. + +Обратите внимание, что запросы, завершившиеся по таймауту, [повторяются дважды по умолчанию](#повторные-попытки). + +## Расширенные возможности + +### Логирование + +Мы используем модуль [`logging`](https://docs.python.org/3/library/logging.html) стандартной библиотеки. + +Вы можете включить логирование, установив переменную окружения `PERPLEXITY_LOG` в `info`. + +```shell +$ export PERPLEXITY_LOG=info +``` + +Или в `debug` для более подробного логирования. + +### Как определить, означает ли `None` значение `null` или отсутствие поля + +В ответе API поле может быть явно `null` или полностью отсутствовать; в обоих случаях его значение в этой библиотеке — `None`. Вы можете различить эти два случая с помощью `.model_fields_set`: + +```py +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}.') +``` + +### Доступ к необработанным данным ответа (например, заголовкам) + +К «необработанному» объекту Response можно получить доступ, добавив префикс `.with_raw_response.` к любому вызову HTTP-метода, например: + +```py +from perplexity import Perplexity + +client = Perplexity() +response = client.chat.completions.with_raw_response.create( + messages=[{ + "role": "user", + "content": "What is the capital of France?", + }], + model="sonar", +) +print(response.headers.get('X-My-Header')) + +completion = response.parse() # get the object that `chat.completions.create()` would have returned +print(completion.id) +``` + +Эти методы возвращают объект [`APIResponse`](https://github.com/perplexityai/perplexity-py/tree/main/src/perplexity/_response.py). + +Асинхронный клиент возвращает [`AsyncAPIResponse`](https://github.com/perplexityai/perplexity-py/tree/main/src/perplexity/_response.py) с той же структурой; единственное отличие — методы с `await` для чтения содержимого ответа. + +#### `.with_streaming_response` + +Интерфейс выше жадно читает полное тело ответа при выполнении запроса, что не всегда желательно. + +Для потоковой передачи тела ответа используйте `.with_streaming_response`, что требует менеджера контекста и читает тело ответа только после вызова `.read()`, `.text()`, `.json()`, `.iter_bytes()`, `.iter_text()`, `.iter_lines()` или `.parse()`. В асинхронном клиенте это асинхронные методы. + +```python +with client.chat.completions.with_streaming_response.create( + messages=[ + { + "role": "user", + "content": "What is the capital of France?", + } + ], + model="sonar", +) as response: + print(response.headers.get("X-My-Header")) + + for line in response.iter_lines(): + print(line) +``` + +Менеджер контекста необходим, чтобы ответ был надёжно закрыт. + +### Выполнение пользовательских/недокументированных запросов + +Эта библиотека типизирована для удобного доступа к документированному API. + +Если вам нужен доступ к недокументированным endpoint'ам, параметрам или свойствам ответа, библиотеку всё равно можно использовать. + +#### Недокументированные endpoint'ы + +Для выполнения запросов к недокументированным endpoint'ам вы можете использовать `client.get`, `client.post` и другие +HTTP-глаголы. Параметры клиента будут учитываться (например, повторные попытки) при выполнении этого запроса. + +```py +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`](https://docs.pydantic.dev/latest/api/base_model/#pydantic.BaseModel.model_extra). + +### Настройка HTTP-клиента + +Вы можете напрямую переопределить [клиент httpx](https://www.python-httpx.org/api/#client) для настройки под ваш случай использования, включая: + +- Поддержку [прокси](https://www.python-httpx.org/advanced/proxies/) +- Пользовательские [транспорты](https://www.python-httpx.org/advanced/transports/) +- Дополнительную [расширенную](https://www.python-httpx.org/advanced/clients/) функциональность + +```python +import httpx +from perplexity import Perplexity, DefaultHttpxClient + +client = Perplexity( + # Or use the `PERPLEXITY_BASE_URL` env var + base_url="http://my.test.server.example.com:8083", + http_client=DefaultHttpxClient( + proxy="http://my.test.proxy.example.com", + transport=httpx.HTTPTransport(local_address="0.0.0.0"), + ), +) +``` + +Вы также можете настраивать клиент для каждого запроса с помощью `with_options()`: + +```python +client.with_options(http_client=DefaultHttpxClient(...)) +``` + +### Управление HTTP-ресурсами + +По умолчанию библиотека закрывает базовые HTTP-соединения, когда клиент [собирается сборщиком мусора](https://docs.python.org/3/reference/datamodel.html#object.__del__). При необходимости вы можете вручную закрыть клиент с помощью метода `.close()` или с помощью менеджера контекста, который закрывается при выходе. + +```py +from perplexity import Perplexity + +with Perplexity() as client: + # make requests here + ... + +# HTTP client is now closed +``` + +## Версионирование + +Этот пакет в целом следует соглашениям [SemVer](https://semver.org/spec/v2.0.0.html), хотя некоторые обратно несовместимые изменения могут выпускаться как минорные версии: + +1. Изменения, которые затрагивают только статические типы, не нарушая поведение во время выполнения. +2. Изменения во внутренних компонентах библиотеки, которые технически являются публичными, но не предназначены или не документированы для внешнего использования. _(Пожалуйста, откройте issue на GitHub, чтобы сообщить нам, если вы полагаетесь на такие внутренние компоненты.)_ +3. Изменения, которые, как мы ожидаем, не повлияют на подавляющее большинство пользователей на практике. + +Мы серьёзно относимся к обратной совместимости и стремимся обеспечить вам плавный процесс обновления. + +Мы будем рады вашим отзывам; пожалуйста, откройте [issue](https://www.github.com/perplexityai/perplexity-py/issues) с вопросами, сообщениями об ошибках или предложениями. + +### Определение установленной версии + +Если вы обновились до последней версии, но не видите ожидаемых новых функций, скорее всего, ваша среда Python всё ещё использует более старую версию. + +Вы можете определить версию, используемую во время выполнения, с помощью: + +```py +import perplexity +print(perplexity.__version__) +``` + +## Требования + +Python 3.9 или выше. + +## Участие в разработке + +См. [документацию по участию](./CONTRIBUTING.md). diff --git a/README-ZH.md b/README-ZH.md new file mode 100644 index 0000000..e48c414 --- /dev/null +++ b/README-ZH.md @@ -0,0 +1,503 @@ +# Perplexity Python API 库 + +**语言 / Languages:** [English](./README.md) · [中文](./README-ZH.md) · [Español](./README-ES.md) · [Français](./README-FR.md) · [Português](./README-PT.md) · [Русский](./README-RU.md) · [Deutsch](./README-DE.md) + + +[![PyPI version](https://img.shields.io/pypi/v/perplexityai.svg?label=pypi%20(stable))](https://pypi.org/project/perplexityai/) + +Perplexity Python 库为任何 Python 3.9+ 应用程序提供了便捷访问 Perplexity REST API 的方式。该库包含所有请求参数和响应字段的类型定义,并提供由 [httpx](https://github.com/encode/httpx) 驱动的同步和异步客户端。 + +该库由 [Stainless](https://www.stainless.com/) 生成。 + +## 文档 + +REST API 文档可在 [docs.perplexity.ai](https://docs.perplexity.ai/) 查看。本库的完整 API 说明见 [api.md](api.md)。 + +## 安装 + +```sh +# install from PyPI +pip install perplexityai +``` + +## Search API + +获取网页搜索结果: + +```python +import os +from perplexity import Perplexity + +client = Perplexity( + api_key=os.environ.get("PERPLEXITY_API_KEY"), # This is the default and can be omitted +) + +search = client.search.create( + query="latest AI developments 2024", + max_results=5 +) + +for result in search.results: + print(f"{result.title}: {result.url}") +``` + +## Chat Completions + +本库的完整 API 说明见 [api.md](api.md)。 + +```python +import os +from perplexity import Perplexity + +client = Perplexity( + api_key=os.environ.get("PERPLEXITY_API_KEY"), # This is the default and can be omitted +) + +stream_chunk = client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "Tell me about the latest developments in AI", + } + ], + model="sonar", +) +print(stream_chunk.id) +``` + +虽然你可以通过 `api_key` 关键字参数传入 API 密钥,但我们建议使用 [python-dotenv](https://pypi.org/project/python-dotenv/) 将 `PERPLEXITY_API_KEY="My API Key"` 添加到 `.env` 文件中,这样 API 密钥就不会被提交到源代码管理中。 + +## 异步用法 + +只需导入 `AsyncPerplexity` 而不是 `Perplexity`,并在每次 API 调用时使用 `await`: + +```python +import os +import asyncio +from perplexity import AsyncPerplexity + +client = AsyncPerplexity( + api_key=os.environ.get("PERPLEXITY_API_KEY"), # This is the default and can be omitted +) + + +async def main() -> None: + stream_chunk = await client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "Tell me about the latest developments in AI", + } + ], + model="sonar", + ) + print(stream_chunk.id) + + +asyncio.run(main()) +``` + +同步客户端与异步客户端的功能在其他方面完全相同。 + +### 使用 aiohttp + +默认情况下,异步客户端使用 `httpx` 发送 HTTP 请求。不过,为了获得更好的并发性能,你也可以使用 `aiohttp` 作为 HTTP 后端。 + +你可以通过安装 `aiohttp` 来启用此功能: + +```sh +# install from PyPI +pip install perplexityai[aiohttp] +``` + +然后,在实例化客户端时传入 `http_client=DefaultAioHttpClient()` 即可启用: + +```python +import os +import asyncio +from perplexity import DefaultAioHttpClient +from perplexity import AsyncPerplexity + + +async def main() -> None: + async with AsyncPerplexity( + api_key=os.environ.get("PERPLEXITY_API_KEY"), # This is the default and can be omitted + http_client=DefaultAioHttpClient(), + ) as client: + stream_chunk = await client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "Tell me about the latest developments in AI", + } + ], + model="sonar", + ) + print(stream_chunk.id) + + +asyncio.run(main()) +``` + +## 流式响应 + +我们支持使用服务端事件(Server Side Events,SSE)进行流式响应。 + +```python +from perplexity import Perplexity + +client = Perplexity() + +stream = client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "Tell me about the latest developments in AI", + } + ], + model="sonar", + stream=True, +) +for stream_chunk in stream: + print(stream_chunk.id) +``` + +异步客户端使用完全相同的接口。 + +```python +from perplexity import AsyncPerplexity + +client = AsyncPerplexity() + +stream = await client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "Tell me about the latest developments in AI", + } + ], + model="sonar", + stream=True, +) +async for stream_chunk in stream: + print(stream_chunk.id) +``` + +## 使用类型 + +嵌套的请求参数是 [TypedDicts](https://docs.python.org/3/library/typing.html#typing.TypedDict)。响应是 [Pydantic 模型](https://docs.pydantic.dev),还提供以下辅助方法: + +- 序列化回 JSON:`model.to_json()` +- 转换为字典:`model.to_dict()` + +类型化的请求和响应可在编辑器中提供自动补全和文档。如果你希望在 VS Code 中看到类型错误以便更早发现 bug,请将 `python.analysis.typeCheckingMode` 设置为 `basic`。 + +## 嵌套参数 + +嵌套参数是字典,使用 `TypedDict` 进行类型标注,例如: + +```python +from perplexity import Perplexity + +client = Perplexity() + +stream_chunk = client.chat.completions.create( + messages=[ + { + "content": "string", + "role": "system", + } + ], + model="model", + web_search_options={}, +) +print(stream_chunk.choices) +``` + +## 错误处理 + +当库无法连接到 API 时(例如由于网络连接问题或超时),会抛出 `perplexity.APIConnectionError` 的子类。 + +当 API 返回非成功状态码(即 4xx 或 5xx 响应)时,会抛出 `perplexity.APIStatusError` 的子类,其中包含 `status_code` 和 `response` 属性。 + +所有错误都继承自 `perplexity.APIError`。 + +```python +import perplexity +from perplexity import Perplexity + +client = Perplexity() + +try: + client.chat.completions.create( + messages=[ + { + "role": "user", + "content": "What is the capital of France?", + } + ], + model="sonar", + ) +except perplexity.APIConnectionError as e: + print("The server could not be reached") + print(e.__cause__) # an underlying Exception, likely raised within httpx. +except perplexity.RateLimitError as e: + print("A 429 status code was received; we should back off a bit.") +except perplexity.APIStatusError as e: + print("Another non-200-range status code was received") + print(e.status_code) + print(e.response) +``` + +错误码对应关系如下: + +| Status Code | Error Type | +| ----------- | -------------------------- | +| 400 | `BadRequestError` | +| 401 | `AuthenticationError` | +| 403 | `PermissionDeniedError` | +| 404 | `NotFoundError` | +| 422 | `UnprocessableEntityError` | +| 429 | `RateLimitError` | +| >=500 | `InternalServerError` | +| N/A | `APIConnectionError` | + +### 重试 + +默认情况下,某些错误会自动重试 2 次,并采用短暂的指数退避策略。连接错误(例如由于网络连接问题)、408 Request Timeout、409 Conflict、429 Rate Limit 以及 >=500 内部错误默认都会重试。 + +你可以使用 `max_retries` 选项来配置或禁用重试设置: + +```python +from perplexity import Perplexity + +# Configure the default for all requests: +client = Perplexity( + # default is 2 + max_retries=0, +) + +# Or, configure per-request: +client.with_options(max_retries=5).chat.completions.create( + messages=[ + { + "role": "user", + "content": "What is the capital of France?", + } + ], + model="sonar", +) +``` + +### 超时 + +默认情况下,请求在 15 分钟后超时。你可以通过 `timeout` 选项进行配置,该选项接受浮点数或 [`httpx.Timeout`](https://www.python-httpx.org/advanced/timeouts/#fine-tuning-the-configuration) 对象: + +```python +import httpx +from perplexity import Perplexity + +# Configure the default for all requests: +client = Perplexity( + # 20 seconds (default is 15 minutes) + timeout=20.0, +) + +# More granular control: +client = Perplexity( + 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": "What is the capital of France?", + } + ], + model="sonar", +) +``` + +超时时会抛出 `APITimeoutError`。 + +请注意,超时的请求[默认会重试两次](#重试)。 + +## 高级用法 + +### 日志 + +我们使用标准库的 [`logging`](https://docs.python.org/3/library/logging.html) 模块。 + +你可以通过将环境变量 `PERPLEXITY_LOG` 设置为 `info` 来启用日志。 + +```shell +$ export PERPLEXITY_LOG=info +``` + +或者设置为 `debug` 以获取更详细的日志输出。 + +### 如何判断 `None` 表示 `null` 还是字段缺失 + +在 API 响应中,某个字段可能显式为 `null`,也可能完全缺失;在这两种情况下,该字段在本库中的值都是 `None`。你可以通过 `.model_fields_set` 来区分这两种情况: + +```py +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}.') +``` + +### 访问原始响应数据(例如 headers) + +可以通过在任何 HTTP 方法调用前加上 `.with_raw_response.` 来访问"原始" Response 对象,例如: + +```py +from perplexity import Perplexity + +client = Perplexity() +response = client.chat.completions.with_raw_response.create( + messages=[{ + "role": "user", + "content": "What is the capital of France?", + }], + model="sonar", +) +print(response.headers.get('X-My-Header')) + +completion = response.parse() # get the object that `chat.completions.create()` would have returned +print(completion.id) +``` + +这些方法返回 [`APIResponse`](https://github.com/perplexityai/perplexity-py/tree/main/src/perplexity/_response.py) 对象。 + +异步客户端返回具有相同结构的 [`AsyncAPIResponse`](https://github.com/perplexityai/perplexity-py/tree/main/src/perplexity/_response.py),唯一的区别是读取响应内容的方法需要使用 `await`。 + +#### `.with_streaming_response` + +上述接口在你发起请求时会立即读取完整的响应体,这可能并不总是你想要的。 + +若要流式读取响应体,请改用 `.with_streaming_response`,它需要配合上下文管理器使用,并且只有在你调用 `.read()`、`.text()`、`.json()`、`.iter_bytes()`、`.iter_text()`、`.iter_lines()` 或 `.parse()` 时才会读取响应体。在异步客户端中,这些是异步方法。 + +```python +with client.chat.completions.with_streaming_response.create( + messages=[ + { + "role": "user", + "content": "What is the capital of France?", + } + ], + model="sonar", +) as response: + print(response.headers.get("X-My-Header")) + + for line in response.iter_lines(): + print(line) +``` + +必须使用上下文管理器,以确保响应能够被可靠地关闭。 + +### 发起自定义/未文档化的请求 + +本库针对已文档化的 API 提供了便捷的类型支持。 + +如果你需要访问未文档化的端点、参数或响应属性,仍然可以使用本库。 + +#### 未文档化的端点 + +要向未文档化的端点发起请求,可以使用 `client.get`、`client.post` 以及其他 HTTP 动词。发起此类请求时,客户端上的配置选项(例如重试)仍然会被尊重。 + +```py +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` 这样访问额外字段。你也可以通过 [`response.model_extra`](https://docs.pydantic.dev/latest/api/base_model/#pydantic.BaseModel.model_extra) 将 Pydantic 模型上的所有额外字段作为字典获取。 + +### 配置 HTTP 客户端 + +你可以直接覆盖 [httpx 客户端](https://www.python-httpx.org/api/#client) 以满足你的使用场景,包括: + +- 支持[代理](https://www.python-httpx.org/advanced/proxies/) +- 自定义[传输层](https://www.python-httpx.org/advanced/transports/) +- 其他[高级](https://www.python-httpx.org/advanced/clients/)功能 + +```python +import httpx +from perplexity import Perplexity, DefaultHttpxClient + +client = Perplexity( + # Or use the `PERPLEXITY_BASE_URL` env var + base_url="http://my.test.server.example.com:8083", + http_client=DefaultHttpxClient( + proxy="http://my.test.proxy.example.com", + transport=httpx.HTTPTransport(local_address="0.0.0.0"), + ), +) +``` + +你也可以通过 `with_options()` 在每次请求的基础上自定义客户端: + +```python +client.with_options(http_client=DefaultHttpxClient(...)) +``` + +### 管理 HTTP 资源 + +默认情况下,当客户端被[垃圾回收](https://docs.python.org/3/reference/datamodel.html#object.__del__)时,库会关闭底层的 HTTP 连接。如果需要,你可以使用 `.close()` 方法手动关闭客户端,或者使用在退出时自动关闭的上下文管理器。 + +```py +from perplexity import Perplexity + +with Perplexity() as client: + # make requests here + ... + +# HTTP client is now closed +``` + +## 版本控制 + +本包通常遵循 [SemVer](https://semver.org/spec/v2.0.0.html) 约定,但某些向后不兼容的变更可能会作为次要版本发布: + +1. 仅影响静态类型、但不破坏运行时行为的变更。 +2. 对库内部实现的变更,这些实现在技术上属于公开 API,但并非为外部使用而设计或文档化。_(如果你依赖此类内部实现,请提交 GitHub issue 告知我们。)_ +3. 我们预计不会对绝大多数用户产生实际影响的变更。 + +我们非常重视向后兼容性,并努力确保你能获得顺畅的升级体验。 + +我们非常欢迎你的反馈;如有问题、bug 或建议,请提交 [issue](https://www.github.com/perplexityai/perplexity-py/issues)。 + +### 确定已安装的版本 + +如果你已升级到最新版本,但没有看到预期的新功能,那么你的 Python 环境可能仍在使用旧版本。 + +你可以通过以下方式确定运行时使用的版本: + +```py +import perplexity +print(perplexity.__version__) +``` + +## 环境要求 + +Python 3.9 或更高版本。 + +## 贡献 + +请参阅[贡献文档](./CONTRIBUTING.md)。 diff --git a/README.md b/README.md index df70fed..e742bf4 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Perplexity Python API library +**Languages:** [English](./README.md) · [中文](./README-ZH.md) · [Español](./README-ES.md) · [Français](./README-FR.md) · [Português](./README-PT.md) · [Русский](./README-RU.md) · [Deutsch](./README-DE.md) + [![PyPI version](https://img.shields.io/pypi/v/perplexityai.svg?label=pypi%20(stable))](https://pypi.org/project/perplexityai/)