gigaserve


Namegigaserve JSON
Version 0.0.51 PyPI version JSON
download
home_pagehttps://github.com/ai-forever/gigaserve
SummaryNone
upload_time2024-03-25 06:50:20
maintainerNone
docs_urlNone
authorLangChain
requires_python<4.0,>=3.8.1
licenseLangServe
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # GigaServe πŸ¦œοΈπŸ“ = LangServe + GigaChat

GigaServe β€” это python-Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°, которая позволяСт Ρ€Π°Π·ΠΌΠ΅Ρ‰Π°Ρ‚ΡŒ Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠΈ ΠΈ runnable-интСрфСйсы GigaChain с прСдоставлСниСм ΠΊ Π½ΠΈΠΌ доступа Ρ‡Π΅Ρ€Π΅Π· REST API.

Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° GigaServe ΠΈΠ½Ρ‚Π΅Π³Ρ€ΠΈΡ€ΠΎΠ²Π°Π½Π° с [FastAPI](https://fastapi.tiangolo.com/) ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ для Π²Π°Π»ΠΈΠ΄Π°Ρ†ΠΈΠΈ Π΄Π°Π½Π½Ρ‹Ρ… [Pydantic](https://docs.pydantic.dev/latest/).

## ΠžΡΠΎΠ±Π΅Π½Π½ΠΎΡΡ‚ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ

Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Π΄Π°Π΅Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ возмоТности:

- АвтоматичСскоС ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ схСм Π²Π²ΠΎΠ΄Π° ΠΈ Π²Ρ‹Π²ΠΎΠ΄Π° основС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° GigaChain. Π‘Ρ…Π΅ΠΌΡ‹ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ запроса ΠΊ API ΠΈ ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΠ²Π°ΡŽΡ‚ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Ρ‹Π΅ сообщСния ΠΎΠ± ΠΎΡˆΠΈΠ±ΠΊΠ°Ρ….
- Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° API-Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ с JSONSchema ΠΈ Swagger.
- Π­Π½Π΄ΠΏΠΎΠΈΠ½Ρ‚Ρ‹ с ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΎΠΉ мноТСства ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… запросов Π½Π° ΠΎΠ΄Π½ΠΎΠΌ сСрвСрС `/invoke`, `/batch` ΠΈ `/stream`.
- Π­Π½Π΄ΠΏΠΎΠΈΠ½Ρ‚ `/stream_log` для ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²ΠΎΠΉ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ всСх ΠΈΠ»ΠΈ Π²Ρ‹Π±Ρ€Π°Π½Π½Ρ‹Ρ… ΠΏΡ€ΠΎΠΌΠ΅ΠΆΡƒΡ‚ΠΎΡ‡Π½Ρ‹Ρ… шагов Ρ€Π°Π±ΠΎΡ‚Ρ‹ Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠΈ/Π°Π³Π΅Π½Ρ‚Π°.
- Π˜Π½Ρ‚Π΅Ρ€Π°ΠΊΡ‚ΠΈΠ²Π½Π°Ρ пСсочница `/playground` с ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²Ρ‹ΠΌ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ΠΌ ΠΈ дСмонстрациСй ΠΏΡ€ΠΎΠΌΠ΅ΠΆΡƒΡ‚ΠΎΡ‡Π½Ρ‹Ρ… шагов.
- ИспользованиС ΠΏΡ€ΠΎΠ²Π΅Ρ€Π΅Π½Π½Ρ‹Ρ… open-source Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ Python Ρ‚Π°ΠΊΠΈΡ…, ΠΊΠ°ΠΊ FastAPI, Pydantic, uvloop ΠΈ asyncio.
- ΠšΠ»ΠΈΠ΅Π½Ρ‚ΡΠΊΠΈΠΉ SDK, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ позволяСт ΠΎΠ±Ρ€Π°Ρ‰Π°Ρ‚ΡŒΡΡ ΠΊ сСрвСру GigaServe Ρ‚Π°ΠΊΠΆΠ΅ ΠΊΠ°ΠΊ ΠΊ Π»ΠΎΠΊΠ°Π»ΡŒΠ½ΠΎΠΌΡƒ runnable-интСрфСйсу ΠΈΠ»ΠΈ Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ HTTP API.

### ΠžΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΡ

- Колбэки ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ΡΡ для событий, происходящих Π½Π° сСрвСрС.
- OpenAPI-спСцификация Π½Π΅ гСнСрируСтся, Ссли Π²Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ Pydantic V2. Π­Ρ‚ΠΎ связанно с Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ Fast API Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ [смСшиваниС пространств ΠΈΠΌΠ΅Π½ pydantic v1 ΠΈ v2](https://github.com/tiangolo/fastapi/issues/10360). ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ Π½ΠΈΠΆΠ΅.

## Установка {#ustanovka}

Для ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ установки ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° ΠΈ сСрвСра ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ:

```bash
pip install "gigaserve[all]"
```

Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΈ сСрвСр ΠΏΠΎ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΊΠΎΠΌΠ°Π½Π΄:

```sh
# Команда установки ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°
pip install "gigaserve[client]"

# Команда установки сСрвСра
pip gigaserve "langserve[server]"
```

## GigaChain CLI πŸ› οΈ

GigaChain CLI β€” это ΡƒΡ‚ΠΈΠ»ΠΈΡ‚Π°, которая ΠΏΠΎΠΌΠΎΠΆΠ΅Ρ‚ быстро Π½Π°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ GigaServe. Для этого ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ:

```sh
gigachain app new ../path/to/directory
```

ΠŸΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с GigaChain CLI всСгда ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ послСднюю Π²Π΅Ρ€ΡΠΈΡŽ ΡƒΡ‚ΠΈΠ»ΠΈΡ‚Ρ‹. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ Π΅Π΅ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹:

```sh
pip install -U gigachain-cli
```

## ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹

Для быстрого старта GigaServe ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ [ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹ GigaChain](https://github.com/ai-forever/gigachain/blob/master/templates/README.md).

Π‘ΠΎΠ»ΡŒΡˆΠ΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠ² шаблонов Π²Ρ‹ Π½Π°ΠΉΠ΄Π΅Ρ‚Π΅ Π² [Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ](https://github.com/ai-forever/gigaserve/tree/main/examples).

### Π‘Π΅Ρ€Π²Π΅Ρ€

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Π½ΠΈΠΆΠ΅ Ρ€Π°Π·Π²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅Ρ‚ Ρ‡Π°Ρ‚-ΠΌΠΎΠ΄Π΅Π»ΠΈ GigaChat ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΡ… LLM, Π° Ρ‚Π°ΠΊΠΆΠ΅ Ρ†Π΅ΠΏΠΎΡ‡ΠΊΡƒ, которая Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ ΡˆΡƒΡ‚ΠΊΡƒ ΠΏΠΎ Π·Π°Π΄Π°Π½Π½ΠΎΠΉ Ρ‚Π΅ΠΌΠ΅ (`topic`) с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΌΠΎΠ΄Π΅Π»ΠΈ Anthropic.

```python
#!/usr/bin/env python
from fastapi import FastAPI
from langchain.prompts import ChatPromptTemplate
from langchain.chat_models import GigaChat, ChatAnthropic, ChatOpenAI

from langserve import add_routes

app = FastAPI(
  title="GigaChain Server",
  version="1.0",
  description="ΠŸΡ€ΠΎΡΡ‚ΠΎΠΉ API-сСрвСр, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΠΉ runnable-интСрфСйсы GigaChain",
)

add_routes(
    app,
    GigaChat(credentials=<Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅>),
    path="/gigachat",
) 

add_routes(
    app,
    ChatOpenAI(),
    path="/openai",
)

add_routes(
    app,
    ChatAnthropic(),
    path="/anthropic",
)

model = ChatAnthropic()
prompt = ChatPromptTemplate.from_template("расскаТи ΡˆΡƒΡ‚ΠΊΡƒ ΠΎ {topic}")
add_routes(
    app,
    prompt | model,
    path="/joke",
)

if __name__ == "__main__":
    import uvicorn

    uvicorn.run(app, host="localhost", port=8000)
```

### ДокумСнтация

БгСнСрированная OpenAPI-докумСнтация ΠΊ сСрвСру, Ρ€Π°Π·Π²Π΅Ρ€Π½ΡƒΡ‚ΠΎΠΌΡƒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅Π³ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°, доступна ΠΏΠΎ адрСсу:

```sh
curl localhost:8000/docs
```

ΠŸΡ€ΠΈ этом, адрСс `localhost:8000` Π±ΡƒΠ΄Π΅Ρ‚ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ ΠΎΡˆΠΈΠ±ΠΊΡƒ 404, ΠΏΠΎΠΊΠ° Π²Ρ‹ Π½Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚Π΅ `@app.get("/")`.

> [!NOTE]
> ΠŸΡ€ΠΈ использовании pydantic v2 [докумСнтация Π½Π΅ гСнСрируСтся](#Ρ€Π°Π±ΠΎΡ‚Π°-с-pydantic) для эндпоинтов `/invoke`, `/batch`, `/stream` ΠΈ `stream_log`.

### ΠšΠ»ΠΈΠ΅Π½Ρ‚

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° Π½Π° основС Python SDK:

```python
from langchain.schema import SystemMessage, HumanMessage
from langchain.prompts import ChatPromptTemplate
from langchain.schema.runnable import RunnableMap
from langserve import RemoteRunnable

openai = RemoteRunnable("http://localhost:8000/openai/")
anthropic = RemoteRunnable("http://localhost:8000/anthropic/")
joke_chain = RemoteRunnable("http://localhost:8000/joke/")

# Π‘ΠΈΠ½Ρ…Ρ€ΠΎΠ½Π½Ρ‹ΠΉ Π²Ρ‹Π·ΠΎΠ²

joke_chain.invoke({"topic": "ΠΏΠΎΠΏΡƒΠ³Π°ΠΈ"})

# Асинхронный Π²Ρ‹Π·ΠΎΠ²
await joke_chain.ainvoke({"topic": "ΠΏΠΎΠΏΡƒΠ³Π°ΠΈ"})

prompt = [
    SystemMessage(content='Π’Π΅Π΄ΠΈ сСбя ΠΊΠ°ΠΊ кошка ΠΈΠ»ΠΈ ΠΏΠΎΠΏΡƒΠ³Π°ΠΉ.'),
    HumanMessage(content='ΠŸΡ€ΠΈΠ²Π΅Ρ‚!')
]

# ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° astream
async for msg in anthropic.astream(prompt):
    print(msg, end="", flush=True)

prompt = ChatPromptTemplate.from_messages(
    [("system", "РасскаТи ΠΌΠ½Π΅ Π΄Π»ΠΈΠ½Π½ΡƒΡŽ ΠΈΡΡ‚ΠΎΡ€ΠΈΡŽ ΠΎ {topic}")]
)

# ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ собствСнных Ρ†Π΅ΠΏΠΎΡ‡Π΅ΠΊ
chain = prompt | RunnableMap({
    "openai": openai,
    "anthropic": anthropic,
})

chain.batch([{ "topic": "ΠΏΠΎΠΏΡƒΠ³Π°ΠΈ" }, { "topic": "кошки" }])
```

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° Π½Π° TypeScript (для Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° трСбуСтся LangChain.js вСрсии 0.0.166 ΠΈΠ»ΠΈ Π²Ρ‹ΡˆΠ΅):

```typescript
import { RemoteRunnable } from "@langchain/core/runnables/remote";

const chain = new RemoteRunnable({
    url: `http://localhost:8000/joke/`,
});
const result = await chain.invoke({
  topic: "кошки",
});
```

ΠšΠ»ΠΈΠ΅Π½Ρ‚, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΠΉ Python-Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ `requests`:

```python
import requests

response = requests.post(
    "http://localhost:8000/joke/invoke/",
    json={'input': {'topic': 'кошки'}}
)
response.json()
```

ИспользованиС cURL:

```sh
curl --location --request POST 'http://localhost:8000/joke/invoke' \
    --header 'Content-Type: application/json' \
    --data-raw '{
        "input": {
            "topic": "кошки"
        }
    }'
```

## Π­Π½Π΄ΠΏΠΎΠΈΠ½Ρ‚Ρ‹

Π‘ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° Π½ΠΈΠΆΠ΅ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π½Π° сСрвСр Π·Π°Ρ€Π°Π½Π΅Π΅ ΠΏΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²Π»Π΅Π½Π½Ρ‹Π΅ эндпоинты для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с runnable-интСрфСйсами:

```python
...
add_routes(
    app,
    runnable,
    path="/my_runnable",
)
```

Бписок эндпоинтов:

- `POST /my_runnable/invoke` β€” Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ runnable-интСрфСйс для Π΅Π΄ΠΈΠ½ΠΈΡ‡Π½Ρ‹Ρ… Π²Ρ…ΠΎΠ΄Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…;
- `POST /my_runnable/batch` β€” Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ runnable-интСрфСйс для Π½Π°Π±ΠΎΡ€Π° Π²Ρ…ΠΎΠ΄Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…;
- `POST /my_runnable/stream` β€” Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ для Π΅Π΄ΠΈΠ½ΠΈΡ‡Π½Ρ‹Ρ… Π²Ρ…ΠΎΠ΄Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… с ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²Ρ‹ΠΌ Π²Ρ‹Π²ΠΎΠ΄ΠΎΠΌ;
- `POST /my_runnable/stream_log` β€” Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ для Π΅Π΄ΠΈΠ½ΠΈΡ‡Π½Ρ‹Ρ… Π²Ρ…ΠΎΠ΄Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… с ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²Ρ‹ΠΌ Π²Ρ‹Π²ΠΎΠ΄ΠΎΠΌ, Π²ΠΊΠ»ΡŽΡ‡Π°Ρ Π²Ρ‹Π²ΠΎΠ΄ ΠΏΡ€ΠΎΠΌΠ΅ΠΆΡƒΡ‚ΠΎΡ‡Π½Ρ‹Ρ… шагов ΠΏΠΎ Ρ…ΠΎΠ΄Ρƒ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ;
- `GET /my_runnable/input_schema` β€” ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ JSON-схСму Π²Ρ…ΠΎΠ΄Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… runnable-интСрфСйса;
- `GET /my_runnable/output_schema` β€” ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ JSON-схСму Π²Ρ‹Ρ…ΠΎΠ΄Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… runnable-интСрфСйса;
- `GET /my_runnable/config_schema` β€” ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ JSON-схСму ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ runnable-интСрфСйса;

> [!NOTE]
> Π­Π½Π΄ΠΏΠΎΠΈΠ½Ρ‚Ρ‹ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ Π² соотвСтствии с [LangChain Expression Language interface (LCEL)](https://python.langchain.com/docs/expression_language/interface) β€” DSL для создания Ρ†Π΅ΠΏΠΎΡ‡Π΅ΠΊ.

## ΠŸΠ΅ΡΠΎΡ‡Π½ΠΈΡ†Π°

Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° пСсочницы доступна ΠΏΠΎ адрСсу `/my_runnable/playground`.
На Π½Π΅ΠΉ прСдставлСн простой интСрфСйс, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ позволяСт Π½Π°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ runnable-интСрфСйса ΠΈ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ запрос ΠΊ Π½Π΅ΠΌΡƒ с ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²Ρ‹ΠΌ Π²Ρ‹Π²ΠΎΠ΄ΠΎΠΌ ΠΈ дСмонстрациСй ΠΏΡ€ΠΎΠΌΠ΅ΠΆΡƒΡ‚ΠΎΡ‡Π½Ρ‹Ρ… шагов.

<p align="center">
<img src="https://github.com/langchain-ai/langserve/assets/3205522/5ca56e29-f1bb-40f4-84b5-15916384a276" width="50%"/>
</p>

### Π’ΠΈΠ΄ΠΆΠ΅Ρ‚Ρ‹

ΠŸΠ΅ΡΠΎΡ‡Π½ΠΈΡ†Π° ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ [Π²ΠΈΠ΄ΠΆΠ΅Ρ‚Ρ‹](#playground-widgets) ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ для тСстирования Π²Π°ΡˆΠΈΡ… Ρ†Π΅ΠΏΠΎΡ‡Π΅ΠΊ с Ρ€Π°Π·Π½Ρ‹ΠΌΠΈ Π²Ρ…ΠΎΠ΄Π½Ρ‹ΠΌΠΈ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ.

ΠšΡ€ΠΎΠΌΠ΅ этого, Ссли Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠ° ΠΌΠΎΠΆΠ΅Ρ‚ Π½Π°ΡΡ‚Ρ€Π°ΠΈΠ²Π°Ρ‚ΡŒΡΡ, пСсочница прСдоставляСт Π·Π°Π΄Π°Ρ‚ΡŒ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠΈ ΠΈ ΠΏΠΎΠ΄Π΅Π»ΠΈΡ‚ΡŒΡΡ ссылкой Π½Π° ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½ΡƒΡŽ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡŽ.

### ОбмСн ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠ΅ΠΉ Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠΈ

In addition, for configurable runnables, the playground will allow you to configure the
runnable and share a link with the configuration:

<p align="center">
<img src="https://github.com/langchain-ai/langserve/assets/3205522/86ce9c59-f8e4-4d08-9fa3-62030e0f521d" width="50%"/>
</p>


## Π Π°Π±ΠΎΡ‚Π° с классичСскими Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠ°ΠΌΠΈ

GigaServe Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ ΠΊΠ°ΠΊ с runnable-интСрфСйсами (написанным с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ [LangChain Expression Language](https://python.langchain.com/docs/expression_language/)), Ρ‚Π°ΠΊ ΠΈ с классичСскими Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠ°ΠΌΠΈ (посрСдством наслСдования ΠΎΡ‚ `Chain`).

ΠŸΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с классичСскими Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠ°ΠΌΠΈ ΡƒΡ‡ΠΈΡ‚Ρ‹Π²Π°ΠΉΡ‚Π΅, Ρ‡Ρ‚ΠΎ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²Ρ…ΠΎΠ΄Π½Ρ‹Π΅ схСмы для Ρ‚Π°ΠΊΠΈΡ… Ρ†Π΅ΠΏΠΎΡ‡Π΅ΠΊ ΠΌΠΎΠ³ΡƒΡ‚ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ошибки, Ρ‚.ΠΊ. ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Π½Π΅ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹ΠΌΠΈ ΠΈΠ»ΠΈ Π½Π΅ΠΏΠΎΠ»Π½Ρ‹ΠΌΠΈ.
Π’Π°ΠΊΠΈΠ΅ ошибки ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ, Ссли ΠΎΠ±Π½ΠΎΠ²ΠΈΡ‚ΡŒ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ `input_schema` Ρ‚Π°ΠΊΠΈΡ… Ρ†Π΅ΠΏΠΎΡ‡Π΅ΠΊ Π² GigaChain.

## Π Π°Π·Π²Π΅Ρ€Ρ‚Ρ‹Π²Π°Π½ΠΈΠ΅

НиТС описаны способы развСртывания Π½Π° Google Cloud Platforms (GCP) ΠΈ Azure.

### Π Π°Π·Π²Π΅Ρ€Ρ‚Ρ‹Π²Π°Π½ΠΈΠ΅ Π½Π° GCP

Для развСртывания Π½Π° GCP Cloud Run ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ:

```sh
gcloud run deploy [your-service-name] --source . --port 8001 --allow-unauthenticated --region us-central1 --set-env-vars=GIGACHAT_API_KEY=your_key
```

### Π Π°Π·Π²Π΅Ρ€Ρ‚Ρ‹Π²Π°Π½ΠΈΠ΅ Π½Π° Azure

Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Ρ€Π°Π·Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ сСрвСр Π½Π° Azure с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Azure Container Apps:

```sh
az containerapp up --name [container-app-name] --source . --resource-group [resource-group-name] --environment  [environment-name] --ingress external --target-port 8001 --env-vars=OPENAI_API_KEY=your_key
```

ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½Π°Ρ информация Π² [ΠΎΡ„ΠΈΡ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠΉ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ](https://learn.microsoft.com/en-us/azure/container-apps/containerapp-up).


## Π Π°Π±ΠΎΡ‚Π° с Pydantic

GigaServe ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ Pydantic v2 с Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌΠΈ ограничСниями:

- ΠŸΡ€ΠΈ использовании Pydantic v2 докумСнтация OpenAPI Π½Π΅ гСнСрируСтся. Π­Ρ‚ΠΎ связанно с Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ Fast API Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ [смСшиваниС пространств ΠΈΠΌΠ΅Π½ pydantic v1 ΠΈ v2](https://github.com/tiangolo/fastapi/issues/10360).
- GigaChain ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ пространство ΠΈΠΌΠ΅Π½ вСрсии v1 Π² Pydantic v2.

Π—Π° ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹Ρ… ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠΉ, эндпоинты API, страница пСсочницы ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ.

## Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ возмоТности

## Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ

О Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΡŽ Π½Π° свой сСрвСр GigaServe β€” Π² Ρ€Π°Π·Π΄Π΅Π»Π°Ρ… Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ FastAPI, посвящСнных [бСзопасности](https://fastapi.tiangolo.com/tutorial/security/) ΠΈ [использованию ΡΠ²ΡΠ·ΡƒΡŽΡ‰Π΅Π³ΠΎ ПО](https://fastapi.tiangolo.com/tutorial/middleware/).

### Π Π°Π±ΠΎΡ‚Π° с Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ

ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Ρ„Π°ΠΉΠ»ΠΎΠ² β€” это типичная Π·Π°Π΄Π°Ρ‡Π° для Π±ΠΎΠ»ΡŒΡˆΠΈΡ… языковых ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ.
Π‘ΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π½Ρ‹Π΅ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Ρ‹ для Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ этой Π·Π°Π΄Π°Ρ‡ΠΈ:

- Π€Π°ΠΉΠ» ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π·Π°Π³Ρ€ΡƒΠΆΠ΅Π½ Π½Π° сСрвСр с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΎΠ΄Π½ΠΎΠ³ΠΎ эндпоинта ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Π½ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ;
- Π€Π°ΠΉΠ» ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ прСдставлСн ΠΊΠ°ΠΊ Π² Π²ΠΈΠ΄Π΅ Π±ΠΈΠ½Π°Ρ€Π½ΠΎΠ³ΠΎ значСния, Ρ‚Π°ΠΊ ΠΈ Π² Π²ΠΈΠ΄Π΅ ссылки, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π½Π° содСрТимоС Ρ„Π°ΠΉΠ»Π°, Ρ€Π°Π·ΠΌΠ΅Ρ‰Π΅Π½Π½ΠΎΠ΅ Π² Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ s3.
- Π­Π½Π΄ΠΏΠΎΠΈΠ½Ρ‚ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΌ ΠΈΠ»ΠΈ Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΌ.
- Π‘Π»ΠΎΠΆΠ½ΡƒΡŽ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹Π΄Π΅Π»ΠΈΡ‚ΡŒ Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΏΡƒΠ» процСссов. 

Π’Ρ‹Π±ΠΈΡ€Π°ΠΉΡ‚Π΅ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ Π² соотвСтствии со своими Π·Π°Π΄Π°Ρ‡Π°ΠΌΠΈ.

> [!NOTE]
> GigaServe Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ Ρ‚ΠΈΠΏ `multipart/form-data`.
> Для Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Π±ΠΈΠ½Π°Ρ€Π½ΠΎΠ³ΠΎ значСния Ρ„Π°ΠΉΠ»Π° Π² runnable-интСрфСйс ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²ΠΊΡƒ base64.
>
> [ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Ρ„Π°ΠΉΠ»Π° Π·Π°ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ base64](https://github.com/ai-forever/gigaserve/tree/main/examples/file_processing).
>
> Π’Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π·Π°Π³Ρ€ΡƒΠΆΠ°Ρ‚ΡŒ Ρ„Π°ΠΉΠ»Ρ‹ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ссылок (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π² Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ s3) ΠΈΠ»ΠΈ Π·Π°Π³Ρ€ΡƒΠΆΠ°Ρ‚ΡŒ ΠΈΡ… Π½Π° ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ эндпоинт ΠΊΠ°ΠΊ `multipart/form-data`.

### НастраиваСмыС Ρ‚ΠΈΠΏΡ‹ Π²Ρ…ΠΎΠ΄Π½Ρ‹Ρ… ΠΈ Π²Ρ‹Ρ…ΠΎΠ΄Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…

Π’ΠΈΠΏΡ‹ Π²Ρ…ΠΎΠ΄Π½Ρ‹Ρ… ΠΈ Π²Ρ‹Ρ…ΠΎΠ΄Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‚ΡΡ для всСх runnable-интСрфСйсов. Они доступны Π² Π°Ρ‚Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π°Ρ… `input_schema` ΠΈ `output_schema`. GigaServe ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ эти Ρ‚ΠΈΠΏΡ‹ для Π²Π°Π»ΠΈΠ΄Π°Ρ†ΠΈΠΈ Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ.

Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΠ΅Ρ€Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ наслСдованныС Ρ‚ΠΈΠΏΡ‹ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° `with_types`.

ΠžΠ±Ρ‰ΠΈΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Ρ‚ΠΈΠΏΠ°ΠΌΠΈ:

```python
from typing import Any

from fastapi import FastAPI
from langchain.schema.runnable import RunnableLambda

app = FastAPI()


def func(x: Any) -> int:
    """ΠžΡˆΠΈΠ±ΠΎΡ‡Π½ΠΎ заданная функция, которая ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π»ΡŽΠ±Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅, хотя Π΄ΠΎΠ»ΠΆΠ½Π° ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ int."""
    return x + 1


runnable = RunnableLambda(func).with_types(
    input_type=int,
)

add_routes(app, runnable)
```

### ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠ΅ Ρ‚ΠΈΠΏΡ‹

Для дСсСриализации Π΄Π°Π½Π½Ρ‹Ρ… Π² pydantic-модСль, Π° Π½Π΅ `dict`, ΡƒΠ½Π°ΡΠ»Π΅Π΄ΡƒΠΉΡ‚Π΅ΡΡŒ ΠΎΡ‚ `CustomUserType`.
ΠŸΡ€ΠΈ наслСдовании ΠΎΡ‚ этого Ρ‚ΠΈΠΏΠ° сСрвСр Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Ρ‹Π²Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ Π² `dict`, Π° Π±ΡƒΠ΄Π΅Ρ‚ ΡΠΎΡ…Ρ€Π°Π½ΡΡ‚ΡŒ ΠΈΡ… ΠΊΠ°ΠΊ pydantic-модСль.

```python
from fastapi import FastAPI
from langchain.schema.runnable import RunnableLambda

from langserve import add_routes
from langserve.schema import CustomUserType

app = FastAPI()


class Foo(CustomUserType):
    bar: int


def func(foo: Foo) -> int:
    """ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, которая ΠΎΠΆΠΈΠ΄Π°Π΅Ρ‚ Ρ‚ΠΈΠΏ Foo, прСдставлСнный Π² Π²ΠΈΠ΄Π΅ ΠΌΠΎΠ΄Π΅ pydantic model"""
    assert isinstance(foo, Foo)
    return foo.bar

# ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ Π²Ρ…ΠΎΠ΄Π½Ρ‹Π΅ ΠΈ Π²Ρ‹Ρ…ΠΎΠ΄Π½Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹ Π½Π°ΡΠ»Π΅Π΄ΡƒΡŽΡ‚ΡΡ автоматичСски!
# Π’Π°ΠΌ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ ΠΈΡ… ΡƒΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ
# runnable = RunnableLambda(func).with_types( # <-- НС Π½ΡƒΠΆΠ½ΠΎ Π² Π΄Π°Π½Π½ΠΎΠΌ случаС
#     input_schema=Foo,
#     output_schema=int,
#
add_routes(app, RunnableLambda(func), path="/foo")
```

> [!NOTE]
> Π’ΠΈΠΏ `CustomUserType` поддСрТиваСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π° сторонС сСрвСра ΠΈ опрСдСляСт ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΈ Π΄Π΅ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ Π΄Π°Π½Π½Ρ‹Ρ….

### Π’ΠΈΠ΄ΠΆΠ΅Ρ‚Ρ‹ ΠΈΠ½Ρ‚Π΅Ρ€Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎΠΉ страницы

На страницС пСсочницы Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ Π²ΠΈΠ΄ΠΆΠ΅Ρ‚Ρ‹, Π΄Π΅ΠΌΠΎΠ½ΡΡ‚Ρ€ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠ΅ Ρ€Π°Π±ΠΎΡ‚Ρƒ runnable-интСрфСйсов вашСго Π±Π΅ΠΊΠ΅Π½Π΄Π°.

- Π’ΠΈΠ΄ΠΆΠ΅Ρ‚ задаСтся Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ поля ΠΈ поставляСтся ΠΊΠ°ΠΊ Ρ‡Π°ΡΡ‚ΡŒ JSON-схСмы Π²Π²ΠΎΠ΄Π½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°.
- Π’ΠΈΠ΄ΠΆΠ΅Ρ‚ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ ΠΊΠ»ΡŽΡ‡ `type`, Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ являСтся ΠΎΠ΄ΠΈΠ½ ΠΈΠ· извСстного списка Π²ΠΈΠ΄ΠΆΠ΅Ρ‚ΠΎΠ².
- Π”Ρ€ΡƒΠ³ΠΈΠ΅ ΠΊΠ»ΡŽΡ‡ΠΈ Π²ΠΈΠ΄ΠΆΠ΅Ρ‚Π° Π±ΡƒΠ΄ΡƒΡ‚ связаны со значСниями, ΠΎΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‰ΠΈΠΌΠΈ ΠΏΡƒΡ‚ΠΈ Π² JSON-ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π΅.

ΠžΠ±Ρ‰Π°Ρ схСма:

```typescript
type JsonPath = number | string | (number | string)[];
type NameSpacedPath = { title: string; path: JsonPath }; // title ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для ΠΈΠΌΠΈΡ‚Π°Ρ†ΠΈΠΈ JSON-схСмы, Π½ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ namespace
type OneOfPath = { oneOf: JsonPath[] };

type Widget = {
    type: string // Какой-Ρ‚ΠΎ Ρ…ΠΎΡ€ΠΎΡˆΠΎ извСстный Ρ‚ΠΈΠΏ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, base64file, chat ΠΈ Π΄Ρ€.
    [key: string]: JsonPath | NameSpacedPath | OneOfPath;
};
```

#### Π’ΠΈΠ΄ΠΆΠ΅Ρ‚ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Ρ„Π°ΠΉΠ»Π°

Π’ΠΈΠ΄ΠΆΠ΅Ρ‚ позволяСт Π·Π°Π³Ρ€ΡƒΠΆΠ°Ρ‚ΡŒ Ρ„Π°ΠΉΠ»Ρ‹ Π² интСрфСйсС пСсочницы. Π Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ для Ρ„Π°ΠΉΠ»ΠΎΠ² Π² Π²ΠΈΠ΄Π΅ base64-строки.

Π€Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°:

```python
try:
    from pydantic.v1 import Field
except ImportError:
    from pydantic import Field

from langserve import CustomUserType


# Π’ΠΠ˜ΠœΠΠΠ˜Π•: ΠΠ°ΡΠ»Π΅Π΄ΡƒΠΉΡ‚Π΅ΡΡŒ ΠΎΡ‚ CustomUserType, Π° Π½Π΅ ΠΎΡ‚ BaseModel. Π’ ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС
#            сСрвСр Π΄Π΅ΠΊΠΎΠ΄ΠΈΡ€ΡƒΠ΅Ρ‚ Π΄Π°Π½Π½Ρ‹Π΅ Π² dict, Π° Π½Π΅ модСль pydantic.
class FileProcessingRequest(CustomUserType):
    """Request including a base64 encoded file."""

    # Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ ΠΏΠΎΠ»Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π·Π°Π΄Π°Ρ‚ΡŒ Π²ΠΈΠ΄ΠΆΠ΅Ρ‚ Π² интСрфСйсС ΠΈΠ½Ρ‚Π΅Ρ€Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎΠΉ страницы.
    file: str = Field(..., extra={"widget": {"type": "base64file"}})
    num_chars: int = 100

```

> [!NOTE]
> [ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½Ρ‹ΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Ρ„Π°ΠΉΠ»Π°](https://github.com/ai-forever/gigaserve/tree/main/examples/file_processing).

<p align="center">
<img src="https://github.com/langchain-ai/langserve/assets/3205522/52199e46-9464-4c2e-8be8-222250e08c3f" width="50%"/>
</p>

### Π’ΠΈΠ΄ΠΆΠ΅Ρ‚ Ρ‡Π°Ρ‚Π° {#vidzhet-chata}

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Π²ΠΈΠ΄ΠΆΠ΅Ρ‚Π° Π² [Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ](https://github.com/ai-forever/gigaserve/blob/main/examples/widgets/server.py).

Π§Ρ‚ΠΎΠ±Ρ‹ Π·Π°Π΄Π°Ρ‚ΡŒ Π²ΠΈΠ΄ΠΆΠ΅Ρ‚ Ρ‡Π°Ρ‚Π° ΠΏΠ΅Ρ€Π΅Π΄Π°ΠΉΡ‚Π΅ `"type": "chat"`:

* ПолС `input` β€” JSONPath ΠΊ полю запроса, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ содСрТит Π½ΠΎΠ²ΠΎΠ΅ входящСС сообщСниС.
* ПолС `output` β€” JSONPath ΠΊ полю ΠΎΡ‚Π²Π΅Ρ‚Π°, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ содСрТит ΠΎΠ΄Π½ΠΎ ΠΈΠ»ΠΈ нСсколько сообщСний.

НС ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΠΉΡ‚Π΅ эти поля, Ссли входящиС ΠΈ исходящиС Π΄Π°Π½Π½Ρ‹Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ прСдставлСны Π² исходном Π²ΠΈΠ΄Π΅.
НапримСр, Ссли Π½ΡƒΠΆΠ½ΠΎ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ исходящиС Π΄Π°Π½Π½Ρ‹Π΅ Π² Π²ΠΈΠ΄Π΅ списка сообщСний.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€:

```py
class ChatHistory(CustomUserType):
    chat_history: List[Tuple[str, str]] = Field(
        ...,
        examples=[[("human input", "ai response")]],
        extra={"widget": {"type": "chat", "input": "question", "output": "answer"}},
    )
    question: str


def _format_to_messages(input: ChatHistory) -> List[BaseMessage]:
    """ΠŸΡ€Π΅Π΄ΡΡ‚Π°Π²Π»Π΅Π½ΠΈΠ΅ Π²Π²ΠΎΠ΄Π΄Π° Π² Π²ΠΈΠ΄Π΅ списка собщСний."""
    history = input.chat_history
    user_input = input.question

    messages = []

    for human, ai in history:
        messages.append(HumanMessage(content=human))
        messages.append(AIMessage(content=ai))
    messages.append(HumanMessage(content=user_input))
    return messages


model = ChatOpenAI()
chat_model = RunnableParallel({"answer": (RunnableLambda(_format_to_messages) | model)})
add_routes(
    app,
    chat_model.with_types(input_type=ChatHistory),
    config_keys=["configurable"],
    path="/chat",
)
```

### Π’ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΈ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ эндпоинтов {#vklyuchenie-i-otklyuchenie-endpointov}

Начиная с вСрсии GigaServe 0.0.33, ΠΌΠΎΠΆΠ½ΠΎ Π²ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒ ΠΈ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹Π΅ эндпоинты.
Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ `enabled_endpoints`, Ссли Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ ΠΏΠ΅Ρ€Π΅Π·Π°ΠΏΠΈΡΡŒ эндпонтов ΠΏΡ€ΠΈ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠΈ вСрсии Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Π½ΠΈΠΆΠ΅ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹ эндпоинтов `invoke`, `batch` ΠΈ `config_hash`.

```python
add_routes(app, chain, enabled_endpoints=["invoke", "batch", "config_hashes"], path="/mychain")
```

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Π½ΠΈΠΆΠ΅ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ страницу пСсочницы для Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠΈ.

```python
add_routes(app, chain, disabled_endpoints=["playground"], path="/mychain")
```

## Π‘Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ‚ΡŒ

Π’ вСрсиях Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ 0.0.13β€”0.0.15 пСсочница, доступная ΠΏΠΎ адрСсу `/playground`, позволяСт ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ доступ ΠΊ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹ΠΌ Ρ„Π°ΠΉΠ»Π°ΠΌ Π½Π° сСрвСрС. Π’Π°ΠΊΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ [исправлСно Π² вСрсии Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ 0.0.16 ΠΈ Π²Ρ‹ΡˆΠ΅](https://github.com/langchain-ai/langserve/pull/98).

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/ai-forever/gigaserve",
    "name": "gigaserve",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<4.0,>=3.8.1",
    "maintainer_email": null,
    "keywords": null,
    "author": "LangChain",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/58/4e/4bce9ce41c1cc6599ff5984b4979ac34ba242e98410eeb3f476a37f14724/gigaserve-0.0.51.tar.gz",
    "platform": null,
    "description": "# GigaServe \ud83e\udd9c\ufe0f\ud83c\udfd3 = LangServe + GigaChat\n\nGigaServe \u2014 \u044d\u0442\u043e python-\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u0442\u044c \u0446\u0435\u043f\u043e\u0447\u043a\u0438 \u0438 runnable-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b GigaChain \u0441 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u043a \u043d\u0438\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0447\u0435\u0440\u0435\u0437 REST API.\n\n\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 GigaServe \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u0441 [FastAPI](https://fastapi.tiangolo.com/) \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0434\u043b\u044f \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 [Pydantic](https://docs.pydantic.dev/latest/).\n\n## \u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438\n\n\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438:\n\n- \u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0441\u0445\u0435\u043c \u0432\u0432\u043e\u0434\u0430 \u0438 \u0432\u044b\u0432\u043e\u0434\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 GigaChain. \u0421\u0445\u0435\u043c\u044b \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043a API \u0438 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u044e\u0442 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0430\u0445.\n- \u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 API-\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0441 JSONSchema \u0438 Swagger.\n- \u042d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u044b \u0441 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u0435 `/invoke`, `/batch` \u0438 `/stream`.\n- \u042d\u043d\u0434\u043f\u043e\u0438\u043d\u0442 `/stream_log` \u0434\u043b\u044f \u043f\u043e\u0442\u043e\u043a\u043e\u0432\u043e\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0432\u0441\u0435\u0445 \u0438\u043b\u0438 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0445 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0445 \u0448\u0430\u0433\u043e\u0432 \u0440\u0430\u0431\u043e\u0442\u044b \u0446\u0435\u043f\u043e\u0447\u043a\u0438/\u0430\u0433\u0435\u043d\u0442\u0430.\n- \u0418\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u0430\u044f \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u0430 `/playground` \u0441 \u043f\u043e\u0442\u043e\u043a\u043e\u0432\u044b\u043c \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c \u0438 \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0435\u0439 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0445 \u0448\u0430\u0433\u043e\u0432.\n- \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u0435\u043d\u043d\u044b\u0445 open-source \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a Python \u0442\u0430\u043a\u0438\u0445, \u043a\u0430\u043a FastAPI, Pydantic, uvloop \u0438 asyncio.\n- \u041a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0439 SDK, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443 GigaServe \u0442\u0430\u043a\u0436\u0435 \u043a\u0430\u043a \u043a \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u043c\u0443 runnable-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443 \u0438\u043b\u0438 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e HTTP API.\n\n### \u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f\n\n- \u041a\u043e\u043b\u0431\u044d\u043a\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435.\n- OpenAPI-\u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u043d\u0435 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f, \u0435\u0441\u043b\u0438 \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 Pydantic V2. \u042d\u0442\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u043e \u0441 \u0442\u0435\u043c, \u0447\u0442\u043e Fast API \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 [\u0441\u043c\u0435\u0448\u0438\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432 \u0438\u043c\u0435\u043d pydantic v1 \u0438 v2](https://github.com/tiangolo/fastapi/issues/10360). \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u043d\u0438\u0436\u0435.\n\n## \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 {#ustanovka}\n\n\u0414\u043b\u044f \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u0443:\n\n```bash\npip install \"gigaserve[all]\"\n```\n\n\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043a\u043b\u0438\u0435\u043d\u0442 \u0438 \u0441\u0435\u0440\u0432\u0435\u0440 \u043f\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043c\u0430\u043d\u0434:\n\n```sh\n# \u041a\u043e\u043c\u0430\u043d\u0434\u0430 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430\npip install \"gigaserve[client]\"\n\n# \u041a\u043e\u043c\u0430\u043d\u0434\u0430 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430\npip gigaserve \"langserve[server]\"\n```\n\n## GigaChain CLI \ud83d\udee0\ufe0f\n\nGigaChain CLI \u2014 \u044d\u0442\u043e \u0443\u0442\u0438\u043b\u0438\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0441\u0442\u0440\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442 GigaServe. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u0443:\n\n```sh\ngigachain app new ../path/to/directory\n```\n\n\u041f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 GigaChain CLI \u0432\u0441\u0435\u0433\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u0443\u0442\u0438\u043b\u0438\u0442\u044b. \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0435\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u044b:\n\n```sh\npip install -U gigachain-cli\n```\n\n## \u041f\u0440\u0438\u043c\u0435\u0440\u044b\n\n\u0414\u043b\u044f \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0441\u0442\u0430\u0440\u0442\u0430 GigaServe \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 [\u0448\u0430\u0431\u043b\u043e\u043d\u044b GigaChain](https://github.com/ai-forever/gigachain/blob/master/templates/README.md).\n\n\u0411\u043e\u043b\u044c\u0448\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432 \u0432\u044b \u043d\u0430\u0439\u0434\u0435\u0442\u0435 \u0432 [\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438](https://github.com/ai-forever/gigaserve/tree/main/examples).\n\n### \u0421\u0435\u0440\u0432\u0435\u0440\n\n\u041f\u0440\u0438\u043c\u0435\u0440 \u043d\u0438\u0436\u0435 \u0440\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442 \u0447\u0430\u0442-\u043c\u043e\u0434\u0435\u043b\u0438 GigaChat \u0438 \u0434\u0440\u0443\u0433\u0438\u0445 LLM, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0446\u0435\u043f\u043e\u0447\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0448\u0443\u0442\u043a\u0443 \u043f\u043e \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0439 \u0442\u0435\u043c\u0435 (`topic`) \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u043e\u0434\u0435\u043b\u0438 Anthropic.\n\n```python\n#!/usr/bin/env python\nfrom fastapi import FastAPI\nfrom langchain.prompts import ChatPromptTemplate\nfrom langchain.chat_models import GigaChat, ChatAnthropic, ChatOpenAI\n\nfrom langserve import add_routes\n\napp = FastAPI(\n  title=\"GigaChain Server\",\n  version=\"1.0\",\n  description=\"\u041f\u0440\u043e\u0441\u0442\u043e\u0439 API-\u0441\u0435\u0440\u0432\u0435\u0440, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0438\u0439 runnable-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b GigaChain\",\n)\n\nadd_routes(\n    app,\n    GigaChat(credentials=<\u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435>),\n    path=\"/gigachat\",\n) \n\nadd_routes(\n    app,\n    ChatOpenAI(),\n    path=\"/openai\",\n)\n\nadd_routes(\n    app,\n    ChatAnthropic(),\n    path=\"/anthropic\",\n)\n\nmodel = ChatAnthropic()\nprompt = ChatPromptTemplate.from_template(\"\u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0438 \u0448\u0443\u0442\u043a\u0443 \u043e {topic}\")\nadd_routes(\n    app,\n    prompt | model,\n    path=\"/joke\",\n)\n\nif __name__ == \"__main__\":\n    import uvicorn\n\n    uvicorn.run(app, host=\"localhost\", port=8000)\n```\n\n### \u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f\n\n\u0421\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0430\u044f OpenAPI-\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443, \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u043e\u043c\u0443 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u0430, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443:\n\n```sh\ncurl localhost:8000/docs\n```\n\n\u041f\u0440\u0438 \u044d\u0442\u043e\u043c, \u0430\u0434\u0440\u0435\u0441 `localhost:8000` \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0443 404, \u043f\u043e\u043a\u0430 \u0432\u044b \u043d\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u0435 `@app.get(\"/\")`.\n\n> [!NOTE]\n> \u041f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 pydantic v2 [\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u043d\u0435 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f](#\u0440\u0430\u0431\u043e\u0442\u0430-\u0441-pydantic) \u0434\u043b\u044f \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u043e\u0432 `/invoke`, `/batch`, `/stream` \u0438 `stream_log`.\n\n### \u041a\u043b\u0438\u0435\u043d\u0442\n\n\u041f\u0440\u0438\u043c\u0435\u0440 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 Python SDK:\n\n```python\nfrom langchain.schema import SystemMessage, HumanMessage\nfrom langchain.prompts import ChatPromptTemplate\nfrom langchain.schema.runnable import RunnableMap\nfrom langserve import RemoteRunnable\n\nopenai = RemoteRunnable(\"http://localhost:8000/openai/\")\nanthropic = RemoteRunnable(\"http://localhost:8000/anthropic/\")\njoke_chain = RemoteRunnable(\"http://localhost:8000/joke/\")\n\n# \u0421\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439 \u0432\u044b\u0437\u043e\u0432\n\njoke_chain.invoke({\"topic\": \"\u043f\u043e\u043f\u0443\u0433\u0430\u0438\"})\n\n# \u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439 \u0432\u044b\u0437\u043e\u0432\nawait joke_chain.ainvoke({\"topic\": \"\u043f\u043e\u043f\u0443\u0433\u0430\u0438\"})\n\nprompt = [\n    SystemMessage(content='\u0412\u0435\u0434\u0438 \u0441\u0435\u0431\u044f \u043a\u0430\u043a \u043a\u043e\u0448\u043a\u0430 \u0438\u043b\u0438 \u043f\u043e\u043f\u0443\u0433\u0430\u0439.'),\n    HumanMessage(content='\u041f\u0440\u0438\u0432\u0435\u0442!')\n]\n\n# \u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 astream\nasync for msg in anthropic.astream(prompt):\n    print(msg, end=\"\", flush=True)\n\nprompt = ChatPromptTemplate.from_messages(\n    [(\"system\", \"\u0420\u0430\u0441\u0441\u043a\u0430\u0436\u0438 \u043c\u043d\u0435 \u0434\u043b\u0438\u043d\u043d\u0443\u044e \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u043e {topic}\")]\n)\n\n# \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u0446\u0435\u043f\u043e\u0447\u0435\u043a\nchain = prompt | RunnableMap({\n    \"openai\": openai,\n    \"anthropic\": anthropic,\n})\n\nchain.batch([{ \"topic\": \"\u043f\u043e\u043f\u0443\u0433\u0430\u0438\" }, { \"topic\": \"\u043a\u043e\u0448\u043a\u0438\" }])\n```\n\n\u041f\u0440\u0438\u043c\u0435\u0440 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u043d\u0430 TypeScript (\u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f LangChain.js \u0432\u0435\u0440\u0441\u0438\u0438 0.0.166 \u0438\u043b\u0438 \u0432\u044b\u0448\u0435):\n\n```typescript\nimport { RemoteRunnable } from \"@langchain/core/runnables/remote\";\n\nconst chain = new RemoteRunnable({\n    url: `http://localhost:8000/joke/`,\n});\nconst result = await chain.invoke({\n  topic: \"\u043a\u043e\u0448\u043a\u0438\",\n});\n```\n\n\u041a\u043b\u0438\u0435\u043d\u0442, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0438\u0439 Python-\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 `requests`:\n\n```python\nimport requests\n\nresponse = requests.post(\n    \"http://localhost:8000/joke/invoke/\",\n    json={'input': {'topic': '\u043a\u043e\u0448\u043a\u0438'}}\n)\nresponse.json()\n```\n\n\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 cURL:\n\n```sh\ncurl --location --request POST 'http://localhost:8000/joke/invoke' \\\n    --header 'Content-Type: application/json' \\\n    --data-raw '{\n        \"input\": {\n            \"topic\": \"\u043a\u043e\u0448\u043a\u0438\"\n        }\n    }'\n```\n\n## \u042d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u044b\n\n\u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043d\u0438\u0436\u0435 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u044b \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 runnable-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430\u043c\u0438:\n\n```python\n...\nadd_routes(\n    app,\n    runnable,\n    path=\"/my_runnable\",\n)\n```\n\n\u0421\u043f\u0438\u0441\u043e\u043a \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u043e\u0432:\n\n- `POST /my_runnable/invoke` \u2014 \u0432\u044b\u0437\u0432\u0430\u0442\u044c runnable-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0434\u043b\u044f \u0435\u0434\u0438\u043d\u0438\u0447\u043d\u044b\u0445 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445;\n- `POST /my_runnable/batch` \u2014 \u0432\u044b\u0437\u0432\u0430\u0442\u044c runnable-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0434\u043b\u044f \u043d\u0430\u0431\u043e\u0440\u0430 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445;\n- `POST /my_runnable/stream` \u2014 \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0435\u0434\u0438\u043d\u0438\u0447\u043d\u044b\u0445 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 \u043f\u043e\u0442\u043e\u043a\u043e\u0432\u044b\u043c \u0432\u044b\u0432\u043e\u0434\u043e\u043c;\n- `POST /my_runnable/stream_log` \u2014 \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0435\u0434\u0438\u043d\u0438\u0447\u043d\u044b\u0445 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 \u043f\u043e\u0442\u043e\u043a\u043e\u0432\u044b\u043c \u0432\u044b\u0432\u043e\u0434\u043e\u043c, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u0432\u044b\u0432\u043e\u0434 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0445 \u0448\u0430\u0433\u043e\u0432 \u043f\u043e \u0445\u043e\u0434\u0443 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438;\n- `GET /my_runnable/input_schema` \u2014 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c JSON-\u0441\u0445\u0435\u043c\u0443 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 runnable-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430;\n- `GET /my_runnable/output_schema` \u2014 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c JSON-\u0441\u0445\u0435\u043c\u0443 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 runnable-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430;\n- `GET /my_runnable/config_schema` \u2014 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c JSON-\u0441\u0445\u0435\u043c\u0443 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 runnable-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430;\n\n> [!NOTE]\n> \u042d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441 [LangChain Expression Language interface (LCEL)](https://python.langchain.com/docs/expression_language/interface) \u2014 DSL \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0446\u0435\u043f\u043e\u0447\u0435\u043a.\n\n## \u041f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u0430\n\n\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u044b \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 `/my_runnable/playground`.\n\u041d\u0430 \u043d\u0435\u0439 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b runnable-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441 \u043a \u043d\u0435\u043c\u0443 \u0441 \u043f\u043e\u0442\u043e\u043a\u043e\u0432\u044b\u043c \u0432\u044b\u0432\u043e\u0434\u043e\u043c \u0438 \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0435\u0439 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0445 \u0448\u0430\u0433\u043e\u0432.\n\n<p align=\"center\">\n<img src=\"https://github.com/langchain-ai/langserve/assets/3205522/5ca56e29-f1bb-40f4-84b5-15916384a276\" width=\"50%\"/>\n</p>\n\n### \u0412\u0438\u0434\u0436\u0435\u0442\u044b\n\n\u041f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u0430 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 [\u0432\u0438\u0434\u0436\u0435\u0442\u044b](#playground-widgets) \u0438 \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u0430\u0448\u0438\u0445 \u0446\u0435\u043f\u043e\u0447\u0435\u043a \u0441 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u0432\u0445\u043e\u0434\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438.\n\n\u041a\u0440\u043e\u043c\u0435 \u044d\u0442\u043e\u0433\u043e, \u0435\u0441\u043b\u0438 \u0446\u0435\u043f\u043e\u0447\u043a\u0430 \u043c\u043e\u0436\u0435\u0442 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c\u0441\u044f, \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u0430 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0437\u0430\u0434\u0430\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0446\u0435\u043f\u043e\u0447\u043a\u0438 \u0438 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441\u0441\u044b\u043b\u043a\u043e\u0439 \u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u0443\u044e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e.\n\n### \u041e\u0431\u043c\u0435\u043d \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0435\u0439 \u0446\u0435\u043f\u043e\u0447\u043a\u0438\n\nIn addition, for configurable runnables, the playground will allow you to configure the\nrunnable and share a link with the configuration:\n\n<p align=\"center\">\n<img src=\"https://github.com/langchain-ai/langserve/assets/3205522/86ce9c59-f8e4-4d08-9fa3-62030e0f521d\" width=\"50%\"/>\n</p>\n\n\n## \u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u0446\u0435\u043f\u043e\u0447\u043a\u0430\u043c\u0438\n\nGigaServe \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u0430\u043a \u0441 runnable-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430\u043c\u0438 (\u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e [LangChain Expression Language](https://python.langchain.com/docs/expression_language/)), \u0442\u0430\u043a \u0438 \u0441 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u0446\u0435\u043f\u043e\u0447\u043a\u0430\u043c\u0438 (\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0442 `Chain`).\n\n\u041f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u0446\u0435\u043f\u043e\u0447\u043a\u0430\u043c\u0438 \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0439\u0442\u0435, \u0447\u0442\u043e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0445\u043e\u0434\u043d\u044b\u0435 \u0441\u0445\u0435\u043c\u044b \u0434\u043b\u044f \u0442\u0430\u043a\u0438\u0445 \u0446\u0435\u043f\u043e\u0447\u0435\u043a \u043c\u043e\u0433\u0443\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0438, \u0442.\u043a. \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u043c\u0438 \u0438\u043b\u0438 \u043d\u0435\u043f\u043e\u043b\u043d\u044b\u043c\u0438.\n\u0422\u0430\u043a\u0438\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0442\u0438\u0442\u044c, \u0435\u0441\u043b\u0438 \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0430\u0442\u0440\u0438\u0431\u0443\u0442 `input_schema` \u0442\u0430\u043a\u0438\u0445 \u0446\u0435\u043f\u043e\u0447\u0435\u043a \u0432 GigaChain.\n\n## \u0420\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u0435\n\n\u041d\u0438\u0436\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u044b \u0441\u043f\u043e\u0441\u043e\u0431\u044b \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u044f \u043d\u0430 Google Cloud Platforms (GCP) \u0438 Azure.\n\n### \u0420\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u0435 \u043d\u0430 GCP\n\n\u0414\u043b\u044f \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u044f \u043d\u0430 GCP Cloud Run \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u0443:\n\n```sh\ngcloud run deploy [your-service-name] --source . --port 8001 --allow-unauthenticated --region us-central1 --set-env-vars=GIGACHAT_API_KEY=your_key\n```\n\n### \u0420\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u0435 \u043d\u0430 Azure\n\n\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440 \u043d\u0430 Azure \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Azure Container Apps:\n\n```sh\naz containerapp up --name [container-app-name] --source . --resource-group [resource-group-name] --environment  [environment-name] --ingress external --target-port 8001 --env-vars=OPENAI_API_KEY=your_key\n```\n\n\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0432 [\u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438](https://learn.microsoft.com/en-us/azure/container-apps/containerapp-up).\n\n\n## \u0420\u0430\u0431\u043e\u0442\u0430 \u0441 Pydantic\n\nGigaServe \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 Pydantic v2 \u0441 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f\u043c\u0438:\n\n- \u041f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 Pydantic v2 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f OpenAPI \u043d\u0435 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f. \u042d\u0442\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u043e \u0441 \u0442\u0435\u043c, \u0447\u0442\u043e Fast API \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 [\u0441\u043c\u0435\u0448\u0438\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432 \u0438\u043c\u0435\u043d pydantic v1 \u0438 v2](https://github.com/tiangolo/fastapi/issues/10360).\n- GigaChain \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u0438\u043c\u0435\u043d \u0432\u0435\u0440\u0441\u0438\u0438 v1 \u0432 Pydantic v2.\n\n\u0417\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0445 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439, \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u044b API, \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u044b \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e.\n\n## \u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438\n\n## \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438\n\n\u041e \u0442\u043e\u043c, \u043a\u0430\u043a \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u043d\u0430 \u0441\u0432\u043e\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 GigaServe \u2014 \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0430\u0445 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 FastAPI, \u043f\u043e\u0441\u0432\u044f\u0449\u0435\u043d\u043d\u044b\u0445 [\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438](https://fastapi.tiangolo.com/tutorial/security/) \u0438 [\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044e \u0441\u0432\u044f\u0437\u0443\u044e\u0449\u0435\u0433\u043e \u041f\u041e](https://fastapi.tiangolo.com/tutorial/middleware/).\n\n### \u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438\n\n\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0444\u0430\u0439\u043b\u043e\u0432 \u2014 \u044d\u0442\u043e \u0442\u0438\u043f\u0438\u0447\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u0434\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u044f\u0437\u044b\u043a\u043e\u0432\u044b\u0445 \u043c\u043e\u0434\u0435\u043b\u0435\u0439.\n\u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u044b\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044b \u0434\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438:\n\n- \u0424\u0430\u0439\u043b \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043e\u0434\u043d\u043e\u0433\u043e \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u0430 \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0434\u0440\u0443\u0433\u043e\u0433\u043e;\n- \u0424\u0430\u0439\u043b \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u043a\u0430\u043a \u0432 \u0432\u0438\u0434\u0435 \u0431\u0438\u043d\u0430\u0440\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u0442\u0430\u043a \u0438 \u0432 \u0432\u0438\u0434\u0435 \u0441\u0441\u044b\u043b\u043a\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0444\u0430\u0439\u043b\u0430, \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u043d\u043e\u0435 \u0432 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 s3.\n- \u042d\u043d\u0434\u043f\u043e\u0438\u043d\u0442 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0449\u0438\u043c \u0438\u043b\u0438 \u043d\u0435\u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0449\u0438\u043c.\n- \u0421\u043b\u043e\u0436\u043d\u0443\u044e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0434\u0435\u043b\u0438\u0442\u044c \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u0443\u043b \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0432. \n\n\u0412\u044b\u0431\u0438\u0440\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0445\u043e\u0434 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441\u043e \u0441\u0432\u043e\u0438\u043c\u0438 \u0437\u0430\u0434\u0430\u0447\u0430\u043c\u0438.\n\n> [!NOTE]\n> GigaServe \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0442\u0438\u043f `multipart/form-data`.\n> \u0414\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0431\u0438\u043d\u0430\u0440\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u0430 \u0432 runnable-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0443 base64.\n>\n> [\u041f\u0440\u0438\u043c\u0435\u0440 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0444\u0430\u0439\u043b\u0430 \u0437\u0430\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e base64](https://github.com/ai-forever/gigaserve/tree/main/examples/file_processing).\n>\n> \u0412\u044b \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0441\u044b\u043b\u043e\u043a (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 s3) \u0438\u043b\u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0438\u0445 \u043d\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442 \u043a\u0430\u043a `multipart/form-data`.\n\n### \u041d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c\u044b\u0435 \u0442\u0438\u043f\u044b \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0438 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445\n\n\u0422\u0438\u043f\u044b \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0438 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u0432\u0441\u0435\u0445 runnable-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u0432. \u041e\u043d\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0432 \u0430\u0442\u0442\u0440\u0438\u0431\u0443\u0442\u0430\u0445 `input_schema` \u0438 `output_schema`. GigaServe \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u044d\u0442\u0438 \u0442\u0438\u043f\u044b \u0434\u043b\u044f \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438.\n\n\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0435\u0442\u043e\u0434\u0430 `with_types`.\n\n\u041e\u0431\u0449\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0442\u0438\u043f\u0430\u043c\u0438:\n\n```python\nfrom typing import Any\n\nfrom fastapi import FastAPI\nfrom langchain.schema.runnable import RunnableLambda\n\napp = FastAPI()\n\n\ndef func(x: Any) -> int:\n    \"\"\"\u041e\u0448\u0438\u0431\u043e\u0447\u043d\u043e \u0437\u0430\u0434\u0430\u043d\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043b\u044e\u0431\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u0445\u043e\u0442\u044f \u0434\u043e\u043b\u0436\u043d\u0430 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c int.\"\"\"\n    return x + 1\n\n\nrunnable = RunnableLambda(func).with_types(\n    input_type=int,\n)\n\nadd_routes(app, runnable)\n```\n\n### \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 \u0442\u0438\u043f\u044b\n\n\u0414\u043b\u044f \u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 pydantic-\u043c\u043e\u0434\u0435\u043b\u044c, \u0430 \u043d\u0435 `dict`, \u0443\u043d\u0430\u0441\u043b\u0435\u0434\u0443\u0439\u0442\u0435\u0441\u044c \u043e\u0442 `CustomUserType`.\n\u041f\u0440\u0438 \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0438 \u043e\u0442 \u044d\u0442\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 `dict`, \u0430 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0438\u0445 \u043a\u0430\u043a pydantic-\u043c\u043e\u0434\u0435\u043b\u044c.\n\n```python\nfrom fastapi import FastAPI\nfrom langchain.schema.runnable import RunnableLambda\n\nfrom langserve import add_routes\nfrom langserve.schema import CustomUserType\n\napp = FastAPI()\n\n\nclass Foo(CustomUserType):\n    bar: int\n\n\ndef func(foo: Foo) -> int:\n    \"\"\"\u041f\u0440\u0438\u043c\u0435\u0440 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u0436\u0438\u0434\u0430\u0435\u0442 \u0442\u0438\u043f Foo, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u0432 \u0432\u0438\u0434\u0435 \u043c\u043e\u0434\u0435 pydantic model\"\"\"\n    assert isinstance(foo, Foo)\n    return foo.bar\n\n# \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0432\u0445\u043e\u0434\u043d\u044b\u0435 \u0438 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u044e\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438!\n# \u0412\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0438\u0445 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c\n# runnable = RunnableLambda(func).with_types( # <-- \u041d\u0435 \u043d\u0443\u0436\u043d\u043e \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435\n#     input_schema=Foo,\n#     output_schema=int,\n#\nadd_routes(app, RunnableLambda(func), path=\"/foo\")\n```\n\n> [!NOTE]\n> \u0422\u0438\u043f `CustomUserType` \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043f\u0440\u0438 \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445.\n\n### \u0412\u0438\u0434\u0436\u0435\u0442\u044b \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b\n\n\u041d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u044b \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0432\u0438\u0434\u0436\u0435\u0442\u044b, \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u044e\u0449\u0438\u0435 \u0440\u0430\u0431\u043e\u0442\u0443 runnable-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u0432 \u0432\u0430\u0448\u0435\u0433\u043e \u0431\u0435\u043a\u0435\u043d\u0434\u0430.\n\n- \u0412\u0438\u0434\u0436\u0435\u0442 \u0437\u0430\u0434\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u043f\u043e\u043b\u044f \u0438 \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u0447\u0430\u0441\u0442\u044c JSON-\u0441\u0445\u0435\u043c\u044b \u0432\u0432\u043e\u0434\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430.\n- \u0412\u0438\u0434\u0436\u0435\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043a\u043b\u044e\u0447 `type`, \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0434\u0438\u043d \u0438\u0437 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e\u0433\u043e \u0441\u043f\u0438\u0441\u043a\u0430 \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432.\n- \u0414\u0440\u0443\u0433\u0438\u0435 \u043a\u043b\u044e\u0447\u0438 \u0432\u0438\u0434\u0436\u0435\u0442\u0430 \u0431\u0443\u0434\u0443\u0442 \u0441\u0432\u044f\u0437\u0430\u043d\u044b \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0438\u043c\u0438 \u043f\u0443\u0442\u0438 \u0432 JSON-\u043e\u0431\u044a\u0435\u043a\u0442\u0435.\n\n\u041e\u0431\u0449\u0430\u044f \u0441\u0445\u0435\u043c\u0430:\n\n```typescript\ntype JsonPath = number | string | (number | string)[];\ntype NameSpacedPath = { title: string; path: JsonPath }; // title \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0438\u043c\u0438\u0442\u0430\u0446\u0438\u0438 JSON-\u0441\u0445\u0435\u043c\u044b, \u043d\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c namespace\ntype OneOfPath = { oneOf: JsonPath[] };\n\ntype Widget = {\n    type: string // \u041a\u0430\u043a\u043e\u0439-\u0442\u043e \u0445\u043e\u0440\u043e\u0448\u043e \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0439 \u0442\u0438\u043f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, base64file, chat \u0438 \u0434\u0440.\n    [key: string]: JsonPath | NameSpacedPath | OneOfPath;\n};\n```\n\n#### \u0412\u0438\u0434\u0436\u0435\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0444\u0430\u0439\u043b\u0430\n\n\u0412\u0438\u0434\u0436\u0435\u0442 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u044b. \u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0434\u043b\u044f \u0444\u0430\u0439\u043b\u043e\u0432 \u0432 \u0432\u0438\u0434\u0435 base64-\u0441\u0442\u0440\u043e\u043a\u0438.\n\n\u0424\u0440\u0430\u0433\u043c\u0435\u043d\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u0430:\n\n```python\ntry:\n    from pydantic.v1 import Field\nexcept ImportError:\n    from pydantic import Field\n\nfrom langserve import CustomUserType\n\n\n# \u0412\u041d\u0418\u041c\u0410\u041d\u0418\u0415: \u041d\u0430\u0441\u043b\u0435\u0434\u0443\u0439\u0442\u0435\u0441\u044c \u043e\u0442 CustomUserType, \u0430 \u043d\u0435 \u043e\u0442 BaseModel. \u0412 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435\n#            \u0441\u0435\u0440\u0432\u0435\u0440 \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u0443\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 dict, \u0430 \u043d\u0435 \u043c\u043e\u0434\u0435\u043b\u044c pydantic.\nclass FileProcessingRequest(CustomUserType):\n    \"\"\"Request including a base64 encoded file.\"\"\"\n\n    # \u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u043b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u0434\u0430\u0442\u044c \u0432\u0438\u0434\u0436\u0435\u0442 \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b.\n    file: str = Field(..., extra={\"widget\": {\"type\": \"base64file\"}})\n    num_chars: int = 100\n\n```\n\n> [!NOTE]\n> [\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0444\u0430\u0439\u043b\u0430](https://github.com/ai-forever/gigaserve/tree/main/examples/file_processing).\n\n<p align=\"center\">\n<img src=\"https://github.com/langchain-ai/langserve/assets/3205522/52199e46-9464-4c2e-8be8-222250e08c3f\" width=\"50%\"/>\n</p>\n\n### \u0412\u0438\u0434\u0436\u0435\u0442 \u0447\u0430\u0442\u0430 {#vidzhet-chata}\n\n\u041f\u0440\u0438\u043c\u0435\u0440 \u0432\u0438\u0434\u0436\u0435\u0442\u0430 \u0432 [\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438](https://github.com/ai-forever/gigaserve/blob/main/examples/widgets/server.py).\n\n\u0427\u0442\u043e\u0431\u044b \u0437\u0430\u0434\u0430\u0442\u044c \u0432\u0438\u0434\u0436\u0435\u0442 \u0447\u0430\u0442\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0439\u0442\u0435 `\"type\": \"chat\"`:\n\n* \u041f\u043e\u043b\u0435 `input` \u2014 JSONPath \u043a \u043f\u043e\u043b\u044e \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043d\u043e\u0432\u043e\u0435 \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435.\n* \u041f\u043e\u043b\u0435 `output` \u2014 JSONPath \u043a \u043f\u043e\u043b\u044e \u043e\u0442\u0432\u0435\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043e\u0434\u043d\u043e \u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439.\n\n\u041d\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0439\u0442\u0435 \u044d\u0442\u0438 \u043f\u043e\u043b\u044f, \u0435\u0441\u043b\u0438 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0438 \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c \u0432\u0438\u0434\u0435.\n\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0432\u0438\u0434\u0435 \u0441\u043f\u0438\u0441\u043a\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439.\n\n\u041f\u0440\u0438\u043c\u0435\u0440:\n\n```py\nclass ChatHistory(CustomUserType):\n    chat_history: List[Tuple[str, str]] = Field(\n        ...,\n        examples=[[(\"human input\", \"ai response\")]],\n        extra={\"widget\": {\"type\": \"chat\", \"input\": \"question\", \"output\": \"answer\"}},\n    )\n    question: str\n\n\ndef _format_to_messages(input: ChatHistory) -> List[BaseMessage]:\n    \"\"\"\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0432\u0432\u043e\u0434\u0434\u0430 \u0432 \u0432\u0438\u0434\u0435 \u0441\u043f\u0438\u0441\u043a\u0430 \u0441\u043e\u0431\u0449\u0435\u043d\u0438\u0439.\"\"\"\n    history = input.chat_history\n    user_input = input.question\n\n    messages = []\n\n    for human, ai in history:\n        messages.append(HumanMessage(content=human))\n        messages.append(AIMessage(content=ai))\n    messages.append(HumanMessage(content=user_input))\n    return messages\n\n\nmodel = ChatOpenAI()\nchat_model = RunnableParallel({\"answer\": (RunnableLambda(_format_to_messages) | model)})\nadd_routes(\n    app,\n    chat_model.with_types(input_type=ChatHistory),\n    config_keys=[\"configurable\"],\n    path=\"/chat\",\n)\n```\n\n### \u0412\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0438 \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u043e\u0432 {#vklyuchenie-i-otklyuchenie-endpointov}\n\n\u041d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 \u0432\u0435\u0440\u0441\u0438\u0438 GigaServe 0.0.33, \u043c\u043e\u0436\u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0438 \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u0435 \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u044b.\n\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442 `enabled_endpoints`, \u0435\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u044c \u044d\u043d\u0434\u043f\u043e\u043d\u0442\u043e\u0432 \u043f\u0440\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 \u0432\u0435\u0440\u0441\u0438\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438.\n\n\u041f\u0440\u0438\u043c\u0435\u0440 \u043d\u0438\u0436\u0435 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u043e\u0432 `invoke`, `batch` \u0438 `config_hash`.\n\n```python\nadd_routes(app, chain, enabled_endpoints=[\"invoke\", \"batch\", \"config_hashes\"], path=\"/mychain\")\n```\n\n\u041f\u0440\u0438\u043c\u0435\u0440 \u043d\u0438\u0436\u0435 \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u044b \u0434\u043b\u044f \u0446\u0435\u043f\u043e\u0447\u043a\u0438.\n\n```python\nadd_routes(app, chain, disabled_endpoints=[\"playground\"], path=\"/mychain\")\n```\n\n## \u0411\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c\n\n\u0412 \u0432\u0435\u0440\u0441\u0438\u044f\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 0.0.13\u20140.0.15 \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u0430, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430\u044f \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 `/playground`, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u043c \u0444\u0430\u0439\u043b\u0430\u043c \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435. \u0422\u0430\u043a\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 [\u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043e \u0432 \u0432\u0435\u0440\u0441\u0438\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 0.0.16 \u0438 \u0432\u044b\u0448\u0435](https://github.com/langchain-ai/langserve/pull/98).\n",
    "bugtrack_url": null,
    "license": "LangServe",
    "summary": null,
    "version": "0.0.51",
    "project_urls": {
        "Homepage": "https://github.com/ai-forever/gigaserve",
        "Repository": "https://github.com/ai-forever/gigaserve"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "b2e786e84e22656e08832a0e2c615635f5d8a551fdc19cde8310ea99cd6dff75",
                "md5": "68c3a8103d4abd1fd9ddeb7775e5fc83",
                "sha256": "6ac5bdc89143f9816e24a5228a94c40c6d696d9080214d5ff6fcf0508eef7f75"
            },
            "downloads": -1,
            "filename": "gigaserve-0.0.51-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "68c3a8103d4abd1fd9ddeb7775e5fc83",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4.0,>=3.8.1",
            "size": 1165210,
            "upload_time": "2024-03-25T06:50:18",
            "upload_time_iso_8601": "2024-03-25T06:50:18.106428Z",
            "url": "https://files.pythonhosted.org/packages/b2/e7/86e84e22656e08832a0e2c615635f5d8a551fdc19cde8310ea99cd6dff75/gigaserve-0.0.51-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "584e4bce9ce41c1cc6599ff5984b4979ac34ba242e98410eeb3f476a37f14724",
                "md5": "3879d7d7e90c4a95f3fd2202b8f89fb6",
                "sha256": "33379572f4b2caea4c69a3f039601ccce16384dbfcb9703a5de060ef8365eba6"
            },
            "downloads": -1,
            "filename": "gigaserve-0.0.51.tar.gz",
            "has_sig": false,
            "md5_digest": "3879d7d7e90c4a95f3fd2202b8f89fb6",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<4.0,>=3.8.1",
            "size": 1131932,
            "upload_time": "2024-03-25T06:50:20",
            "upload_time_iso_8601": "2024-03-25T06:50:20.422254Z",
            "url": "https://files.pythonhosted.org/packages/58/4e/4bce9ce41c1cc6599ff5984b4979ac34ba242e98410eeb3f476a37f14724/gigaserve-0.0.51.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-03-25 06:50:20",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "ai-forever",
    "github_project": "gigaserve",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "gigaserve"
}
        
Elapsed time: 0.56808s