openepd 6.4.0__tar.gz → 6.4.1__tar.gz

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 (139) hide show
  1. {openepd-6.4.0 → openepd-6.4.1}/PKG-INFO +1 -1
  2. {openepd-6.4.0 → openepd-6.4.1}/pyproject.toml +1 -1
  3. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/__version__.py +1 -1
  4. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/common.py +13 -1
  5. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/epd.py +2 -1
  6. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/lcia.py +52 -28
  7. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/org.py +2 -1
  8. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/enums.py +1 -1
  9. {openepd-6.4.0 → openepd-6.4.1}/LICENSE +0 -0
  10. {openepd-6.4.0 → openepd-6.4.1}/README.md +0 -0
  11. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/__init__.py +0 -0
  12. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/api/__init__.py +0 -0
  13. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/api/average_dataset/__init__.py +0 -0
  14. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/api/average_dataset/generic_estimate_sync_api.py +0 -0
  15. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/api/average_dataset/industry_epd_sync_api.py +0 -0
  16. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/api/base_sync_client.py +0 -0
  17. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/api/category/__init__.py +0 -0
  18. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/api/category/dto.py +0 -0
  19. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/api/category/sync_api.py +0 -0
  20. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/api/common.py +0 -0
  21. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/api/dto/__init__.py +0 -0
  22. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/api/dto/base.py +0 -0
  23. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/api/dto/common.py +0 -0
  24. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/api/dto/meta.py +0 -0
  25. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/api/dto/mf.py +0 -0
  26. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/api/dto/params.py +0 -0
  27. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/api/epd/__init__.py +0 -0
  28. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/api/epd/dto.py +0 -0
  29. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/api/epd/sync_api.py +0 -0
  30. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/api/errors.py +0 -0
  31. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/api/pcr/__init__.py +0 -0
  32. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/api/pcr/sync_api.py +0 -0
  33. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/api/sync_client.py +0 -0
  34. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/api/test/__init__.py +0 -0
  35. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/api/utils.py +0 -0
  36. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/bundle/__init__.py +0 -0
  37. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/bundle/base.py +0 -0
  38. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/bundle/model.py +0 -0
  39. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/bundle/reader.py +0 -0
  40. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/bundle/writer.py +0 -0
  41. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/compat/__init__.py +0 -0
  42. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/compat/compat_functional_validators.py +0 -0
  43. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/compat/pydantic.py +0 -0
  44. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/__init__.py +0 -0
  45. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/base.py +0 -0
  46. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/category.py +0 -0
  47. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/declaration.py +0 -0
  48. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/factory.py +0 -0
  49. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/generic_estimate.py +0 -0
  50. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/geography.py +0 -0
  51. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/industry_epd.py +0 -0
  52. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/pcr.py +0 -0
  53. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/README.md +0 -0
  54. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/__init__.py +0 -0
  55. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/asphalt.py +0 -0
  56. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/base.py +0 -0
  57. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/concrete.py +0 -0
  58. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/__init__.py +0 -0
  59. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/accessories.py +0 -0
  60. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/aggregates.py +0 -0
  61. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/aluminium.py +0 -0
  62. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/asphalt.py +0 -0
  63. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/bulk_materials.py +0 -0
  64. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/cast_decks_and_underlayment.py +0 -0
  65. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/cladding.py +0 -0
  66. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/cmu.py +0 -0
  67. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/concrete.py +0 -0
  68. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/conveying_equipment.py +0 -0
  69. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/electrical.py +0 -0
  70. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/electrical_transmission_and_distribution_equipment.py +0 -0
  71. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/electricity.py +0 -0
  72. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/finishes.py +0 -0
  73. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/fire_and_smoke_protection.py +0 -0
  74. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/furnishings.py +0 -0
  75. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/grouting.py +0 -0
  76. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/manufacturing_inputs.py +0 -0
  77. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/masonry.py +0 -0
  78. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/material_handling.py +0 -0
  79. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/mechanical.py +0 -0
  80. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/mechanical_insulation.py +0 -0
  81. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/network_infrastructure.py +0 -0
  82. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/openings.py +0 -0
  83. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/other_electrical_equipment.py +0 -0
  84. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/other_materials.py +0 -0
  85. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/plumbing.py +0 -0
  86. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/precast_concrete.py +0 -0
  87. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/sheathing.py +0 -0
  88. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/steel.py +0 -0
  89. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/thermal_moisture_protection.py +0 -0
  90. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/utility_piping.py +0 -0
  91. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/wood.py +0 -0
  92. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/range/wood_joists.py +0 -0
  93. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/__init__.py +0 -0
  94. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/accessories.py +0 -0
  95. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/aggregates.py +0 -0
  96. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/aluminium.py +0 -0
  97. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/asphalt.py +0 -0
  98. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/bulk_materials.py +0 -0
  99. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/cast_decks_and_underlayment.py +0 -0
  100. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/cladding.py +0 -0
  101. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/cmu.py +0 -0
  102. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/common.py +0 -0
  103. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/concrete.py +0 -0
  104. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/conveying_equipment.py +0 -0
  105. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/electrical.py +0 -0
  106. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/electrical_transmission_and_distribution_equipment.py +0 -0
  107. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/electricity.py +0 -0
  108. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/finishes.py +0 -0
  109. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/fire_and_smoke_protection.py +0 -0
  110. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/furnishings.py +0 -0
  111. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/grouting.py +0 -0
  112. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/manufacturing_inputs.py +0 -0
  113. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/masonry.py +0 -0
  114. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/material_handling.py +0 -0
  115. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/mechanical.py +0 -0
  116. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/mechanical_insulation.py +0 -0
  117. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/mixins/__init__.py +0 -0
  118. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/mixins/conduit_mixin.py +0 -0
  119. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/network_infrastructure.py +0 -0
  120. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/openings.py +0 -0
  121. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/other_electrical_equipment.py +0 -0
  122. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/other_materials.py +0 -0
  123. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/plumbing.py +0 -0
  124. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/precast_concrete.py +0 -0
  125. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/sheathing.py +0 -0
  126. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/steel.py +0 -0
  127. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/thermal_moisture_protection.py +0 -0
  128. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/utility_piping.py +0 -0
  129. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/wood.py +0 -0
  130. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/specs/singular/wood_joists.py +0 -0
  131. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/standard.py +0 -0
  132. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/validation/__init__.py +0 -0
  133. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/validation/common.py +0 -0
  134. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/validation/enum.py +0 -0
  135. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/validation/numbers.py +0 -0
  136. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/validation/quantity.py +0 -0
  137. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/model/versioning.py +0 -0
  138. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/patch_pydantic.py +0 -0
  139. {openepd-6.4.0 → openepd-6.4.1}/src/openepd/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: openepd
3
- Version: 6.4.0
3
+ Version: 6.4.1
4
4
  Summary: Python library to work with OpenEPD format
5
5
  Home-page: https://github.com/cchangelabs/openepd
6
6
  License: Apache-2.0
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "openepd"
3
- version = "6.4.0"
3
+ version = "6.4.1"
4
4
  license = "Apache-2.0"
5
5
  description = "Python library to work with OpenEPD format"
6
6
  authors = ["C-Change Labs <support@c-change-labs.com>"]
@@ -13,4 +13,4 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
  #
16
- VERSION = "6.4.0"
16
+ VERSION = "6.4.1"
@@ -24,7 +24,7 @@ from openepd.model.validation.numbers import RatioFloat
24
24
  class Amount(BaseOpenEpdSchema):
25
25
  """A value-and-unit pairing for amounts that do not have an uncertainty."""
26
26
 
27
- qty: float | None = pyd.Field(description="How much of this in the amount.", default=None)
27
+ qty: float | None = pyd.Field(description="How much of this in the amount.", ge=0, default=None)
28
28
  unit: str | None = pyd.Field(description="Which unit. SI units are preferred.", example="kg", default=None)
29
29
 
30
30
  @pyd.root_validator
@@ -117,6 +117,18 @@ class Ingredient(BaseOpenEpdSchema):
117
117
  )
118
118
  citation: str | None = pyd.Field(default=None, description="Text citation describing the data source ")
119
119
 
120
+ @pyd.root_validator(skip_on_failure=True)
121
+ def _validate_evidence(cls, values: dict[str, Any]) -> dict[str, Any]:
122
+ # gwp_fraction should be backed by some type of evidence (fraction coming from product EPD etc) to be accounted
123
+ # for in the calculation of uncertainty
124
+ if values.get("gwp_fraction"):
125
+ if not values.get("evidence_type"):
126
+ raise ValueError("evidence_type is required if gwp_fraction is provided")
127
+ if not (values.get("citation") or values.get("link")):
128
+ raise ValueError("link or citation is required if gwp_fraction is provided")
129
+
130
+ return values
131
+
120
132
 
121
133
  class LatLng(BaseOpenEpdSchema):
122
134
  """A latitude and longitude."""
@@ -38,6 +38,7 @@ MANUFACTURER_DESCRIPTION = (
38
38
  'JSON object for declaring Org. Sometimes called the "Declaration Holder" or "Declaration Owner".'
39
39
  )
40
40
 
41
+ PLANT_DESCRIPTION = "List of object(s) for one or more plant(s) that this declaration applies to."
41
42
 
42
43
  #
43
44
  # Copyright 2024 by C Change Labs Inc. www.c-change-labs.com
@@ -161,7 +162,7 @@ class EpdPreviewV0(
161
162
  manufacturer: Org | None = pyd.Field(description=MANUFACTURER_DESCRIPTION)
162
163
  plants: list[Plant] = pyd.Field(
163
164
  max_items=32,
164
- description="List of object(s) for one or more plant(s) that this declaration applies to.",
165
+ description=PLANT_DESCRIPTION,
165
166
  default_factory=list,
166
167
  )
167
168
 
@@ -357,6 +357,30 @@ class ScopeSetDiseaseIncidence(ScopeSet):
357
357
  allowed_units = "AnnualPerCapita"
358
358
 
359
359
 
360
+ class ScopeSetMass(ScopeSet):
361
+ """ScopeSet measuring mass in kg."""
362
+
363
+ allowed_units = "kg"
364
+
365
+
366
+ class ScopeSetVolume(ScopeSet):
367
+ """ScopeSet measuring mass in kg."""
368
+
369
+ allowed_units = "m3"
370
+
371
+
372
+ class ScopeSetMassOrVolume(ScopeSet):
373
+ """ScopeSet measuring mass in kg OR volume in m3, example: radioactive waste."""
374
+
375
+ allowed_units = ("kg", "m3")
376
+
377
+
378
+ class ScopeSetEnergy(ScopeSet):
379
+ """ScopeSet measuring mass in kg."""
380
+
381
+ allowed_units = "MJ"
382
+
383
+
360
384
  class ImpactSet(ScopesetByNameBase):
361
385
  """A set of impacts, such as GWP, ODP, AP, EP, POCP, EP-marine, EP-terrestrial, EP-freshwater, etc."""
362
386
 
@@ -554,71 +578,71 @@ class Impacts(pyd.BaseModel):
554
578
  class ResourceUseSet(ScopesetByNameBase):
555
579
  """A set of resource use indicators, such as RPRec, RPRm, etc."""
556
580
 
557
- RPRec: ScopeSet | None = pyd.Field(
581
+ RPRec: ScopeSetEnergy | None = pyd.Field(
558
582
  description="Renewable primary resources used as energy carrier (fuel). "
559
583
  "First use bio-based materials used as an energy source. Hydropower, solar and wind power used "
560
584
  "in the technosphere are also included in this indicator",
561
585
  default=None,
562
586
  )
563
- RPRm: ScopeSet | None = pyd.Field(
587
+ RPRm: ScopeSetEnergy | None = pyd.Field(
564
588
  description="Renewable primary resources with energy content used as material. "
565
589
  "First use biobased materials used as materials (e.g. wood, hemp, etc.).",
566
590
  default=None,
567
591
  )
568
- rpre: ScopeSet | None = pyd.Field(
592
+ rpre: ScopeSetEnergy | None = pyd.Field(
569
593
  description="Renewable primary energy resources as energy",
570
594
  default=None,
571
595
  )
572
- nrpre: ScopeSet | None = pyd.Field(
596
+ nrpre: ScopeSetEnergy | None = pyd.Field(
573
597
  description="Non-renewable primary resources as energy (fuel)",
574
598
  default=None,
575
599
  )
576
- nrprm: ScopeSet | None = pyd.Field(
600
+ nrprm: ScopeSetEnergy | None = pyd.Field(
577
601
  description="Non-renewable primary resources as material",
578
602
  default=None,
579
603
  )
580
- fw: ScopeSet | None = pyd.Field(
604
+ fw: ScopeSetVolume | None = pyd.Field(
581
605
  description="Use of net fresh water",
582
606
  default=None,
583
607
  )
584
- sm: ScopeSet | None = pyd.Field(
608
+ sm: ScopeSetMass | None = pyd.Field(
585
609
  description="Use of secondary materials",
586
610
  default=None,
587
611
  )
588
- rsf: ScopeSet | None = pyd.Field(
612
+ rsf: ScopeSetEnergy | None = pyd.Field(
589
613
  description="Use of renewable secondary materials",
590
614
  default=None,
591
615
  )
592
- nrsf: ScopeSet | None = pyd.Field(
616
+ nrsf: ScopeSetEnergy | None = pyd.Field(
593
617
  description="Use of non-renewable secondary fuels",
594
618
  default=None,
595
619
  )
596
- re: ScopeSet | None = pyd.Field(
620
+ re: ScopeSetEnergy | None = pyd.Field(
597
621
  description="Renewable energy resources",
598
622
  default=None,
599
623
  )
600
- pere: ScopeSet | None = pyd.Field(
624
+ pere: ScopeSetEnergy | None = pyd.Field(
601
625
  description="Use of renewable primary energy excluding renewable primary energy resources used as raw materials",
602
626
  default=None,
603
627
  )
604
- perm: ScopeSet | None = pyd.Field(
628
+ perm: ScopeSetEnergy | None = pyd.Field(
605
629
  description="Use of renewable primary energy resources used as raw materials",
606
630
  default=None,
607
631
  )
608
- pert: ScopeSet | None = pyd.Field(
632
+ pert: ScopeSetEnergy | None = pyd.Field(
609
633
  description="Total use of renewable primary energy resources",
610
634
  default=None,
611
635
  )
612
- penre: ScopeSet | None = pyd.Field(
636
+ penre: ScopeSetEnergy | None = pyd.Field(
613
637
  description="Use of non-renewable primary energy excluding "
614
638
  "non-renewable primary energy resources used as raw materials",
615
639
  default=None,
616
640
  )
617
- penrm: ScopeSet | None = pyd.Field(
641
+ penrm: ScopeSetEnergy | None = pyd.Field(
618
642
  description="Use of non-renewable primary energy resources used as raw materials",
619
643
  default=None,
620
644
  )
621
- penrt: ScopeSet | None = pyd.Field(
645
+ penrt: ScopeSetEnergy | None = pyd.Field(
622
646
  description="Total use of non-renewable primary energy resources",
623
647
  default=None,
624
648
  )
@@ -627,51 +651,51 @@ class ResourceUseSet(ScopesetByNameBase):
627
651
  class OutputFlowSet(ScopesetByNameBase):
628
652
  """A set of output flows, such as waste, emissions, etc."""
629
653
 
630
- twd: ScopeSet | None = pyd.Field(
654
+ twd: ScopeSetMass | None = pyd.Field(
631
655
  description="Total waste disposed",
632
656
  default=None,
633
657
  )
634
- hwd: ScopeSet | None = pyd.Field(
658
+ hwd: ScopeSetMass | None = pyd.Field(
635
659
  description="Hazardous waste disposed",
636
660
  default=None,
637
661
  )
638
- nhwd: ScopeSet | None = pyd.Field(
662
+ nhwd: ScopeSetMass | None = pyd.Field(
639
663
  description="Non-hazardous waste disposed",
640
664
  default=None,
641
665
  )
642
- rwd: ScopeSet | None = pyd.Field(
666
+ rwd: ScopeSetMass | None = pyd.Field(
643
667
  description="Radioactive waste disposed",
644
668
  default=None,
645
669
  )
646
- hlrw: ScopeSet | None = pyd.Field(
670
+ hlrw: ScopeSetMassOrVolume | None = pyd.Field(
647
671
  description="High level radioactive waste disposed",
648
672
  default=None,
649
673
  )
650
- illrw: ScopeSet | None = pyd.Field(
674
+ illrw: ScopeSetMassOrVolume | None = pyd.Field(
651
675
  description="Intermediate level radioactive waste disposed",
652
676
  default=None,
653
677
  )
654
- cru: ScopeSet | None = pyd.Field(
678
+ cru: ScopeSetMass | None = pyd.Field(
655
679
  description="Components for re-use",
656
680
  default=None,
657
681
  )
658
- mr: ScopeSet | None = pyd.Field(
682
+ mr: ScopeSetMass | None = pyd.Field(
659
683
  description="Recycled materials",
660
684
  default=None,
661
685
  )
662
- mfr: ScopeSet | None = pyd.Field(
686
+ mfr: ScopeSetMass | None = pyd.Field(
663
687
  description="Materials for recycling",
664
688
  default=None,
665
689
  )
666
- mer: ScopeSet | None = pyd.Field(
690
+ mer: ScopeSetMass | None = pyd.Field(
667
691
  description="Materials for energy recovery",
668
692
  default=None,
669
693
  )
670
- ee: ScopeSet | None = pyd.Field(
694
+ ee: ScopeSetEnergy | None = pyd.Field(
671
695
  description="Exported energy",
672
696
  default=None,
673
697
  )
674
- eh: ScopeSet | None = pyd.Field(
698
+ eh: ScopeSetEnergy | None = pyd.Field(
675
699
  description="Exported heat",
676
700
  default=None,
677
701
  )
@@ -66,7 +66,6 @@ class Org(WithAttachmentsMixin, WithAltIdsMixin, OrgRef):
66
66
  class Plant(WithAttachmentsMixin, WithAltIdsMixin, BaseOpenEpdSchema):
67
67
  """Represent a manufacturing plant."""
68
68
 
69
- # TODO: Add proper validator
70
69
  id: str | None = pyd.Field(
71
70
  description="Plus code (aka Open Location Code) of plant's location and "
72
71
  "owner's web domain joined with `.`(dot).",
@@ -110,6 +109,8 @@ class Plant(WithAttachmentsMixin, WithAltIdsMixin, BaseOpenEpdSchema):
110
109
 
111
110
  @pyd.validator("id")
112
111
  def _validate_id(cls, v: str) -> str:
112
+ if not v:
113
+ return v
113
114
  try:
114
115
  pluscode, web_domain = v.split(".", maxsplit=1)
115
116
  except ValueError as e:
@@ -2215,7 +2215,7 @@ class AciExposureClass(EnumGroupingAware, StrEnum):
2215
2215
  S1 = "aci.S1"
2216
2216
  S2 = "aci.S2"
2217
2217
  S3 = "aci.S3"
2218
- C0 = "aci.C1"
2218
+ C0 = "aci.C0"
2219
2219
  C1 = "aci.C1"
2220
2220
  C2 = "aci.C2"
2221
2221
  W0 = "aci.W0"
File without changes
File without changes
File without changes
File without changes