Skip to main content

lztmarket

Неофициальный клиент. Проект не связан с владельцами LOLZTEAM/LZT Market и не поддерживается ими.

Современный синхронный и асинхронный Python-клиент для LOLZTEAM Market API.

Главный принцип библиотеки: публичные методы возвращают Pydantic-объекты, а не неструктурированные JSON-словари. Например, цена доступна как item.price (Decimal), продавец — как item.seller.username, а информация о лимите — как response.metadata.rate_limit.remaining.

Возможности

  • Python 3.14, Pydantic 2 и HTTPX;
  • синхронный LZTMarket и асинхронный AsyncLZTMarket с одинаковой структурой;
  • типизированные доменные модели, request-модели и enum;
  • безопасное хранение токена через SecretStr и отсутствие токена в repr;
  • стандартная иерархия ошибок для 401, 403, 404, 429, транспорта и валидации ответа;
  • metadata из rate-limit заголовков на каждом корневом response-объекте;
  • retry с exponential backoff только для идемпотентных запросов;
  • автоматическая пагинация;
  • внедрение собственного httpx.Client/AsyncClient для прокси, observability и тестов;
  • типизированный escape hatch для новых методов API без возврата raw JSON.

Установка

pip install lztmarket

Для разработки:

uv sync --all-groups

Быстрый старт

from decimal import Decimal

from lztmarketapi import CategoryName, LZTMarket, OrderBy, SearchParams

with LZTMarket("YOUR_ACCESS_TOKEN", locale="ru-RU") as market:
    response = market.categories.search(
        CategoryName.STEAM,
        SearchParams(
            pmin=Decimal("1000"),
            pmax=Decimal("5000"),
            order_by=OrderBy.PRICE_ASC,
            tag_ids=[12, 34],
        ),
    )

    for item in response.items:
        print(item.item_id, item.title, item.price)
        if item.seller is not None:
            print(item.seller.username)

    if response.metadata and response.metadata.rate_limit:
        print(response.metadata.rate_limit.remaining)

Категорийные фильтры, специфичные для Steam, Telegram, Riot и других категорий, можно передать как дополнительные поля SearchParams. Pydantic сохранит их, а клиент сериализует вместе с типизированными общими фильтрами:

params = SearchParams.model_validate(
    {
        "pmin": "500",
        "game[]": [730],
        "hours_played[730]": 100,
    }
)
response = market.categories.search(CategoryName.STEAM, params)

Асинхронный клиент

import asyncio

from lztmarketapi import AsyncLZTMarket


async def main() -> None:
    async with AsyncLZTMarket("YOUR_ACCESS_TOKEN") as market:
        response = await market.items.get(123456789)
        print(response.item.title)


asyncio.run(main())

Асинхронная пагинация не загружает все страницы в память:

async for item in market.categories.iter_items(max_pages=3):
    print(item.item_id)

Создание и изменение лота

from decimal import Decimal

from lztmarketapi import (
    AddItemRequest,
    CategoryID,
    Currency,
    EditItemRequest,
    ItemOrigin,
)

created = market.items.add(
    AddItemRequest(
        title="Steam account",
        price=Decimal("2500"),
        category_id=CategoryID.STEAM,
        currency=Currency.RUB,
        item_origin=ItemOrigin.PERSONAL,
        information="login:password",
    )
)

market.items.edit(
    created.item.item_id,
    EditItemRequest(price=Decimal("2400"), allow_ask_discount=True),
)

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

from lztmarketapi import APIError, RateLimitError, ResponseValidationError

try:
    item = market.items.get(123)
except RateLimitError as error:
    print(error.retry_after)
except APIError as error:
    print(error.status_code, error.error)
except ResponseValidationError:
    # Контракт ответа API изменился или сервер вернул повреждённые данные.
    ...

POST-запросы автоматически не повторяются: это предотвращает случайную повторную покупку, публикацию или денежный перевод. GET, PUT и DELETE повторяются при 429 и временных 5xx согласно RetryConfig.

Новые и редкие endpoints

Группы categories, items, profile, cart, purchasing, payments, proxies и general покрывают основные пользовательские сценарии. Если официальный API добавил маршрут раньше обновления клиента, используйте типизированный escape hatch:

from lztmarketapi import StatusResponse

result = market.general.request(
    "POST",
    "/123456789/change-password",
    StatusResponse,
    json={"cancel": False},
)
print(result.message)  # известные поля типизированы
print(result.model_extra)  # новые поля API не теряются

Путь обязан быть относительным к Market API. Полные внешние URL запрещены, чтобы токен нельзя было случайно отправить стороннему хосту.

Локальная проверка

uv run pytest
uv run ruff check .
uv run mypy src tests
uv build

Контракт сверялся с официальной документацией Market API и актуальной OpenAPI 3.1 схемой версии 1.1.100 (126 операций на момент разработки).

Лицензия

Исходный код распространяется по лицензии MIT. Полный текст находится в файле LICENSE.

Metadata

Release files for lztmarket 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for lztmarket 0.1.0
File Size Uploaded Provenance
lztmarket-0.1.0.tar.gz 21.7 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for lztmarket 0.1.0
File Interpreter ABI Platform
lztmarket-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 45.6 kB

Release files / lztmarket-0.1.0.tar.gz

Download URL lztmarket-0.1.0.tar.gz
Size 21.7 kB
Tags Source
SHA-256 checksum
How to use checksums
a4393fba18aceb030bbaadfbe518ba99dae3ef1c9349e53b4904c9259ba206cb
BLAKE2b-256 checksum
How to use checksums
bdfad44656e092605ad407c9b27fe28e4b9b70f510f448ece3edb68e43198e56
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.7

Release files / lztmarket-0.1.0-py3-none-any.whl

Download URL lztmarket-0.1.0-py3-none-any.whl
Size 24.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f7e4426879f7f6786af7a30db9676edff9233ff09359a7451d8bae274f91d18a
BLAKE2b-256 checksum
How to use checksums
434bfa22b62203384f96ec773d08abb92703b12cad8d496a8859a7abd03e8239
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.7

Security for lztmarket 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page