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.1

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.1
File Size Uploaded Provenance
lztmarket-0.1.1.tar.gz 21.2 kB Without provenance Details

Built distribution (wheel)

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

Total release size: 45.3 kB

Release files / lztmarket-0.1.1.tar.gz

Download URL lztmarket-0.1.1.tar.gz
Size 21.2 kB
Tags Source
SHA-256 checksum
How to use checksums
aa6c252d6e48ea11847610f2fee502fd8a80746000cb1d56d0c85dd91dca0c29
BLAKE2b-256 checksum
How to use checksums
0d14a625829e3055f478be3cc7ead4644bebc99d3d99e25917d376765acafc6d
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.1-py3-none-any.whl

Download URL lztmarket-0.1.1-py3-none-any.whl
Size 24.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5265a19d4b767ee1126b25273b1fbcf92d7aa3a816433a88e25fb978011fb254
BLAKE2b-256 checksum
How to use checksums
8981c516fe7438843d41f45644bf662db5e337d7f808240585c0640675888111
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.1

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.1 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