• Сообщения
  • Управляемые агенты
  • Администрирование
Search...
⌘K
CLI, SDK и библиотеки
Обзор
ant CLI
Быстрый стартВарианты аутентификацииИспользование CLIСкрипты и автоматизация
Клиентские SDK
Промежуточное ПОPythonTypeScriptC#GoJavaPHPRuby
Библиотеки и интеграции
Apple Foundation ModelsСовместимость с OpenAI SDK
Log in
Python
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...

Solutions

  • AI agents
  • Code modernization
  • Coding
  • Customer support
  • Education
  • Financial services
  • Government
  • Life sciences

Partners

  • Amazon Bedrock
  • Google Cloud's Vertex AI

Learn

  • Blog
  • Courses
  • Use cases
  • Connectors
  • Customer stories
  • Engineering at Anthropic
  • Events
  • Powered by Claude
  • Service partners
  • Startups program

Company

  • Anthropic
  • Careers
  • Economic Futures
  • Research
  • News
  • Responsible Scaling Policy
  • Security and compliance
  • Transparency

Learn

  • Blog
  • Courses
  • Use cases
  • Connectors
  • Customer stories
  • Engineering at Anthropic
  • Events
  • Powered by Claude
  • Service partners
  • Startups program

Help and security

  • Availability
  • Status
  • Support
  • Discord

Terms and policies

  • Privacy policy
  • Responsible disclosure policy
  • Terms of service: Commercial
  • Terms of service: Consumer
  • Usage policy
CLI, SDK и библиотеки/Клиентские SDK

Python SDK

Установка и настройка Anthropic Python SDK с поддержкой синхронного и асинхронного клиентов

Anthropic Python SDK предоставляет удобный доступ к Anthropic REST API из приложений на Python. Он поддерживает как синхронные, так и асинхронные операции, потоковую передачу, а также интеграции с Amazon Bedrock, Vertex AI, Microsoft Foundry и Claude Platform на AWS.

Документацию по функциям API с примерами кода см. в справочнике по API. На этой странице рассматриваются специфичные для Python возможности и настройки SDK.

Установка

pip install anthropic

Для интеграций с конкретными платформами или улучшенной асинхронной производительности установите пакет с дополнительными зависимостями:

# Для поддержки Amazon Bedrock
pip install "anthropic[bedrock]"

# Для поддержки Vertex AI
pip install "anthropic[vertex]"

# Для поддержки Claude Platform на AWS
pip install "anthropic[aws]"

# Поддержка Microsoft Foundry включена в базовый пакет

# Для улучшенной асинхронной производительности с aiohttp
pip install "anthropic[aiohttp]"

Требования

Требуется Python 3.9 или более поздней версии.

Использование

import os
from anthropic import Anthropic

client = Anthropic(
    # Это значение по умолчанию, его можно опустить
    api_key=os.environ.get("ANTHROPIC_API_KEY"),
)

message = client.messages.create(
    max_tokens=1024,
    messages=[
        {
            "role": "user",
            "content": "Hello, Claude",
        }
    ],
    model="claude-opus-4-8",
)
print(message.content)

Рекомендуется использовать python-dotenv, чтобы добавить ANTHROPIC_API_KEY="my-anthropic-api-key" в файл .env — так ваш ключ API не попадёт в систему контроля версий.

Варианты аутентификации, включая Workload Identity Federation, см. в разделе Аутентификация.

Асинхронное использование

import os
import asyncio
from anthropic import AsyncAnthropic

client = AsyncAnthropic(
    api_key=os.environ.get("ANTHROPIC_API_KEY"),
)


async def main() -> None:
    message = await client.messages.create(
        max_tokens=1024,
        messages=[
            {
                "role": "user",
                "content": "Hello, Claude",
            }
        ],
        model="claude-opus-4-8",
    )
    print(message.content)


asyncio.run(main())

Использование aiohttp для лучшей конкурентности

Для улучшенной асинхронной производительности вы можете использовать HTTP-бэкенд aiohttp вместо httpx, используемого по умолчанию:

import os
import asyncio
from anthropic import AsyncAnthropic, DefaultAioHttpClient


async def main() -> None:
    async with AsyncAnthropic(
        api_key=os.environ.get("ANTHROPIC_API_KEY"),
        http_client=DefaultAioHttpClient(),
    ) as client:
        message = await client.messages.create(
            max_tokens=1024,
            messages=[
                {
                    "role": "user",
                    "content": "Hello, Claude",
                }
            ],
            model="claude-opus-4-8",
        )
        print(message.content)


asyncio.run(main())

Потоковая передача ответов

SDK поддерживает потоковую передачу ответов с использованием «Server-Sent Events» (события, отправляемые сервером), или SSE.

client = Anthropic()

stream = client.messages.create(
    max_tokens=1024,
    messages=[
        {
            "role": "user",
            "content": "Hello, Claude",
        }
    ],
    model="claude-opus-4-8",
    stream=True,
)
for event in stream:
    print(event.type)

Асинхронный клиент использует точно такой же интерфейс:

client = AsyncAnthropic()

stream = await client.messages.create(
    max_tokens=1024,
    messages=[
        {
            "role": "user",
            "content": "Hello, Claude",
        }
    ],
    model="claude-opus-4-8",
    stream=True,
)
async for event in stream:
    print(event.type)

Вспомогательные функции потоковой передачи

SDK также предоставляет вспомогательные функции потоковой передачи, которые используют менеджеры контекста и дают доступ к накопленному тексту и итоговому сообщению:

async def main() -> None:
    async with client.messages.stream(
        max_tokens=1024,
        messages=[
            {
                "role": "user",
                "content": "Say hello there!",
            }
        ],
        model="claude-opus-4-8",
    ) as stream:
        async for text in stream.text_stream:
            print(text, end="", flush=True)
        print()

        message = await stream.get_final_message()
        print(message.to_json())


asyncio.run(main())

Потоковая передача с помощью client.messages.stream(...) предоставляет различные вспомогательные возможности, включая накопление и специфичные для SDK события.

В качестве альтернативы вы можете использовать client.messages.create(..., stream=True), который возвращает только итерируемый объект событий потока и использует меньше памяти (он не формирует для вас итоговый объект сообщения).

Подсчёт токенов

Вы можете увидеть точное использование для конкретного запроса через свойство ответа usage:

message = client.messages.create(...)
print(message.usage)
# Usage(input_tokens=25, output_tokens=13)

Вы также можете подсчитать токены до выполнения запроса:

count = client.messages.count_tokens(
    model="claude-opus-4-8", messages=[{"role": "user", "content": "Hello, world"}]
)
print(count.input_tokens)  # 10

Использование инструментов

Этот SDK поддерживает использование инструментов, также известное как вызов функций. Подробнее см. в разделе Использование инструментов с Claude.

Вспомогательные функции для инструментов

SDK предоставляет вспомогательные функции для определения и запуска инструментов как обычных функций Python. Декоратор @beta_tool генерирует схему инструмента на основе сигнатуры функции и её строки документации:

import json
from anthropic import Anthropic, beta_tool

client = Anthropic()


@beta_tool
def get_weather(location: str) -> str:
    """Get the weather for a given location.

    Args:
        location: The city and state, for example, San Francisco, CA
    Returns:
        A JSON-encoded string with the location, temperature, and weather condition.
    """
    return json.dumps(
        {
            "location": location,
            "temperature": "68°F",
            "condition": "Sunny",
        }
    )


# Используйте tool_runner для автоматической обработки вызовов инструментов
runner = client.beta.messages.tool_runner(
    max_tokens=1024,
    model="claude-opus-4-8",
    tools=[get_weather],
    messages=[
        {"role": "user", "content": "What is the weather in SF?"},
    ],
)
for message in runner:
    print(message)

На каждой итерации выполняется запрос к API. Если Claude хочет вызвать один из предоставленных инструментов, он вызывается автоматически, а результат возвращается непосредственно модели на следующей итерации.

Пакеты сообщений

Этот SDK поддерживает Message Batches API через client.messages.batches.

Создание пакета

Message Batches принимает массив запросов, где каждый объект содержит идентификатор custom_id и те же параметры запроса params, что и стандартный Messages API:

client.messages.batches.create(
    requests=[
        {
            "custom_id": "my-first-request",
            "params": {
                "model": "claude-opus-4-8",
                "max_tokens": 1024,
                "messages": [{"role": "user", "content": "Hello, world"}],
            },
        },
        {
            "custom_id": "my-second-request",
            "params": {
                "model": "claude-opus-4-8",
                "max_tokens": 1024,
                "messages": [{"role": "user", "content": "Hi again, friend"}],
            },
        },
    ]
)

Получение результатов из пакета

После того как пакет сообщений обработан, что обозначается .processing_status == 'ended', вы можете получить доступ к результатам с помощью .batches.results():

client = anthropic.Anthropic()
batch_id = "batch_abc123"
result_stream = client.messages.batches.results(batch_id)
for entry in result_stream:
    if entry.result.type == "succeeded":
        print(entry.result.message.content)

Загрузка файлов

Параметры запроса, соответствующие загрузке файлов, могут передаваться в различных формах:

  • Объект PathLike (например, pathlib.Path)
  • Кортеж (filename, content, content_type)
  • Файлоподобный объект BinaryIO
from pathlib import Path
from anthropic import Anthropic

client = Anthropic()

# Загрузка с использованием пути к файлу
client.beta.files.upload(
    file=Path("/path/to/file"),
)

# Загрузка с использованием байтов
client.beta.files.upload(
    file=("file.txt", b"my bytes", "text/plain"),
)

Асинхронный клиент использует точно такой же интерфейс. Если вы передаёте экземпляр PathLike, содержимое файла автоматически считывается асинхронно.

Обработка ошибок

Когда библиотека не может подключиться к API или если API возвращает код состояния, отличный от успешного (то есть ответ 4xx или 5xx), генерируется подкласс APIError:

import anthropic
# ...
try:
    message = client.messages.create(
        max_tokens=1024,
        messages=[
            {
                "role": "user",
                "content": "Hello, Claude",
            }
        ],
        model="claude-opus-4-8",
    )
except anthropic.APIConnectionError as e:
    print("The server could not be reached")
    print(e.__cause__)  # an underlying Exception, likely raised within httpx
except anthropic.RateLimitError as e:
    print("A 429 status code was received; we should back off a bit.")
except anthropic.APIStatusError as e:
    print("Another non-200-range status code was received")
    print(e.status_code)
    print(e.response)

Коды ошибок приведены ниже:

Код состоянияТип ошибки
400BadRequestError
401AuthenticationError
403PermissionDeniedError
404NotFoundError
409ConflictError
422UnprocessableEntityError
429RateLimitError
>=500InternalServerError
N/AAPIConnectionError

Идентификаторы запросов

Дополнительную информацию об отладке запросов см. в разделе Идентификатор запроса.

Все объектные ответы в SDK предоставляют свойство _request_id, которое добавляется из заголовка ответа request-id, чтобы вы могли быстро логировать неудачные запросы и сообщать о них в Anthropic.

message = client.messages.create(
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello, Claude"}],
    model="claude-opus-4-8",
)
print(message._request_id)  # e.g., req_018EeWyXxfu5pfWkrYcMdjWG

В отличие от других свойств с префиксом _, свойство _request_id является публичным. Если не указано иное, все остальные свойства, методы и модули с префиксом _ являются приватными.

Повторные попытки

Определённые ошибки по умолчанию автоматически повторяются 2 раза с короткой экспоненциальной задержкой. Ошибки подключения (например, из-за проблем с сетевым соединением), 408 Request Timeout, 409 Conflict, 429 Rate Limit и внутренние ошибки >=500 — все они повторяются по умолчанию.

Вы можете использовать параметр max_retries, чтобы настроить или отключить это поведение:

# Настройте значение по умолчанию для всех запросов:
client = Anthropic(
    max_retries=0,  # default is 2
)

# Или настройте для отдельного запроса:
client.with_options(max_retries=5).messages.create(
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello, Claude"}],
    model="claude-opus-4-8",
)

Тайм-ауты

По умолчанию время ожидания запросов истекает через 10 минут. Вы можете настроить это с помощью параметра timeout, который принимает число с плавающей точкой или объект httpx.Timeout:

import httpx
from anthropic import Anthropic

# Настройте значение по умолчанию для всех запросов:
client = Anthropic(
    timeout=20.0,  # 20 seconds (default is 10 minutes)
)

# Более детальный контроль:
client = Anthropic(
    timeout=httpx.Timeout(60.0, read=5.0, write=10.0, connect=2.0),
)

# Переопределение для отдельного запроса:
client.with_options(timeout=5.0).messages.create(
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello, Claude"}],
    model="claude-opus-4-8",
)

При истечении времени ожидания генерируется исключение APITimeoutError.

Обратите внимание, что запросы, время ожидания которых истекло, по умолчанию повторяются дважды.

Длительные запросы

Рекомендуется использовать потоковый Messages API для более длительных запросов.

Избегайте установки большого значения max_tokens без использования потоковой передачи. Некоторые сети могут разрывать неактивные соединения по истечении определённого времени, что может привести к сбою запроса или тайм-ауту без получения ответа от Anthropic.

SDK сгенерирует исключение ValueError, если ожидается, что непотоковый запрос займёт более примерно 10 минут. Передача stream=True или переопределение параметра timeout на уровне клиента или запроса отключает эту ошибку.

Если ожидаемая задержка запроса превышает тайм-аут для непотокового запроса, клиент разорвёт соединение и повторит попытку, не получив ответа.

SDK устанавливает параметр TCP socket keep-alive, чтобы снизить влияние тайм-аутов неактивных соединений в некоторых сетях. Это можно переопределить, передав клиенту пользовательский параметр http_client.

Автоматическая пагинация

Методы списков в Claude API используют пагинацию. Вы можете использовать синтаксис for для итерации по элементам на всех страницах:

client = Anthropic()

all_batches = []
# Автоматически загружает дополнительные страницы по мере необходимости.
for batch in client.messages.batches.list(limit=20):
    all_batches.append(batch)
print(all_batches)

Для асинхронной итерации:

async def main() -> None:
    all_batches = []
    async for batch in client.messages.batches.list(limit=20):
        all_batches.append(batch)
    print(all_batches)


asyncio.run(main())

В качестве альтернативы вы можете использовать методы .has_next_page(), .next_page_info() или .get_next_page() для более детального управления работой со страницами:

first_page = await client.messages.batches.list(limit=20)

if first_page.has_next_page():
    print(f"will fetch next page using these details: {first_page.next_page_info()}")
    next_page = await first_page.get_next_page()
    print(f"number of items we just fetched: {len(next_page.data)}")

# Удалите `await` для неасинхронного использования.

Или работать напрямую с возвращёнными данными:

first_page = await client.messages.batches.list(limit=20)

print(f"next page cursor: {first_page.last_id}")
for batch in first_page.data:
    print(batch.id)

# Удалите `await` для неасинхронного использования.

Заголовки по умолчанию

SDK автоматически отправляет заголовок anthropic-version со значением 2023-06-01.

При необходимости вы можете переопределить его, установив заголовки по умолчанию на объекте клиента или для отдельного запроса.

Переопределение заголовков по умолчанию может привести к некорректным типам и другому неожиданному или неопределённому поведению SDK.

# Задайте заголовки по умолчанию для всех запросов клиента
client = Anthropic(
    default_headers={"anthropic-version": "My-Custom-Value"},
)

# Или переопределите для отдельного запроса
client.messages.with_raw_response.create(
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello, Claude"}],
    model="claude-opus-4-8",
    extra_headers={"anthropic-version": "My-Custom-Value"},
)

Система типов

Параметры запроса

Вложенные параметры запроса представлены как TypedDicts. Ответы — это модели Pydantic, которые также имеют вспомогательные методы, например для сериализации обратно в JSON (v1, v2).

Типизированные запросы и ответы обеспечивают автодополнение и документацию в вашем редакторе. Если вы хотите видеть ошибки типов в VS Code, чтобы раньше выявлять баги, установите python.analysis.typeCheckingMode в значение basic.

Модели ответов

Чтобы преобразовать модель Pydantic в словарь, используйте вспомогательные методы:

message = client.messages.create(...)

# Преобразовать в строку JSON
json_str = message.to_json()

# Преобразовать в словарь
data = message.to_dict()

Обработка null и отсутствующих полей

В ответах вы можете различать поля, которые явно равны null, и поля, которые не были возвращены (отсутствуют):

response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello"}],
)
if response.my_field is None:
    if "my_field" not in response.model_fields_set:
        print("field was not in the response")
    else:
        print("field was null")

Расширенное использование

Доступ к необработанным данным ответа (например, заголовкам)

«Сырой» объект Response, возвращаемый httpx, доступен через свойство .with_raw_response клиента. Это полезно для доступа к заголовкам ответа или другим метаданным:

client = Anthropic()

response = client.messages.with_raw_response.create(
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello, Claude"}],
    model="claude-opus-4-8",
)

print(response.headers.get("request-id"))
message = (
    response.parse()
)  # get the object that `messages.create()` would have returned
print(message.content)

Эти методы возвращают объект APIResponse.

Потоковая передача тела ответа

Подход .with_raw_response сразу считывает всё тело ответа при выполнении запроса. Чтобы вместо этого передавать тело ответа потоком, используйте .with_streaming_response, который требует менеджера контекста и считывает тело ответа только при вызове .read(), .text(), .json(), .iter_bytes(), .iter_text(), .iter_lines() или .parse(). В асинхронном клиенте это асинхронные методы.

with client.messages.with_streaming_response.create(
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello, Claude"}],
    model="claude-opus-4-8",
) as response:
    print(response.headers.get("request-id"))

    for line in response.iter_lines():
        print(line)

Менеджер контекста обязателен, чтобы ответ был надёжно закрыт.

Логирование

SDK использует модуль logging стандартной библиотеки.

Вы можете включить логирование, установив переменную окружения ANTHROPIC_LOG в значение debug или info:

export ANTHROPIC_LOG=debug

Выполнение пользовательских/недокументированных запросов

Эта библиотека типизирована для удобного доступа к документированному API. Если вам нужен доступ к недокументированным конечным точкам, параметрам или свойствам ответа, библиотеку всё равно можно использовать.

Недокументированные конечные точки

Для выполнения запросов к недокументированным конечным точкам вы можете использовать client.get, client.post и другие HTTP-методы. Параметры клиента, такие как повторные попытки, будут учитываться при выполнении этих запросов.

import httpx

response = client.post(
    "/foo",
    cast_to=httpx.Response,
    body={"my_param": True},
)

print(response.json())

Недокументированные параметры запроса

Если вы хотите явно отправить дополнительный параметр, вы можете сделать это с помощью параметров запроса extra_query, extra_body и extra_headers.

Параметры extra_ переопределяют документированные параметры с тем же именем. По соображениям безопасности убедитесь, что эти методы используются только с доверенными входными данными.

Недокументированные свойства ответа

Для доступа к недокументированным свойствам ответа вы можете обращаться к дополнительным полям, например response.unknown_prop. Вы также можете получить все дополнительные поля модели Pydantic в виде словаря с помощью response.model_extra.

Настройка HTTP-клиента

Вы можете напрямую переопределить клиент httpx, чтобы настроить его под ваш сценарий использования, включая поддержку прокси и транспортов:

import httpx
from anthropic import Anthropic, DefaultHttpxClient

client = Anthropic(
    # Или используйте переменную окружения `ANTHROPIC_BASE_URL`
    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():

client.with_options(http_client=DefaultHttpxClient(...))

Используйте DefaultHttpxClient и DefaultAsyncHttpxClient вместо обычных httpx.Client и httpx.AsyncClient, чтобы сохранить конфигурацию SDK по умолчанию (тайм-ауты, лимиты соединений и т. д.).

Управление HTTP-ресурсами

По умолчанию библиотека закрывает базовые HTTP-соединения, когда клиент собирается сборщиком мусора. При желании вы можете вручную закрыть клиент с помощью метода .close() или с помощью менеджера контекста, который закрывает его при выходе.

with Anthropic() as client:
    message = client.messages.create(...)

# HTTP-клиент закрывается автоматически

Бета-функции

Бета-функции доступны до общего выпуска, чтобы получить ранние отзывы и протестировать новую функциональность. Вы можете проверить доступность всех возможностей и инструментов Claude в обзоре разработки с Claude.

Вы можете получить доступ к большинству бета-функций API через свойство beta клиента. Чтобы включить конкретную бета-функцию, вам нужно добавить соответствующий бета-заголовок в поле betas при создании сообщения.

Например, чтобы использовать Files API:

client = Anthropic()

response = client.beta.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    messages=[
        {
            "role": "user",
            "content": [
                {"type": "text", "text": "Please summarize this document for me."},
                {
                    "type": "document",
                    "source": {
                        "type": "file",
                        "file_id": "file_abc123",
                    },
                },
            ],
        },
    ],
    betas=["files-api-2025-04-14"],
)

Интеграции с платформами

Подробные руководства по настройке платформ с примерами кода см. здесь:

  • Amazon Bedrock
  • Amazon Bedrock (устаревший)
  • Vertex AI
  • Microsoft Foundry
  • Claude Platform на AWS

Все пять классов клиентов включены в базовый пакет anthropic:

ПровайдерКлиентДополнительные зависимости
Bedrockfrom anthropic import AnthropicBedrockMantlepip install "anthropic[bedrock]"
Bedrock (путь bedrock-runtime)from anthropic import AnthropicBedrockpip install "anthropic[bedrock]"
Vertex AIfrom anthropic import AnthropicVertexpip install "anthropic[vertex]"
Foundryfrom anthropic import AnthropicFoundryНет
Claude Platform на AWSfrom anthropic import AnthropicAWSpip install "anthropic[aws]"

Клиент AnthropicAWS находится в бета-версии. Передайте workspace_id в конструктор или установите переменную окружения ANTHROPIC_AWS_WORKSPACE_ID.

Используйте AnthropicBedrockMantle для новых проектов; AnthropicBedrock остаётся для существующих приложений, использующих Bedrock InvokeModel API.

Семантическое версионирование

Этот пакет в целом следует соглашениям SemVer, хотя некоторые обратно несовместимые изменения могут выпускаться как минорные версии:

  1. Изменения, которые затрагивают только статические типы, не нарушая поведение во время выполнения.
  2. Изменения во внутренних компонентах библиотеки, которые технически являются публичными, но не предназначены и не документированы для внешнего использования.
  3. Изменения, которые на практике не должны затронуть подавляющее большинство пользователей.

Определение установленной версии

Если вы обновились до последней версии, но не видите ожидаемых новых функций, вероятно, ваше окружение Python всё ещё использует более старую версию. Вы можете определить используемую версию во время выполнения с помощью:

print(anthropic.__version__)

Дополнительные ресурсы

  • Репозиторий GitHub
  • Справочник по API
  • Потоковая передача сообщений
  • Использование инструментов с Claude

Was this page helpful?

  • Установка
  • Требования
  • Использование
  • Асинхронное использование
  • Использование aiohttp для лучшей конкурентности
  • Потоковая передача ответов
  • Вспомогательные функции потоковой передачи
  • Подсчёт токенов
  • Использование инструментов
  • Вспомогательные функции для инструментов
  • Пакеты сообщений
  • Создание пакета
  • Получение результатов из пакета
  • Загрузка файлов
  • Обработка ошибок
  • Идентификаторы запросов
  • Повторные попытки
  • Тайм-ауты
  • Длительные запросы
  • Автоматическая пагинация
  • Заголовки по умолчанию
  • Система типов
  • Параметры запроса
  • Модели ответов
  • Обработка null и отсутствующих полей
  • Расширенное использование
  • Доступ к необработанным данным ответа (например, заголовкам)
  • Потоковая передача тела ответа
  • Логирование
  • Выполнение пользовательских/недокументированных запросов
  • Настройка HTTP-клиента
  • Управление HTTP-ресурсами
  • Бета-функции
  • Интеграции с платформами
  • Семантическое версионирование
  • Определение установленной версии
  • Дополнительные ресурсы