tcgplayer-client


Nametcgplayer-client JSON
Version 2.0.3 PyPI version JSON
download
home_pageNone
SummaryPython client library for TCGplayer API with async support, rate limiting, and comprehensive endpoint coverage
upload_time2025-08-25 04:45:18
maintainerNone
docs_urlNone
authorNone
requires_python>=3.8
licenseMIT
keywords tcgplayer api trading-cards async mtg pokemon yugioh
VCS
bugtrack_url
requirements aiohttp pytest pytest-asyncio pytest-cov black isort flake8 mypy setuptools wheel build
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # TCGplayer Client - Python API Client

[![Python
3.8+](<https://img.shields.io/badge/python-3.8+-blue.svg)>](<https://www.python.org/downloads/)>
[![License:
MIT](<https://img.shields.io/badge/License-MIT-yellow.svg)>](<https://opensource.org/licenses/MIT)>
[![Code style:
black](<https://img.shields.io/badge/code%20style-black-000000.svg)>](<https://github.com/psf/black)>
[![Imports:
isort](<https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336)>](<https://pycqa.github.io/isort/)>

## โš ๏ธ **CRITICAL RATE LIMITING WARNING**

**TCGplayer's API enforces a hard maximum of 10 requests per second.** Exceeding
this limit can result in:

- API access being permanently revoked
- Account suspension
- Legal consequences

This client automatically enforces this limit to protect your API access.

A comprehensive, production-ready Python client library for the TCGplayer API
with async support, intelligent rate limiting, caching, and comprehensive
endpoint coverage. Built for developers who need reliable, scalable access to
TCGplayer's trading card data.

## ๐Ÿš€ Features

- **๐Ÿ”Œ Full API Coverage**: All 55+ documented TCGplayer API endpoints with
comprehensive error handling (buylist endpoints removed - discontinued by
TCGPlayer)
- **โšก Async/Await Support**: Built with modern Python async patterns for
high-performance applications
- **๐Ÿ”„ Intelligent Rate Limiting**: Adaptive request throttling that respects API
limits and prevents rate limit errors
- **๐Ÿ’พ Smart Caching**: Configurable response caching with TTL and LRU eviction
for improved performance
- **๐Ÿ” Robust Authentication**: OAuth2 token management with automatic refresh
and session persistence
- **๐Ÿ›ก๏ธ Enterprise-Grade Error Handling**: Custom exception hierarchy with
detailed error context and retry logic
- **๐Ÿ“Š Comprehensive Logging**: Structured logging with configurable levels and
multiple output formats
- **โš™๏ธ Flexible Configuration**: Environment variables, config files, and
runtime configuration management
- **๐Ÿงช Full Test Coverage**: Comprehensive test suite with pytest and async
testing support
- **๐Ÿ“ Type Hints**: Full type annotation support for better development
experience and IDE integration

## ๐Ÿ“ฆ Installation

### From Source (Development)

```bash

git clone <https://github.com/joshwilhelmi/tcgplayer-python.git>
cd tcgplayer-python
pip install -e .

```

### From PyPI

```bash

pip install tcgplayer-client

```

## ๐Ÿš€ Quick Start

### Migration from v1.x

If you're upgrading from version 1.x, be aware of these breaking changes:

```python

# โŒ OLD (v1.x) - Buylist methods (no longer available)


# await client.endpoints.buylist.get_buylist_prices([12345])


# await client.endpoints.pricing.get_buylist_prices([12345])

# โœ… NEW (v2.0.1) - Market prices only

await client.endpoints.pricing.get_market_prices([12345])
await client.endpoints.pricing.get_sku_market_prices([67890])

```

**Note**: Buylist functionality was discontinued by TCGPlayer and has been
removed from this client.

### Basic Usage

```python

import asyncio
from tcgplayer_client import TCGPlayerClient

async def main():
    # Initialize client with your API credentials
    client = TCGPlayerClient(
        client_id="your_client_id",
        client_secret="your_client_secret"
    )
    
    # Authenticate automatically
    await client.authenticate()
    
    # Use endpoints
    categories = await client.endpoints.catalog.get_categories()
    print(f"Found {len(categories)} product categories")
    
    # Get pricing for a specific product
    prices = await client.endpoints.pricing.get_product_prices(product_id=12345)
    print(f"Product prices: {prices}")

if __name__ == "__main__":
    asyncio.run(main())

```

### Advanced Configuration

```python

from tcgplayer_client import TCGPlayerClient, ClientConfig

# Custom configuration

config = ClientConfig(
    max_requests_per_second=20,
    enable_caching=True,
    cache_ttl=300,  # 5 minutes
    log_level="DEBUG"
)

client = TCGPlayerClient(
    client_id="your_client_id",
    client_secret="your_client_secret",
    config=config
)

```

### Environment Variables

```bash

export TCGPLAYER_CLIENT_ID="your_client_id"
export TCGPLAYER_CLIENT_SECRET="your_client_secret"
export TCGPLAYER_LOG_LEVEL="INFO"
export TCGPLAYER_ENABLE_CACHING="true"
export TCGPLAYER_CACHE_TTL="300"

```

## ๐Ÿ”Œ API Endpoints

The client provides organized access to all TCGplayer API endpoints through
specialized endpoint classes:

### ๐Ÿ“š Catalog Endpoints

- **Categories**: Product categories and hierarchies
- **Groups**: Product groups and classifications  
- **Products**: Detailed product information
- **Search**: Advanced product search and filtering

### ๐Ÿ’ฐ Pricing Endpoints

- **Market Prices**: Current market pricing data
- **Price Guides**: Historical price trends and guides
- **SKU Pricing**: Product variant pricing information

### ๐Ÿช Store Endpoints

- **Store Information**: Store details and metadata
- **Store Inventory**: Available inventory and stock levels
- **Store Locations**: Geographic store information

### ๐Ÿ“ฆ Order Endpoints

- **Order Management**: Create, update, and track orders
- **Order History**: Historical order data and analytics
- **Order Status**: Real-time order status updates

### ๐Ÿ“‹ Inventory Endpoints

- **Inventory Management**: Add, update, and remove inventory
- **Stock Levels**: Current stock quantities and availability
- **Inventory Analytics**: Inventory performance metrics

## โš™๏ธ Configuration

### โš ๏ธ **Critical Rate Limiting Restriction**

**IMPORTANT**: TCGplayer's API enforces a **hard maximum of 10 requests per
second**. Exceeding this limit can result in:

- API access being temporarily suspended
- Permanent API access revocation
- Account restrictions

The client **automatically enforces this limit** regardless of your
configuration to prevent API violations.

### Client Configuration

```python

from tcgplayer_client import ClientConfig

config = ClientConfig(
    # API Configuration
    base_url="<https://api.tcgplayer.com>",
    api_version="v1.0",
    
    # Rate Limiting (MAXIMUM: 10 requests per second)
    max_requests_per_second=10,  # Will be capped to 10 if higher
    rate_limit_window=1.0,
    max_retries=3,
    base_delay=1.0,
    
    # Session Management
    max_connections=100,
    max_connections_per_host=10,
    keepalive_timeout=30.0,
    
    # Caching
    enable_caching=True,
    cache_ttl=300,
    max_cache_size=1000,
    
    # Logging
    log_level="INFO",
    log_file="tcgplayer.log",
    enable_console_logging=True,
    enable_file_logging=True
)

```

### Rate Limiting

```python

client = TCGPlayerClient(
    max_requests_per_second=20,    # โš ๏ธ Will be automatically capped to 10
    rate_limit_window=1.0,         # 1 second window
    max_retries=5,                 # 5 retry attempts
    base_delay=2.0                 # 2 second base delay
)

# The client will log a warning and cap the rate limit to 10 req/s


# This prevents accidental API violations

```

### Caching Configuration

```python

client = TCGPlayerClient(
    config=ClientConfig(
        enable_caching=True,
        cache_ttl=600,              # 10 minutes
        max_cache_size=5000,        # 5000 cached responses
        cache_cleanup_interval=300  # Cleanup every 5 minutes
    )
)

```

## ๐Ÿ›ก๏ธ Error Handling

The library provides a comprehensive exception hierarchy for different error
scenarios:

```python

from tcgplayer_client import (
    TCGPlayerError,
    AuthenticationError,
    RateLimitError,
    APIError,
    NetworkError,
    TimeoutError,
    RetryExhaustedError,
    InvalidResponseError
)

try:
    result = await client.endpoints.catalog.get_categories()
except AuthenticationError:
    print("Authentication failed - check your credentials")
except RateLimitError as e:
    print(f"Rate limit exceeded - retry after {e.retry_after} seconds")
except APIError as e:
    print(f"API error {e.status_code}: {e.message}")
    print(f"Error type: {e.error_type}")
    print(f"Request ID: {e.request_id}")
except NetworkError as e:
    print(f"Network error: {e}")
    print(f"Retry count: {e.retry_count}")
except TimeoutError:
    print("Request timed out")
except RetryExhaustedError:
    print("Max retries exceeded")

```

### Error Context and Retry Information

```python

try:
    result = await client.endpoints.pricing.get_product_prices(product_id=12345)
except APIError as e:
    print(f"Error occurred during pricing request:")
    print(f"  Endpoint: {e.endpoint}")
    print(f"  Method: {e.method}")
    print(f"  Status: {e.status_code}")
    print(f"  Message: {e.message}")
    print(f"  Request ID: {e.request_id}")
    print(f"  Timestamp: {e.timestamp}")

```

## ๐Ÿ“Š Logging

### Basic Logging Setup

```python

from tcgplayer_client.logging_config import setup_logging, get_logger

# Setup logging with default configuration

setup_logging()

# Get logger for your module

logger = get_logger(__name__)

# Use structured logging

logger.info("Starting TCGplayer client", extra={
    "client_id": "your_client_id",
    "endpoint": "catalog",
    "operation": "get_categories"
})

```

### Advanced Logging Configuration

```python

from tcgplayer_client.logging_config import TCGPlayerLogger

# Custom logger configuration

logger = TCGPlayerLogger(
    name="my_app",
    level="DEBUG",
    enable_console=True,
    enable_file=True,
    log_file="app.log",
    enable_json=True,
    formatter="structured"
)

logger.info("Custom logger configured", extra={"component": "tcgplayer_client"})

```

## ๐Ÿ”ง Development

### Setup Development Environment

```bash

# Clone repository

git clone <https://github.com/joshwilhelmi/tcgplayer-python.git>
cd tcgplayer-python

# Create virtual environment

python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

# Install in development mode

pip install -e ".[dev]"

# Install pre-commit hooks (optional)

pre-commit install

```

### Local Testing Pipeline

The project includes a comprehensive local testing pipeline that mimics GitHub
Actions:

```bash

# Run full local CI pipeline (recommended before pushing)

make ci

# Quick quality checks

make quick-check

# Individual tools

make format      # Black + isort
make lint        # Flake8
make type-check  # MyPy
make security    # Bandit + Safety + Semgrep
make test        # Pytest with coverage

# See [LOCAL_TESTING.md](LOCAL_TESTING.md) for detailed usage
```

### Running Tests

```bash

# Run all tests

pytest

# Run with coverage

pytest --cov=tcgplayer_client --cov-report=html

# Run specific test file

pytest tests/test_client.py

# Run tests with verbose output

pytest -v

# Run tests in parallel

pytest -n auto

```

### Code Quality

```bash

# Code formatting

black .
isort .

# Linting

flake8 tcgplayer_client/
mypy tcgplayer_client/

# Run all quality checks

make quality  # If Makefile is available

```

### Security Testing

```bash

# Security scanning with Bandit

bandit -r tcgplayer_client/ -f json -o bandit-report.json

# Dependency vulnerability scanning

safety check

# Advanced security analysis

pip install semgrep
semgrep --config=auto tcgplayer_client/

# Dependency security audit

pip-audit

```

**Note**: Security issues have been identified and fixed in the codebase:

- โœ… **MD5 โ†’ SHA256**: Replaced weak MD5 hashing with secure SHA256 for cache
keys
- โœ… **Try-except-pass**: Fixed silent exception handling with proper logging
- โœ… **Assert statements**: Replaced with proper runtime error handling

**โœ… COMPLETED**: Security tools are now integrated into the CI/CD pipeline for
automated security testing.

### **Comprehensive Testing Strategy**

The project includes multiple layers of testing to ensure code quality and
security:

#### **1. Unit Testing (pytest)**

```bash

# Run all tests with coverage

pytest --cov=tcgplayer_client --cov-report=html --cov-report=term-missing

# Run specific test categories

pytest tests/test_auth.py          # Authentication tests
pytest tests/test_client.py        # Main client tests
pytest tests/test_endpoints/       # API endpoint tests
pytest tests/test_rate_limiter.py  # Rate limiting tests
pytest tests/test_cache.py         # Caching tests

# Run tests in parallel

pytest -n auto --dist=loadfile

# Generate coverage reports

pytest --cov=tcgplayer_client --cov-report=html --cov-report=xml

```

#### **2. Security Testing (Automated)**

```bash

# Bandit security scanning

bandit -r tcgplayer_client/ -f json -o bandit-report.json
bandit -r tcgplayer_client/ -f txt

# Safety dependency scanning

safety check --json --output safety-report.json
safety check

# Semgrep static analysis

semgrep --config=auto --json --output=semgrep-report.json tcgplayer_client/

# Pip audit for dependencies

pip-audit --desc --format=json --output=pip-audit-report.json

```

#### **3. Code Quality Testing**

```bash

# Black code formatting

black --check --diff .

# Import sorting

isort --check-only --diff .

# Flake8 linting

flake8 tcgplayer_client/ tests/ --max-line-length=88 --extend-ignore=E203,W503

# MyPy type checking

mypy tcgplayer_client/ --ignore-missing-imports

# Pre-commit hooks (if installed)

pre-commit run --all-files

```

#### **4. Performance Testing**

```bash

# Run performance benchmarks

python -m pytest tests/test_performance.py -v

# Memory usage profiling

python -m memory_profiler tests/test_memory.py

# Async performance testing

python -m pytest tests/test_async_performance.py -v

```

#### **5. Integration Testing**

```bash

# Test with real TCGplayer API (requires credentials)

export TCGPLAYER_CLIENT_ID="your_client_id"
export TCGPLAYER_CLIENT_SECRET="your_client_secret"
python -m pytest tests/test_integration.py -v

# Test rate limiting compliance

python -m pytest tests/test_rate_limit_compliance.py -v

```

#### **6. Test Coverage Goals**

- **Current Coverage**: 95%+ (90+ tests passing)
- **Target Coverage**: 95%+ for production quality
- **Critical Paths**: 100% coverage for authentication, rate limiting, and error
handling
- **New Features**: 95%+ coverage requirement before merge

### Testing Examples

```python

import pytest
from tcgplayer_client import TCGPlayerClient

@pytest.mark.asyncio
async def test_catalog_endpoints():
    client = TCGPlayerClient()
    
    # Test categories endpoint
    categories = await client.endpoints.catalog.get_categories()
    assert isinstance(categories, list)
    assert len(categories) > 0
    
    # Test product search
    products = await client.endpoints.catalog.search_products(
        search_term="Black Lotus"
    )
    assert isinstance(products, list)

```

## ๐Ÿ“‹ Requirements

### Core Dependencies

- **Python**: 3.8 or higher
- **aiohttp**: 3.8.0 or higher (async HTTP client)

### Development Dependencies

- **pytest**: Testing framework
- **pytest-asyncio**: Async testing support
- **pytest-cov**: Coverage reporting
- **black**: Code formatting
- **isort**: Import sorting
- **flake8**: Linting
- **mypy**: Type checking

## ๐Ÿ—๏ธ Architecture

### Core Components

```text
tcgplayer_client/
โ”œโ”€โ”€ client.py              # Main client class
โ”œโ”€โ”€ auth.py                # Authentication management
โ”œโ”€โ”€ rate_limiter.py        # Rate limiting and throttling
โ”œโ”€โ”€ session_manager.py     # HTTP session management
โ”œโ”€โ”€ cache.py               # Response caching system
โ”œโ”€โ”€ config.py              # Configuration management
โ”œโ”€โ”€ validation.py          # Input validation
โ”œโ”€โ”€ logging_config.py      # Logging configuration
โ”œโ”€โ”€ exceptions.py          # Custom exception hierarchy
โ””โ”€โ”€ endpoints/             # API endpoint implementations
    โ”œโ”€โ”€ catalog.py         # Catalog operations
    โ”œโ”€โ”€ pricing.py         # Pricing operations
    โ”œโ”€โ”€ stores.py          # Store operations
    โ”œโ”€โ”€ orders.py          # Order operations
    โ”œโ”€โ”€ inventory.py       # Inventory operations
    โ””โ”€โ”€ pricing.py         # Pricing operations (market prices, price guides)
```

### Design Patterns

- **Async/Await**: Modern Python async patterns for non-blocking I/O
- **Factory Pattern**: Endpoint creation and management
- **Strategy Pattern**: Configurable rate limiting and caching strategies
- **Observer Pattern**: Event-driven logging and monitoring
- **Builder Pattern**: Configuration object construction

## ๐Ÿ“š Examples

### Bulk Product Processing

```python

async def process_products_bulk(client, product_ids):
    """Process multiple products efficiently with rate limiting."""
    results = []
    
    for product_id in product_ids:
        try:
            # Get product details
            product = await client.endpoints.catalog.get_product(product_id)
            
            # Get current pricing
pricing = await client.endpoints.pricing.get_product_prices(product_id)
            
            # Get store inventory
inventory = await client.endpoints.stores.get_store_inventory(product_id)
            
            results.append({
                'product': product,
                'pricing': pricing,
                'inventory': inventory
            })
            
        except Exception as e:
            logger.error(f"Error processing product {product_id}: {e}")
            continue
    
    return results

```

### Store Inventory Monitoring

```python

async def monitor_store_inventory(client, store_id, product_ids):
    """Monitor store inventory levels for specific products."""
    while True:
        try:
            for product_id in product_ids:
                inventory = await client.endpoints.stores.get_store_inventory(
                    store_id=store_id,
                    product_id=product_id
                )
                
                if inventory and inventory.get('quantity', 0) > 0:
logger.info(f"Product {product_id} available at store {store_id}")
                    
            # Wait before next check
            await asyncio.sleep(300)  # 5 minutes
            
        except Exception as e:
            logger.error(f"Inventory monitoring error: {e}")
            await asyncio.sleep(60)  # Wait 1 minute on error

```

### Price Alert System

```python

async def price_alert_system(client, product_id, target_price):
    """Monitor product prices and alert when target price is reached."""
    while True:
        try:
prices = await client.endpoints.pricing.get_product_prices(product_id)
            
            if prices and len(prices) > 0:
                current_price = prices[0].get('price', float('inf'))
                
                if current_price <= target_price:
logger.info(f"Price alert! Product {product_id} is now ${current_price}")
                    # Send notification (email, webhook, etc.)
                    break
            
            await asyncio.sleep(3600)  # Check every hour
            
        except Exception as e:
            logger.error(f"Price monitoring error: {e}")
            await asyncio.sleep(300)  # Wait 5 minutes on error

```

## ๐Ÿค Contributing

We welcome contributions! Please see our [Contributing
Guidelines](CONTRIBUTING.md) for details.

### Development Workflow

1. **Fork** the repository
2. **Create** a feature branch (`git checkout -b feature/amazing-feature`)
3. **Commit** your changes (`git commit -m 'Add amazing feature'`)
4. **Push** to the branch (`git push origin feature/amazing-feature`)
5. **Open** a Pull Request

### Code Standards

- Follow PEP 8 style guidelines
- Use type hints for all function parameters and return values
- Write comprehensive docstrings
- Include tests for new functionality
- Ensure all tests pass before submitting

## ๐Ÿ“„ License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
for details.

## ๐Ÿ†˜ Support

### Getting Help

- **๐Ÿ“– Documentation**: This README and inline code documentation
- **๐Ÿ› Issues**: [GitHub
Issues](<https://github.com/joshwilhelmi/tcgplayer-python/issues)>
- **๐Ÿ’ฌ Discussions**: [GitHub
Discussions](<https://github.com/joshwilhelmi/tcgplayer-python/discussions)>
- **๐Ÿ“ง Email**: [josh@gobby.ai](mailto:josh@gobby.ai)

### Common Issues

#### Authentication Errors

- Verify your `client_id` and `client_secret` are correct
- Check that your TCGplayer API account is active
- Ensure your IP address is whitelisted if required

#### Rate Limiting Issues

- Reduce your request frequency
- Implement exponential backoff in your application
- Use the built-in rate limiting features

#### Network Issues

- Check your internet connection
- Verify firewall settings
- Use the retry mechanisms built into the client

## ๐Ÿ“ˆ Roadmap

### Upcoming Features

- [ ] **WebSocket Support**: Real-time data streaming
- [ ] **GraphQL Interface**: Alternative to REST API
- [ ] **Data Export**: CSV/JSON export functionality
- [ ] **Analytics Dashboard**: Built-in data visualization
- [ ] **Webhook Support**: Event-driven notifications
- [ ] **Multi-API Support**: Integration with other trading card APIs

### Version History

See [CHANGELOG.md](CHANGELOG.md) for a detailed history of changes and
improvements.

## ๐Ÿ™ Acknowledgments

- **TCGplayer** for providing the comprehensive API
- **Python Community** for excellent async libraries and tools
- **Contributors** who help improve this library
- **Open Source Community** for inspiration and best practices

## ๐Ÿ“Š Project Status

- **Development Status**: Production Ready
- **Python Version Support**: 3.8+
- **Test Coverage**: 95%+
- **Documentation**: Comprehensive
- **License**: MIT (Open Source)
- **CI/CD**: Automated testing, security scanning, and PyPI publishing

---

**Made with โค๏ธ by [Josh Wilhelmi](mailto:josh@gobby.ai)**

*If you find this library helpful, please consider giving it a โญ on GitHub!*

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "tcgplayer-client",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": "Josh Wilhelmi <josh@gobby.ai>",
    "keywords": "tcgplayer, api, trading-cards, async, mtg, pokemon, yugioh",
    "author": null,
    "author_email": "Josh Wilhelmi <josh@gobby.ai>",
    "download_url": "https://files.pythonhosted.org/packages/b8/10/73983e63610b7435a1f031d35d355a9d65eb3f6acd8276d16b81c8ecf06f/tcgplayer_client-2.0.3.tar.gz",
    "platform": null,
    "description": "# TCGplayer Client - Python API Client\n\n[![Python\n3.8+](<https://img.shields.io/badge/python-3.8+-blue.svg)>](<https://www.python.org/downloads/)>\n[![License:\nMIT](<https://img.shields.io/badge/License-MIT-yellow.svg)>](<https://opensource.org/licenses/MIT)>\n[![Code style:\nblack](<https://img.shields.io/badge/code%20style-black-000000.svg)>](<https://github.com/psf/black)>\n[![Imports:\nisort](<https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336)>](<https://pycqa.github.io/isort/)>\n\n## \u26a0\ufe0f **CRITICAL RATE LIMITING WARNING**\n\n**TCGplayer's API enforces a hard maximum of 10 requests per second.** Exceeding\nthis limit can result in:\n\n- API access being permanently revoked\n- Account suspension\n- Legal consequences\n\nThis client automatically enforces this limit to protect your API access.\n\nA comprehensive, production-ready Python client library for the TCGplayer API\nwith async support, intelligent rate limiting, caching, and comprehensive\nendpoint coverage. Built for developers who need reliable, scalable access to\nTCGplayer's trading card data.\n\n## \ud83d\ude80 Features\n\n- **\ud83d\udd0c Full API Coverage**: All 55+ documented TCGplayer API endpoints with\ncomprehensive error handling (buylist endpoints removed - discontinued by\nTCGPlayer)\n- **\u26a1 Async/Await Support**: Built with modern Python async patterns for\nhigh-performance applications\n- **\ud83d\udd04 Intelligent Rate Limiting**: Adaptive request throttling that respects API\nlimits and prevents rate limit errors\n- **\ud83d\udcbe Smart Caching**: Configurable response caching with TTL and LRU eviction\nfor improved performance\n- **\ud83d\udd10 Robust Authentication**: OAuth2 token management with automatic refresh\nand session persistence\n- **\ud83d\udee1\ufe0f Enterprise-Grade Error Handling**: Custom exception hierarchy with\ndetailed error context and retry logic\n- **\ud83d\udcca Comprehensive Logging**: Structured logging with configurable levels and\nmultiple output formats\n- **\u2699\ufe0f Flexible Configuration**: Environment variables, config files, and\nruntime configuration management\n- **\ud83e\uddea Full Test Coverage**: Comprehensive test suite with pytest and async\ntesting support\n- **\ud83d\udcdd Type Hints**: Full type annotation support for better development\nexperience and IDE integration\n\n## \ud83d\udce6 Installation\n\n### From Source (Development)\n\n```bash\n\ngit clone <https://github.com/joshwilhelmi/tcgplayer-python.git>\ncd tcgplayer-python\npip install -e .\n\n```\n\n### From PyPI\n\n```bash\n\npip install tcgplayer-client\n\n```\n\n## \ud83d\ude80 Quick Start\n\n### Migration from v1.x\n\nIf you're upgrading from version 1.x, be aware of these breaking changes:\n\n```python\n\n# \u274c OLD (v1.x) - Buylist methods (no longer available)\n\n\n# await client.endpoints.buylist.get_buylist_prices([12345])\n\n\n# await client.endpoints.pricing.get_buylist_prices([12345])\n\n# \u2705 NEW (v2.0.1) - Market prices only\n\nawait client.endpoints.pricing.get_market_prices([12345])\nawait client.endpoints.pricing.get_sku_market_prices([67890])\n\n```\n\n**Note**: Buylist functionality was discontinued by TCGPlayer and has been\nremoved from this client.\n\n### Basic Usage\n\n```python\n\nimport asyncio\nfrom tcgplayer_client import TCGPlayerClient\n\nasync def main():\n    # Initialize client with your API credentials\n    client = TCGPlayerClient(\n        client_id=\"your_client_id\",\n        client_secret=\"your_client_secret\"\n    )\n    \n    # Authenticate automatically\n    await client.authenticate()\n    \n    # Use endpoints\n    categories = await client.endpoints.catalog.get_categories()\n    print(f\"Found {len(categories)} product categories\")\n    \n    # Get pricing for a specific product\n    prices = await client.endpoints.pricing.get_product_prices(product_id=12345)\n    print(f\"Product prices: {prices}\")\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n\n```\n\n### Advanced Configuration\n\n```python\n\nfrom tcgplayer_client import TCGPlayerClient, ClientConfig\n\n# Custom configuration\n\nconfig = ClientConfig(\n    max_requests_per_second=20,\n    enable_caching=True,\n    cache_ttl=300,  # 5 minutes\n    log_level=\"DEBUG\"\n)\n\nclient = TCGPlayerClient(\n    client_id=\"your_client_id\",\n    client_secret=\"your_client_secret\",\n    config=config\n)\n\n```\n\n### Environment Variables\n\n```bash\n\nexport TCGPLAYER_CLIENT_ID=\"your_client_id\"\nexport TCGPLAYER_CLIENT_SECRET=\"your_client_secret\"\nexport TCGPLAYER_LOG_LEVEL=\"INFO\"\nexport TCGPLAYER_ENABLE_CACHING=\"true\"\nexport TCGPLAYER_CACHE_TTL=\"300\"\n\n```\n\n## \ud83d\udd0c API Endpoints\n\nThe client provides organized access to all TCGplayer API endpoints through\nspecialized endpoint classes:\n\n### \ud83d\udcda Catalog Endpoints\n\n- **Categories**: Product categories and hierarchies\n- **Groups**: Product groups and classifications  \n- **Products**: Detailed product information\n- **Search**: Advanced product search and filtering\n\n### \ud83d\udcb0 Pricing Endpoints\n\n- **Market Prices**: Current market pricing data\n- **Price Guides**: Historical price trends and guides\n- **SKU Pricing**: Product variant pricing information\n\n### \ud83c\udfea Store Endpoints\n\n- **Store Information**: Store details and metadata\n- **Store Inventory**: Available inventory and stock levels\n- **Store Locations**: Geographic store information\n\n### \ud83d\udce6 Order Endpoints\n\n- **Order Management**: Create, update, and track orders\n- **Order History**: Historical order data and analytics\n- **Order Status**: Real-time order status updates\n\n### \ud83d\udccb Inventory Endpoints\n\n- **Inventory Management**: Add, update, and remove inventory\n- **Stock Levels**: Current stock quantities and availability\n- **Inventory Analytics**: Inventory performance metrics\n\n## \u2699\ufe0f Configuration\n\n### \u26a0\ufe0f **Critical Rate Limiting Restriction**\n\n**IMPORTANT**: TCGplayer's API enforces a **hard maximum of 10 requests per\nsecond**. Exceeding this limit can result in:\n\n- API access being temporarily suspended\n- Permanent API access revocation\n- Account restrictions\n\nThe client **automatically enforces this limit** regardless of your\nconfiguration to prevent API violations.\n\n### Client Configuration\n\n```python\n\nfrom tcgplayer_client import ClientConfig\n\nconfig = ClientConfig(\n    # API Configuration\n    base_url=\"<https://api.tcgplayer.com>\",\n    api_version=\"v1.0\",\n    \n    # Rate Limiting (MAXIMUM: 10 requests per second)\n    max_requests_per_second=10,  # Will be capped to 10 if higher\n    rate_limit_window=1.0,\n    max_retries=3,\n    base_delay=1.0,\n    \n    # Session Management\n    max_connections=100,\n    max_connections_per_host=10,\n    keepalive_timeout=30.0,\n    \n    # Caching\n    enable_caching=True,\n    cache_ttl=300,\n    max_cache_size=1000,\n    \n    # Logging\n    log_level=\"INFO\",\n    log_file=\"tcgplayer.log\",\n    enable_console_logging=True,\n    enable_file_logging=True\n)\n\n```\n\n### Rate Limiting\n\n```python\n\nclient = TCGPlayerClient(\n    max_requests_per_second=20,    # \u26a0\ufe0f Will be automatically capped to 10\n    rate_limit_window=1.0,         # 1 second window\n    max_retries=5,                 # 5 retry attempts\n    base_delay=2.0                 # 2 second base delay\n)\n\n# The client will log a warning and cap the rate limit to 10 req/s\n\n\n# This prevents accidental API violations\n\n```\n\n### Caching Configuration\n\n```python\n\nclient = TCGPlayerClient(\n    config=ClientConfig(\n        enable_caching=True,\n        cache_ttl=600,              # 10 minutes\n        max_cache_size=5000,        # 5000 cached responses\n        cache_cleanup_interval=300  # Cleanup every 5 minutes\n    )\n)\n\n```\n\n## \ud83d\udee1\ufe0f Error Handling\n\nThe library provides a comprehensive exception hierarchy for different error\nscenarios:\n\n```python\n\nfrom tcgplayer_client import (\n    TCGPlayerError,\n    AuthenticationError,\n    RateLimitError,\n    APIError,\n    NetworkError,\n    TimeoutError,\n    RetryExhaustedError,\n    InvalidResponseError\n)\n\ntry:\n    result = await client.endpoints.catalog.get_categories()\nexcept AuthenticationError:\n    print(\"Authentication failed - check your credentials\")\nexcept RateLimitError as e:\n    print(f\"Rate limit exceeded - retry after {e.retry_after} seconds\")\nexcept APIError as e:\n    print(f\"API error {e.status_code}: {e.message}\")\n    print(f\"Error type: {e.error_type}\")\n    print(f\"Request ID: {e.request_id}\")\nexcept NetworkError as e:\n    print(f\"Network error: {e}\")\n    print(f\"Retry count: {e.retry_count}\")\nexcept TimeoutError:\n    print(\"Request timed out\")\nexcept RetryExhaustedError:\n    print(\"Max retries exceeded\")\n\n```\n\n### Error Context and Retry Information\n\n```python\n\ntry:\n    result = await client.endpoints.pricing.get_product_prices(product_id=12345)\nexcept APIError as e:\n    print(f\"Error occurred during pricing request:\")\n    print(f\"  Endpoint: {e.endpoint}\")\n    print(f\"  Method: {e.method}\")\n    print(f\"  Status: {e.status_code}\")\n    print(f\"  Message: {e.message}\")\n    print(f\"  Request ID: {e.request_id}\")\n    print(f\"  Timestamp: {e.timestamp}\")\n\n```\n\n## \ud83d\udcca Logging\n\n### Basic Logging Setup\n\n```python\n\nfrom tcgplayer_client.logging_config import setup_logging, get_logger\n\n# Setup logging with default configuration\n\nsetup_logging()\n\n# Get logger for your module\n\nlogger = get_logger(__name__)\n\n# Use structured logging\n\nlogger.info(\"Starting TCGplayer client\", extra={\n    \"client_id\": \"your_client_id\",\n    \"endpoint\": \"catalog\",\n    \"operation\": \"get_categories\"\n})\n\n```\n\n### Advanced Logging Configuration\n\n```python\n\nfrom tcgplayer_client.logging_config import TCGPlayerLogger\n\n# Custom logger configuration\n\nlogger = TCGPlayerLogger(\n    name=\"my_app\",\n    level=\"DEBUG\",\n    enable_console=True,\n    enable_file=True,\n    log_file=\"app.log\",\n    enable_json=True,\n    formatter=\"structured\"\n)\n\nlogger.info(\"Custom logger configured\", extra={\"component\": \"tcgplayer_client\"})\n\n```\n\n## \ud83d\udd27 Development\n\n### Setup Development Environment\n\n```bash\n\n# Clone repository\n\ngit clone <https://github.com/joshwilhelmi/tcgplayer-python.git>\ncd tcgplayer-python\n\n# Create virtual environment\n\npython -m venv venv\nsource venv/bin/activate  # On Windows: venv\\Scripts\\activate\n\n# Install in development mode\n\npip install -e \".[dev]\"\n\n# Install pre-commit hooks (optional)\n\npre-commit install\n\n```\n\n### Local Testing Pipeline\n\nThe project includes a comprehensive local testing pipeline that mimics GitHub\nActions:\n\n```bash\n\n# Run full local CI pipeline (recommended before pushing)\n\nmake ci\n\n# Quick quality checks\n\nmake quick-check\n\n# Individual tools\n\nmake format      # Black + isort\nmake lint        # Flake8\nmake type-check  # MyPy\nmake security    # Bandit + Safety + Semgrep\nmake test        # Pytest with coverage\n\n# See [LOCAL_TESTING.md](LOCAL_TESTING.md) for detailed usage\n```\n\n### Running Tests\n\n```bash\n\n# Run all tests\n\npytest\n\n# Run with coverage\n\npytest --cov=tcgplayer_client --cov-report=html\n\n# Run specific test file\n\npytest tests/test_client.py\n\n# Run tests with verbose output\n\npytest -v\n\n# Run tests in parallel\n\npytest -n auto\n\n```\n\n### Code Quality\n\n```bash\n\n# Code formatting\n\nblack .\nisort .\n\n# Linting\n\nflake8 tcgplayer_client/\nmypy tcgplayer_client/\n\n# Run all quality checks\n\nmake quality  # If Makefile is available\n\n```\n\n### Security Testing\n\n```bash\n\n# Security scanning with Bandit\n\nbandit -r tcgplayer_client/ -f json -o bandit-report.json\n\n# Dependency vulnerability scanning\n\nsafety check\n\n# Advanced security analysis\n\npip install semgrep\nsemgrep --config=auto tcgplayer_client/\n\n# Dependency security audit\n\npip-audit\n\n```\n\n**Note**: Security issues have been identified and fixed in the codebase:\n\n- \u2705 **MD5 \u2192 SHA256**: Replaced weak MD5 hashing with secure SHA256 for cache\nkeys\n- \u2705 **Try-except-pass**: Fixed silent exception handling with proper logging\n- \u2705 **Assert statements**: Replaced with proper runtime error handling\n\n**\u2705 COMPLETED**: Security tools are now integrated into the CI/CD pipeline for\nautomated security testing.\n\n### **Comprehensive Testing Strategy**\n\nThe project includes multiple layers of testing to ensure code quality and\nsecurity:\n\n#### **1. Unit Testing (pytest)**\n\n```bash\n\n# Run all tests with coverage\n\npytest --cov=tcgplayer_client --cov-report=html --cov-report=term-missing\n\n# Run specific test categories\n\npytest tests/test_auth.py          # Authentication tests\npytest tests/test_client.py        # Main client tests\npytest tests/test_endpoints/       # API endpoint tests\npytest tests/test_rate_limiter.py  # Rate limiting tests\npytest tests/test_cache.py         # Caching tests\n\n# Run tests in parallel\n\npytest -n auto --dist=loadfile\n\n# Generate coverage reports\n\npytest --cov=tcgplayer_client --cov-report=html --cov-report=xml\n\n```\n\n#### **2. Security Testing (Automated)**\n\n```bash\n\n# Bandit security scanning\n\nbandit -r tcgplayer_client/ -f json -o bandit-report.json\nbandit -r tcgplayer_client/ -f txt\n\n# Safety dependency scanning\n\nsafety check --json --output safety-report.json\nsafety check\n\n# Semgrep static analysis\n\nsemgrep --config=auto --json --output=semgrep-report.json tcgplayer_client/\n\n# Pip audit for dependencies\n\npip-audit --desc --format=json --output=pip-audit-report.json\n\n```\n\n#### **3. Code Quality Testing**\n\n```bash\n\n# Black code formatting\n\nblack --check --diff .\n\n# Import sorting\n\nisort --check-only --diff .\n\n# Flake8 linting\n\nflake8 tcgplayer_client/ tests/ --max-line-length=88 --extend-ignore=E203,W503\n\n# MyPy type checking\n\nmypy tcgplayer_client/ --ignore-missing-imports\n\n# Pre-commit hooks (if installed)\n\npre-commit run --all-files\n\n```\n\n#### **4. Performance Testing**\n\n```bash\n\n# Run performance benchmarks\n\npython -m pytest tests/test_performance.py -v\n\n# Memory usage profiling\n\npython -m memory_profiler tests/test_memory.py\n\n# Async performance testing\n\npython -m pytest tests/test_async_performance.py -v\n\n```\n\n#### **5. Integration Testing**\n\n```bash\n\n# Test with real TCGplayer API (requires credentials)\n\nexport TCGPLAYER_CLIENT_ID=\"your_client_id\"\nexport TCGPLAYER_CLIENT_SECRET=\"your_client_secret\"\npython -m pytest tests/test_integration.py -v\n\n# Test rate limiting compliance\n\npython -m pytest tests/test_rate_limit_compliance.py -v\n\n```\n\n#### **6. Test Coverage Goals**\n\n- **Current Coverage**: 95%+ (90+ tests passing)\n- **Target Coverage**: 95%+ for production quality\n- **Critical Paths**: 100% coverage for authentication, rate limiting, and error\nhandling\n- **New Features**: 95%+ coverage requirement before merge\n\n### Testing Examples\n\n```python\n\nimport pytest\nfrom tcgplayer_client import TCGPlayerClient\n\n@pytest.mark.asyncio\nasync def test_catalog_endpoints():\n    client = TCGPlayerClient()\n    \n    # Test categories endpoint\n    categories = await client.endpoints.catalog.get_categories()\n    assert isinstance(categories, list)\n    assert len(categories) > 0\n    \n    # Test product search\n    products = await client.endpoints.catalog.search_products(\n        search_term=\"Black Lotus\"\n    )\n    assert isinstance(products, list)\n\n```\n\n## \ud83d\udccb Requirements\n\n### Core Dependencies\n\n- **Python**: 3.8 or higher\n- **aiohttp**: 3.8.0 or higher (async HTTP client)\n\n### Development Dependencies\n\n- **pytest**: Testing framework\n- **pytest-asyncio**: Async testing support\n- **pytest-cov**: Coverage reporting\n- **black**: Code formatting\n- **isort**: Import sorting\n- **flake8**: Linting\n- **mypy**: Type checking\n\n## \ud83c\udfd7\ufe0f Architecture\n\n### Core Components\n\n```text\ntcgplayer_client/\n\u251c\u2500\u2500 client.py              # Main client class\n\u251c\u2500\u2500 auth.py                # Authentication management\n\u251c\u2500\u2500 rate_limiter.py        # Rate limiting and throttling\n\u251c\u2500\u2500 session_manager.py     # HTTP session management\n\u251c\u2500\u2500 cache.py               # Response caching system\n\u251c\u2500\u2500 config.py              # Configuration management\n\u251c\u2500\u2500 validation.py          # Input validation\n\u251c\u2500\u2500 logging_config.py      # Logging configuration\n\u251c\u2500\u2500 exceptions.py          # Custom exception hierarchy\n\u2514\u2500\u2500 endpoints/             # API endpoint implementations\n    \u251c\u2500\u2500 catalog.py         # Catalog operations\n    \u251c\u2500\u2500 pricing.py         # Pricing operations\n    \u251c\u2500\u2500 stores.py          # Store operations\n    \u251c\u2500\u2500 orders.py          # Order operations\n    \u251c\u2500\u2500 inventory.py       # Inventory operations\n    \u2514\u2500\u2500 pricing.py         # Pricing operations (market prices, price guides)\n```\n\n### Design Patterns\n\n- **Async/Await**: Modern Python async patterns for non-blocking I/O\n- **Factory Pattern**: Endpoint creation and management\n- **Strategy Pattern**: Configurable rate limiting and caching strategies\n- **Observer Pattern**: Event-driven logging and monitoring\n- **Builder Pattern**: Configuration object construction\n\n## \ud83d\udcda Examples\n\n### Bulk Product Processing\n\n```python\n\nasync def process_products_bulk(client, product_ids):\n    \"\"\"Process multiple products efficiently with rate limiting.\"\"\"\n    results = []\n    \n    for product_id in product_ids:\n        try:\n            # Get product details\n            product = await client.endpoints.catalog.get_product(product_id)\n            \n            # Get current pricing\npricing = await client.endpoints.pricing.get_product_prices(product_id)\n            \n            # Get store inventory\ninventory = await client.endpoints.stores.get_store_inventory(product_id)\n            \n            results.append({\n                'product': product,\n                'pricing': pricing,\n                'inventory': inventory\n            })\n            \n        except Exception as e:\n            logger.error(f\"Error processing product {product_id}: {e}\")\n            continue\n    \n    return results\n\n```\n\n### Store Inventory Monitoring\n\n```python\n\nasync def monitor_store_inventory(client, store_id, product_ids):\n    \"\"\"Monitor store inventory levels for specific products.\"\"\"\n    while True:\n        try:\n            for product_id in product_ids:\n                inventory = await client.endpoints.stores.get_store_inventory(\n                    store_id=store_id,\n                    product_id=product_id\n                )\n                \n                if inventory and inventory.get('quantity', 0) > 0:\nlogger.info(f\"Product {product_id} available at store {store_id}\")\n                    \n            # Wait before next check\n            await asyncio.sleep(300)  # 5 minutes\n            \n        except Exception as e:\n            logger.error(f\"Inventory monitoring error: {e}\")\n            await asyncio.sleep(60)  # Wait 1 minute on error\n\n```\n\n### Price Alert System\n\n```python\n\nasync def price_alert_system(client, product_id, target_price):\n    \"\"\"Monitor product prices and alert when target price is reached.\"\"\"\n    while True:\n        try:\nprices = await client.endpoints.pricing.get_product_prices(product_id)\n            \n            if prices and len(prices) > 0:\n                current_price = prices[0].get('price', float('inf'))\n                \n                if current_price <= target_price:\nlogger.info(f\"Price alert! Product {product_id} is now ${current_price}\")\n                    # Send notification (email, webhook, etc.)\n                    break\n            \n            await asyncio.sleep(3600)  # Check every hour\n            \n        except Exception as e:\n            logger.error(f\"Price monitoring error: {e}\")\n            await asyncio.sleep(300)  # Wait 5 minutes on error\n\n```\n\n## \ud83e\udd1d Contributing\n\nWe welcome contributions! Please see our [Contributing\nGuidelines](CONTRIBUTING.md) for details.\n\n### Development Workflow\n\n1. **Fork** the repository\n2. **Create** a feature branch (`git checkout -b feature/amazing-feature`)\n3. **Commit** your changes (`git commit -m 'Add amazing feature'`)\n4. **Push** to the branch (`git push origin feature/amazing-feature`)\n5. **Open** a Pull Request\n\n### Code Standards\n\n- Follow PEP 8 style guidelines\n- Use type hints for all function parameters and return values\n- Write comprehensive docstrings\n- Include tests for new functionality\n- Ensure all tests pass before submitting\n\n## \ud83d\udcc4 License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file\nfor details.\n\n## \ud83c\udd98 Support\n\n### Getting Help\n\n- **\ud83d\udcd6 Documentation**: This README and inline code documentation\n- **\ud83d\udc1b Issues**: [GitHub\nIssues](<https://github.com/joshwilhelmi/tcgplayer-python/issues)>\n- **\ud83d\udcac Discussions**: [GitHub\nDiscussions](<https://github.com/joshwilhelmi/tcgplayer-python/discussions)>\n- **\ud83d\udce7 Email**: [josh@gobby.ai](mailto:josh@gobby.ai)\n\n### Common Issues\n\n#### Authentication Errors\n\n- Verify your `client_id` and `client_secret` are correct\n- Check that your TCGplayer API account is active\n- Ensure your IP address is whitelisted if required\n\n#### Rate Limiting Issues\n\n- Reduce your request frequency\n- Implement exponential backoff in your application\n- Use the built-in rate limiting features\n\n#### Network Issues\n\n- Check your internet connection\n- Verify firewall settings\n- Use the retry mechanisms built into the client\n\n## \ud83d\udcc8 Roadmap\n\n### Upcoming Features\n\n- [ ] **WebSocket Support**: Real-time data streaming\n- [ ] **GraphQL Interface**: Alternative to REST API\n- [ ] **Data Export**: CSV/JSON export functionality\n- [ ] **Analytics Dashboard**: Built-in data visualization\n- [ ] **Webhook Support**: Event-driven notifications\n- [ ] **Multi-API Support**: Integration with other trading card APIs\n\n### Version History\n\nSee [CHANGELOG.md](CHANGELOG.md) for a detailed history of changes and\nimprovements.\n\n## \ud83d\ude4f Acknowledgments\n\n- **TCGplayer** for providing the comprehensive API\n- **Python Community** for excellent async libraries and tools\n- **Contributors** who help improve this library\n- **Open Source Community** for inspiration and best practices\n\n## \ud83d\udcca Project Status\n\n- **Development Status**: Production Ready\n- **Python Version Support**: 3.8+\n- **Test Coverage**: 95%+\n- **Documentation**: Comprehensive\n- **License**: MIT (Open Source)\n- **CI/CD**: Automated testing, security scanning, and PyPI publishing\n\n---\n\n**Made with \u2764\ufe0f by [Josh Wilhelmi](mailto:josh@gobby.ai)**\n\n*If you find this library helpful, please consider giving it a \u2b50 on GitHub!*\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Python client library for TCGplayer API with async support, rate limiting, and comprehensive endpoint coverage",
    "version": "2.0.3",
    "project_urls": {
        "Changelog": "https://github.com/joshwilhelmi/tcgplayer-python/blob/main/CHANGELOG.md",
        "Documentation": "https://github.com/joshwilhelmi/tcgplayer-python#readme",
        "Homepage": "https://github.com/joshwilhelmi/tcgplayer-python",
        "Issues": "https://github.com/joshwilhelmi/tcgplayer-python/issues",
        "Repository": "https://github.com/joshwilhelmi/tcgplayer-python"
    },
    "split_keywords": [
        "tcgplayer",
        " api",
        " trading-cards",
        " async",
        " mtg",
        " pokemon",
        " yugioh"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "9ef35c5ec37c632e8b862a6876eb9958c1bb017c9d4843347e3601b7a23e6cdb",
                "md5": "b5a9982ec7e430de949983fdcedd9eb0",
                "sha256": "99bdc1fe3f0868754afd1b7dada71545dee5d549b76f3acb9b794d29abf9f73f"
            },
            "downloads": -1,
            "filename": "tcgplayer_client-2.0.3-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "b5a9982ec7e430de949983fdcedd9eb0",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 38085,
            "upload_time": "2025-08-25T04:45:16",
            "upload_time_iso_8601": "2025-08-25T04:45:16.988262Z",
            "url": "https://files.pythonhosted.org/packages/9e/f3/5c5ec37c632e8b862a6876eb9958c1bb017c9d4843347e3601b7a23e6cdb/tcgplayer_client-2.0.3-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "b81073983e63610b7435a1f031d35d355a9d65eb3f6acd8276d16b81c8ecf06f",
                "md5": "9bc8cc3b98fb694a561c87276b669ae3",
                "sha256": "456a2564c724d275f94d3217d617a91fbf25de39a324ec382a3d82c2a19b8b07"
            },
            "downloads": -1,
            "filename": "tcgplayer_client-2.0.3.tar.gz",
            "has_sig": false,
            "md5_digest": "9bc8cc3b98fb694a561c87276b669ae3",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 47378,
            "upload_time": "2025-08-25T04:45:18",
            "upload_time_iso_8601": "2025-08-25T04:45:18.170171Z",
            "url": "https://files.pythonhosted.org/packages/b8/10/73983e63610b7435a1f031d35d355a9d65eb3f6acd8276d16b81c8ecf06f/tcgplayer_client-2.0.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-25 04:45:18",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "joshwilhelmi",
    "github_project": "tcgplayer-python",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [
        {
            "name": "aiohttp",
            "specs": [
                [
                    ">=",
                    "3.8.0"
                ]
            ]
        },
        {
            "name": "pytest",
            "specs": [
                [
                    ">=",
                    "7.0.0"
                ]
            ]
        },
        {
            "name": "pytest-asyncio",
            "specs": [
                [
                    ">=",
                    "0.21.0"
                ]
            ]
        },
        {
            "name": "pytest-cov",
            "specs": [
                [
                    ">=",
                    "4.0.0"
                ]
            ]
        },
        {
            "name": "black",
            "specs": [
                [
                    ">=",
                    "23.0.0"
                ]
            ]
        },
        {
            "name": "isort",
            "specs": [
                [
                    ">=",
                    "5.12.0"
                ]
            ]
        },
        {
            "name": "flake8",
            "specs": [
                [
                    ">=",
                    "6.0.0"
                ]
            ]
        },
        {
            "name": "mypy",
            "specs": [
                [
                    ">=",
                    "1.0.0"
                ]
            ]
        },
        {
            "name": "setuptools",
            "specs": [
                [
                    ">=",
                    "61.0"
                ]
            ]
        },
        {
            "name": "wheel",
            "specs": [
                [
                    ">=",
                    "0.37.0"
                ]
            ]
        },
        {
            "name": "build",
            "specs": [
                [
                    ">=",
                    "0.10.0"
                ]
            ]
        }
    ],
    "lcname": "tcgplayer-client"
}
        
Elapsed time: 0.69833s