HVBrowser
HVBrowser provides typed browser automation components for HentaiVerse. It
builds on hbrowser for one authenticated browser transport; reusable battle
operations remain in the separate hvbattle package.
Component graph
HentaiVerseSession is the public composition root. HVDriver is deliberately
limited to browser lifecycle and authenticated transport, while every
HentaiVerse feature has a named component:
HentaiVerseSession
├── browser: HVDriver
├── realm: RealmNavigator
├── player: PlayerClient
├── equipment: EquipmentRepairClient
├── market: MarketClient
├── lottery: LotteryClient
└── monster_lab: MonsterLabClient
from hvbrowser import HentaiVerseSession, Realm
async with HentaiVerseSession(headless=True) as session:
player = await session.player.inspect()
realm = await session.realm.current()
print(player.level, player.stamina, realm is Realm.ISEKAI)
The session initializes the browser, authenticates, enters Persistent, and
closes the browser on exit. An application may inject a configured but
not-yet-started transport with HentaiVerseSession(browser=browser); after
injection, the session owns that transport's lifecycle.
All components share the same browser page. Call their operations sequentially; concurrent navigation by multiple components is not supported.
Player and equipment
Player reads and mutations are explicit. Stamina recovery returns a
StaminaRecoveryReport; a successful report confirms that the visible stamina
increased. Missing controls and unknown submission outcomes raise typed errors.
before = await session.player.read_stamina()
report = await session.player.recover_stamina(expected_before=before)
if report.recovered:
print(report.before, report.after)
Equipment repair separates inspection from mutation and scopes snapshots to a
typed Realm. repair_all() returns NO_REPAIR_NEEDED, REPAIRED, or
MATERIALS_UNAVAILABLE. It verifies a disabled submit control against a fresh
server page before reporting unavailable materials.
snapshot = await session.equipment.inspect()
report = await session.equipment.repair_all(expected_before=snapshot)
if not report.ready:
print(report.outcome)
Lottery and Monster Lab
Lottery inspection returns the current ticket count, shared GP balance, and fixed ticket price. Purchasing requires an explicit kind and positive quantity, then verifies the exact ticket increase and GP decrease.
The page reader takes one atomic visible-text snapshot and requires exactly one
complete label for the ticket count, GP balance, and ticket price. Missing,
malformed, duplicate, or unsupported-price fields fail closed. inspect() may
perform its documented one-time direct reload after an unreadable landing;
inspect_once() performs no recovery navigation and is intended for tightly
bounded read-only probes. The ticket-count label is read from the page's
You hold <owned> of <sold> sold tickets field; the owned amount is returned,
while the sold total is validated as an integrity boundary.
from hvbrowser import LotteryKind, MaintenanceNavigationContext
snapshot = await session.lottery.inspect(
LotteryKind.WEAPON,
context=MaintenanceNavigationContext.ORDINARY,
)
report = await session.lottery.purchase(
LotteryKind.WEAPON,
25,
context=MaintenanceNavigationContext.ORDINARY,
expected_before=snapshot,
)
Target counts, Weapon-versus-Armor priority, and limited-GP behavior are application policy and do not belong in this package.
Monster Lab similarly exposes each resource as one atomic operation:
from hvbrowser import MaintenanceNavigationContext, MonsterLabFeed
snapshot = await session.monster_lab.inspect(
context=MaintenanceNavigationContext.ORDINARY
)
food = await session.monster_lab.feed_all(
MonsterLabFeed.FOOD,
context=MaintenanceNavigationContext.ORDINARY,
)
drugs = await session.monster_lab.feed_all(
MonsterLabFeed.DRUGS,
context=MaintenanceNavigationContext.ORDINARY,
)
Lottery, Monster Lab, and equipment repair open canonical realm-scoped URLs directly; they do not depend on Bazaar/Armory menu visibility, hover, or click behavior. Every operation checks an atomic DOM snapshot before navigation and again after landing, then verifies the destination realm, origin, path, query, and page structure before reading or mutating state.
The snapshot classifies timed challenge, final-completion, next-floor, and
active-battle markers. Equipment repair blocks on all four states. Lottery and
Monster Lab require every public operation to declare a
MaintenanceNavigationContext. ORDINARY blocks all four states;
POST_BATTLE may leave an already-observed, trusted Persistent final completion
only on the operation's initial navigation. It still blocks challenge,
next-floor, and active states, and any battle marker observed after direct
navigation blocks all further maintenance.
URL identity and all four marker booleans are read in one atomic browser
evaluation. Origin, expected realm, and realm root path are trusted before a
marker can become MaintenanceNavigationBlockedError; a marker paired with an
untrusted origin, wrong realm, or unexpected path is a navigation-safety error.
A browser-generation failure remains terminal and is never followed by another
same-browser probe.
Market
Market inspection and sale planning are read-only. A MarketSaleRequest
contains immutable item-name selections, and the resulting plan records its
realm.
from hvbrowser import MarketSaleRequest
snapshot = await session.market.inspect()
plan = await session.market.plan_sales(
MarketSaleRequest(materials=("Low-Grade Metals",)),
)
print(snapshot.realm, plan.total_units)
Submission requires an explicit submit_sales(plan) call. It remains blocked
by a fail-closed runtime gate until the current live quote and pricing semantics
have been verified. The guarded implementation never deposits credits or
re-lists unrelated orders.
Guarded live smoke test
The surrounding application owns account selection. The smoke probe requires credentials through environment indirection, verifies the first Persistent landing before any feature navigation, stops on challenge, completion, next-floor, or active-battle markers, and performs no purchase, feed-all, Market submission, repair, recovery, or battle action:
uv run --no-sync python scripts/live_readonly_smoke.py \
--skip-market \
--inspect-lotteries \
--inspect-monster-lab
Lottery and Monster Lab inspection are skipped in Isekai without switching realms.
Development
HVBrowser 0.10 requires the authentication-only Driver.login() contract from
hbrowser>=0.44.0,<0.45; earlier compatibility lines are not supported.
Build a clean environment backed by the PyPI release of hbrowser:
bash scripts/rebuild-env.sh
For coordinated local development, overlay the local checkout after rebuilding:
uv pip install --python .venv/bin/python --reinstall --no-deps --editable \
/path/to/hbrowser
Commands that must preserve the editable overlay use uv run --no-sync.
License
This project is licensed under GPL-3.0-only. See LICENSE.
Metadata
Release files for hvbrowser 0.10.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| hvbrowser-0.10.2.tar.gz | 78.4 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| hvbrowser-0.10.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 135.5 kB
Release files / hvbrowser-0.10.2.tar.gz
| Download URL | hvbrowser-0.10.2.tar.gz |
|---|---|
| Size | 78.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
aaa7ed0edb5a6cfe91dc037357c8e8548d7612653740aa3f4225d354e6694cfb
|
|
BLAKE2b-256 checksum How to use checksums |
ffedd8a37f7551a274b895ed93bde654878137b6f775f232d5fcf87887c2f9bc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 4, 2026.
Transparency logRelease files / hvbrowser-0.10.2-py3-none-any.whl
| Download URL | hvbrowser-0.10.2-py3-none-any.whl |
|---|---|
| Size | 57.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
707e9139e9dad199b01a3e150ffa1307c98a428cf979624169313d9b341f3395
|
|
BLAKE2b-256 checksum How to use checksums |
fb7b3227cbb5358efbeaba819b0cf1cbf08d7e2e8313d1b4a7dd33e91a512e60
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 4, 2026.
Transparency logSecurity for hvbrowser 0.10.2
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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for hvbrowser-0.10.2.tar.gz
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 Sep 4, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.