Metadata-Version: 2.4
Name: lol-history-api
Version: 0.1.0
Summary: League of Legends history bridge and Python client SDK
Author: LoL History API contributors
License-Expression: MIT
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: aiohttp<4,>=3.9
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"

# LoL History API

A local Windows bridge for League of Legends match history, player rank, and deterministic match analysis.

The service reads credentials from the logged-in League client and exposes a small HTTP API for local tools or a bot. Authentication tokens are never returned by the API.

## Project Structure

```text
lol_history_api/
  api.py          aiohttp routes, validation, HTTP error mapping
  service.py      player and match-history use cases
  clients.py      LCU and Tencent RSO/SGP network clients
  credentials.py League client process/log credential discovery
  regions.py      region whitelist and SGP URL routing
  normalizers.py  pure response and rank normalization helpers
  matches.py      stable match response construction
  analytics.py    ROFL-style deterministic metrics and scoring
python -m lol_history_api module entry point
tests/            unit tests with no live League client required
```

Dependencies flow inward from HTTP to services to clients/pure transformations. Network code is isolated from scoring and response normalization, so each layer can be tested independently.

## Start

```powershell
python -m pip install -r requirements.txt
python -X utf8 -m lol_history_api
```

The League client must be running and logged in.

## Endpoints

### Health

```text
GET /health
```

### Regions

```text
GET /lol/regions
```

### Player and Current Rank

```text
GET /lol/player?game_name=Player&tag_line=1234
GET /lol/player?region=HN10&game_name=Player&tag_line=1234
```

The normalized `player.ranked` object contains:

```json
{
  "available": true,
  "solo": {
    "queue_type": "RANKED_SOLO_5x5",
    "tier": "DIAMOND",
    "division": "II",
    "league_points": 70,
    "wins": 120,
    "losses": 98,
    "games": 218
  },
  "flex": null,
  "queues": [],
  "raw": {}
}
```

The LCU client may expose rank for an arbitrary PUUID through `ranked-stats/{puuid}`. If that is unavailable, the bridge only falls back to `current-ranked-stats` when the requested PUUID belongs to the currently logged-in account. In other cases `available` is `false` instead of failing the whole request.

### Match History

```text
GET /lol/history?game_name=Player&tag_line=1234&count=10
GET /lol/history?region=HN10&game_name=Player&tag_line=1234&count=10
```

`count` is limited to 1-20.

Each match keeps the original compatible summary fields and adds:

- `player`: complete target participant payload.
- `participants`: all participant payloads returned upstream.
- `participant_identities`: LCU participant-to-player mapping.
- `participant_analyses`: normalized ROFL-style analysis for every participant.
- `teams`: team and objective payloads.
- `analysis`: deterministic ROFL-style target-player analysis.
- `raw`: complete upstream match payload.

The `analysis` object includes:

- Position, team, level, items, summoner spells, and perks.
- KDA, champion damage, damage taken, healing, shielding, crowd control, and time dead.
- Gold, lane minions, jungle minions, and total CS.
- Vision score, wards placed, wards cleared, and control wards.
- Turrets, dragons, barons, elders, heralds, Atakhan, stolen objectives, and objective damage.
- Kill participation, damage share, gold share, and per-minute rates.
- Combat, economy, farm, objective, vision, teamplay, survival, and total score.

## ROFL Comparison

The API can produce analysis close to the final-statistics portion of `rofl_analysis`, but it cannot invent fields that the selected LCU/SGP response does not contain.

Match history usually provides final participant and team statistics. A `.rofl` replay may contain additional replay metadata, while neither source reliably provides voice communication or complete decision-level interpretation. Frame-by-frame events, recalls, purchases, movement, and skill casts require a separate ROFL timeline parser and should remain a separate module from this HTTP history service.

## Authentication

Localhost mode may run without a bridge token. Any non-localhost bind requires `LOL_LCU_BRIDGE_TOKEN`.

```powershell
.\start_api.ps1 -BindAddress 0.0.0.0 -Port 18181 -Token "long-random-token"
```

Clients then send:

```text
X-LCU-Bridge-Token: long-random-token
```

Do not expose the bridge directly to the public internet.

## Tests

```powershell
$env:PYTHONDONTWRITEBYTECODE='1'
python -B -m unittest discover -s tests -v
```



## Python Client SDK

The package includes a small synchronous client for calling a deployed public API:

```python
from lol_history_api import LoLHistoryClient

client = LoLHistoryClient(
    base_url="http://111.228.5.172:18080",
    api_key="your-public-api-key",
)

health = client.health()
result = client.history(
    game_name="Player",
    tag_line="1234",
    region="黑色玫瑰",
    count=10,
)
```

The SDK only needs the public API key. It never needs the private `LOL_LCU_BRIDGE_TOKEN` used by the Windows bridge.

### Install the Python package

Install from a local checkout:

```powershell
python -m pip install .
```

Install directly from a Git repository:

```powershell
python -m pip install git+https://your-git-host/your-user/lol-history-api.git
```

Then call the deployed public API:

```python
from lol_history_api import LoLHistoryClient

client = LoLHistoryClient(
    base_url="http://111.228.5.172:18080",
    api_key="your-public-api-key",
)

result = client.history("Player", "1234", count=10)
print(result["matches"])
```

The public client uses `X-API-Key`. It does not need the private `LOL_LCU_BRIDGE_TOKEN` used by the Windows bridge.
