Skip to content

Surface co-product allocation in pyvolca#150

Merged
ccomb merged 5 commits into
mainfrom
facteur_alloc
Jun 24, 2026
Merged

Surface co-product allocation in pyvolca#150
ccomb merged 5 commits into
mainfrom
facteur_alloc

Conversation

@ccomb

@ccomb ccomb commented Jun 24, 2026

Copy link
Copy Markdown
Owner

A multi-output process splits its parent activity's burden across its
co-products — a cheese activity, for instance, also yields whey, cream,
permeate and whey concentrate, each carrying a share that sums to ~100%. The
engine already emits these shares as allocationPercent on every
allProducts entry, but the Python client silently dropped them: Activity
declared only its identity/quantity fields, and FromJson keeps only declared
keys — so the share never reached ActivityDetail.all_products.

What changes

  • Activity.allocation_percent / Activity.allocation_formula are now decoded
    (optional — search results carry no share). They populate every
    ActivityDetail.all_products entry, so you can read how a process's impact
    is split across its products:

    detail = client.get_activity("…cheese…")
    for p in detail.all_products:
        print(p.product_name, p.product_amount, p.allocation_percent)
  • ActivityDetail.allocation_percent returns the fetched process's own share.

  • is_allocated and the Agribalyse decompose helper now read these
    structured shares instead of scraping the description text. That text is
    rounded and can drift from the factor the engine actually applied (e.g. an
    allocation comment reading 52.62% where the applied share is 51.4%);
    parse_allocation is kept only for the human-readable allocation method
    label, which the wire doesn't carry.

Notes

Client-only and additive: it reads wire fields the engine already produces, so
the wire contract is unchanged. Released as pyvolca 0.7.0.

ccomb added 4 commits June 24, 2026 17:28
A multi-output process splits its parent activity's burden across its
co-products, and the engine carries each share as `allocationPercent` on
every `allProducts` entry. The typed client dropped it: `Activity`
declared only its six identity/quantity fields and `FromJson` keeps only
declared keys, so the share never reached `ActivityDetail.all_products`.

Declare `allocation_percent` / `allocation_formula` on `Activity` (both
optional — search results carry no share) and add
`ActivityDetail.allocation_percent` for the fetched process's own share.
`is_allocated` now counts the structured shares rather than importing the
description-text parser.
…ield

`is_allocated` and `decompose`'s co-product enumeration scraped the
allocation factors out of the description text. That text is rounded and
can drift from the factor the engine actually applied — e.g. a cheese
whose allocation comment reads 52.62% but whose applied share is 51.4%.

Read the per-product shares from `all_products` instead, falling back to
the text parse only when structured shares are absent (older databases).
`parse_allocation` stays for the one thing the wire doesn't carry: the
human-readable allocation method label.
Adds co-product allocation shares to the typed client. Client-only and
additive — it reads wire fields the engine already emits, so the wire
contract is unchanged.
Generated by scripts/gen_api_md.py — picks up the new Activity
allocation_percent / allocation_formula fields. Keeps the
test_readme_api_reference_in_sync drift gate green.
is_allocated had become a thin alias to ActivityDetail.is_allocated, which
reads structured allocation_percent only. On older Agribalyse databases that
carry no structured shares — just an allocation block in the description — a
genuinely allocated process then reported False, disagreeing with decompose,
which still parses that text to enumerate co-products.

Restore the prefer-structured-then-text precedence decompose uses, so the
Agribalyse-specific helper keeps the text fallback while the generic property
stays structured-only.
@ccomb ccomb merged commit 88b7d20 into main Jun 24, 2026
10 checks passed
@ccomb ccomb deleted the facteur_alloc branch June 24, 2026 16:21
@ccomb ccomb mentioned this pull request Jun 24, 2026
ccomb added a commit that referenced this pull request Jun 24, 2026
Patch release. The only engine change since v0.8.0 is the #151 scoring
fix:
aggregate single scores (e.g. PEF) failed with `Unknown variable` on JRC
ILCD
method collections such as EF 3.1, because methods sharing a coarse
damage
category collapsed in the scoring input map. #151 keys that map by
method name,
so the per-method scoring variables resolve.

- Bump `volca.cabal` 0.8.0 → 0.8.1
- Add `## [0.8.1]` CHANGELOG section

#150 is also on main since v0.8.0 but is pyvolca-only (already shipped
on its own
`pyvolca-v0.7.0` tag) and adds no engine surface, so this stays a patch,
not a minor.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant