Skip to main content

Rust binding for python. To calculate star ratings and performance points for all osu! gamemodes, and quickly parse Beatmap into python objects.

Project description

peace-performance-python

Fast, To calculate star ratings and performance points for all osu! gamemodes, And, quickly parse Beatmap into python objects.

!! Now with https://github.com/MaxOhn/rosu-pp

rosu-pp (Rust) binding for python based on PyO3.

Cross-platform support. Support synchronous and asynchronous(tokio and async_std).

Faster than oppai-ng, see the benchmark for details.

Install by pip

PyPI: https://pypi.org/project/peace-performance-python

pip install peace-performance-python

Reliability:

check_your_osu_songs.py

Testing on my local machine, about 70,000 maps can be calculated properly.

[ Walking (E:\osu\songs) Start... ]
[ 69146 ] .osu files founded...
[ Walking Done! ]
[ Start task ]
69146/69146; ok: 69142, err: 0; total time: 23825.90ms, avg: 0.34ms
[ All DONE ]

PP Calculate

Minimal Examples

from peace_performance_python.prelude import *
from peace_performance_python.objects.utils import Mods

# Beatmap can be cached and reused!
beatmap = Beatmap('path_to_osu_file') 
result = Calculator(acc=98.8, miss=3, mods=Mods.HARDROCK | Mods.HIDDEN).calculate(beatmap) # HDHR

# Async support!
beatmap = await Beatmap.create_async_rs('path_to_osu_file')

Full Examples

# import all
from peace_performance_python.prelude import *
# or
# from peace_performance_python.objects import Beatmap, Calculator

from peace_performance_python.objects.utils import Mods

from tests import async_run, join_beatmap, HITORIGOTO, UNFORGIVING

# *No longer available by default (compile without `rust_logger` features enabled)*
# Initialize Rust logger (optional)
'''
set_log_level('trace')
init_logger()
'''


# Choose a style you like
def calculate(beatmap: Beatmap, calculator: Calculator) -> CalcResult:
    return calculator.calculate(beatmap)


def calculate_2(beatmap: Beatmap) -> CalcResult:
    # --
    c = Calculator()
    c.set_acc(98.8)
    c.set_miss(3)
    c.set_mods(Mods.HARDROCK | Mods.HIDDEN)

    # or
    c.acc = 98.8
    c.miss = 3
    c.mods = Mods.HARDROCK | Mods.HIDDEN

    # or
    c.setattr('acc', 98.8)
    c.setattr('miss', 3)
    c.setattr('mods', Mods.HARDROCK | Mods.HIDDEN)
    return calculate(beatmap, c)


def calculate_3(beatmap: Beatmap) -> CalcResult:
    c = Calculator()
    c.set_with_dict({'acc': 98.8, 'miss': 3})
    return calculate(beatmap, c)


def calculate_4(beatmap: Beatmap) -> CalcResult:
    return Calculator({'acc': 98.8, 'miss': 3}).calculate(beatmap)


def calculate_5(beatmap: Beatmap) -> CalcResult:
    return Calculator(acc=98.8, miss=3).calculate(beatmap)


async def main() -> None:
    path = join_beatmap(HITORIGOTO)
    # Load beatmap
    beatmap = Beatmap(path)
    # beatmap = Beatmap.create(path)

    # Async
    # beatmap = await Beatmap.create_async_rs(path)
    # beatmap = await Beatmap.create_async_py(path)
    # or
    # beatmap = await AsyncBeatmapRust(path)
    # beatmap = await AsyncBeatmapPython(path)
    print('\n>>>>> Beatmap:', beatmap)

    # Calculate pp
    # result = calculate_5(beatmap)
    c = Calculator(acc=98.8, miss=3)
    print('\n>>>>> Calculator as dict:', c.attrs_dict)
    result = c.calculate(beatmap)

    # Print results
    # print('\n>>>>> result:', result)
    print('\n>>>>> result.pp:', result.pp)
    print('\n>>>>> result as dict:', result.attrs_dict)
    # print('\n>>>>> result.raw_stars as dict:', result.raw_stars.attrs_dict)
    # print('\n>>>>> result.raw_pp as dict:', result.raw_pp.attrs_dict)

    # Reset calculator
    c.reset()
    print('\n>>>>> reseted Calculator as dict:', c.attrs_dict)

    # Calc again
    result2 = c.calculate(beatmap)
    print('\n>>>>> result2 as dict:', result2.attrs_dict)

    # Load another .osu files
    path2 = join_beatmap(UNFORGIVING)
    beatmap.init(path2)
    print(beatmap)

    # Convert calculate
    result3 = Calculator(mode=3).calculate(beatmap)
    print(result3)


if __name__ == '__main__':
    async_run(main())

Running results

 TRACE peace_performance_python::methods::common > function=sync_read_file duration=73.3µs
 TRACE peace_performance_python::methods::pp     > function=sync_parse_beatmap duration=181.9µs

>>>>> Beatmap: <Beatmap object (
        path: ./test_beatmaps/hitorigoto.osu, 
        is_initialized: True, 
        mode: 0, 
        mode_str: std, 
        version: 14, 
        n_circles: 207, 
        n_sliders: 132, 
        n_spinners: 1, 
        ar: 9, 
        od: 8.5, 
        cs: 4, 
        hp: 6, 
        sv: 1.7, 
        tick_rate: 1, 
        stack_leniency: None
    )>

>>>>> Calculator as dict: {
    'mode': None, 
    'mods': None, 
    'n50': None, 
    'n100': None, 
    'n300': None, 
    'katu': None, 
    'acc': 98.80000305175781, 
    'passed_obj': None, 
    'combo': None, 
    'miss': 3
    }
 TRACE peace_performance_python::methods::pp         > function=calc_with_any_pp duration=55.7µs
 TRACE peace_performance_python::objects::calculator > function=calc duration=103.2µs


>>>>> result.pp: 152.19204711914062


>>>>> result as dict: {
    'mode': 0, 
    'mods': 0, 
    'pp': 152.19204711914062, 
    'stars': 5.162832260131836, 
    'raw_pp': {
        'aim': 73.0337905883789, 
        'spd': 31.048368453979492, 
        'str': None, 
        'acc': 45.17241287231445, 
        'total': 152.19204711914062}, 
    'raw_stars': {
        'stars': 5.162832260131836, 
        'max_combo': 476, 
        'ar': 9.0, 
        'n_fruits': None, 
        'n_droplets': None, 
        'n_tiny_droplets': None, 
        'od': 8.5, 
        'speed_strain': 2.0723509788513184, 
        'aim_strain': 2.7511043548583984, 
        'n_circles': 207, 
        'n_spinners': 1
        }
    }

...

Beatmap parse

Examples

from peace_performance_python.prelude import *
from tests import join_beatmap, HITORIGOTO

# *No longer available by default (compile without `rust_logger` features enabled)*
# Initialize Rust logger (optional)
'''
set_log_level('trace')
init_logger()
'''

def main():
    path = join_beatmap(HITORIGOTO)
    # Load beatmap
    b = Beatmap(path)
    print('\n>>>>> Beatmap:', b)
    print('\n>>>>> Beatmap.hit_objects (0-3):', b.hit_objects[:3])
    print('\n>>>>> Beatmap.timing_points:', b.timing_points)
    print('\n>>>>> Beatmap.difficulty_points (0-3):', b.difficulty_points[:3])
    print('\n>>>>> Beatmap.hit_objects[0].pos:', b.hit_objects[0].pos)
    print('\n>>>>> Beatmap.hit_objects[3].kind:', b.hit_objects[3].kind)
    print('\n>>>>> Beatmap.hit_objects[3].kind.curve_points:',
          b.hit_objects[3].kind.curve_points)

    pos_0 = b.hit_objects[0].pos
    pos_1 = b.hit_objects[1].pos
    print('\n>>>>> Beatmap object(0):', b.hit_objects[0])
    print('\n>>>>> Beatmap object(1):', b.hit_objects[1])
    print('\n>>>>> Beatmap object pos(0):', pos_0)
    print('\n>>>>> Beatmap object pos(1):', pos_1)
    print('\n>>>>> Beatmap object pos(0) length, squared:',
          pos_0.length, pos_0.length_squared)
    print('\n>>>>> Beatmap object pos(0 and 1) distance:', pos_0.distance(pos_1))
    print('\n>>>>> Beatmap object pos(0 and 1) add:', pos_0.add(pos_1))
    print('\n>>>>> Beatmap object pos(0 and 1) sub:', pos_0.sub(pos_1))


if __name__ == '__main__':
    main()

Running results

 TRACE peace_performance_python::methods::common > function=sync_read_file duration=78.3µs
 TRACE peace_performance_python::methods::pp     > function=sync_parse_beatmap duration=193.4µs

>>>>> Beatmap: <Beatmap object (
        path: ./test_beatmaps/hitorigoto.osu, 
        is_initialized: True, 
        mode: 0, mode_str: std, version: 14, 
        n_circles: 207, n_sliders: 132, n_spinners: 1, 
        ar: 9, od: 8.5, cs: 4, hp: 6, sv: 1.7, tick_rate: 1, 
        stack_leniency: None
    ), hidden: hit_objects, timing_points, difficulty_points>

>>>>> Beatmap.hit_objects (0-3): [
    <HitObject object (
        start_time: 536, sound: 4, end_time: 536, kind: circle, pos: (44, 136))>, 
    <HitObject object (
        start_time: 717, sound: 0, end_time: 717, kind: circle, pos: (315, 196))>, 
    <HitObject object (
        start_time: 899, sound: 0, end_time: 899, kind: slider, pos: (152, 304))>]

>>>>> Beatmap.timing_points: [<TimingPoint object (time: 536, beat_len: 363.63635)>]

>>>>> Beatmap.difficulty_points (0-3): [
    <DifficultyPoint object (time: 23808, speed_multiplier: 1)>, 
    <DifficultyPoint object (time: 35445, speed_multiplier: 0.8)>, 
    <DifficultyPoint object (time: 41263, speed_multiplier: 1)>]

>>>>> Beatmap.hit_objects[0].pos: <Pos2 object (x: 44, y: 136)>

>>>>> Beatmap.hit_objects[3].kind: <HitObjectKind object (
    kind: slider, pixel_len: Some(85.0), repeats: Some(1), 
    path_type: Some("perfect_curve"), end_time: None)>

>>>>> Beatmap.hit_objects[3].kind.curve_points: [
    <Pos2 object (x: 315, y: 196)>, 
    <Pos2 object (x: 277, y: 176)>, 
    <Pos2 object (x: 248, y: 145)>]

>>>>> Beatmap object(0): <HitObject object (
    start_time: 536, sound: 4, end_time: 536, kind: circle, pos: (44, 136))>

>>>>> Beatmap object(1): <HitObject object (
    start_time: 717, sound: 0, end_time: 717, kind: circle, pos: (315, 196))>

>>>>> Beatmap object pos(0): <Pos2 object (x: 44, y: 136)>

>>>>> Beatmap object pos(1): <Pos2 object (x: 315, y: 196)>

>>>>> Beatmap object pos(0) length, squared: 142.9405517578125 20432.0

>>>>> Beatmap object pos(0 and 1) distance: 277.5625915527344

>>>>> Beatmap object pos(0 and 1) add: <Pos2 object (x: 359, y: 332)>

>>>>> Beatmap object pos(0 and 1) sub: <Pos2 object (x: -271, y: -60)>

Building

This package is intended to be built using rust, maturin or setuptools_rust.

1. Install Rust

posix

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

windows

https://static.rust-lang.org/rustup/dist/x86_64-pc-windows-msvc/rustup-init.exe

2. Install python dev dependencies

pip install -r requirements-dev.txt

3. Build native python lib

maturin develop --release

OR

python setup.py develop

Compile to .whl to use pip installation

maturin build --release

OR

python setup.py bdist_wheel

install .whl

# maturin build
pip install target/wheels/<name>.whl

# setup.py build
pip install dist/<name>.whl

Run tests and benchmarks

Build native modules (.pyd or .so)

python setup.py develop

Then run

pytest

or bench and draw a image

pytest --benchmark-histogram

Complete bench

pytest --benchmark-disable-gc --benchmark-warmup=True --benchmark-histogram

Run examples

python examples.py

Features

Flag Description
default Enable async_tokio, all modes and choose the all_included version for osu!standard. Set default_features = false to disable.
score_v2_buff Buff ScoreV2 (STD) - acc *= 1.25
ppysb_edition Special changes for RELAX and AUTOPILOT
relax_nerf Nerf relax and autopilot pp. Relax: aim * 0.9, spd * 0.3, acc *0.8; Autopilot: aim * 0.3, spd * 0.9, acc * 0.8
taiko Enable osu!taiko.
fruits Enable osu!ctb.
mania Enable osu!mania.
osu Enable osu!standard. Requires to also enable exactly one of the features no_leniency, no_sliders_no_leniency, or all_included.
no_leniency When calculating difficulty attributes in osu!standard, ignore stack leniency but consider sliders. Solid middleground between performance and precision, hence the default version.
no_sliders_no_leniency When calculating difficulty attributes in osu!standard, ignore stack leniency and sliders. Best performance but slightly less precision than no_leniency.
all_included When calculating difficulty attributes in osu!standard, consider both stack leniency and sliders. Best precision but significantly worse performance than no_leniency.
async_tokio Beatmap parsing will be async through tokio
async_std Beatmap parsing will be async through async-std

Vs Oppai-ng

peace-performance Python bindings vs C89 oppai-ng Python bindings.

Rust is Faster. The longer the map, the more obvious the advantages of rust.

peace-performance enables the no_sliders_no_leniency feature to be consistent with oppai's algorithm (faster, but loses precision).

If you need maximum precision (osu-performance) rather than performance, use all_included features.

This test was run on my subsystem and had performance issues with a minimum time greater than 1ms. (The minimum time in windows is 86us (padoru) and the next smallest is 192us (hitorigoto)

------------------------------------------------------------------------ benchmark 'bench-oppai-vs-rust': 12 tests -------------------------------------------------------------------------
Name (time in ms)               Min                Max               Mean            StdDev             Median               IQR            Outliers       OPS            Rounds  Iterations
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
test_rust_padoru             1.3805 (1.0)       1.7463 (1.0)       1.4447 (1.0)      0.0518 (1.0)       1.4301 (1.0)      0.0444 (1.01)        68;32  692.1759 (1.0)         358           1
test_rust_hitorigoto         1.6154 (1.17)      2.0133 (1.15)      1.7433 (1.21)     0.0587 (1.13)      1.7407 (1.22)     0.0439 (1.0)        129;82  573.6085 (0.83)        498           1
test_oppai_padoru            1.8734 (1.36)      2.3294 (1.33)      1.9799 (1.37)     0.0845 (1.63)      1.9659 (1.37)     0.0931 (2.12)        47;11  505.0744 (0.73)        204           1
test_oppai_hitorigoto        2.5925 (1.88)      3.1272 (1.79)      2.7537 (1.91)     0.0883 (1.70)      2.7357 (1.91)     0.0887 (2.02)        84;21  363.1464 (0.52)        346           1
test_rust_freedom_dive       3.0829 (2.23)      3.6729 (2.10)      3.1865 (2.21)     0.0687 (1.33)      3.1715 (2.22)     0.0685 (1.56)        70;18  313.8282 (0.45)        303           1
test_rust_sotarks            3.6848 (2.67)      4.0976 (2.35)      3.7886 (2.62)     0.0748 (1.45)      3.7676 (2.63)     0.0748 (1.70)        51;17  263.9489 (0.38)        240           1
test_rust_galaxy_burst       5.1418 (3.72)      5.7422 (3.29)      5.2629 (3.64)     0.0851 (1.64)      5.2349 (3.66)     0.0911 (2.08)         44;9  190.0092 (0.27)        184           1
test_oppai_freedom_dive      5.8532 (4.24)      6.3883 (3.66)      6.0279 (4.17)     0.1154 (2.23)      5.9971 (4.19)     0.1660 (3.78)         45;2  165.8948 (0.24)        161           1
test_oppai_sotarks           6.2822 (4.55)      7.0327 (4.03)      6.4706 (4.48)     0.1350 (2.61)      6.4400 (4.50)     0.1544 (3.52)         36;4  154.5453 (0.22)        145           1
test_oppai_galaxy_burst      8.2669 (5.99)      9.4358 (5.40)      8.5453 (5.91)     0.1838 (3.55)      8.5012 (5.94)     0.1732 (3.95)         25;8  117.0232 (0.17)        114           1
test_rust_unforgiving       10.9350 (7.92)     11.6170 (6.65)     11.1305 (7.70)     0.1289 (2.49)     11.1028 (7.76)     0.1701 (3.87)         26;2   89.8429 (0.13)         88           1
test_oppai_unforgiving      22.8311 (16.54)    23.7671 (13.61)    23.1481 (16.02)    0.2352 (4.54)     23.0818 (16.14)    0.2999 (6.83)         10;1   43.2001 (0.06)         43           1
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Simple Benchmarks

Native vs Wrapped beatmap object, Sync vs Async, Py async vs Rust async

Note: Rust has its own event loop (independent of python) and has performance issues due to rust's need to convert built-in futures to python coroutine. So rust async is the worst performer.

Read and parsing time spent on beatmap of different sizes (forgiving is a beatmap over 50 minutes long and takes the longest)

There are also subtle differences in the different calling methods


MIT

pure-peace

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

peace-performance-python-2.0.0.tar.gz (29.7 kB view details)

Uploaded Source

Built Distributions

peace_performance_python-2.0.0-cp310-cp310-win_amd64.whl (515.8 kB view details)

Uploaded CPython 3.10 Windows x86-64

peace_performance_python-2.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (572.8 kB view details)

Uploaded CPython 3.10 manylinux: glibc 2.17+ x86-64

peace_performance_python-2.0.0-cp310-cp310-macosx_11_0_x86_64.whl (674.9 kB view details)

Uploaded CPython 3.10 macOS 11.0+ x86-64

peace_performance_python-2.0.0-cp39-cp39-win_amd64.whl (515.9 kB view details)

Uploaded CPython 3.9 Windows x86-64

peace_performance_python-2.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (572.9 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.17+ x86-64

peace_performance_python-2.0.0-cp39-cp39-macosx_11_0_x86_64.whl (675.0 kB view details)

Uploaded CPython 3.9 macOS 11.0+ x86-64

peace_performance_python-2.0.0-cp38-cp38-win_amd64.whl (516.1 kB view details)

Uploaded CPython 3.8 Windows x86-64

peace_performance_python-2.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (573.2 kB view details)

Uploaded CPython 3.8 manylinux: glibc 2.17+ x86-64

peace_performance_python-2.0.0-cp38-cp38-macosx_11_0_x86_64.whl (675.3 kB view details)

Uploaded CPython 3.8 macOS 11.0+ x86-64

peace_performance_python-2.0.0-cp37-cp37m-win_amd64.whl (516.1 kB view details)

Uploaded CPython 3.7m Windows x86-64

peace_performance_python-2.0.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (573.2 kB view details)

Uploaded CPython 3.7m manylinux: glibc 2.17+ x86-64

peace_performance_python-2.0.0-cp37-cp37m-macosx_11_0_x86_64.whl (675.3 kB view details)

Uploaded CPython 3.7m macOS 11.0+ x86-64

File details

Details for the file peace-performance-python-2.0.0.tar.gz.

File metadata

File hashes

Hashes for peace-performance-python-2.0.0.tar.gz
Algorithm Hash digest
SHA256 12d73dcc62602fb06e07ee5631a410890e9290728eea598b10d54967765125ce
MD5 f1cb008e429fd0e7839f90debb5cbb17
BLAKE2b-256 a674f2234c1a41410aafedae2c7e4fd711bb9c0163c7c3ad5f26a950c573631f

See more details on using hashes here.

File details

Details for the file peace_performance_python-2.0.0-cp310-cp310-win_amd64.whl.

File metadata

File hashes

Hashes for peace_performance_python-2.0.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 1addfefa503c43cc2056f1e37aafc096634c4f0232351d3210e6052176332179
MD5 60325a744967155c42d1c83a6e931f5b
BLAKE2b-256 170572399c5fb0d35a356d945cee7db611773d6328377bcc476034150fe97aa2

See more details on using hashes here.

File details

Details for the file peace_performance_python-2.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for peace_performance_python-2.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 5f319b1f5ae70a0e87555be5d390fff8dd5ec1bedb7d6c40d18879fcfe88352e
MD5 b1b81db21f5dda2f2261674dc1a54162
BLAKE2b-256 524c6d1e8d2cba93d398e499414e2c2ebbf8ab9a0482d996cdc239fc2df17f26

See more details on using hashes here.

File details

Details for the file peace_performance_python-2.0.0-cp310-cp310-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for peace_performance_python-2.0.0-cp310-cp310-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 056da723aad50ab933ed62fd18360d22380359d6157659afb43fd09029d753cd
MD5 b9ca5d335c5951bb6b885395ea47299a
BLAKE2b-256 17c9e34b008ccf5bab03e8246a4d00ce18030b48920b1a56f55f5ffd20b41745

See more details on using hashes here.

File details

Details for the file peace_performance_python-2.0.0-cp39-cp39-win_amd64.whl.

File metadata

File hashes

Hashes for peace_performance_python-2.0.0-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 e7bfd170f43b0ad44088e7fcb4591c61f06d9b1d56a1e46fee6c1a0eec149f79
MD5 dd2e5c6605cd8e54f4a3d503f1ad01d0
BLAKE2b-256 cd59427e8e1cf83c876bb356117056d73d501b686a81a2cc71dd7fa7f57db0ed

See more details on using hashes here.

File details

Details for the file peace_performance_python-2.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for peace_performance_python-2.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 024692b25d8c1ae5676c03bf747ab3ce071b8228610787bfbe82b82367169ca4
MD5 4fd319ce32f1ddcd25f6da206d8600ab
BLAKE2b-256 26d488151323330a53158724c40213499b04550ebf26f4cf5e11929852e1af8f

See more details on using hashes here.

File details

Details for the file peace_performance_python-2.0.0-cp39-cp39-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for peace_performance_python-2.0.0-cp39-cp39-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 8909ebb0ef1d972e09fd21ba53e773d6430c58ff98f8b914e6f6e5a287f738d3
MD5 eb3a7e627d7202b8a95371e96f8f9010
BLAKE2b-256 7a3920e9df679180293ec0b31b354991c9a5ce24dca411cd71620ec86449cbd5

See more details on using hashes here.

File details

Details for the file peace_performance_python-2.0.0-cp38-cp38-win_amd64.whl.

File metadata

File hashes

Hashes for peace_performance_python-2.0.0-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 7d028f06856ec0b2a275839835d95708c25dbabc7f285c7c3519aa64e02b5e12
MD5 4ec62e16e7f22d4a41e3cbc85a2930df
BLAKE2b-256 7711a34c7d4e1759fc449203acda4db998f0be2f6c22f69e5c5946bd54482a96

See more details on using hashes here.

File details

Details for the file peace_performance_python-2.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for peace_performance_python-2.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 3f0b3ecec6ff4699466a4eb75cec569204dc986b3586014f74b79ceb67e62a82
MD5 8594c15339fa15ab5bdfa0967ed47ecd
BLAKE2b-256 8db6ed7e6ed89b651d66577d81e88e87fcdabdf729cc764ad2a0ba031f81805b

See more details on using hashes here.

File details

Details for the file peace_performance_python-2.0.0-cp38-cp38-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for peace_performance_python-2.0.0-cp38-cp38-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 573e0b128a48e1895926e2b69ec65982312ec0d454e3664923ab2c4fc7b5a9ec
MD5 056797cdf16aad66cf9d45d3388442cb
BLAKE2b-256 ab266f27b316b51e81ac0865ec8a6a196c44d06fd32cbb2c7513513d62c2136f

See more details on using hashes here.

File details

Details for the file peace_performance_python-2.0.0-cp37-cp37m-win_amd64.whl.

File metadata

File hashes

Hashes for peace_performance_python-2.0.0-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 dda470feef1f003e937f9e47c08c7d75275c32013100225b21c409b5cba4cea8
MD5 0a07541e675f0ee28551d627bbc2fd66
BLAKE2b-256 a05902e317a388809fce28e7a00b1a5e092f7382307561cf2995ef4698cbef59

See more details on using hashes here.

File details

Details for the file peace_performance_python-2.0.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for peace_performance_python-2.0.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 bc195942a5c9e7c0032f4fadc528df9390b813ea724f494951012165ae3fcfa0
MD5 ae787fafc9bb632fd703e4769f5f41e1
BLAKE2b-256 58d839fdd2b2ce9fd41cadfd7f3357947b596c37f8869c12ef7d8bcb32782304

See more details on using hashes here.

File details

Details for the file peace_performance_python-2.0.0-cp37-cp37m-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for peace_performance_python-2.0.0-cp37-cp37m-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 612306be776520db5a7d6b2ff7a7c96cb503b8b94f823cde59e664e87f3099d2
MD5 2fc9913baabd4bb5fda40925fac895d0
BLAKE2b-256 c2f7d8a7650da4681d2b0a693b4eca56a1329be8f12d2db349e03df1f42fa74a

See more details on using hashes here.

Supported by

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