Metadata-Version: 2.4
Name: pysofascore
Version: 0.3.0
Summary: Python library for SofaScore data extraction. Built on scrapling/curl_cffi stealth engine.
Author: kirill52300
License: MIT
Project-URL: Homepage, https://github.com/Kirill52300/sofascore_api
Project-URL: Repository, https://github.com/Kirill52300/sofascore_api
Project-URL: Issues, https://github.com/Kirill52300/sofascore_api/issues
Keywords: sofascore,football,api,scraping,xg,statistics,live-scores
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: curl-cffi>=0.7
Provides-Extra: scrapling
Requires-Dist: scrapling>=0.4; extra == "scrapling"
Dynamic: license-file

# pysofascore

> **Disclaimer / Отказ от ответственности**
>
> This project and library is created and used **exclusively for educational
> and research purposes**. It is not intended for commercial use, automated
> data collection at scale, or any activity that violates SofaScore's Terms
> of Service.  The project is **not actively maintained** — use at your own risk.
>
> Данный проект и библиотека созданы и используются **исключительно в
> познавательных (educational) целях**. Проект не предназначен для
> коммерческого использования или массового автоматизированного сбора данных.
> Проект **не поддерживается на постоянной основе**.

---

Python library for SofaScore data extraction — matches, live scores, statistics, xG, lineups and more.

**Built on top of [scrapling](https://github.com/D4Vinci/Scrapling)** — uses [curl_cffi](https://github.com/lexiforest/curl_cffi) with Chrome TLS fingerprint impersonation to bypass SofaScore anti-bot protection. No browser binary required.

## Installation

```bash
pip install pysofascore
```

That's it. No browser downloads needed.

## Quick Start

```python
from sofascore_api import SofaScoreClient

client = SofaScoreClient()

# Get all football categories (countries)
categories = client.get_categories("football")
for cat in categories[:5]:
    print(f"{cat['id']}: {cat['name']}")

# Get today's matches
events = client.get_events_today("football")
print(f"\nToday: {len(events)} matches")

# Get live matches
live = client.get_live_events("football")
for ev in live[:5]:
    home = ev["homeTeam"]["name"]
    away = ev["awayTeam"]["name"]
    hs = ev.get("homeScore", {}).get("current", "?")
    as_ = ev.get("awayScore", {}).get("current", "?")
    print(f"  LIVE: {home} {hs} - {as_} {away}")

client.close()
```

Or use as a context manager:

```python
with SofaScoreClient() as client:
    events = client.get_events_today()
```

## Features

### Categories & Sports

```python
# All categories for a sport
categories = client.get_categories("football")
categories = client.get_all_categories("basketball")

# Tournaments within a category (country)
tournaments = client.get_category_tournaments(category_id=1)  # England
```

### Matches by Date

```python
# Specific date
events = client.get_events_by_date("football", "2026-04-07")

# Today
events = client.get_events_today("football")

# Next 7 days (returns {date: [events]})
week = client.get_events_week("football")

# Next 30 days
month = client.get_events_month("football")

# Custom range
events = client.get_events_range("football", start="2026-04-01", end="2026-04-15")
```

### Live Matches

```python
live = client.get_live_events("football")
tournaments = client.get_live_tournaments("football")
```

### Match Statistics & xG

```python
event_id = 13981725

# Full statistics (possession, shots, corners, xG, etc.)
stats = client.get_event_statistics(event_id)

# Shot map with per-shot xG and xGOT
shotmap = client.get_event_shotmap(event_id)
for shot in shotmap:
    print(f"{shot['player']['name']}: xG={shot['xg']:.3f}, type={shot['shotType']}")

# Match incidents (goals, cards, substitutions)
incidents = client.get_event_incidents(event_id)

# Lineups
lineups = client.get_event_lineups(event_id)

# Momentum graph
graph = client.get_event_graph(event_id)

# Head-to-head
h2h = client.get_event_h2h(event_id)

# Best players
best = client.get_event_best_players(event_id)
```

### Search

```python
results = client.search("Barcelona")
```

### Tournaments

```python
seasons = client.get_tournament_seasons(17)  # Premier League
standings = client.get_tournament_standings(17, season_id=76986)
top_scorers = client.get_tournament_top_players(17, season_id=76986, kind="goals")
```

### Teams & Players

```python
team = client.get_team(2817)               # Barcelona
players = client.get_team_players(2817)
recent = client.get_team_events(2817, direction="last")

player = client.get_player(284363)
transfers = client.get_player_transfer_history(284363)
heatmap = client.get_player_heatmap(284363, event_id=13981725)
```

## Proxy Support

```python
# HTTP proxy
client = SofaScoreClient(proxy="http://user:pass@proxy.example.com:8080")

# SOCKS5 proxy
client = SofaScoreClient(proxy="socks5://proxy.example.com:1080")
```

## Configuration

```python
client = SofaScoreClient(
    proxy=None,        # Proxy URL
    timeout=15,        # Request timeout in seconds
    retries=3,         # Retry attempts on 403/network errors
    retry_delay=2.0,   # Initial delay between retries (doubles each attempt)
)
```

## How It Works

SofaScore protects their API with anti-bot measures (Cloudflare, TLS fingerprinting).
Regular HTTP libraries like `requests` or `httpx` get blocked with 403.

This library uses [curl_cffi](https://github.com/lexiforest/curl_cffi) (the same engine that powers [scrapling](https://github.com/D4Vinci/Scrapling)'s `Fetcher`) to:

1. Impersonate Chrome's TLS fingerprint (JA3/JA4, cipher suites, ALPN)
2. Send browser-like headers (Referer, Origin, Accept)
3. Automatically retry on 403 with exponential backoff
4. Return parsed JSON responses

No browser binary, no Selenium, no Playwright — just HTTP with the right fingerprint.

## Supported Sports

`football`, `basketball`, `tennis`, `ice-hockey`, `table-tennis`, `baseball`,
`handball`, `american-football`, `volleyball`, `darts`, `esports`, `mma`,
`motorsport`, `cricket`, `rugby`, `futsal`, `waterpolo`, `snooker`, `cycling`,
`badminton`

## License

MIT
