Skip to main content

A Python Library for Consuming Transactions from Pro Sports Transactions (https://www.prosportstransactions.com)

Project description

Version: PyPI Total Downloads License: MIT

Pro Sports Transactions API

Pro Sports Transactions is a Python API client-library for https://www.prosportstransactions.com enabling software engineers, data scientists, and sports fans with the ability to easily retrieve trades, free agent movements, signings, injuries, disciplinary actions, legal/criminal actions, and much more for five of the North American professional leagues: MLB, MLS, NBA, NFL, and NHL.

⚠️ Important Notice

Due to Cloudflare protection on prosportstransactions.com, direct requests are typically blocked. To use this library effectively, you'll need to run the Unflare service alongside this library and use the UnflareRequestHandler.

Features

  • 🏀 Multi-Sport Support: MLB, MLS, NBA, NFL, and NHL
  • 🚀 Multiple Request Handlers: Direct requests or Cloudflare bypass with UnflareRequestHandler
  • Performance Testing: Built-in configurable performance benchmarks
  • 🧪 Comprehensive Testing: Unit, integration, and performance test suites
  • 📊 Multiple Output Formats: DataFrame, dict, or JSON
  • 🔧 Configurable: Performance thresholds and request handling options

 

About

What is sports data without the transactions?

  • "Did he just throw his mouthpiece into the stands?"
  • "Yep."

2023-01-27 | Warriors | • Stephen Curry | fined $25,000 by NBA for throwing his mouthpiece into the stands

 

Getting Started

Prerequisites

⚠️ Important: Due to Cloudflare protection, you'll need to set up Unflare before using this library:

  1. Install and run Unflare service: Follow the setup instructions at https://github.com/iamyegor/Unflare
  2. Start the Unflare service (typically runs on http://localhost:5002)
  3. Use UnflareRequestHandler in your code (see examples below)

Quick Start (Recommended)

from datetime import date
import asyncio
import pro_sports_transactions as pst
from pro_sports_transactions.handlers import UnflareRequestHandler, UnflareConfig

# Configure Unflare handler (REQUIRED for bypassing Cloudflare)
config = UnflareConfig(url="http://localhost:5002/scrape")  # Your Unflare service URL
handler = UnflareRequestHandler(config)

# League (MLB, MLS, NBA, NFL, and NHL)
league = pst.League.NBA

# Transaction types: Disciplinary Actions, Injured List, Injuries,
# Legal Incidents, Minor League To/For, Personal Reasons,
# and Movement (e.g., Trades, Acquisitions, Waivers, Draft Picks, etc.)
transaction_types = tuple([t for t in pst.TransactionType])

# Date range: 2022-23 NBA Regular Season
start_date = date.fromisoformat("2022-10-18")
end_date = date.fromisoformat("2023-04-09")

# Pagination: Pro Sports Transactions provides 25 rows per page
starting_row = 0

# Define the coroutine for searching transactions
async def search_transactions() -> str:
    # Search for transactions using Unflare handler
    return await pst.Search(
        league=league,
        transaction_types=transaction_types,
        start_date=start_date,
        end_date=end_date,
        player="LeBron James",
        team="Lakers",
        starting_row=starting_row,
        request_handler=handler  # IMPORTANT: Use Unflare handler
    ).get_dataframe()  # Also supports get_dict() and get_json()

# Example execution block
if __name__ == "__main__":
    df = asyncio.run(search_transactions())

Direct Usage (May Not Work)

# ⚠️ WARNING: Direct requests often fail due to Cloudflare protection
# This example is provided for completeness but may not work reliably

async def search_transactions_direct():
    # Direct usage without handler (likely to be blocked)
    return await pst.Search(
        league=pst.League.NBA,
        transaction_types=tuple([t for t in pst.TransactionType]),
        player="LeBron James"
    ).get_dataframe()

Advanced Usage

Request Handlers

The library supports different request handlers for various scenarios:

Unflare Handler (Recommended - Cloudflare Bypass)

from pro_sports_transactions.handlers import UnflareRequestHandler, UnflareConfig

# Configure Unflare service - REQUIRED for reliable access
# First, set up Unflare: https://github.com/iamyegor/Unflare
config = UnflareConfig(
    url="http://localhost:5002/scrape",  # Your Unflare service URL
    timeout=60000,  # Request timeout in milliseconds
    proxy={"host": "proxy.example.com", "port": 8080}  # Optional proxy
)

handler = UnflareRequestHandler(config)
search = pst.Search(
    league=pst.League.NBA,
    transaction_types=(pst.TransactionType.Movement,),
    request_handler=handler
)

# The handler automatically caches cookies for improved performance
print(f"Cache valid: {handler.is_cache_valid()}")
print(f"Has cached cookies: {handler.has_cached_cookies}")

Direct Handler (Not Recommended - Often Blocked)

from pro_sports_transactions.handlers import DirectRequestHandler

# ⚠️ WARNING: Direct requests are typically blocked by Cloudflare
# Use this only for testing or if you have alternative access
handler = DirectRequestHandler()
search = pst.Search(
    league=pst.League.NBA,
    transaction_types=(pst.TransactionType.Movement,),
    request_handler=handler
)

Performance Testing

The library includes built-in performance testing capabilities with configurable thresholds:

# Configure performance thresholds in pyproject.toml
[tool.performance-thresholds]
unflare_cache_hit_speedup = 10.0  # Cache hits should be 10x faster than misses
direct_request_timeout = 5.0       # Direct requests should timeout within 5s
unflare_first_request_max = 30.0  # First Unflare request max time in seconds

Run performance tests:

# Run performance tests
poetry run pytest tests/performance/ -m performance

# Run specific performance tests
poetry run pytest tests/performance/handlers/test_unflare_performance.py::test_unflare_cache_speedup

Troubleshooting

Common Issues

"Connection refused" or "Service unavailable" errors

  • Cause: Unflare service is not running
  • Solution:
    1. Ensure you've installed Unflare: https://github.com/iamyegor/Unflare
    2. Start the Unflare service (usually http://localhost:5002)
    3. Verify the service is accessible: curl http://localhost:5002/health (if available)

"TypeError: cannot parse from 'NoneType'" errors

  • Cause: Direct requests being blocked by Cloudflare
  • Solution: Use UnflareRequestHandler instead of default direct requests

Slow performance on first request

  • Expected: First Unflare request takes longer as it bypasses Cloudflare
  • Optimization: Subsequent requests use cached cookies and are much faster

Getting Help

Results

# DataFrame
print(df)

# returns
          Date    Team        Acquired    Relinquished                                     Notes
0   2022-11-10  Lakers                  • LeBron James  placed on IL with strained left adductor
1   2022-11-25  Lakers  • LeBron James                                         activated from IL
2   2022-12-07  Lakers                  • LeBron James         placed on IL with sore left ankle
3   2022-12-09  Lakers  • LeBron James                                         activated from IL
4   2022-12-19  Lakers                  • LeBron James         placed on IL with sore left ankle
5   2022-12-21  Lakers  • LeBron James                                         activated from IL
6   2023-01-09  Lakers                  • LeBron James         placed on IL with sore left ankle
7   2023-01-12  Lakers  • LeBron James                                         activated from IL
8   2023-02-09  Lakers                  • LeBron James         placed on IL with sore left ankle
9   2023-02-15  Lakers  • LeBron James                                         activated from IL
10  2023-02-27  Lakers                  • LeBron James       placed on IL with right foot injury
11  2023-03-26  Lakers  • LeBron James                                         activated from IL

# Pages
print(df.attrs["pages])

# returns
1

Testing

The library includes comprehensive test suites with different categories:

Running Tests

# Run all unit tests (default)
poetry run pytest

# Run integration tests (requires external services)
poetry run pytest tests/integration/ -m integration

# Run performance tests
poetry run pytest tests/performance/ -m performance

# Run all tests
poetry run pytest tests/ -m "unit or integration or performance"

# Run tests with coverage
poetry run pytest --cov=src/pro_sports_transactions

Test Categories

  • Unit Tests: Fast, isolated tests of individual components
  • Integration Tests: Tests requiring external services (may be skipped if services unavailable)
  • Performance Tests: Benchmarks with configurable thresholds from pyproject.toml

Development

Code Quality

The project maintains high code quality standards:

# Code formatting
poetry run black .

# Linting (10/10 score maintained)
poetry run pylint .

# Import sorting
poetry run isort .

# Type checking
poetry run flake8

Contributing

  1. Install dependencies: poetry install
  2. Run tests: poetry run pytest
  3. Ensure pylint score: poetry run pylint . (should be 10/10)
  4. Format code: poetry run black .

Requirements

Pro Sports Transactions presents data in an HTML table. To make retrieval easy, pandas.read_html is used which in turn results in additional depencies. The following are a list of required libraries:

Runtime Dependencies

  • python = "^3.11"
  • aiohttp = "^3.8.4"
  • pandas = "^2.0.0"
  • brotli = "^1.0.9"
  • lxml = "^4.9.2"
  • html5lib = "^1.1"
  • bs4 = "^0.0.1"

Development Dependencies

  • black = "^23.3.0"
  • flake8 = "^6.0.0"
  • pytest = "^7.3.1"
  • pytest-asyncio = "^0.21.0"
  • pytest-mock = "^3.10.0"
  • isort = "^6.0.1"
  • pylint = "^3.3.7"

 

Thank You Frank Marousek!

Huge thanks to Frank Marousek @ Pro Sports Transactions for all of his efforts, and the efforts of those who have helped him, in compiling an excellent source of transactional information.

 

Disclaimer on accuracy, usage, and completeness of information.

The Pro Sports Transactions API is in no way affiliated with Pro Sports Transactions. The Pro Sports Transactions API provides a means for programatic access to Pro Sports Transactions. While the The Pro Sports Transactions API is open source under an MIT License, usage of all information obtained via the Pro Sports Transactions API is subject to all rights reserved by Pro Sports Transactions. No warranty, express or implied, is made regarding accuracy, adequacy, completeness, legality, reliability or usefulness of any information.

For questions, concerns, or other regarding the information provided via the Pro Sports Transaction API, please visit Pro Sports Transactions.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pro_sports_transactions-1.1.2.tar.gz (14.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pro_sports_transactions-1.1.2-py3-none-any.whl (13.3 kB view details)

Uploaded Python 3

File details

Details for the file pro_sports_transactions-1.1.2.tar.gz.

File metadata

  • Download URL: pro_sports_transactions-1.1.2.tar.gz
  • Upload date:
  • Size: 14.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.3.2 CPython/3.11.13 Linux/5.15.167.4-microsoft-standard-WSL2

File hashes

Hashes for pro_sports_transactions-1.1.2.tar.gz
Algorithm Hash digest
SHA256 68c3018a958e79e8ea29f8ce6145c173c09015eb17bb1cbbd37510531aa6a82a
MD5 4c5889e9821f48b6755dc4518495ac4b
BLAKE2b-256 5ea0208c9ecac2be05c22c2788312b6957e699da0bf8a325e0db98cdbfde5f92

See more details on using hashes here.

File details

Details for the file pro_sports_transactions-1.1.2-py3-none-any.whl.

File metadata

  • Download URL: pro_sports_transactions-1.1.2-py3-none-any.whl
  • Upload date:
  • Size: 13.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.3.2 CPython/3.11.13 Linux/5.15.167.4-microsoft-standard-WSL2

File hashes

Hashes for pro_sports_transactions-1.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 82f94a1c79d1b91d9a16f821aaa20f70ba7087a4af7510d4e2e7966183320ede
MD5 3cdf128cf00fb86e98e533f1748fd89c
BLAKE2b-256 408497212a33b3325da03668707a71b4be12f88e5bd9f67fca5dd1ede1756018

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page