Python bindings for the PoE2 crafting simulator
Project description
crafting-sim
Python bindings for the PoE2 crafting simulator (crates/crafting-sim),
built for writing fast crafting simulations.
The extension consumes the same crafting-sim-api catalog, import, replay,
and query contract as the WebAssembly binding. Its only additional domain
dependency is the intentionally Python-specific offline pricing library.
Game data is embedded in the compiled extension at build time — the package needs no data files, environment variables, or network access at runtime. All randomness derives from an explicit seed, so every simulation is reproducible.
Usage
from crafting_sim import Item, Omen, Tier, ops
from crafting_sim.data import Base, Family
item = Item(Base.SAPPHIRE_RING, item_level=82, seed=42)
item.alchemy()
# Spam Chaos Orbs until the ring has T2-or-better Fire Resistance.
while not item.has_mod(Family.FIRE_RESISTANCE, min_tier=2):
item.chaos(tier=Tier.PERFECT)
item.set_active_omens([Omen.DEXTRAL_EXALTATION])
item.exalt() # guaranteed suffix
item.clear_omens()
item.divine()
item.vaal() # modifies the item unpredictably and corrupts it
for mod in item.mods:
print(mod.id, mod.tier, mod.text)
# Exact outcome distributions, without applying:
p = item.outcomes(ops.annulment()).probability(
lambda it: it.has_mod(Family.FIRE_RESISTANCE)
)
branch = item.copy() # exact clone, including the current random stream
# Successful operations are tracked by canonical game-data currency item.
for currency, count in item.currency_used.most_common():
print(count, currency.name, currency.id)
# Offline prices are embedded alongside the simulator.
from crafting_sim.pricing import value_currency_usage
cost = value_currency_usage(item.currency_used)
print(cost.total_divines) # None when cost.missing is non-empty
# Applications can request current rates explicitly.
from crafting_sim.pricing import fetch_poe2_currency_rates
live_rates = fetch_poe2_currency_rates("Standard")
live_cost = value_currency_usage(item.currency_used, live_rates)
Existing PoE2 items can be imported from their raw trade listing JSON. The
result is the same canonical Item used by crafting simulations; listing
metadata such as price and indexed time intentionally remains the caller's
responsibility.
item = Item.from_trade_listing(listing_json, seed=42)
# Auto-detect either trade JSON or copied in-game text:
item = Item.from_paste(clipboard_text, seed=42)
Everything is strongly typed. Small structural values such as Tier,
Rarity, and Slot are integer-backed Python enums. Bases, mod families,
essences, omens, and catalysts are generated StrEnums under
crafting_sim.data because their values are canonical game-data IDs; members
also expose their in-game descriptions. Item mutates in place and verbs
chain. Equal items have the same canonical item state, and mutable items are
intentionally unhashable. Item.currency_used is derived from session history,
so failed operations are not counted and copied items retain their usage.
The lazy crafting_sim.catalog value exposes the same bases, operations,
Omens, and reachable modifiers as the browser binding. Generated identifier
enums carry member-specific runtime documentation for help() and IDE use.
Development
just dev # rebuild the extension into the uv venv after Rust changes
just test # pytest
just lint # ruff + mypy
just gen-enums # regenerate crafting_sim/data/_generated.py after a data update
The extension crate lives at crates/crafting-sim-py. Queries such as
has_mod execute in Rust; a chaos-spam loop runs at roughly 10^5
applies/second single-threaded.
Releases
Linux wheels (manylinux x86_64 and aarch64, Python >= 3.13 via abi3) are
published to PyPI (pip install optimalexile-crafting-sim) by
.github/workflows/python-release.yml; no sdist is published. To cut
a release: bump version here and [workspace.package] version in the root
Cargo.toml to the same value, then push a vX.Y.Z tag — CI fails if the
three disagree.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file optimalexile_crafting_sim-0.2.3-cp313-abi3-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: optimalexile_crafting_sim-0.2.3-cp313-abi3-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 3.1 MB
- Tags: CPython 3.13+, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
438dffc855ddf15b9b6eb5b3de8a9ea04f41c9cc551b00fe590d858245d8a0ec
|
|
| MD5 |
d14e91001ee71c18ffcbe55834e61521
|
|
| BLAKE2b-256 |
0d12358de8b8c84a391871cd36792d32357191eda1c3c7a38bcf2cdc214c1c28
|
Provenance
The following attestation bundles were made for optimalexile_crafting_sim-0.2.3-cp313-abi3-manylinux_2_28_x86_64.whl:
Publisher:
python-release.yml on optimalexile/optimalexile
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
optimalexile_crafting_sim-0.2.3-cp313-abi3-manylinux_2_28_x86_64.whl -
Subject digest:
438dffc855ddf15b9b6eb5b3de8a9ea04f41c9cc551b00fe590d858245d8a0ec - Sigstore transparency entry: 2194311357
- Sigstore integration time:
-
Permalink:
optimalexile/optimalexile@ba64ab6ee389f98f47d4f62f25d21038968631f6 -
Branch / Tag:
refs/tags/v0.2.3 - Owner: https://github.com/optimalexile
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-release.yml@ba64ab6ee389f98f47d4f62f25d21038968631f6 -
Trigger Event:
push
-
Statement type:
File details
Details for the file optimalexile_crafting_sim-0.2.3-cp313-abi3-manylinux_2_28_aarch64.whl.
File metadata
- Download URL: optimalexile_crafting_sim-0.2.3-cp313-abi3-manylinux_2_28_aarch64.whl
- Upload date:
- Size: 3.0 MB
- Tags: CPython 3.13+, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ae765b2b2258f02425ad3f6cd183230f6501818efbfece2955b922634563b57b
|
|
| MD5 |
7f53e3b75da6096249c88a4e7bb34ba7
|
|
| BLAKE2b-256 |
7532b3b4ec84ec2da348f432ea1d2a47d25911b143d0e0ae65841279c2dcfa7e
|
Provenance
The following attestation bundles were made for optimalexile_crafting_sim-0.2.3-cp313-abi3-manylinux_2_28_aarch64.whl:
Publisher:
python-release.yml on optimalexile/optimalexile
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
optimalexile_crafting_sim-0.2.3-cp313-abi3-manylinux_2_28_aarch64.whl -
Subject digest:
ae765b2b2258f02425ad3f6cd183230f6501818efbfece2955b922634563b57b - Sigstore transparency entry: 2194311371
- Sigstore integration time:
-
Permalink:
optimalexile/optimalexile@ba64ab6ee389f98f47d4f62f25d21038968631f6 -
Branch / Tag:
refs/tags/v0.2.3 - Owner: https://github.com/optimalexile
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-release.yml@ba64ab6ee389f98f47d4f62f25d21038968631f6 -
Trigger Event:
push
-
Statement type: