Skip to main content

Python bindings for bethkit — a Bethesda plugin and archive toolkit

Project description

bethkit.py

License Python PyPI

Python bindings for bethkit - a fast Rust library for reading and writing Bethesda game plugin and archive files. bethkit.py wraps the bethkit_ffi C ABI via ctypes; no compiler or build tools required.

Features

  • Plugin reading - open .esp/.esm/.esl files by path or from in-memory bytes; iterate groups and records; look up records by FormID or EditorID; inspect sub-records
  • Plugin writing - build new plugins from scratch with PluginWriter, WritableGroup, and WritableRecord
  • BSA / BA2 archives - open and extract entries from BSA (TES4/SSE) and BA2 (GNRL/DX10) archives; write new archives with BsaWriter, Ba2GnrlWriter, and Ba2Dx10Writer
  • String tables - read, edit, and write .STRINGS/.DLSTRINGS/.ILSTRINGS localisation files; apply translation sets with LocalizationSet
  • Schema - decode sub-records into typed FieldValue variants (integers, floats, FormIDs, enums with resolved names, flags, structs, arrays) via RecordView and SchemaRegistry
  • Load-order utilities - LoadOrder, GlobalFormId, and PluginCache for winning-override lookups and EditorID search across multiple plugins

Requirements

Requirement Version
Python ≥ 3.10
pydantic ≥ 2.0

The native bethkit_ffi library is bundled in the wheel — no separate installation required.

Installation

uv add bethkit

or

pip install bethkit

Quick Start

Reading a plugin

from pathlib import Path
from bethkit import Plugin, Game

with Plugin.open(Path("Ordinator - Perks of Skyrim.esp"), Game.SKYRIM_SE) as plugin:
    print("Masters:", plugin.masters)
    print("Kind:", plugin.kind)

    for group in plugin:
        for child in group:
            if hasattr(child, "form_id"):
                print(f"  0x{child.form_id:08X}  {child.editor_id}")

Building a plugin from scratch

from pathlib import Path
from bethkit import Game, PluginWriter, WritableGroup, WritableRecord

with PluginWriter(Game.SKYRIM_SE) as writer:
    with WritableGroup.new(b"NPC_") as group:
        rec = WritableRecord.new(b"NPC_", form_id=0x000D62)
        rec.add_subrecord(b"EDID", b"MyNPC\x00")
        group.add_record(rec)
        writer.add_group(group)
    writer.write_to_file(Path("MyMod.esp"))

Extracting from an archive

from pathlib import Path
from bethkit import Archive

with Archive.open(Path("Skyrim - Meshes.bsa")) as arc:
    data = arc.extract("meshes/actors/character/character assets/skeleton.nif")
    if data:
        Path("skeleton.nif").write_bytes(data)

Load-order and FormID resolution

from pathlib import Path
from bethkit import Game, Plugin, PluginCache, PluginKind, LoadOrder

lo = LoadOrder()
lo.push("Skyrim.esm", PluginKind.FULL)
lo.push("MyMod.esp", PluginKind.FULL)

cache = PluginCache()
cache.add("Skyrim.esm", Plugin.open(Path("Skyrim.esm"), Game.SKYRIM_SE))

hit = cache.find_by_editor_id("ArmorIronCuirass")
if hit:
    print(hit.global_form_id)   # Skyrim.esm:0x012E49
    print(hit.record.editor_id)

Development

git clone https://github.com/Modding-Forge/bethkit.py
cd bethkit.py
uv sync --extra dev
uv run pytest

Linting and type-checking:

uv tool run ruff check src/ tests/
uv tool run pyright src/ tests/

Related projects

  • bethkit - the underlying Rust library; bethkit.py wraps its C ABI

License

Apache-2.0 - see LICENSE.

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

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

bethkit-1.0.3-py3-none-win_amd64.whl (391.4 kB view details)

Uploaded Python 3Windows x86-64

bethkit-1.0.3-py3-none-manylinux_2_34_x86_64.whl (519.2 kB view details)

Uploaded Python 3manylinux: glibc 2.34+ x86-64

File details

Details for the file bethkit-1.0.3-py3-none-win_amd64.whl.

File metadata

  • Download URL: bethkit-1.0.3-py3-none-win_amd64.whl
  • Upload date:
  • Size: 391.4 kB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for bethkit-1.0.3-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 4d1266835547359544aff10ef9952bfbc8b9998ab7b6664f597c29a9bece8a71
MD5 0eaabd89ba5b416df8b323b288552d77
BLAKE2b-256 ecc388f0e21c4c307abf4784b0ca8aa222759a8646a87a9cb6e0f88b4ad42506

See more details on using hashes here.

File details

Details for the file bethkit-1.0.3-py3-none-manylinux_2_34_x86_64.whl.

File metadata

  • Download URL: bethkit-1.0.3-py3-none-manylinux_2_34_x86_64.whl
  • Upload date:
  • Size: 519.2 kB
  • Tags: Python 3, manylinux: glibc 2.34+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for bethkit-1.0.3-py3-none-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 b24b7f993a034d506cfdfb9f5e07d57a3adc126548f42d43f4f28c7c448ba58c
MD5 93c2a635c0d1c3fd33c41f0f44b95fed
BLAKE2b-256 c587a56e93dcd036a6b0f2e6535df3f65aefc0629bb83053086726c8a4c166b7

See more details on using hashes here.

Supported by

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