osu-tools-py
A high-performance Python wrapper for ppy/osu-tools, powered by pythonnet.
This library allows you to calculate Performance Points (PP), Star Ratings (SR), and other difficulty attributes for osu! beatmaps directly from Python. It embeds the official C# DLLs (compiled from osu!lazer), ensuring results are identical to the official game algorithms.
Features:
- 🚀 Accurate: Uses the actual C# code from osu!lazer for calculations.
- 📦 Batteries Included: Comes with pre-compiled DLLs (no need to compile C# yourself).
- 🖥️ Cross-Platform: Supports Windows, Linux, and macOS (Intel & Apple Silicon/M1/M2).
- 🧩 Type Safe: Fully typed Python API with data classes.
📋 Prerequisites
Before installing the Python package, you must have the .NET 8 Runtime installed on your system.
- Download .NET 8.0 Runtime
- Note: You only need the "Run console apps" version (Runtime); the SDK is not required for usage.
📦 Installation
pip install osu-tools-py
🚀 Quick Start
1. Calculate osu!stable PP
To get PP values that match the official osu! website (osu!stable), you must follow two rules:
- Add the "CL" (Classic) mod to your mod list.
- Provide a
legacy_total_score(any value > 0).
from osu_tools import OsuCalculator
# Initialize (loads .NET runtime)
calc = OsuCalculator()
# Example: Calculate Max PP for HDDT on Standard Mode
result = calc.calculate(
file_path="beatmaps/12345.osu",
mode=0,
# Rule 1: Always include "CL" for Stable calculations
mods=["HD", "DT", "CL"],
acc=100.0,
# Rule 2: Provide a legacy score > 0 to enable Stable physics/scoring
legacy_total_score=1000000
)
if result.is_success:
print(f"Stars: {result.stars:.2f}")
print(f"PP: {result.pp:.2f}")
print(f"Aim: {result.pp_aim:.2f}")
print(f"Speed: {result.pp_speed:.2f}")
else:
print(f"Error: {result.error}")
2. Calculate Real Score (from Replay/API)
When calculating a specific score for osu!stable, pass the hit statistics and ensure you include the Stable compatibility flags.
# Real stats from a score
stats = {
'great': 450,
'ok': 12,
'meh': 1,
'miss': 2
}
result = calc.calculate(
file_path="beatmaps/12345.osu",
mode=0,
mods=["HD", "CL"], # Don't forget CL!
combo=850,
statistics=stats,
legacy_total_score=1000000 # Required for Stable logic
)
print(f"Real PP: {result.pp:.2f}")
print(f"Real PPAcc: {result.pp_acc:.2f}") # PP from Accuracy
Batch Calculation
When calculating multiple scores for the same beatmap/mode/mods, use
calculate_many() to reuse beatmap decoding and difficulty calculation:
results = calc.calculate_many([
{"file_path": "beatmaps/12345.osu", "mode": 0, "mods": ["HD", "CL"], "acc": 100.0},
{"file_path": "beatmaps/12345.osu", "mode": 0, "mods": ["HD", "CL"], "acc": 98.5, "misses": 1},
])
Lazer Calculation Example
If you want to calculate PP for the Lazer scoring system (where slider tails affect accuracy):
# Lazer calculation example
lazer_stats = {
'great': 450,
'ok': 10,
'miss': 5,
'slider_tail_hit': 200, # Lazer specific stat
'large_tick_hit': 50 # Lazer specific stat
}
result = calc.calculate(
file_path="beatmaps/12345.osu",
mode=0,
mods=[],
combo=800,
statistics=lazer_stats,
)
Supported Inputs
- Mods: Supports list of strings
["HD", "DT"], list of dicts[{"acronym": "HD"}], or objects. - Modes:
0: osu! (Standard)1: osu!taiko2: osu!catch3: osu!mania
Return Data
The function returns a CalculationResult object:
@dataclass
class CalculationResult:
mode: int
stars: float
pp: float
pp_aim: float
pp_speed: float
pp_acc: float
pp_flashlight: float
max_combo: int
error: Optional[str]
# ...
🛠️ Building from Source
If you want to modify the C# logic or build the wheels yourself:
-
Requirements:
- Python 3.10+
- .NET 8.0 SDK
uv(Python package manager)
-
Clone:
git clone --recursive https://github.com/yaowan233/osu-tools-py.git cd osu-tools-py
-
Build: The project uses GitHub Actions for matrix builds (Windows/Linux/macOS), but you can build locally:
# 1. Compile C# DLLs cd osu-tools/PerformanceCalculator dotnet publish -c Release -o ../../src/osu_tools/lib # 2. Build Python Wheel cd ../.. uv build
⚠️ Troubleshooting
-
RuntimeError: Failed to create a default .NET runtime:- Ensure you installed .NET 8 Runtime.
- On Linux/macOS, ensure
dotnetis in your PATH.
-
PP seems lower than official site:
- Did you add
"CL"to your mods list? - Did you pass
legacy_total_score=1000000?
- Did you add
📄 License
This project is licensed under the MIT License. Based on ppy/osu-tools (MIT) and pythonnet (MIT).
Metadata
Release files for osu-tools-py 0.1.7
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| osu_tools_py-0.1.7-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details |
| osu_tools_py-0.1.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | Python 3 | none | Linux glibc 2.17+ x86-64 | Details |
| osu_tools_py-0.1.7-py3-none-macosx_11_0_arm64.whl | Python 3 | none | macOS 11.0+ ARM64 | Details |
| osu_tools_py-0.1.7-py3-none-macosx_10_15_x86_64.whl | Python 3 | none | macOS 10.15+ x86-64 | Details |
Total release size: 152.2 MB
Release files / osu_tools_py-0.1.7-py3-none-win_amd64.whl
| Download URL | osu_tools_py-0.1.7-py3-none-win_amd64.whl |
|---|---|
| Size | 32.9 MB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
d951a4acc4854017c66cdc44a452b44cfb806b3d40224e250f76bb49c03ac7f0
|
|
BLAKE2b-256 checksum How to use checksums |
e7e8add4fd50676c3a111429659c91064f50a2c95aa43d5f052fa0cd0705dd19
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 13, 2026.
Transparency logRelease files / osu_tools_py-0.1.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | osu_tools_py-0.1.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 38.0 MB |
| Tags | Linux glibc 2.17+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
1abff111eb1de1ef553a915c9de951d629dfb37967abd5c7434275d213177cb1
|
|
BLAKE2b-256 checksum How to use checksums |
59621dc751c934e1d5b4a118f7f7d3b892277d2009107bc6ce789a702d8d8372
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 13, 2026.
Transparency logRelease files / osu_tools_py-0.1.7-py3-none-macosx_11_0_arm64.whl
| Download URL | osu_tools_py-0.1.7-py3-none-macosx_11_0_arm64.whl |
|---|---|
| Size | 40.4 MB |
| Tags | Python 3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
9beead9ac7141c6dc02fb2a61dfae248ad80f950bf889a1d247825f6e3c6219a
|
|
BLAKE2b-256 checksum How to use checksums |
498e8ce55e3c2bb1cbfb922f682c1963ed6d39ca7270fa02adeacd450fb2da58
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 13, 2026.
Transparency logRelease files / osu_tools_py-0.1.7-py3-none-macosx_10_15_x86_64.whl
| Download URL | osu_tools_py-0.1.7-py3-none-macosx_10_15_x86_64.whl |
|---|---|
| Size | 40.8 MB |
| Tags | Python 3 macOS 10.15+ x86-64 |
|
SHA-256 checksum How to use checksums |
50d0d44c2973f7356ceff13ae1fef243cb1144da8f8a38848953b52c80449417
|
|
BLAKE2b-256 checksum How to use checksums |
07f5040835108c316debdc6a59d40cacf8ce025f67f1fcdc878f1edc97c9e3b1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 13, 2026.
Transparency log