openepd 6.2.0__tar.gz → 6.3.0__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.2.0 → openepd-6.3.0}/PKG-INFO +1 -1
  2. {openepd-6.2.0 → openepd-6.3.0}/pyproject.toml +1 -1
  3. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/__version__.py +1 -1
  4. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/declaration.py +75 -2
  5. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/epd.py +87 -3
  6. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/lcia.py +7 -7
  7. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/org.py +6 -0
  8. {openepd-6.2.0 → openepd-6.3.0}/LICENSE +0 -0
  9. {openepd-6.2.0 → openepd-6.3.0}/README.md +0 -0
  10. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/__init__.py +0 -0
  11. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/api/__init__.py +0 -0
  12. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/api/average_dataset/__init__.py +0 -0
  13. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/api/average_dataset/generic_estimate_sync_api.py +0 -0
  14. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/api/average_dataset/industry_epd_sync_api.py +0 -0
  15. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/api/base_sync_client.py +0 -0
  16. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/api/category/__init__.py +0 -0
  17. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/api/category/dto.py +0 -0
  18. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/api/category/sync_api.py +0 -0
  19. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/api/common.py +0 -0
  20. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/api/dto/__init__.py +0 -0
  21. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/api/dto/base.py +0 -0
  22. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/api/dto/common.py +0 -0
  23. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/api/dto/meta.py +0 -0
  24. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/api/dto/mf.py +0 -0
  25. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/api/dto/params.py +0 -0
  26. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/api/epd/__init__.py +0 -0
  27. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/api/epd/dto.py +0 -0
  28. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/api/epd/sync_api.py +0 -0
  29. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/api/errors.py +0 -0
  30. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/api/pcr/__init__.py +0 -0
  31. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/api/pcr/sync_api.py +0 -0
  32. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/api/sync_client.py +0 -0
  33. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/api/test/__init__.py +0 -0
  34. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/api/utils.py +0 -0
  35. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/bundle/__init__.py +0 -0
  36. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/bundle/base.py +0 -0
  37. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/bundle/model.py +0 -0
  38. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/bundle/reader.py +0 -0
  39. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/bundle/writer.py +0 -0
  40. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/compat/__init__.py +0 -0
  41. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/compat/compat_functional_validators.py +0 -0
  42. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/compat/pydantic.py +0 -0
  43. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/__init__.py +0 -0
  44. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/base.py +0 -0
  45. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/category.py +0 -0
  46. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/common.py +0 -0
  47. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/factory.py +0 -0
  48. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/generic_estimate.py +0 -0
  49. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/geography.py +0 -0
  50. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/industry_epd.py +0 -0
  51. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/pcr.py +0 -0
  52. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/README.md +0 -0
  53. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/__init__.py +0 -0
  54. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/asphalt.py +0 -0
  55. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/base.py +0 -0
  56. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/concrete.py +0 -0
  57. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/enums.py +0 -0
  58. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/__init__.py +0 -0
  59. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/accessories.py +0 -0
  60. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/aggregates.py +0 -0
  61. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/aluminium.py +0 -0
  62. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/asphalt.py +0 -0
  63. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/bulk_materials.py +0 -0
  64. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/cast_decks_and_underlayment.py +0 -0
  65. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/cladding.py +0 -0
  66. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/cmu.py +0 -0
  67. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/concrete.py +0 -0
  68. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/conveying_equipment.py +0 -0
  69. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/electrical.py +0 -0
  70. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/electrical_transmission_and_distribution_equipment.py +0 -0
  71. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/electricity.py +0 -0
  72. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/finishes.py +0 -0
  73. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/fire_and_smoke_protection.py +0 -0
  74. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/furnishings.py +0 -0
  75. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/grouting.py +0 -0
  76. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/manufacturing_inputs.py +0 -0
  77. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/masonry.py +0 -0
  78. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/material_handling.py +0 -0
  79. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/mechanical.py +0 -0
  80. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/mechanical_insulation.py +0 -0
  81. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/network_infrastructure.py +0 -0
  82. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/openings.py +0 -0
  83. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/other_electrical_equipment.py +0 -0
  84. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/other_materials.py +0 -0
  85. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/plumbing.py +0 -0
  86. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/precast_concrete.py +0 -0
  87. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/sheathing.py +0 -0
  88. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/steel.py +0 -0
  89. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/thermal_moisture_protection.py +0 -0
  90. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/utility_piping.py +0 -0
  91. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/wood.py +0 -0
  92. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/range/wood_joists.py +0 -0
  93. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/__init__.py +0 -0
  94. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/accessories.py +0 -0
  95. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/aggregates.py +0 -0
  96. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/aluminium.py +0 -0
  97. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/asphalt.py +0 -0
  98. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/bulk_materials.py +0 -0
  99. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/cast_decks_and_underlayment.py +0 -0
  100. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/cladding.py +0 -0
  101. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/cmu.py +0 -0
  102. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/common.py +0 -0
  103. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/concrete.py +0 -0
  104. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/conveying_equipment.py +0 -0
  105. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/electrical.py +0 -0
  106. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/electrical_transmission_and_distribution_equipment.py +0 -0
  107. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/electricity.py +0 -0
  108. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/finishes.py +0 -0
  109. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/fire_and_smoke_protection.py +0 -0
  110. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/furnishings.py +0 -0
  111. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/grouting.py +0 -0
  112. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/manufacturing_inputs.py +0 -0
  113. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/masonry.py +0 -0
  114. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/material_handling.py +0 -0
  115. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/mechanical.py +0 -0
  116. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/mechanical_insulation.py +0 -0
  117. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/mixins/__init__.py +0 -0
  118. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/mixins/conduit_mixin.py +0 -0
  119. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/network_infrastructure.py +0 -0
  120. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/openings.py +0 -0
  121. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/other_electrical_equipment.py +0 -0
  122. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/other_materials.py +0 -0
  123. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/plumbing.py +0 -0
  124. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/precast_concrete.py +0 -0
  125. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/sheathing.py +0 -0
  126. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/steel.py +0 -0
  127. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/thermal_moisture_protection.py +0 -0
  128. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/utility_piping.py +0 -0
  129. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/wood.py +0 -0
  130. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/specs/singular/wood_joists.py +0 -0
  131. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/standard.py +0 -0
  132. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/validation/__init__.py +0 -0
  133. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/validation/common.py +0 -0
  134. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/validation/enum.py +0 -0
  135. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/validation/numbers.py +0 -0
  136. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/validation/quantity.py +0 -0
  137. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/model/versioning.py +0 -0
  138. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/patch_pydantic.py +0 -0
  139. {openepd-6.2.0 → openepd-6.3.0}/src/openepd/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: openepd
3
- Version: 6.2.0
3
+ Version: 6.3.0
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.2.0"
3
+ version = "6.3.0"
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.2.0"
16
+ VERSION = "6.3.0"
@@ -15,6 +15,7 @@
15
15
  #
16
16
  import abc
17
17
  import datetime
18
+ from enum import StrEnum
18
19
 
19
20
  from openepd.compat.pydantic import pyd
20
21
  from openepd.model.base import BaseOpenEpdSchema, OpenXpdUUID, RootDocument
@@ -50,7 +51,7 @@ class BaseDeclaration(RootDocument, abc.ABC):
50
51
  description="Last date the document is valid on, including any extensions.",
51
52
  )
52
53
 
53
- version: pyd.PositiveInt | None = pyd.Field(
54
+ version: pyd.NonNegativeInt | None = pyd.Field(
54
55
  description="Version of this document. The document's issuer should increment it anytime even a single "
55
56
  "character changes, as this value is used to determine the most recent version.",
56
57
  example=1,
@@ -137,7 +138,7 @@ class BaseDeclaration(RootDocument, abc.ABC):
137
138
  description="Link to data object on original registrar's site",
138
139
  example="https://epd-online.com/EmbeddedEpdList/Download/6029",
139
140
  )
140
- kg_C_per_declared_unit: AmountGWP | None = pyd.Field(
141
+ kg_C_per_declared_unit: AmountMass | None = pyd.Field(
141
142
  default=None,
142
143
  description="Mass of elemental carbon, per declared unit, contained in the product itself at the manufacturing "
143
144
  "facility gate. Used (among other things) to check a carbon balance or calculate incineration "
@@ -236,3 +237,75 @@ class RefBase(BaseOpenEpdSchema, title="Ref Object"):
236
237
  example="https://openepd.buildingtransparency.org/api/generic_estimates/EC300001",
237
238
  description="Reference to this JSON object",
238
239
  )
240
+
241
+
242
+ class OriginalDataFormat(StrEnum):
243
+ """
244
+ Original data format for this EPD.
245
+
246
+ A system receiving an EPD via openEPD should preserve this field if it exists. Otherwise, it is up to the
247
+ receiving system to infer the original data format based on the source.
248
+ """
249
+
250
+ OPENEPD_1_0 = "openEPDv1.0"
251
+ """
252
+ Data was generated in an openEPD-compliant system, such as by manual entry in EC3 or generation in an openEPD
253
+ compliant EPD generator.
254
+ """
255
+
256
+ CUSTOM_API = "custom_api"
257
+ """
258
+ Data was gathered from a non-standardized API offered by a data provider. Numerical and text data is very likely
259
+ to be correct and up to date, but important fields may be absent and identification of organizations, plants, and
260
+ addresses may be ambiguous.
261
+ """
262
+
263
+ ILCD_EPD_v1_2 = "ILCD+EPDv1_2"
264
+ """
265
+ Data was generated and published in ILCD+EPD format, version 1.2 Numerical and text data is very likely to be
266
+ correct and up to date, but important fields may be absent and identification of organizations, plants, and
267
+ addresses may be ambiguous.
268
+ """
269
+
270
+ ILCD_EPD_v1_1 = "ILCD+EPDv1_1"
271
+ """
272
+ Data was generated and published in ILCD+EPD format, version 1.1 Numerical and text data is very likely to be
273
+ correct and up to date, but important fields may be absent and identification of organizations, plants, and
274
+ addresses may be ambiguous.
275
+ """
276
+
277
+ ILCD_EPD_v1_0 = "ILCD+EPDv1_0"
278
+ """
279
+ Data was generated and published in ILCD+EPD format, version 1.0 Numerical and text data is very likely to be
280
+ correct and up to date, but important fields may be absent and identification of organizations, plants, and
281
+ addresses may be ambiguous.
282
+ """
283
+
284
+ WEB = "web"
285
+ """
286
+ Data was gathered through comprehension of a viewable HTML page, typically offered by a program operator.
287
+ This is more reliable than PDF, but less reliable than API or a standardized XML like ILCD+EPD.
288
+ """
289
+
290
+ PDF_MANUAL = "pdf_manual"
291
+ """
292
+ Data was entered by hand based on PDF and/or validated by a qualified professional.
293
+ """
294
+
295
+ PDF_MIXED = "pdf_mixed"
296
+ """
297
+ Data is a mix of structured data from an information system, but with significant missing data filled in by
298
+ extraction from a PDF.
299
+ """
300
+
301
+ PDF = "pdf"
302
+ """
303
+ Data was extracted by analyzing or comprehending a PDF document. Includes documents where up to 4 fields (e.g.
304
+ program operator) were inferred from sources outside the PDF. This method is prone to errors and omissions due
305
+ to the many different formats and terms used in these relatively unstructured documents.
306
+ """
307
+
308
+ OTHER = "other"
309
+ """
310
+ Data source is not of a type listed here.
311
+ """
@@ -13,20 +13,21 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
  #
16
- from typing import Annotated
17
16
 
18
17
  from openepd.compat.pydantic import pyd
19
- from openepd.model.base import BaseDocumentFactory, OpenEpdDoctypes
18
+ from openepd.model.base import BaseDocumentFactory, BaseOpenEpdSchema, OpenEpdDoctypes
20
19
  from openepd.model.common import Ingredient, WithAltIdsMixin, WithAttachmentsMixin
21
20
  from openepd.model.declaration import (
22
21
  DEVELOPER_DESCRIPTION,
23
22
  PROGRAM_OPERATOR_DESCRIPTION,
24
23
  THIRD_PARTY_VERIFIER_DESCRIPTION,
25
24
  BaseDeclaration,
25
+ OriginalDataFormat,
26
26
  WithEpdDeveloperMixin,
27
27
  WithProgramOperatorMixin,
28
28
  WithVerifierMixin,
29
29
  )
30
+ from openepd.model.geography import Geography
30
31
  from openepd.model.lcia import WithLciaMixin
31
32
  from openepd.model.org import Org, Plant
32
33
  from openepd.model.specs.singular import Specs
@@ -37,6 +38,88 @@ MANUFACTURER_DESCRIPTION = (
37
38
  )
38
39
 
39
40
 
41
+ #
42
+ # Copyright 2024 by C Change Labs Inc. www.c-change-labs.com
43
+ #
44
+ # Licensed under the Apache License, Version 2.0 (the "License");
45
+ # you may not use this file except in compliance with the License.
46
+ # You may obtain a copy of the License at
47
+ #
48
+ # http://www.apache.org/licenses/LICENSE-2.0
49
+ #
50
+ # Unless required by applicable law or agreed to in writing, software
51
+ # distributed under the License is distributed on an "AS IS" BASIS,
52
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
53
+ # See the License for the specific language governing permissions and
54
+ # limitations under the License.
55
+ #
56
+ # This software was developed with support from the Skanska USA,
57
+ # Charles Pankow Foundation, Microsoft Sustainability Fund, Interface, MKA Foundation, and others.
58
+ # Find out more at www.BuildingTransparency.org
59
+ #
60
+
61
+
62
+ class Ec3EpdExtension(BaseOpenEpdSchema):
63
+ """Extension for EC3 specific fields on openEPD."""
64
+
65
+ # While the extensions should be stored under the 'ext' key - extension point of the BaseOpenepdModel - the EC3
66
+ # extension was started before the introduction of extension management, and so is located at the root of the EPD
67
+ # object.
68
+
69
+ uaGWP_a1a2a3_traci21: float | None = pyd.Field(
70
+ default=None,
71
+ description="""The A1A2A3 uncertainty-adjusted GWP, in kgCO2e per declared unit, calculated for the TRACI 2.1
72
+ LCIA method. This is the value that should be used to compare EPDs against each other, or against an
73
+ uncertainty-adjusted limit/benchmark, once both have been converted to the same declared unit. This is a
74
+ materialized value provided for the convenience of integrators, and can be regenerated at any time from the
75
+ specificity and EC3 category. The value is provided per comparison_unit.""",
76
+ example=22.5,
77
+ )
78
+ uaGWP_a1a2a3_ar5: float | None = pyd.Field(
79
+ default=None,
80
+ description="""The A1A2A3 uncertainty-adjusted GWP, calculated for the IPCC AR5 LCIA method. This is the value
81
+ that should be used to compare EPDs against each other, or against an uncertainty-adjusted limit/benchmark,
82
+ once both have been converted to the same declared unit. This is a materialized value, and can be regenerated
83
+ at any time from the specificity and EC3 category.""",
84
+ example=22.5,
85
+ )
86
+ category: str | None = pyd.Field(
87
+ default=None,
88
+ description="The category of the EPD in EC3 notation. Same as EC3 category from root EPD's product_classes for "
89
+ "EC3.",
90
+ )
91
+ manufacturer_specific: bool | None = pyd.Field(
92
+ default=None,
93
+ description="""An EPD is Manufacturer Specific if it is based on data from a single manufacturer, as opposed
94
+ to an industry group, sector, or generic process. This field should always be true for openEPD documents
95
+ (as opposed to openIndustryEPDs).""",
96
+ )
97
+ plant_specific: bool | None = pyd.Field(
98
+ default=None,
99
+ description="""An EPD is Product Specific if it is based on data regarding the specific product being
100
+ delivered, as opposed to a range of products whose GWP per unit may vary by more than 10%.""",
101
+ )
102
+ product_specific: bool | None = pyd.Field(
103
+ default=None,
104
+ description="""An EPD is Product Specific if it is based on data regarding the specific product being
105
+ delivered, as opposed to a range of products whose GWP per unit may vary by more than 10%.""",
106
+ )
107
+ batch_specific: bool | None = pyd.Field(
108
+ default=None,
109
+ description="""An EPD is Product Specific if it is created with production data for a single production run of
110
+ no more than 90 days. Typically these must be generated on a just-in-time or on-demand basis.""",
111
+ )
112
+ supply_chain_specificity: float | None = pyd.Field(
113
+ default=None,
114
+ description="""An EPD is Supply Chain Specific to the extent that impacts of process inputs are based on
115
+ product-specific, facility-specific EPDs or third-party verified LCA for those inputs. For example, a concrete
116
+ where the cement impacts are based on a plant-specific, product-specific EPD for the actual cement used would
117
+ have around 85% supply chain specificity.""",
118
+ )
119
+
120
+ original_data_format: OriginalDataFormat | None = pyd.Field(default=None)
121
+
122
+
40
123
  class EpdPreviewV0(
41
124
  WithAttachmentsMixin,
42
125
  WithProgramOperatorMixin,
@@ -85,7 +168,7 @@ class EpdPreviewV0(
85
168
  "product volume is 123,456 m3, a value of 120,000, 100,000 or even 87,654 would be acceptable.",
86
169
  example=10000,
87
170
  )
88
- applicable_in: list[Annotated[str, pyd.Field(min_length=2, max_length=2)]] | None = pyd.Field(
171
+ applicable_in: list[Geography] | None = pyd.Field(
89
172
  max_items=100,
90
173
  default=None,
91
174
  description="Jurisdiction(s) in which EPD is applicable. An empty array, or absent properties, "
@@ -122,6 +205,7 @@ class EpdPreviewV0(
122
205
  "Each one should be an EPD or digitized LCI process.",
123
206
  default_factory=list,
124
207
  )
208
+ ec3: Ec3EpdExtension | None = pyd.Field(default=None, description="EC3-specific EPD extension.")
125
209
 
126
210
  @pyd.validator("doctype")
127
211
  def validate_doctype(cls, v: str | None) -> str:
@@ -104,7 +104,7 @@ class ScopeSet(BaseOpenEpdSchema):
104
104
  )
105
105
  B1_years: float | None = pyd.Field(
106
106
  gt=0,
107
- lt=11,
107
+ lt=100,
108
108
  description="Timeframe over which B1 is evaluated, in years. "
109
109
  "For example, an impact of 1.23 kgCO2e per year for ten years could be B1=1.23kgCO2e, "
110
110
  "B1_years=1.0 or B1=12.3kgCO2e, B1_years=10.0",
@@ -116,7 +116,7 @@ class ScopeSet(BaseOpenEpdSchema):
116
116
  )
117
117
  B2_years: float | None = pyd.Field(
118
118
  gt=0,
119
- lt=11,
119
+ lt=100,
120
120
  description="Predicted Maintenance Impacts over Reference Service Life",
121
121
  default=None,
122
122
  )
@@ -126,7 +126,7 @@ class ScopeSet(BaseOpenEpdSchema):
126
126
  )
127
127
  B3_years: float | None = pyd.Field(
128
128
  gt=0,
129
- lt=11,
129
+ lt=100,
130
130
  description="Timeframe over which B3 is evaluated, in years",
131
131
  default=None,
132
132
  )
@@ -137,7 +137,7 @@ class ScopeSet(BaseOpenEpdSchema):
137
137
  )
138
138
  B4_years: float | None = pyd.Field(
139
139
  gt=0,
140
- lt=11,
140
+ lt=100,
141
141
  description="Timeframe over which B4 is evaluated, in years",
142
142
  default=None,
143
143
  )
@@ -148,7 +148,7 @@ class ScopeSet(BaseOpenEpdSchema):
148
148
  )
149
149
  B5_years: float | None = pyd.Field(
150
150
  gt=0,
151
- lt=11,
151
+ lt=100,
152
152
  description="Timeframe over which B5 is evaluated, in years",
153
153
  default=None,
154
154
  )
@@ -158,7 +158,7 @@ class ScopeSet(BaseOpenEpdSchema):
158
158
  )
159
159
  B6_years: float | None = pyd.Field(
160
160
  gt=0,
161
- lt=11,
161
+ lt=100,
162
162
  description="Timeframe over which B6 is evaluated, in years",
163
163
  default=None,
164
164
  )
@@ -168,7 +168,7 @@ class ScopeSet(BaseOpenEpdSchema):
168
168
  )
169
169
  B7_years: float | None = pyd.Field(
170
170
  gt=0,
171
- lt=11,
171
+ lt=100,
172
172
  description="Timeframe over which B7 is evaluated, in years",
173
173
  default=None,
174
174
  )
@@ -71,6 +71,12 @@ class Plant(WithAttachmentsMixin, WithAltIdsMixin, BaseOpenEpdSchema):
71
71
  example="865P2W3V+3W.interface.com",
72
72
  default=None,
73
73
  )
74
+ pluscode: str | None = pyd.Field(
75
+ default=None,
76
+ description="(deprecated) Plus code (aka Open Location Code) of plant's location",
77
+ deprecated="Pluscode field is deprecated. If users need a pluscode they can obtain it from "
78
+ "`id` like this: `id.spit('.', maxsplit=1)[0]`",
79
+ )
74
80
  owner: Org | None = pyd.Field(description="Organization that owns the plant", default=None)
75
81
  name: str | None = pyd.Field(
76
82
  max_length=200,
File without changes
File without changes
File without changes
File without changes