Skip to content

Latest commit

 

History

History
392 lines (312 loc) · 11.2 KB

File metadata and controls

392 lines (312 loc) · 11.2 KB

Vinted Api Kit logo

Lightweight asynchronous Python client library for accessing Vinted API and scraping item data.

Package Version Python Version codecov Downloads Code style: ruff Typed License

✨ Features

  • 🚀 Asynchronous - Built with asyncio for high performance
  • 🌍 Auto-locale Detection - Automatically detects locale from URL
  • 🔍 Item Search - Search catalog with filters, sorting and pagination
  • 📦 Item Details - Get complete item information with rich metadata
  • 🍪 Cookie Persistence - Automatic session management with multiple storage formats
  • 🔐 Proxy Support - Simple string-based proxy configuration
  • 📊 Type Hints - Full typing support with Literal types for better IDE experience
  • 🎯 Dataclass Models - Fast and efficient data models (15% performance boost)
  • 🛡️ Custom Exceptions - Detailed error hierarchy for precise error handling
  • 💾 Flexible Storage - Choose between pickle, JSON, or Mozilla cookie formats

📚 Table of Contents

Installation

Install via pip:

pip install vinted-api-kit

Or using poetry:

poetry add vinted-api-kit

Usage

Basic Example

import asyncio
from vinted import VintedClient

async def main():
    async with VintedClient() as client:
        items = await client.search_items(
            url="https://www.vinted.com/catalog?search_text=nike",
            per_page=5
        )

        for item in items:
            print(f"• {item.title} - {item.price} {item.currency}")

asyncio.run(main())

Configuration

🔐 Proxy Support

Use a proxy by passing a simple connection string:

async with VintedClient(
    proxy="user:pass@proxy.example.com:8080"  # Format: [user:pass@]host:port
) as client:
    items = await client.search_items(url)

💾 Cookie Persistence

Save cookies between sessions to avoid repeated authentication:

from pathlib import Path

async with VintedClient(
    persist_cookies=True,              # Enable persistence
    cookies_dir=Path("./cookies"),     # Storage directory
    storage_format="json"              # Format: pickle | json | mozilla
) as client:
    items = await client.search_items(url)

Storage formats:

  • "json" (default) - Human-readable, portable across platforms
  • "pickle" - Fastest, Python-native binary format
  • "mozilla" - Browser-compatible Netscape format

🔍 Search Options

Use type-safe sorting and pagination:

from vinted import SortOrder

items = await client.search_items(
    url="https://www.vinted.de/catalog?brand_ids[]=53",
    per_page=20,                      # Items per page (1-96)
    page=1,                           # Page number
    order="price_low_to_high"         # Sort order (IDE auto-complete)
)

Available sort orders:

  • newest_first - Most recent items
  • relevance - Best match
  • price_low_to_high - Cheapest first
  • price_high_to_low - Most expensive first

📦 Raw Data

Get raw JSON dictionaries instead of parsed models:

raw_items = await client.search_items(
    url="https://www.vinted.com/catalog?search_text=shoes",
    raw_data=True  # Returns list[dict] instead of list[CatalogItem]
)

Item Details

Fetch detailed information about a specific item:

item = await client.item_details(
    url="https://www.vinted.com/items/1234567890"
)

print(f"Title: {item.title}")
print(f"Brand: {item.brand_title}")
print(f"Size: {item.size_title}")
print(f"Price: {item.price} {item.currency}")
print(f"Total: {item.total_item_price}")
print(f"Description: {item.description}")

# Or get raw JSON
raw_item = await client.item_details(url, raw_data=True)

Parameters

Parameter Type Default Description
proxy str | None None Proxy string: "user:pass@host:port" or "host:port"
cookies_dir Path | None Path(".") Directory for cookie storage
persist_cookies bool False Enable cookie persistence between sessions
storage_format "json" | "pickle" | "mozilla" "json" Cookie storage format

Storage formats: json (default), pickle, mozilla. See Storage Formats for details.

Exception Handling

from vinted import (
    VintedClient,
    VintedError,           # Base exception
    VintedAPIError,        # API errors (4xx, 5xx)
    VintedAuthError,       # Authentication failures
    VintedNetworkError,    # Network/connection errors
    VintedConfigError,     # Invalid configuration
    VintedValidationError, # Input validation errors
    VintedRateLimitError,  # Rate limiting (429)
)

try:
    async with VintedClient(proxy="invalid://proxy") as client:
        items = await client.search_items(url)
except VintedConfigError as e:
    print(f"Configuration error: {e}")
except VintedValidationError as e:
    print(f"Invalid input: {e}")
except VintedRateLimitError as e:
    print(f"Rate limited: {e.status_code}")
except VintedAuthError as e:
    print(f"Auth failed: {e}")
except VintedNetworkError as e:
    print(f"Network error: {e.original_error}")
except VintedAPIError as e:
    print(f"API error: {e.status_code}")

Migration Guide

(v0.x → v1.0)

Breaking Changes

If you're upgrading from version 0.x, here are the key changes:

1. Import Path Changed

# ❌ Old (v0.x)
from vinted_api_kit import VintedApi

# ✅ New (v1.0)
from vinted import VintedClient

2. Class Renamed

# ❌ Old
async with VintedApi() as api:
    pass

# ✅ New
async with VintedClient() as client:
    pass

3. Locale Parameter Removed

# ❌ Old (manual locale)
async with VintedApi(locale="fr") as api:
    items = await api.search_items(url)

# ✅ New (auto-detected from URL)
async with VintedClient() as client:
    items = await client.search_items(url)  # Locale detected from URL

4. Proxy Configuration Changed

# ❌ Old (dict format)
async with VintedApi(
    proxies={"http": "http://user:pass@proxy:8080"}
) as api:
    pass

# ✅ New (simple string)
async with VintedClient(
    proxy="user:pass@proxy:8080"  # ← Without "http://"
) as client:
    pass

5. New Storage Format Option

# ✅ New feature in v1.0
async with VintedClient(
    persist_cookies=True,
    storage_format="json"  # Choose: "json", "pickle", "mozilla"
) as client:
    pass

Quick Migration Checklist

  • Change import: vinted_api_kitvinted
  • Rename class: VintedApiVintedClient
  • Remove locale parameter (auto-detected)
  • Update proxy format: dict → string
  • Optional: Choose storage format

Full Example

Before (v0.x):

from vinted_api_kit import VintedApi

async with VintedApi(
    locale="fr",
    proxies={"http": "http://proxy:8080"},
    persist_cookies=True
) as api:
    items = await api.search_items(
        url="https://www.vinted.fr/catalog?search_text=nike"
    )

After (v1.0):

from vinted import VintedClient

async with VintedClient(
    proxy="proxy:8080",
    persist_cookies=True,
    storage_format="pickle"  # New option!
) as client:
    items = await client.search_items(
        url="https://www.vinted.fr/catalog?search_text=nike"
    )

Development

Setup

git clone https://github.com/vlymar1/vinted-api-kit.git
cd vinted-api-kit

pip install hatch
hatch shell

Project Structure

vinted-api-kit/
├── vinted/             # Main package
│   ├── api/            # API endpoint handlers
│   ├── models/         # Data models (dataclasses)
│   ├── storage/        # Cookie storage strategies
│   ├── client.py       # Main client (VintedClient)
│   ├── session.py      # HTTP session management
│   ├── auth.py         # Authentication logic
│   ├── constants.py    # Constants and type definitions
│   ├── exceptions.py   # Custom exceptions
│   └── utils.py        # Utility functions
├── tests/              # Test suite
└── examples/           # Usage examples

Testing

make test-coverage      # Run tests with coverage
make test-coverage-view # View coverage report in browser

Code Quality

make lint-check         # Check code with ruff and mypy
make lint-reformat      # Format and fix code with ruff

Cleanup

make clean              # Remove cache files and build artifacts

Development Guidelines

  • Follow PEP 8 style guidelines
  • Use type hints for all functions
  • Write tests for new features
  • Update CHANGELOG.md for notable changes
  • Run make lint-check before committing
  • Contributions welcome! Open issues or pull requests

Changelog

See CHANGELOG.md for the list of notable changes per version.

How to create and maintain changelog?

  • Start a CHANGELOG.md file at the root of your repo.
  • Follow Keep a Changelog format for consistent structure.
  • For each release version, record:
    • Added — new features
    • Changed — updates/improvements
    • Fixed — bug fixes
    • Removed — deprecated or removed features
  • Update changelog before tagging a new release (e.g., v1.0.0).
  • Automate changelog generation optionally by tools such as:

License

This project is licensed under the MIT License - see the LICENSE file for details.

⚠ Disclaimer

This library is intended for personal and lawful use only. The author is not responsible for any misuse, including but not limited to:

  • Violations of applicable laws or regulations
  • Breaches of terms of service of third-party websites

By using this library, you agree that you are solely responsible for your actions.


Maintainers / Contacts

Feel free to open issues or contact for support and collaborations.