openepd 6.13.2__py3-none-any.whl → 7.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. openepd/__init__.py +4 -4
  2. openepd/__version__.py +1 -1
  3. openepd/api/average_dataset/generic_estimate_sync_api.py +11 -10
  4. openepd/api/average_dataset/industry_epd_sync_api.py +9 -8
  5. openepd/api/base_sync_client.py +53 -9
  6. openepd/api/category/sync_api.py +1 -1
  7. openepd/api/dto/base.py +4 -4
  8. openepd/api/dto/common.py +24 -16
  9. openepd/api/dto/meta.py +15 -11
  10. openepd/api/dto/mf.py +9 -8
  11. openepd/api/epd/dto.py +43 -33
  12. openepd/api/epd/sync_api.py +9 -9
  13. openepd/api/pcr/sync_api.py +2 -2
  14. openepd/bundle/model.py +11 -10
  15. openepd/bundle/reader.py +12 -5
  16. openepd/bundle/writer.py +17 -6
  17. openepd/model/base.py +60 -43
  18. openepd/model/category.py +13 -10
  19. openepd/model/common.py +100 -55
  20. openepd/model/declaration.py +93 -64
  21. openepd/model/epd.py +51 -43
  22. openepd/model/generic_estimate.py +28 -13
  23. openepd/model/industry_epd.py +15 -9
  24. openepd/model/lcia.py +132 -113
  25. openepd/model/org.py +54 -33
  26. openepd/model/pcr.py +38 -32
  27. openepd/model/specs/asphalt.py +31 -22
  28. openepd/model/specs/base.py +11 -9
  29. openepd/model/specs/concrete.py +60 -39
  30. openepd/model/specs/range/aggregates.py +9 -9
  31. openepd/model/specs/range/aluminium.py +7 -7
  32. openepd/model/specs/range/asphalt.py +22 -19
  33. openepd/model/specs/range/cladding.py +16 -16
  34. openepd/model/specs/range/cmu.py +10 -9
  35. openepd/model/specs/range/concrete.py +36 -27
  36. openepd/model/specs/range/conveying_equipment.py +16 -15
  37. openepd/model/specs/range/electrical.py +24 -22
  38. openepd/model/specs/range/finishes.py +109 -104
  39. openepd/model/specs/range/fire_and_smoke_protection.py +7 -7
  40. openepd/model/specs/range/furnishings.py +16 -12
  41. openepd/model/specs/range/manufacturing_inputs.py +16 -16
  42. openepd/model/specs/range/masonry.py +16 -16
  43. openepd/model/specs/range/mechanical.py +47 -47
  44. openepd/model/specs/range/mechanical_insulation.py +7 -7
  45. openepd/model/specs/range/network_infrastructure.py +54 -46
  46. openepd/model/specs/range/openings.py +36 -31
  47. openepd/model/specs/range/plumbing.py +15 -13
  48. openepd/model/specs/range/precast_concrete.py +20 -16
  49. openepd/model/specs/range/sheathing.py +18 -18
  50. openepd/model/specs/range/steel.py +25 -25
  51. openepd/model/specs/range/thermal_moisture_protection.py +20 -20
  52. openepd/model/specs/range/utility_piping.py +9 -9
  53. openepd/model/specs/range/wood.py +19 -19
  54. openepd/model/specs/range/wood_joists.py +8 -8
  55. openepd/model/specs/singular/__init__.py +9 -5
  56. openepd/model/specs/singular/aggregates.py +22 -15
  57. openepd/model/specs/singular/aluminium.py +20 -5
  58. openepd/model/specs/singular/asphalt.py +44 -20
  59. openepd/model/specs/singular/cladding.py +38 -23
  60. openepd/model/specs/singular/cmu.py +26 -11
  61. openepd/model/specs/singular/common.py +3 -2
  62. openepd/model/specs/singular/concrete.py +85 -48
  63. openepd/model/specs/singular/conveying_equipment.py +30 -17
  64. openepd/model/specs/singular/deprecated/__init__.py +3 -2
  65. openepd/model/specs/singular/deprecated/concrete.py +68 -33
  66. openepd/model/specs/singular/deprecated/steel.py +28 -15
  67. openepd/model/specs/singular/electrical.py +69 -41
  68. openepd/model/specs/singular/finishes.py +250 -140
  69. openepd/model/specs/singular/fire_and_smoke_protection.py +9 -6
  70. openepd/model/specs/singular/furnishings.py +16 -14
  71. openepd/model/specs/singular/manufacturing_inputs.py +23 -14
  72. openepd/model/specs/singular/masonry.py +66 -21
  73. openepd/model/specs/singular/mechanical.py +48 -47
  74. openepd/model/specs/singular/mechanical_insulation.py +7 -6
  75. openepd/model/specs/singular/mixins/conduit_mixin.py +13 -10
  76. openepd/model/specs/singular/network_infrastructure.py +111 -52
  77. openepd/model/specs/singular/openings.py +127 -95
  78. openepd/model/specs/singular/plumbing.py +15 -12
  79. openepd/model/specs/singular/precast_concrete.py +68 -54
  80. openepd/model/specs/singular/sheathing.py +47 -27
  81. openepd/model/specs/singular/steel.py +69 -45
  82. openepd/model/specs/singular/thermal_moisture_protection.py +36 -20
  83. openepd/model/specs/singular/utility_piping.py +11 -8
  84. openepd/model/specs/singular/wood.py +48 -24
  85. openepd/model/specs/singular/wood_joists.py +19 -6
  86. openepd/model/standard.py +15 -8
  87. openepd/model/validation/common.py +9 -3
  88. openepd/model/validation/numbers.py +0 -13
  89. openepd/model/validation/quantity.py +53 -25
  90. openepd/model/versioning.py +9 -6
  91. openepd/patch_pydantic.py +0 -93
  92. {openepd-6.13.2.dist-info → openepd-7.0.0.dist-info}/METADATA +1 -1
  93. openepd-7.0.0.dist-info/RECORD +142 -0
  94. openepd/compat/__init__.py +0 -15
  95. openepd/compat/compat_functional_validators.py +0 -25
  96. openepd/compat/pydantic.py +0 -30
  97. openepd-6.13.2.dist-info/RECORD +0 -145
  98. {openepd-6.13.2.dist-info → openepd-7.0.0.dist-info}/LICENSE +0 -0
  99. {openepd-6.13.2.dist-info → openepd-7.0.0.dist-info}/WHEEL +0 -0
openepd/model/lcia.py CHANGED
@@ -16,7 +16,9 @@
16
16
  from enum import StrEnum
17
17
  from typing import Any, ClassVar
18
18
 
19
- from openepd.compat.pydantic import pyd
19
+ import pydantic
20
+ from pydantic import ConfigDict
21
+
20
22
  from openepd.model.base import BaseOpenEpdSchema
21
23
  from openepd.model.common import Measurement
22
24
  from openepd.model.validation.quantity import ExternalValidationConfig
@@ -30,34 +32,34 @@ class EolScenario(BaseOpenEpdSchema):
30
32
  otherwise the outcomes can be statistically combined.
31
33
  """
32
34
 
33
- name: str = pyd.Field(
35
+ name: str = pydantic.Field(
34
36
  max_length=40,
35
- example="Landfill",
37
+ examples=["Landfill"],
36
38
  description="A brief text description of the scenario, preferably from list eol_scenario_names",
37
39
  )
38
- likelihood: float | None = pyd.Field(
40
+ likelihood: float | None = pydantic.Field(
39
41
  description="The weigting of this scenario used in the C1 .. C4 dataset. For example, the overall C1 shoudl be "
40
42
  "equal to weighted sum of C1 from all the scenarios, weighted by likelihood.",
41
- example=0.33,
43
+ examples=[0.33],
42
44
  default=None,
43
45
  )
44
- C1: Measurement | None = pyd.Field(
46
+ C1: Measurement | None = pydantic.Field(
45
47
  description="Deconstruction and Demolition under this scenario",
46
48
  default=None,
47
49
  )
48
- C2: Measurement | None = pyd.Field(
50
+ C2: Measurement | None = pydantic.Field(
49
51
  description="Transport to waste processing or disposal under this scenario.",
50
52
  default=None,
51
53
  )
52
- C3: Measurement | None = pyd.Field(
54
+ C3: Measurement | None = pydantic.Field(
53
55
  description="Waste Processing under this scenario",
54
56
  default=None,
55
57
  )
56
- C4: Measurement | None = pyd.Field(
58
+ C4: Measurement | None = pydantic.Field(
57
59
  description="Disposal under this scenario",
58
60
  default=None,
59
61
  )
60
- D: Measurement | None = pyd.Field(
62
+ D: Measurement | None = pydantic.Field(
61
63
  description="Potential net benefits from reuse, recycling, and/or energy recovery beyond "
62
64
  "the system boundary under this scenario",
63
65
  default=None,
@@ -74,35 +76,35 @@ class ScopeSet(BaseOpenEpdSchema):
74
76
 
75
77
  allowed_units: ClassVar[str | tuple[str, ...] | None] = None
76
78
 
77
- A1A2A3: Measurement | None = pyd.Field(
79
+ A1A2A3: Measurement | None = pydantic.Field(
78
80
  description="Sum of A1..A3",
79
81
  default=None,
80
82
  )
81
- A1: Measurement | None = pyd.Field(
83
+ A1: Measurement | None = pydantic.Field(
82
84
  description="Raw Material Supply",
83
85
  default=None,
84
86
  )
85
- A2: Measurement | None = pyd.Field(
87
+ A2: Measurement | None = pydantic.Field(
86
88
  description="Transport to Manufacturing",
87
89
  default=None,
88
90
  )
89
- A3: Measurement | None = pyd.Field(
91
+ A3: Measurement | None = pydantic.Field(
90
92
  description="Manufacturing",
91
93
  default=None,
92
94
  )
93
- A4: Measurement | None = pyd.Field(
95
+ A4: Measurement | None = pydantic.Field(
94
96
  description="Transport to Construction",
95
97
  default=None,
96
98
  )
97
- A5: Measurement | None = pyd.Field(
99
+ A5: Measurement | None = pydantic.Field(
98
100
  description="Construction",
99
101
  default=None,
100
102
  )
101
- B1: Measurement | None = pyd.Field(
103
+ B1: Measurement | None = pydantic.Field(
102
104
  description="Use impacts over Reference Service Life (Predicted)",
103
105
  default=None,
104
106
  )
105
- B1_years: float | None = pyd.Field(
107
+ B1_years: float | None = pydantic.Field(
106
108
  gt=0,
107
109
  lt=100,
108
110
  description="Timeframe over which B1 is evaluated, in years. "
@@ -110,95 +112,95 @@ class ScopeSet(BaseOpenEpdSchema):
110
112
  "B1_years=1.0 or B1=12.3kgCO2e, B1_years=10.0",
111
113
  default=None,
112
114
  )
113
- B2: Measurement | None = pyd.Field(
115
+ B2: Measurement | None = pydantic.Field(
114
116
  description="Predicted Maintenance Impacts over Reference Service Life",
115
117
  default=None,
116
118
  )
117
- B2_years: float | None = pyd.Field(
119
+ B2_years: float | None = pydantic.Field(
118
120
  gt=0,
119
121
  lt=100,
120
122
  description="Predicted Maintenance Impacts over Reference Service Life",
121
123
  default=None,
122
124
  )
123
- B3: Measurement | None = pyd.Field(
125
+ B3: Measurement | None = pydantic.Field(
124
126
  description="Predicted Repair impacts over Reference Service Life",
125
127
  default=None,
126
128
  )
127
- B3_years: float | None = pyd.Field(
129
+ B3_years: float | None = pydantic.Field(
128
130
  gt=0,
129
131
  lt=100,
130
132
  description="Timeframe over which B3 is evaluated, in years",
131
133
  default=None,
132
134
  )
133
- B4: Measurement | None = pyd.Field(
135
+ B4: Measurement | None = pydantic.Field(
134
136
  description="Predicted Replacement Impacts over the Building lifetime "
135
137
  "('Estimated Construction Works lifespan') specified in the PCR.",
136
138
  default=None,
137
139
  )
138
- B4_years: float | None = pyd.Field(
140
+ B4_years: float | None = pydantic.Field(
139
141
  gt=0,
140
142
  lt=100,
141
143
  description="Timeframe over which B4 is evaluated, in years",
142
144
  default=None,
143
145
  )
144
- B5: Measurement | None = pyd.Field(
146
+ B5: Measurement | None = pydantic.Field(
145
147
  description="Predicted Refurbishment Impacts over the Building lifetime "
146
148
  "('Estimated Construction Works lifespan') specified in the PCR.",
147
149
  default=None,
148
150
  )
149
- B5_years: float | None = pyd.Field(
151
+ B5_years: float | None = pydantic.Field(
150
152
  gt=0,
151
153
  lt=100,
152
154
  description="Timeframe over which B5 is evaluated, in years",
153
155
  default=None,
154
156
  )
155
- B6: Measurement | None = pyd.Field(
157
+ B6: Measurement | None = pydantic.Field(
156
158
  description="Predicted Impacts related to Operational Energy Use",
157
159
  default=None,
158
160
  )
159
- B6_years: float | None = pyd.Field(
161
+ B6_years: float | None = pydantic.Field(
160
162
  gt=0,
161
163
  lt=100,
162
164
  description="Timeframe over which B6 is evaluated, in years",
163
165
  default=None,
164
166
  )
165
- B7: Measurement | None = pyd.Field(
167
+ B7: Measurement | None = pydantic.Field(
166
168
  description="Predicted Impacts related to Operational Water Use",
167
169
  default=None,
168
170
  )
169
- B7_years: float | None = pyd.Field(
171
+ B7_years: float | None = pydantic.Field(
170
172
  gt=0,
171
173
  lt=100,
172
174
  description="Timeframe over which B7 is evaluated, in years",
173
175
  default=None,
174
176
  )
175
- C_scenarios: list[EolScenario] | None = pyd.Field(
177
+ C_scenarios: list[EolScenario] | None = pydantic.Field(
176
178
  description="A list of possible end-of-life scenarios, "
177
179
  "for use in analyses where the end-of-life can be predicted.",
178
180
  default=None,
179
181
  )
180
- C1: Measurement | None = pyd.Field(
182
+ C1: Measurement | None = pydantic.Field(
181
183
  description="Deconstruction and Demolition",
182
184
  default=None,
183
185
  )
184
- C2: Measurement | None = pyd.Field(
186
+ C2: Measurement | None = pydantic.Field(
185
187
  description="Transport to waste processing or disposal.",
186
188
  default=None,
187
189
  )
188
- C3: Measurement | None = pyd.Field(
190
+ C3: Measurement | None = pydantic.Field(
189
191
  description="Waste Processing",
190
192
  default=None,
191
193
  )
192
- C4: Measurement | None = pyd.Field(
194
+ C4: Measurement | None = pydantic.Field(
193
195
  description="Disposal",
194
196
  default=None,
195
197
  )
196
- D: Measurement | None = pyd.Field(
198
+ D: Measurement | None = pydantic.Field(
197
199
  default=None,
198
200
  description="Potential net benefits from reuse, recycling, and/or energy recovery beyond the system boundary.",
199
201
  )
200
202
 
201
- @pyd.root_validator
203
+ @pydantic.model_validator(mode="before")
202
204
  def _unit_validator(cls, values: dict[str, Any]) -> dict[str, Any]:
203
205
  all_units = set()
204
206
 
@@ -273,7 +275,7 @@ class ScopesetByNameBase(BaseOpenEpdSchema, extra="allow"):
273
275
  # probably unknown impact, coming from 'extra' fields
274
276
  return getattr(self, name, None)
275
277
 
276
- @pyd.root_validator(skip_on_failure=True)
278
+ @pydantic.model_validator(mode="before")
277
279
  def _extra_scopeset_validator(cls, values: dict[str, Any]) -> dict[str, Any]:
278
280
  for f in values:
279
281
  # only interested in validating the extra fields
@@ -392,29 +394,36 @@ class ScopeSetEnergy(ScopeSet):
392
394
  class ImpactSet(ScopesetByNameBase):
393
395
  """A set of impacts, such as GWP, ODP, AP, EP, POCP, EP-marine, EP-terrestrial, EP-freshwater, etc."""
394
396
 
395
- gwp: ScopeSetGwp | None = pyd.Field(
397
+ gwp: ScopeSetGwp | None = pydantic.Field(
396
398
  default=None,
397
399
  description="GWP100, calculated per IPCC guidelines. If any CO2 removals are "
398
400
  "part of this figure, the gwp-fossil, gwp-bioganic, gwp-luluc, an "
399
401
  "gwp-nonCO2 fields are required, as is "
400
402
  "kg_C_biogenic_per_declared_unit.",
401
403
  )
402
- odp: ScopeSetOdp | None = pyd.Field(default=None, description="Ozone Depletion Potential")
403
- ap: ScopeSetAp | None = pyd.Field(default=None, description="Acidification Potential")
404
- ep: ScopeSetEpNe | None = pyd.Field(
405
- default=None, description="Eutrophication Potential in Marine Ecosystems. Has the same meaning as ep-marine."
404
+ odp: ScopeSetOdp | None = pydantic.Field(default=None, description="Ozone Depletion Potential")
405
+ ap: ScopeSetAp | None = pydantic.Field(default=None, description="Acidification Potential")
406
+ ep: ScopeSetEpNe | None = pydantic.Field(
407
+ default=None,
408
+ description="Eutrophication Potential in Marine Ecosystems. Has the same meaning as ep-marine.",
409
+ )
410
+ pocp: ScopeSetPocp | None = pydantic.Field(
411
+ default=None, description="Photochemical Smog (Ozone) creation potential"
406
412
  )
407
- pocp: ScopeSetPocp | None = pyd.Field(default=None, description="Photochemical Smog (Ozone) creation potential")
408
- ep_marine: ScopeSetEpNe | None = pyd.Field(
413
+ ep_marine: ScopeSetEpNe | None = pydantic.Field(
409
414
  alias="ep-marine", default=None, description="Has the same meaning as 'ep'"
410
415
  )
411
- ep_fresh: ScopeSetEpFresh | None = pyd.Field(
412
- alias="ep-fresh", default=None, description="Eutrophication Potential in Freshwater Ecosystems"
416
+ ep_fresh: ScopeSetEpFresh | None = pydantic.Field(
417
+ alias="ep-fresh",
418
+ default=None,
419
+ description="Eutrophication Potential in Freshwater Ecosystems",
413
420
  )
414
- ep_terr: ScopeSetEpTerr | None = pyd.Field(
415
- alias="ep-terr", default=None, description="Eutrophication Potential in Terrestrial Ecosystems"
421
+ ep_terr: ScopeSetEpTerr | None = pydantic.Field(
422
+ alias="ep-terr",
423
+ default=None,
424
+ description="Eutrophication Potential in Terrestrial Ecosystems",
416
425
  )
417
- gwp_biogenic: ScopeSetGwp | None = pyd.Field(
426
+ gwp_biogenic: ScopeSetGwp | None = pydantic.Field(
418
427
  alias="gwp-biogenic",
419
428
  default=None,
420
429
  description="Net GWP from removals of atmospheric CO2 into biomass and emissions of CO2 from biomass sources. "
@@ -423,7 +432,7 @@ class ImpactSet(ScopesetByNameBase):
423
432
  "space (similar biome). They must not have been sold, committed, or credited to any other "
424
433
  "product. Harvesting from native forests is handled under GWP_luluc for EN15804.",
425
434
  )
426
- gwp_luluc: ScopeSetGwp | None = pyd.Field(
435
+ gwp_luluc: ScopeSetGwp | None = pydantic.Field(
427
436
  alias="gwp-luluc",
428
437
  default=None,
429
438
  description="Climate change effects related to land use and land use change, for example biogenic carbon "
@@ -431,46 +440,46 @@ class ImpactSet(ScopesetByNameBase):
431
440
  "emissions). All related emissions for native forests are included under this category. "
432
441
  "Uptake for native forests is set to 0 kgCO2 for EN15804.",
433
442
  )
434
- gwp_nonCO2: ScopeSetGwp | None = pyd.Field(
443
+ gwp_nonCO2: ScopeSetGwp | None = pydantic.Field(
435
444
  alias="gwp-nonCO2",
436
445
  default=None,
437
446
  description="GWP from non-CO2, non-fossil sources, such as livestock-sourced CH4 and agricultural N2O.",
438
447
  )
439
- gwp_fossil: ScopeSetGwp | None = pyd.Field(
448
+ gwp_fossil: ScopeSetGwp | None = pydantic.Field(
440
449
  alias="gwp-fossil",
441
450
  default=None,
442
451
  description="Climate change effects due to greenhouse gas emissions originating from the oxidation or "
443
452
  "reduction of fossil fuels or materials containing fossil carbon. [Source: EN15804]",
444
453
  )
445
- WDP: ScopeSetM3Aware | None = pyd.Field(
454
+ WDP: ScopeSetM3Aware | None = pydantic.Field(
446
455
  default=None,
447
456
  description="Deprivation-weighted water consumption, calculated by the AWARE method "
448
457
  "(https://wulca-waterlca.org/aware/what-is-aware)",
449
458
  )
450
- PM: ScopeSetDiseaseIncidence | None = pyd.Field(
459
+ PM: ScopeSetDiseaseIncidence | None = pydantic.Field(
451
460
  default=None,
452
461
  description="Potential incidence of disease due to particulate matter emissions.",
453
462
  )
454
- IRP: ScopeSetIrp | None = pyd.Field(
463
+ IRP: ScopeSetIrp | None = pydantic.Field(
455
464
  default=None,
456
465
  description="Potential ionizing radiation effect on human health, relative to U235.",
457
466
  )
458
- ETP_fw: ScopeSetCTUe | None = pyd.Field(
467
+ ETP_fw: ScopeSetCTUe | None = pydantic.Field(
459
468
  alias="ETP-fw",
460
469
  default=None,
461
470
  description="Ecotoxicity in freshwater, in potential Comparative Toxic Unit for ecosystems.",
462
471
  )
463
- HTP_c: ScopeSetCTUh | None = pyd.Field(
472
+ HTP_c: ScopeSetCTUh | None = pydantic.Field(
464
473
  alias="HTP-c",
465
474
  default=None,
466
475
  description="Human toxicity, cancer effects in potential Comparative Toxic Units for humans.",
467
476
  )
468
- HTP_nc: ScopeSetCTUh | None = pyd.Field(
477
+ HTP_nc: ScopeSetCTUh | None = pydantic.Field(
469
478
  alias="HTP-nc",
470
479
  default=None,
471
480
  description="Human toxicity, noncancer effects in potential Comparative Toxic Units for humans.",
472
481
  )
473
- SQP: ScopeSet | None = pyd.Field(
482
+ SQP: ScopeSet | None = pydantic.Field(
474
483
  default=None,
475
484
  description="Land use related impacts / Soil quality, in potential soil quality parameters.",
476
485
  )
@@ -520,24 +529,31 @@ class LCIAMethod(StrEnum):
520
529
  return cls.UNKNOWN
521
530
 
522
531
 
523
- class Impacts(pyd.BaseModel):
532
+ class Impacts(pydantic.RootModel[dict[LCIAMethod, ImpactSet]]):
524
533
  """List of environmental impacts, compiled per one of the standard Impact Assessment methods."""
525
534
 
526
- class Config:
527
- # pydantic schema generator gets lost in this structure, so we need to re-establish it manually for openapi
528
- schema_extra = {
529
- "properties": {
530
- str(lm): {"description": str(lm), "allOf": [{"$ref": "#/components/schemas/ImpactSet"}]}
531
- for lm in LCIAMethod
532
- },
533
- "additionalProperties": None,
534
- }
535
-
536
- __root__: dict[LCIAMethod, ImpactSet]
535
+ @staticmethod
536
+ def _update_schema_extra(schema, model):
537
+ schema.update(
538
+ {
539
+ "properties": {
540
+ str(lm): {
541
+ "description": str(lm),
542
+ # This is an internal representation of the reference which exists in Pydantic during
543
+ # generation process
544
+ "allOf": [{"$ref": "#/components/schemas/openepd__model__lcia__ImpactSet-Input__1"}],
545
+ }
546
+ for lm in LCIAMethod
547
+ },
548
+ "additionalProperties": None,
549
+ }
550
+ )
551
+
552
+ model_config: ClassVar[ConfigDict] = ConfigDict(json_schema_extra=_update_schema_extra)
537
553
 
538
554
  def set_unknown_lcia(self, impact_set: ImpactSet):
539
555
  """Set the impact set as an unknown LCIA method."""
540
- self.__root__[LCIAMethod.UNKNOWN] = impact_set
556
+ self.root[LCIAMethod.UNKNOWN] = impact_set
541
557
 
542
558
  def set_impact_set(self, lcia_method: LCIAMethod | str | None, impact_set: ImpactSet):
543
559
  """
@@ -550,7 +566,7 @@ class Impacts(pyd.BaseModel):
550
566
  else:
551
567
  if isinstance(lcia_method, str):
552
568
  lcia_method = LCIAMethod.get_by_name(lcia_method)
553
- self.__root__[lcia_method] = impact_set
569
+ self.root[lcia_method] = impact_set
554
570
 
555
571
  def replace_lcia_method(self, lcia_method: LCIAMethod, new_lcia_method: LCIAMethod) -> None:
556
572
  """
@@ -562,95 +578,95 @@ class Impacts(pyd.BaseModel):
562
578
  if impact_set is None:
563
579
  return None
564
580
  self.set_impact_set(new_lcia_method, impact_set)
565
- del self.__root__[lcia_method]
581
+ del self.root[lcia_method]
566
582
 
567
583
  def get_impact_set(
568
584
  self, lcia_method: LCIAMethod | str | None, default_val: ImpactSet | None = None
569
585
  ) -> ImpactSet | None:
570
586
  """Return the impact set for the given LCIA method."""
571
587
  if lcia_method is None:
572
- return self.__root__.get(LCIAMethod.UNKNOWN, default_val)
588
+ return self.root.get(LCIAMethod.UNKNOWN, default_val)
573
589
  if isinstance(lcia_method, str):
574
590
  lcia_method = LCIAMethod.get_by_name(lcia_method)
575
- return self.__root__.get(lcia_method, default_val)
591
+ return self.root.get(lcia_method, default_val)
576
592
 
577
593
  def available_methods(self) -> set[LCIAMethod]:
578
594
  """Return a list of available LCIA methods."""
579
- return set(self.__root__.keys())
595
+ return set(self.root.keys())
580
596
 
581
597
  def as_dict(self) -> dict[LCIAMethod, ImpactSet]:
582
598
  """Return the impacts as a dictionary."""
583
- return self.__root__
599
+ return self.root
584
600
 
585
601
 
586
602
  class ResourceUseSet(ScopesetByNameBase):
587
603
  """A set of resource use indicators, such as RPRec, RPRm, etc."""
588
604
 
589
- RPRec: ScopeSetEnergy | None = pyd.Field(
605
+ RPRec: ScopeSetEnergy | None = pydantic.Field(
590
606
  description="Renewable primary resources used as energy carrier (fuel). "
591
607
  "First use bio-based materials used as an energy source. Hydropower, solar and wind power used "
592
608
  "in the technosphere are also included in this indicator",
593
609
  default=None,
594
610
  )
595
- RPRm: ScopeSetEnergy | None = pyd.Field(
611
+ RPRm: ScopeSetEnergy | None = pydantic.Field(
596
612
  description="Renewable primary resources with energy content used as material. "
597
613
  "First use biobased materials used as materials (e.g. wood, hemp, etc.).",
598
614
  default=None,
599
615
  )
600
- rpre: ScopeSetEnergy | None = pyd.Field(
616
+ rpre: ScopeSetEnergy | None = pydantic.Field(
601
617
  description="Renewable primary energy resources as energy",
602
618
  default=None,
603
619
  )
604
- nrpre: ScopeSetEnergy | None = pyd.Field(
620
+ nrpre: ScopeSetEnergy | None = pydantic.Field(
605
621
  description="Non-renewable primary resources as energy (fuel)",
606
622
  default=None,
607
623
  )
608
- nrprm: ScopeSetEnergy | None = pyd.Field(
624
+ nrprm: ScopeSetEnergy | None = pydantic.Field(
609
625
  description="Non-renewable primary resources as material",
610
626
  default=None,
611
627
  )
612
- fw: ScopeSetVolume | None = pyd.Field(
628
+ fw: ScopeSetVolume | None = pydantic.Field(
613
629
  description="Use of net fresh water",
614
630
  default=None,
615
631
  )
616
- sm: ScopeSetMass | None = pyd.Field(
632
+ sm: ScopeSetMass | None = pydantic.Field(
617
633
  description="Use of secondary materials",
618
634
  default=None,
619
635
  )
620
- rsf: ScopeSetEnergy | None = pyd.Field(
636
+ rsf: ScopeSetEnergy | None = pydantic.Field(
621
637
  description="Use of renewable secondary materials",
622
638
  default=None,
623
639
  )
624
- nrsf: ScopeSetEnergy | None = pyd.Field(
640
+ nrsf: ScopeSetEnergy | None = pydantic.Field(
625
641
  description="Use of non-renewable secondary fuels",
626
642
  default=None,
627
643
  )
628
- re: ScopeSetEnergy | None = pyd.Field(
644
+ re: ScopeSetEnergy | None = pydantic.Field(
629
645
  description="Renewable energy resources",
630
646
  default=None,
631
647
  )
632
- pere: ScopeSetEnergy | None = pyd.Field(
648
+ pere: ScopeSetEnergy | None = pydantic.Field(
633
649
  description="Use of renewable primary energy excluding renewable primary energy resources used as raw materials",
634
650
  default=None,
635
651
  )
636
- perm: ScopeSetEnergy | None = pyd.Field(
652
+ perm: ScopeSetEnergy | None = pydantic.Field(
637
653
  description="Use of renewable primary energy resources used as raw materials",
638
654
  default=None,
639
655
  )
640
- pert: ScopeSetEnergy | None = pyd.Field(
656
+ pert: ScopeSetEnergy | None = pydantic.Field(
641
657
  description="Total use of renewable primary energy resources",
642
658
  default=None,
643
659
  )
644
- penre: ScopeSetEnergy | None = pyd.Field(
660
+ penre: ScopeSetEnergy | None = pydantic.Field(
645
661
  description="Use of non-renewable primary energy excluding "
646
662
  "non-renewable primary energy resources used as raw materials",
647
663
  default=None,
648
664
  )
649
- penrm: ScopeSetEnergy | None = pyd.Field(
665
+ penrm: ScopeSetEnergy | None = pydantic.Field(
650
666
  description="Use of non-renewable primary energy resources used as raw materials",
651
667
  default=None,
652
668
  )
653
- penrt: ScopeSetEnergy | None = pyd.Field(
669
+ penrt: ScopeSetEnergy | None = pydantic.Field(
654
670
  description="Total use of non-renewable primary energy resources",
655
671
  default=None,
656
672
  )
@@ -659,51 +675,51 @@ class ResourceUseSet(ScopesetByNameBase):
659
675
  class OutputFlowSet(ScopesetByNameBase):
660
676
  """A set of output flows, such as waste, emissions, etc."""
661
677
 
662
- twd: ScopeSetMass | None = pyd.Field(
678
+ twd: ScopeSetMass | None = pydantic.Field(
663
679
  description="Total waste disposed",
664
680
  default=None,
665
681
  )
666
- hwd: ScopeSetMass | None = pyd.Field(
682
+ hwd: ScopeSetMass | None = pydantic.Field(
667
683
  description="Hazardous waste disposed",
668
684
  default=None,
669
685
  )
670
- nhwd: ScopeSetMass | None = pyd.Field(
686
+ nhwd: ScopeSetMass | None = pydantic.Field(
671
687
  description="Non-hazardous waste disposed",
672
688
  default=None,
673
689
  )
674
- rwd: ScopeSetMass | None = pyd.Field(
690
+ rwd: ScopeSetMass | None = pydantic.Field(
675
691
  description="Radioactive waste disposed",
676
692
  default=None,
677
693
  )
678
- hlrw: ScopeSetMassOrVolume | None = pyd.Field(
694
+ hlrw: ScopeSetMassOrVolume | None = pydantic.Field(
679
695
  description="High level radioactive waste disposed",
680
696
  default=None,
681
697
  )
682
- illrw: ScopeSetMassOrVolume | None = pyd.Field(
698
+ illrw: ScopeSetMassOrVolume | None = pydantic.Field(
683
699
  description="Intermediate level radioactive waste disposed",
684
700
  default=None,
685
701
  )
686
- cru: ScopeSetMass | None = pyd.Field(
702
+ cru: ScopeSetMass | None = pydantic.Field(
687
703
  description="Components for re-use",
688
704
  default=None,
689
705
  )
690
- mr: ScopeSetMass | None = pyd.Field(
706
+ mr: ScopeSetMass | None = pydantic.Field(
691
707
  description="Recycled materials",
692
708
  default=None,
693
709
  )
694
- mfr: ScopeSetMass | None = pyd.Field(
710
+ mfr: ScopeSetMass | None = pydantic.Field(
695
711
  description="Materials for recycling",
696
712
  default=None,
697
713
  )
698
- mer: ScopeSetMass | None = pyd.Field(
714
+ mer: ScopeSetMass | None = pydantic.Field(
699
715
  description="Materials for energy recovery",
700
716
  default=None,
701
717
  )
702
- ee: ScopeSetEnergy | None = pyd.Field(
718
+ ee: ScopeSetEnergy | None = pydantic.Field(
703
719
  description="Exported energy",
704
720
  default=None,
705
721
  )
706
- eh: ScopeSetEnergy | None = pyd.Field(
722
+ eh: ScopeSetEnergy | None = pydantic.Field(
707
723
  description="Exported heat",
708
724
  default=None,
709
725
  )
@@ -712,16 +728,19 @@ class OutputFlowSet(ScopesetByNameBase):
712
728
  class WithLciaMixin(BaseOpenEpdSchema):
713
729
  """Mixin for LCIA data."""
714
730
 
715
- impacts: Impacts | None = pyd.Field(
731
+ impacts: Impacts | None = pydantic.Field(
716
732
  description="List of environmental impacts, compiled per one of the standard Impact Assessment methods",
717
- example={"TRACI 2.1": {"gwp": {"A1A2A3": {"mean": 22.4, "unit": "kgCO2e"}}}},
733
+ examples=[{"TRACI 2.1": {"gwp": {"A1A2A3": {"mean": 22.4, "unit": "kgCO2e"}}}}],
734
+ default=None,
718
735
  )
719
- resource_uses: ResourceUseSet | None = pyd.Field(
736
+ resource_uses: ResourceUseSet | None = pydantic.Field(
720
737
  description="Set of Resource Use Indicators, over various LCA scopes",
721
- example={"RPRe": {"A1A2A3": {"mean": 12, "unit": "MJ", "rsd": 0.12}}},
738
+ examples=[{"RPRe": {"A1A2A3": {"mean": 12, "unit": "MJ", "rsd": 0.12}}}],
739
+ default=None,
722
740
  )
723
- output_flows: OutputFlowSet | None = pyd.Field(
741
+ output_flows: OutputFlowSet | None = pydantic.Field(
724
742
  description="Set of Waste and Output Flow indicators which describe the waste categories "
725
743
  "and other material output flows derived from the LCI.",
726
- example={"hwd": {"A1A2A3": {"mean": 2300, "unit": "kg", "rsd": 0.22}}},
744
+ examples=[{"hwd": {"A1A2A3": {"mean": 2300, "unit": "kg", "rsd": 0.22}}}],
745
+ default=None,
727
746
  )