A Python library for scraping UFC fighter and event data from UFC.com.
- π₯ Fighter Data: Stats, records, fight history, striking/takedown accuracy
- π Event Data: Fight cards, results, schedules, broadcast info
- β‘ Async Support: Both synchronous and asynchronous API clients
- π Rich Data Models: Typed dataclasses for all data structures
Using uv (recommended):
uv add pyfightOr with pip:
pip install pyfightInstall from source:
git clone https://github.com/JaINTP/pyfight.git
cd pyfight
uv syncfrom pyfight import UfcApiClient
client = UfcApiClient()
fighter = client.get_fighter("Jon Jones")
print(f"Name: {fighter.name}")
print(f"Nickname: {fighter.nickname}")
print(f"Record: {fighter.wins['total']}-{fighter.losses['total']}-{fighter.draws}")
print(f"Age: {fighter.age}")
print(f"Striking Accuracy: {fighter.striking_accuracy}")
print(f"Takedown Accuracy: {fighter.takedown_accuracy}")from pyfight import UfcApiClient
client = UfcApiClient()
event = client.get_event("UFC 324")
print(f"Event: {event.name}")
print(f"Date: {event.date}")
print(f"Venue: {event.venue}")
print(f"Status: {event.status}") # upcoming, live, or completed
print(f"Main Card: {event.main_card_schedule.start_time}")
for fight in event.main_card_fights:
print(f"{fight.red_corner.name} vs {fight.blue_corner.name}")
if fight.winner:
print(f" Winner: {fight.winner}")
print(f" Method: {fight.method}, Round: {fight.round}")import asyncio
from pyfight import AsyncUfcApiClient
async def main():
client = AsyncUfcApiClient()
fighter = await client.get_fighter("Israel Adesanya")
print(f"{fighter.name}: {fighter.wins['total']}-{fighter.losses['total']}")
event = await client.get_event("UFC 300")
print(f"{event.name} - {event.date}")
asyncio.run(main())from pyfight import UfcApiClient
client = UfcApiClient()
events = client.get_upcoming_events()
for event_name, event in events.items():
print(f"{event.name} - {event.date} at {event.venue}")| Field | Description |
|---|---|
name, nickname |
Fighter identity |
age, height, weight, reach |
Physical attributes |
wins, losses, draws |
Record (with breakdown by method) |
striking_accuracy, takedown_accuracy |
Accuracy percentages |
sig_strikes_landed_per_min |
Strikes per minute |
fights |
List of fight history |
| Field | Description |
|---|---|
name, date, location, venue |
Event info |
status |
upcoming, live, or completed |
main_card_fights, prelim_fights, early_prelim_fights |
Fight cards |
main_card_schedule, prelims_schedule |
Start times & broadcasts |
| Field | Description |
|---|---|
red_corner, blue_corner |
Fighter corners with name, ranking, odds |
weightclass |
Division |
winner, method, round, time |
Result (for completed fights) |
Run the test suite:
# Install dev dependencies
uv sync
# Run tests with coverage
uv run pytest
# View coverage report
open htmlcov/index.htmlTest Results: 103 tests passing with 90% code coverage.
pyfight/
βββ __init__.py # Package exports
βββ api_client.py # UfcApiClient & AsyncUfcApiClient
βββ models.py # Dataclass definitions
βββ clients/
β βββ http_client.py # HTTP request handling
βββ parsers/
βββ ufc_parser.py # HTML parsing logic
- Python 3.10+
requests- Sync HTTP clienthttpx- Async HTTP clientlxml- HTML parsing
This project was inspired by ufc-api by Fritz Capuyan. However, that project no longer works due to:
- Sherdog bot mitigation - The original relied on scraping Sherdog.com, which now blocks automated requests
- Google Search dependency - Used Google Search to find fighter URLs, which is unreliable
- Not maintained - The original hasn't been updated in years
pyfight is a complete rewrite that:
- Scrapes directly from UFC.com (no third-party dependencies)
- Constructs URLs directly (no Google Search)
- Has full test coverage and proper error handling
MIT License - see LICENSE for details.
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Run the tests (
pytest) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request