openepd 6.13.1__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 (102) 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/m49/__init__.py +2 -0
  18. openepd/m49/const.py +5 -2
  19. openepd/m49/{geo_converter.py → utils.py} +24 -2
  20. openepd/model/base.py +60 -43
  21. openepd/model/category.py +13 -10
  22. openepd/model/common.py +100 -55
  23. openepd/model/declaration.py +93 -64
  24. openepd/model/epd.py +51 -43
  25. openepd/model/generic_estimate.py +28 -13
  26. openepd/model/industry_epd.py +15 -9
  27. openepd/model/lcia.py +132 -113
  28. openepd/model/org.py +54 -33
  29. openepd/model/pcr.py +38 -32
  30. openepd/model/specs/asphalt.py +31 -22
  31. openepd/model/specs/base.py +11 -9
  32. openepd/model/specs/concrete.py +60 -39
  33. openepd/model/specs/range/aggregates.py +9 -9
  34. openepd/model/specs/range/aluminium.py +7 -7
  35. openepd/model/specs/range/asphalt.py +22 -19
  36. openepd/model/specs/range/cladding.py +16 -16
  37. openepd/model/specs/range/cmu.py +10 -9
  38. openepd/model/specs/range/concrete.py +36 -27
  39. openepd/model/specs/range/conveying_equipment.py +16 -15
  40. openepd/model/specs/range/electrical.py +24 -22
  41. openepd/model/specs/range/finishes.py +109 -104
  42. openepd/model/specs/range/fire_and_smoke_protection.py +7 -7
  43. openepd/model/specs/range/furnishings.py +16 -12
  44. openepd/model/specs/range/manufacturing_inputs.py +16 -16
  45. openepd/model/specs/range/masonry.py +16 -16
  46. openepd/model/specs/range/mechanical.py +47 -47
  47. openepd/model/specs/range/mechanical_insulation.py +7 -7
  48. openepd/model/specs/range/network_infrastructure.py +54 -46
  49. openepd/model/specs/range/openings.py +36 -31
  50. openepd/model/specs/range/plumbing.py +15 -13
  51. openepd/model/specs/range/precast_concrete.py +20 -16
  52. openepd/model/specs/range/sheathing.py +18 -18
  53. openepd/model/specs/range/steel.py +25 -25
  54. openepd/model/specs/range/thermal_moisture_protection.py +20 -20
  55. openepd/model/specs/range/utility_piping.py +9 -9
  56. openepd/model/specs/range/wood.py +19 -19
  57. openepd/model/specs/range/wood_joists.py +8 -8
  58. openepd/model/specs/singular/__init__.py +9 -5
  59. openepd/model/specs/singular/aggregates.py +22 -15
  60. openepd/model/specs/singular/aluminium.py +20 -5
  61. openepd/model/specs/singular/asphalt.py +44 -20
  62. openepd/model/specs/singular/cladding.py +38 -23
  63. openepd/model/specs/singular/cmu.py +26 -11
  64. openepd/model/specs/singular/common.py +3 -2
  65. openepd/model/specs/singular/concrete.py +85 -48
  66. openepd/model/specs/singular/conveying_equipment.py +30 -17
  67. openepd/model/specs/singular/deprecated/__init__.py +3 -2
  68. openepd/model/specs/singular/deprecated/concrete.py +68 -33
  69. openepd/model/specs/singular/deprecated/steel.py +28 -15
  70. openepd/model/specs/singular/electrical.py +69 -41
  71. openepd/model/specs/singular/finishes.py +250 -140
  72. openepd/model/specs/singular/fire_and_smoke_protection.py +9 -6
  73. openepd/model/specs/singular/furnishings.py +16 -14
  74. openepd/model/specs/singular/manufacturing_inputs.py +23 -14
  75. openepd/model/specs/singular/masonry.py +66 -21
  76. openepd/model/specs/singular/mechanical.py +48 -47
  77. openepd/model/specs/singular/mechanical_insulation.py +7 -6
  78. openepd/model/specs/singular/mixins/conduit_mixin.py +13 -10
  79. openepd/model/specs/singular/network_infrastructure.py +111 -52
  80. openepd/model/specs/singular/openings.py +127 -95
  81. openepd/model/specs/singular/plumbing.py +15 -12
  82. openepd/model/specs/singular/precast_concrete.py +68 -54
  83. openepd/model/specs/singular/sheathing.py +47 -27
  84. openepd/model/specs/singular/steel.py +69 -45
  85. openepd/model/specs/singular/thermal_moisture_protection.py +36 -20
  86. openepd/model/specs/singular/utility_piping.py +11 -8
  87. openepd/model/specs/singular/wood.py +48 -24
  88. openepd/model/specs/singular/wood_joists.py +19 -6
  89. openepd/model/standard.py +15 -8
  90. openepd/model/validation/common.py +9 -3
  91. openepd/model/validation/numbers.py +0 -13
  92. openepd/model/validation/quantity.py +53 -25
  93. openepd/model/versioning.py +9 -6
  94. openepd/patch_pydantic.py +0 -93
  95. {openepd-6.13.1.dist-info → openepd-7.0.0.dist-info}/METADATA +1 -1
  96. openepd-7.0.0.dist-info/RECORD +142 -0
  97. openepd/compat/__init__.py +0 -15
  98. openepd/compat/compat_functional_validators.py +0 -25
  99. openepd/compat/pydantic.py +0 -30
  100. openepd-6.13.1.dist-info/RECORD +0 -145
  101. {openepd-6.13.1.dist-info → openepd-7.0.0.dist-info}/LICENSE +0 -0
  102. {openepd-6.13.1.dist-info → openepd-7.0.0.dist-info}/WHEEL +0 -0
@@ -13,7 +13,8 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
  #
16
- from openepd.compat.pydantic import pyd
16
+ import pydantic
17
+
17
18
  from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
18
19
  from openepd.model.specs.enums import (
19
20
  AccessFlooringCoreMaterial,
@@ -43,7 +44,6 @@ from openepd.model.specs.enums import (
43
44
  WoodFlooringTimberSpecies,
44
45
  )
45
46
  from openepd.model.specs.singular.common import HasForestPracticesCertifiers
46
- from openepd.model.validation.numbers import RatioFloat
47
47
  from openepd.model.validation.quantity import (
48
48
  AreaPerVolumeStr,
49
49
  ForceNStr,
@@ -70,28 +70,55 @@ class AccessFlooringV1(BaseOpenEpdHierarchicalSpec):
70
70
  _EXT_VERSION = "1.0"
71
71
 
72
72
  # Own fields:
73
- core_material: AccessFlooringCoreMaterial | None = pyd.Field(default=None, description="", example="Cementitious")
74
- finish_material: AccessFlooringFinishMaterial | None = pyd.Field(default=None, description="", example="Linoleum")
75
- stringers: AccessFlooringStringers | None = pyd.Field(default=None, description="", example="Standard")
76
- seismic_rating: AccessFlooringSeismicRating | None = pyd.Field(default=None, description="", example="Type 0")
77
- magnetically_attached_finish: bool | None = pyd.Field(default=None, description="", example=True)
78
- permanent_finish: bool | None = pyd.Field(default=None, description="", example=True)
79
- drylay: bool | None = pyd.Field(default=None, description="", example=True)
80
- adjustable_height: bool | None = pyd.Field(default=None, description="", example=True)
81
- fixed_height: bool | None = pyd.Field(default=None, description="", example=True)
82
- finished_floor_height: LengthMmStr | None = pyd.Field(default=None, description="", example="1 m")
83
- panel_thickness: LengthMmStr | None = pyd.Field(default=None, description="", example="1 m")
84
- concentrated_load: PressureMPaStr | None = pyd.Field(default=None, description="", example="1 MPa")
85
- uniform_load: PressureMPaStr | None = pyd.Field(default=None, description="", example="1 MPa")
86
- rolling_load_10_pass: ForceNStr | None = pyd.Field(default=None, description="", example="1 N")
87
- rolling_load_10000_pass: ForceNStr | None = pyd.Field(default=None, description="", example="1 N")
88
-
89
- _access_flooring_rolling_load_10_pass_is_quantity_validator = pyd.validator(
90
- "rolling_load_10_pass", allow_reuse=True
91
- )(validate_quantity_unit_factory("N"))
92
- _access_flooring_rolling_load_10000_pass_is_quantity_validator = pyd.validator(
93
- "rolling_load_10000_pass", allow_reuse=True
94
- )(validate_quantity_unit_factory("N"))
73
+ core_material: AccessFlooringCoreMaterial | None = pydantic.Field(
74
+ default=None, description="", examples=["Cementitious"]
75
+ )
76
+ finish_material: AccessFlooringFinishMaterial | None = pydantic.Field(
77
+ default=None, description="", examples=["Linoleum"]
78
+ )
79
+ stringers: AccessFlooringStringers | None = pydantic.Field(default=None, description="", examples=["Standard"])
80
+ seismic_rating: AccessFlooringSeismicRating | None = pydantic.Field(
81
+ default=None, description="", examples=["Type 0"]
82
+ )
83
+ magnetically_attached_finish: bool | None = pydantic.Field(
84
+ default=None,
85
+ description="",
86
+ examples=[True],
87
+ )
88
+ permanent_finish: bool | None = pydantic.Field(
89
+ default=None,
90
+ description="",
91
+ examples=[True],
92
+ )
93
+ drylay: bool | None = pydantic.Field(
94
+ default=None,
95
+ description="",
96
+ examples=[True],
97
+ )
98
+ adjustable_height: bool | None = pydantic.Field(
99
+ default=None,
100
+ description="",
101
+ examples=[True],
102
+ )
103
+ fixed_height: bool | None = pydantic.Field(
104
+ default=None,
105
+ description="",
106
+ examples=[True],
107
+ )
108
+ finished_floor_height: LengthMmStr | None = pydantic.Field(default=None, description="", examples=["1 m"])
109
+ panel_thickness: LengthMmStr | None = pydantic.Field(default=None, description="", examples=["1 m"])
110
+ concentrated_load: PressureMPaStr | None = pydantic.Field(default=None, description="", examples=["1 MPa"])
111
+ uniform_load: PressureMPaStr | None = pydantic.Field(default=None, description="", examples=["1 MPa"])
112
+ rolling_load_10_pass: ForceNStr | None = pydantic.Field(default=None, description="", examples=["1 N"])
113
+ rolling_load_10000_pass: ForceNStr | None = pydantic.Field(default=None, description="", examples=["1 N"])
114
+
115
+ @pydantic.field_validator("rolling_load_10_pass", mode="before", check_fields=False)
116
+ def _access_flooring_rolling_load_10_pass_is_quantity_validator(cls, value):
117
+ return validate_quantity_unit_factory("N")(cls, value)
118
+
119
+ @pydantic.field_validator("rolling_load_10000_pass", mode="before", check_fields=False)
120
+ def _access_flooring_rolling_load_10000_pass_is_quantity_validator(cls, value):
121
+ return validate_quantity_unit_factory("N")(cls, value)
95
122
 
96
123
 
97
124
  class CarpetV1(BaseOpenEpdHierarchicalSpec):
@@ -100,27 +127,40 @@ class CarpetV1(BaseOpenEpdHierarchicalSpec):
100
127
  _EXT_VERSION = "1.0"
101
128
 
102
129
  # Own fields:
103
- length: LengthMStr | None = pyd.Field(default=None, description="", example="1 m")
104
- width: LengthMStr | None = pyd.Field(default=None, description="", example="1 m")
105
- intended_application: list[CarpetIntendedApplication] | None = pyd.Field(
106
- default=None, description="", example=["Res"]
130
+ length: LengthMStr | None = pydantic.Field(default=None, description="", examples=["1 m"])
131
+ width: LengthMStr | None = pydantic.Field(default=None, description="", examples=["1 m"])
132
+ intended_application: list[CarpetIntendedApplication] | None = pydantic.Field(
133
+ default=None, description="", examples=[["Res"]]
107
134
  )
108
- manufacture_type: CarpetManufactureType | None = pyd.Field(default=None, description="", example="Tufted")
109
- form_factor: CarpetFormFactor | None = pyd.Field(default=None, description="", example="Tiles")
110
- yarn_weight: YarnWeightStr | None = pyd.Field(default=None, description="", example="1 g / m2")
111
- yarn_type: CarpetYarnType | None = pyd.Field(default=None, description="", example="Nylon 6,6")
112
- fire_radiant_panel_rating_astme648: str | None = pyd.Field(default=None, description="")
113
- fire_smoke_density_rating_astme648: str | None = pyd.Field(default=None, description="")
114
- voc_emissions: str | None = pyd.Field(default=None, description="", example="test_valueValidatedStringProperty")
115
- cushioned: bool | None = pyd.Field(default=None, description="", example=True)
116
- bleachable: bool | None = pyd.Field(default=None, description="", example=True)
117
- gwp_factor_base: GwpKgCo2eStr | None = pyd.Field(default=None, description="", example="1 kgCO2e")
118
- gwp_factor_yarn: GwpKgCo2eStr | None = pyd.Field(default=None, description="", example="1 kgCO2e")
119
-
120
- _yarn_weight_is_quantity_validator = pyd.validator("yarn_weight", allow_reuse=True)(
121
- validate_quantity_unit_factory("g / m2")
135
+ manufacture_type: CarpetManufactureType | None = pydantic.Field(default=None, description="", examples=["Tufted"])
136
+ form_factor: CarpetFormFactor | None = pydantic.Field(default=None, description="", examples=["Tiles"])
137
+ yarn_weight: YarnWeightStr | None = pydantic.Field(default=None, description="", examples=["1 g / m2"])
138
+ yarn_type: CarpetYarnType | None = pydantic.Field(default=None, description="", examples=["Nylon 6,6"])
139
+ fire_radiant_panel_rating_astme648: str | None = pydantic.Field(default=None, description="")
140
+ fire_smoke_density_rating_astme648: str | None = pydantic.Field(default=None, description="")
141
+ voc_emissions: str | None = pydantic.Field(
142
+ default=None, description="", examples=["test_valueValidatedStringProperty"]
143
+ )
144
+ cushioned: bool | None = pydantic.Field(
145
+ default=None,
146
+ description="",
147
+ examples=[True],
122
148
  )
123
- _yarn_weight_ge_validator = pyd.validator("yarn_weight", allow_reuse=True)(validate_quantity_ge_factory("0 g / m2"))
149
+ bleachable: bool | None = pydantic.Field(
150
+ default=None,
151
+ description="",
152
+ examples=[True],
153
+ )
154
+ gwp_factor_base: GwpKgCo2eStr | None = pydantic.Field(default=None, description="", examples=["1 kgCO2e"])
155
+ gwp_factor_yarn: GwpKgCo2eStr | None = pydantic.Field(default=None, description="", examples=["1 kgCO2e"])
156
+
157
+ @pydantic.field_validator("yarn_weight", mode="before", check_fields=False)
158
+ def _yarn_weight_is_quantity_validator(cls, value):
159
+ return validate_quantity_unit_factory("g / m2")(cls, value)
160
+
161
+ @pydantic.field_validator("yarn_weight", mode="before", check_fields=False)
162
+ def _yarn_weight_ge_validator(cls, value):
163
+ return validate_quantity_ge_factory("0 g / m2")(cls, value)
124
164
 
125
165
 
126
166
  class LaminateV1(BaseOpenEpdHierarchicalSpec):
@@ -145,19 +185,43 @@ class ResilientFlooringV1(BaseOpenEpdHierarchicalSpec):
145
185
  _EXT_VERSION = "1.0"
146
186
 
147
187
  # Own fields:
148
- length: LengthMStr | None = pyd.Field(default=None, description="", example="1 m")
149
- width: LengthMStr | None = pyd.Field(default=None, description="", example="1 m")
150
- form_factor: ResilientFlooringFormFactor | None = pyd.Field(default=None, description="", example="Loose Lay")
151
- material: ResilientFlooringMaterial | None = pyd.Field(default=None, description="", example="VCT")
152
- sheet_construction: VinylSheetConstruction | None = pyd.Field(default=None, description="", example="Homogeneous")
153
- wear_layer: LengthMmStr | None = pyd.Field(default=None, description="", example="1 m")
154
- delta_iic: float | None = pyd.Field(default=None, description="", example=2.3)
155
- thickness: ResilientFlooringThickness | None = pyd.Field(default=None, description="", example="≤ 2mm")
156
- sport_flooring: bool | None = pyd.Field(default=None, description="", example=True)
157
- conductive_flooring: bool | None = pyd.Field(default=None, description="", example=True)
158
- zwtl: bool | None = pyd.Field(default=None, description="", example=True)
159
- floor_score: bool | None = pyd.Field(default=None, description="", example=True)
160
- nsf332: bool | None = pyd.Field(default=None, description="", example=True)
188
+ length: LengthMStr | None = pydantic.Field(default=None, description="", examples=["1 m"])
189
+ width: LengthMStr | None = pydantic.Field(default=None, description="", examples=["1 m"])
190
+ form_factor: ResilientFlooringFormFactor | None = pydantic.Field(
191
+ default=None, description="", examples=["Loose Lay"]
192
+ )
193
+ material: ResilientFlooringMaterial | None = pydantic.Field(default=None, description="", examples=["VCT"])
194
+ sheet_construction: VinylSheetConstruction | None = pydantic.Field(
195
+ default=None, description="", examples=["Homogeneous"]
196
+ )
197
+ wear_layer: LengthMmStr | None = pydantic.Field(default=None, description="", examples=["1 m"])
198
+ delta_iic: float | None = pydantic.Field(default=None, description="", examples=[2.3])
199
+ thickness: ResilientFlooringThickness | None = pydantic.Field(default=None, description="", examples=["≤ 2mm"])
200
+ sport_flooring: bool | None = pydantic.Field(
201
+ default=None,
202
+ description="",
203
+ examples=[True],
204
+ )
205
+ conductive_flooring: bool | None = pydantic.Field(
206
+ default=None,
207
+ description="",
208
+ examples=[True],
209
+ )
210
+ zwtl: bool | None = pydantic.Field(
211
+ default=None,
212
+ description="",
213
+ examples=[True],
214
+ )
215
+ floor_score: bool | None = pydantic.Field(
216
+ default=None,
217
+ description="",
218
+ examples=[True],
219
+ )
220
+ nsf332: bool | None = pydantic.Field(
221
+ default=None,
222
+ description="",
223
+ examples=[True],
224
+ )
161
225
 
162
226
 
163
227
  class WallBaseV1(BaseOpenEpdHierarchicalSpec):
@@ -166,7 +230,7 @@ class WallBaseV1(BaseOpenEpdHierarchicalSpec):
166
230
  _EXT_VERSION = "1.0"
167
231
 
168
232
  # Own fields:
169
- wall_base_material: WallBaseMaterial | None = pyd.Field(default=None, description="", example="Rubber")
233
+ wall_base_material: WallBaseMaterial | None = pydantic.Field(default=None, description="", examples=["Rubber"])
170
234
 
171
235
 
172
236
  class WoodFlooringV1(BaseOpenEpdHierarchicalSpec, HasForestPracticesCertifiers):
@@ -180,9 +244,11 @@ class WoodFlooringV1(BaseOpenEpdHierarchicalSpec, HasForestPracticesCertifiers):
180
244
  _EXT_VERSION = "1.0"
181
245
 
182
246
  # Own fields:
183
- thickness: LengthMmStr | None = pyd.Field(default=None, description="", example="10 mm")
184
- timber_species: WoodFlooringTimberSpecies | None = pyd.Field(default=None, description="", example="Oak")
185
- fabrication: WoodFlooringFabrication | None = pyd.Field(default=None, description="", example="Solid hardwood")
247
+ thickness: LengthMmStr | None = pydantic.Field(default=None, description="", examples=["10 mm"])
248
+ timber_species: WoodFlooringTimberSpecies | None = pydantic.Field(default=None, description="", examples=["Oak"])
249
+ fabrication: WoodFlooringFabrication | None = pydantic.Field(
250
+ default=None, description="", examples=["Solid hardwood"]
251
+ )
186
252
 
187
253
 
188
254
  class AcousticalCeilingsV1(BaseOpenEpdHierarchicalSpec):
@@ -191,7 +257,7 @@ class AcousticalCeilingsV1(BaseOpenEpdHierarchicalSpec):
191
257
  _EXT_VERSION = "1.0"
192
258
 
193
259
  # Own fields:
194
- thickness: LengthMmStr | None = pyd.Field(default=None, description="", example="10 mm")
260
+ thickness: LengthMmStr | None = pydantic.Field(default=None, description="", examples=["10 mm"])
195
261
 
196
262
 
197
263
  class CeramicTileV1(BaseOpenEpdHierarchicalSpec):
@@ -200,36 +266,38 @@ class CeramicTileV1(BaseOpenEpdHierarchicalSpec):
200
266
  _EXT_VERSION = "1.0"
201
267
 
202
268
  # Own fields:
203
- porcelain: bool | None = pyd.Field(
204
- default=None, description="A dense and durable ceramic tile made from fine porcelain clay.", example=True
269
+ porcelain: bool | None = pydantic.Field(
270
+ default=None,
271
+ description="A dense and durable ceramic tile made from fine porcelain clay.",
272
+ examples=[True],
205
273
  )
206
- quarry: bool | None = pyd.Field(
274
+ quarry: bool | None = pydantic.Field(
207
275
  default=None,
208
276
  description="A type of unglazed ceramic tile made from natural clay with a slightly rough texture.",
209
- example=True,
277
+ examples=[True],
210
278
  )
211
- pressed_floor_tile: bool | None = pyd.Field(
279
+ pressed_floor_tile: bool | None = pydantic.Field(
212
280
  default=None,
213
281
  description="A durable and low-maintenance type of tile made by compressing clay or "
214
282
  "other materials at high pressure.",
215
- example=True,
283
+ examples=[True],
216
284
  )
217
- wall_tile: bool | None = pyd.Field(
285
+ wall_tile: bool | None = pydantic.Field(
218
286
  default=None,
219
287
  description="A decorative tile designed for use on vertical surfaces such as walls or backsplashes.",
220
- example=True,
288
+ examples=[True],
221
289
  )
222
- mosaic_tile: bool | None = pyd.Field(
290
+ mosaic_tile: bool | None = pydantic.Field(
223
291
  default=None,
224
292
  description="A small decorative tile made of glass, stone, or ceramic, arranged in a pattern "
225
293
  "to create a design.",
226
- example=True,
294
+ examples=[True],
227
295
  )
228
- specialty: bool | None = pyd.Field(
296
+ specialty: bool | None = pydantic.Field(
229
297
  default=None,
230
298
  description="A unique and customized type of tile, often made from unconventional materials or with "
231
299
  "specialized designs or finishes.",
232
- example=True,
300
+ examples=[True],
233
301
  )
234
302
 
235
303
 
@@ -243,19 +311,19 @@ class GaugedTileV1(BaseOpenEpdHierarchicalSpec):
243
311
  _EXT_VERSION = "1.0"
244
312
 
245
313
  # Own fields:
246
- tile_panels: bool | None = pyd.Field(
314
+ tile_panels: bool | None = pydantic.Field(
247
315
  default=None,
248
316
  description="Large-format porcelain or natural stone tiles that are typically over 3 feet in length and width, "
249
317
  "designed for use in floor and wall installations to create a seamless and uninterrupted "
250
318
  "appearance.",
251
- example=True,
319
+ examples=[True],
252
320
  )
253
- tile_pavers: bool | None = pyd.Field(
321
+ tile_pavers: bool | None = pydantic.Field(
254
322
  default=None,
255
323
  description="Thick and durable porcelain or natural stone tiles that are commonly used in outdoor "
256
324
  "applications, such as patios, walkways, and driveways, due to their high resistance to weather "
257
325
  "and wear.",
258
- example=True,
326
+ examples=[True],
259
327
  )
260
328
 
261
329
 
@@ -265,29 +333,29 @@ class GlassTileV1(BaseOpenEpdHierarchicalSpec):
265
333
  _EXT_VERSION = "1.0"
266
334
 
267
335
  # Own fields:
268
- regular: bool | None = pyd.Field(
336
+ regular: bool | None = pydantic.Field(
269
337
  default=None,
270
338
  description="Glass tile that is typically square or rectangular in shape, and used for a variety of "
271
339
  "decorative applications, such as kitchen backsplashes, shower walls, and accent borders.",
272
- example=True,
340
+ examples=[True],
273
341
  )
274
- glass_mosaic: bool | None = pyd.Field(
342
+ glass_mosaic: bool | None = pydantic.Field(
275
343
  default=None,
276
344
  description="A small, decorative glass tile made in a variety of shapes and colors, used for intricate "
277
345
  "designs and patterns on walls, floors, and other surfaces.",
278
- example=True,
346
+ examples=[True],
279
347
  )
280
- miniature_mosaic: bool | None = pyd.Field(
348
+ miniature_mosaic: bool | None = pydantic.Field(
281
349
  default=None,
282
350
  description="Glass mosaic tile that is smaller in size than regular glass mosaic tile, often used for "
283
351
  "intricate details and designs in backsplashes, shower walls, and decorative accents.",
284
- example=True,
352
+ examples=[True],
285
353
  )
286
- large_format: bool | None = pyd.Field(
354
+ large_format: bool | None = pydantic.Field(
287
355
  default=None,
288
356
  description="Glass tile that is larger in size than regular glass tile, often used to create a dramatic and "
289
357
  "modern effect in commercial and residential spaces.",
290
- example=True,
358
+ examples=[True],
291
359
  )
292
360
 
293
361
 
@@ -319,17 +387,23 @@ class CeilingPanelV1(BaseOpenEpdHierarchicalSpec):
319
387
  """Modular Ceiling Panels"""
320
388
 
321
389
  # Own fields:
322
- fire_rating: CeilingPanelFireRating | None = pyd.Field(default=None, description="", example="Class A")
323
- core_material: CeilingPanelCoreMaterial | None = pyd.Field(default=None, description="", example="Fiberglass")
324
- nrc: RatioFloat | None = pyd.Field(
390
+ fire_rating: CeilingPanelFireRating | None = pydantic.Field(default=None, description="", examples=["Class A"])
391
+ core_material: CeilingPanelCoreMaterial | None = pydantic.Field(
392
+ default=None, description="", examples=["Fiberglass"]
393
+ )
394
+ nrc: float | None = pydantic.Field(
325
395
  default=None,
326
396
  description="Noise Reduction Coefficient (NRC) or Sound Absorbtion Average (SAA) per ASTM C423",
327
- example=0.5,
397
+ examples=[0.5],
328
398
  ge=0,
329
399
  le=1,
330
400
  )
331
- cac: int | None = pyd.Field(
332
- default=None, description="Ceiling Attenuation Class (CAC) per ASTM E1414", example=13, ge=10, le=50
401
+ cac: int | None = pydantic.Field(
402
+ default=None,
403
+ description="Ceiling Attenuation Class (CAC) per ASTM E1414",
404
+ examples=[13],
405
+ ge=10,
406
+ le=50,
333
407
  )
334
408
 
335
409
  # Nested specs:
@@ -348,13 +422,13 @@ class CementBoardV1(BaseOpenEpdHierarchicalSpec):
348
422
  _EXT_VERSION = "1.0"
349
423
 
350
424
  # Own fields:
351
- thickness: CementBoardThickness | None = pyd.Field(
352
- default=None, description="", example=str(CementBoardThickness.INCH_1_2)
425
+ thickness: CementBoardThickness | None = pydantic.Field(
426
+ default=None, description="", examples=[str(CementBoardThickness.INCH_1_2)]
353
427
  )
354
428
 
355
- _cement_board_thickness_is_quantity_validator = pyd.validator("thickness", allow_reuse=True)(
356
- validate_quantity_unit_factory("m")
357
- )
429
+ @pydantic.field_validator("thickness")
430
+ def _cement_board_thickness_is_quantity_validator(cls, value):
431
+ return validate_quantity_unit_factory("m")(cls, value)
358
432
 
359
433
 
360
434
  class TilingV1(BaseOpenEpdHierarchicalSpec):
@@ -367,52 +441,60 @@ class TilingV1(BaseOpenEpdHierarchicalSpec):
367
441
  _EXT_VERSION = "1.0"
368
442
 
369
443
  # Own fields:
370
- thickness: LengthMmStr | None = pyd.Field(default=None, description="", example="9 mm")
371
- flooring: bool | None = pyd.Field(default=None, description="Tiling intended for walking.", example=True)
372
- wall_finish: bool | None = pyd.Field(
444
+ thickness: LengthMmStr | None = pydantic.Field(default=None, description="", examples=["9 mm"])
445
+ flooring: bool | None = pydantic.Field(
446
+ default=None,
447
+ description="Tiling intended for walking.",
448
+ examples=[True],
449
+ )
450
+ wall_finish: bool | None = pydantic.Field(
373
451
  default=None,
374
452
  description="A decorative tile designed for use on vertical surfaces such as walls or backsplashes.",
375
- example=True,
453
+ examples=[True],
376
454
  )
377
- cladding: bool | None = pyd.Field(
455
+ cladding: bool | None = pydantic.Field(
378
456
  default=None,
379
457
  description="Tiling for exterior use, primarily used for the walls of buildings and structures, providing a "
380
458
  "protective and decorative layer that enhances the aesthetic appearance and weather resistance "
381
459
  "of the underlying structure.",
382
- example=True,
460
+ examples=[True],
383
461
  )
384
- other: bool | None = pyd.Field(
385
- default=None, description="Tiling used as countertops, ceilings, furnishings, hardscapes etc.", example=True
462
+ other: bool | None = pydantic.Field(
463
+ default=None,
464
+ description="Tiling used as countertops, ceilings, furnishings, hardscapes etc.",
465
+ examples=[True],
386
466
  )
387
- residential_only: bool | None = pyd.Field(
467
+ residential_only: bool | None = pydantic.Field(
388
468
  default=None,
389
469
  description="All commercial tile can also be used in residential applications, but the opposite may not be "
390
470
  "true. This selection allows to filter out tiling that is not intended for commercial "
391
471
  "applications.",
392
- example=True,
472
+ examples=[True],
393
473
  )
394
- reinforced: bool | None = pyd.Field(
474
+ reinforced: bool | None = pydantic.Field(
395
475
  default=None,
396
476
  description="Steel-reinforced ceramic tiles or tiles with other special reinforcing technology.",
397
- example=True,
477
+ examples=[True],
398
478
  )
399
- total_recycled_content: RatioFloat | None = pyd.Field(
479
+ total_recycled_content: float | None = pydantic.Field(
400
480
  default=None,
401
481
  description="Proportion of this product that is sourced from recycled content. Pre-consumer recycling is "
402
482
  "given a 50% weighting, 100% for post-consumer, by mass.",
403
- example=0.5,
483
+ examples=[0.5],
404
484
  ge=0,
405
485
  le=1,
406
486
  )
407
- post_consumer_recycled_content: RatioFloat | None = pyd.Field(
487
+ post_consumer_recycled_content: float | None = pydantic.Field(
408
488
  default=None,
409
489
  description="Proportion of this product that is sourced from post-consumer recycled content, by mass.",
410
- example=0.5,
490
+ examples=[0.5],
411
491
  ge=0,
412
492
  le=1,
413
493
  )
414
494
 
415
- _thickness_max_validator = pyd.validator("thickness", allow_reuse=True)(validate_quantity_le_factory("50 mm"))
495
+ @pydantic.field_validator("thickness", mode="before")
496
+ def _thickness_max_validator(cls, value):
497
+ return validate_quantity_le_factory("50 mm")(cls, value)
416
498
 
417
499
  # Nested specs:
418
500
  CeramicTile: CeramicTileV1 | None = None
@@ -426,12 +508,24 @@ class DeckingBoardsV1(BaseOpenEpdHierarchicalSpec, HasForestPracticesCertifiers)
426
508
  _EXT_VERSION = "1.0"
427
509
 
428
510
  # Own fields:
429
- timber_species: SawnTimberSpecies | None = pyd.Field(default=None, description="", example="Alaska Cedar")
430
- fabrication: AllFabrication | None = pyd.Field(default=None, description="", example="LVL")
431
- weather_exposed: bool | None = pyd.Field(default=None, description="", example=True)
432
- fire_retardant: bool | None = pyd.Field(default=None, description="", example=True)
433
- decay_resistant: bool | None = pyd.Field(default=None, description="", example=True)
434
- material: DeckingBoardMaterial | None = pyd.Field(default=None, description="", example="Wood")
511
+ timber_species: SawnTimberSpecies | None = pydantic.Field(default=None, description="", examples=["Alaska Cedar"])
512
+ fabrication: AllFabrication | None = pydantic.Field(default=None, description="", examples=["LVL"])
513
+ weather_exposed: bool | None = pydantic.Field(
514
+ default=None,
515
+ description="",
516
+ examples=[True],
517
+ )
518
+ fire_retardant: bool | None = pydantic.Field(
519
+ default=None,
520
+ description="",
521
+ examples=[True],
522
+ )
523
+ decay_resistant: bool | None = pydantic.Field(
524
+ default=None,
525
+ description="",
526
+ examples=[True],
527
+ )
528
+ material: DeckingBoardMaterial | None = pydantic.Field(default=None, description="", examples=["Wood"])
435
529
 
436
530
 
437
531
  class GlassFiberReinforcedGypsumFabricationsV1(BaseOpenEpdHierarchicalSpec):
@@ -446,24 +540,40 @@ class GypsumV1(BaseOpenEpdHierarchicalSpec):
446
540
  _EXT_VERSION = "1.1"
447
541
 
448
542
  # Own fields:
449
- fire_rating: GypsumFireRating | None = pyd.Field(default=None, description="", example="-")
450
- thickness: GypsumThickness | None = pyd.Field(default=None, description="", example="1 m")
451
- facing: GypsumFacing | None = pyd.Field(default=None, description="", example="Paper")
452
- r_factor: RFactorStr | None = pyd.Field(default=None, description="", example="1 RSI")
453
- flame_spread_astm_e84: int | None = pyd.Field(default=None, description="", example=3)
454
- smoke_production_astm_e84: int | None = pyd.Field(default=None, description="", example=3)
455
- surface_abrasion_d4977: int | None = pyd.Field(default=None, description="", example=3)
456
- indentation_d5420: int | None = pyd.Field(default=None, description="", example=3)
457
- soft_body_impact_e695: int | None = pyd.Field(default=None, description="", example=3)
458
- hard_body_impact_c1929: int | None = pyd.Field(default=None, description="", example=3)
459
- mold_resistant: bool | None = pyd.Field(default=None, description="", example=True)
460
- foil_backing: bool | None = pyd.Field(default=None, description="", example=True)
461
- moisture_resistant: bool | None = pyd.Field(default=None, description="", example=True)
462
- abuse_resistant: bool | None = pyd.Field(default=None, description="", example=True)
463
-
464
- _gypsum_r_factor_is_quantity_validator = pyd.validator("r_factor", allow_reuse=True)(
465
- validate_quantity_unit_factory("RSI")
543
+ fire_rating: GypsumFireRating | None = pydantic.Field(default=None, description="", examples=["-"])
544
+ thickness: GypsumThickness | None = pydantic.Field(default=None, description="", examples=["1 m"])
545
+ facing: GypsumFacing | None = pydantic.Field(default=None, description="", examples=["Paper"])
546
+ r_factor: RFactorStr | None = pydantic.Field(default=None, description="", examples=["1 RSI"])
547
+ flame_spread_astm_e84: int | None = pydantic.Field(default=None, description="", examples=[3])
548
+ smoke_production_astm_e84: int | None = pydantic.Field(default=None, description="", examples=[3])
549
+ surface_abrasion_d4977: int | None = pydantic.Field(default=None, description="", examples=[3])
550
+ indentation_d5420: int | None = pydantic.Field(default=None, description="", examples=[3])
551
+ soft_body_impact_e695: int | None = pydantic.Field(default=None, description="", examples=[3])
552
+ hard_body_impact_c1929: int | None = pydantic.Field(default=None, description="", examples=[3])
553
+ mold_resistant: bool | None = pydantic.Field(
554
+ default=None,
555
+ description="",
556
+ examples=[True],
466
557
  )
558
+ foil_backing: bool | None = pydantic.Field(
559
+ default=None,
560
+ description="",
561
+ examples=[True],
562
+ )
563
+ moisture_resistant: bool | None = pydantic.Field(
564
+ default=None,
565
+ description="",
566
+ examples=[True],
567
+ )
568
+ abuse_resistant: bool | None = pydantic.Field(
569
+ default=None,
570
+ description="",
571
+ examples=[True],
572
+ )
573
+
574
+ @pydantic.field_validator("r_factor")
575
+ def _gypsum_r_factor_is_quantity_validator(cls, value):
576
+ return validate_quantity_unit_factory("RSI")(cls, value)
467
577
 
468
578
  # Nested specs:
469
579
  GypsumSupports: GypsumSupportsV1 | None = None
@@ -521,7 +631,7 @@ class WallFinishesV1(BaseOpenEpdHierarchicalSpec):
521
631
  _EXT_VERSION = "1.0"
522
632
 
523
633
  # Own fields:
524
- thickness: LengthMmStr | None = pyd.Field(default=None, description="", example="10 mm")
634
+ thickness: LengthMmStr | None = pydantic.Field(default=None, description="", examples=["10 mm"])
525
635
 
526
636
 
527
637
  class PlasterV1(BaseOpenEpdHierarchicalSpec):
@@ -536,11 +646,11 @@ class PlasterV1(BaseOpenEpdHierarchicalSpec):
536
646
  _EXT_VERSION = "1.0"
537
647
 
538
648
  # Own fields:
539
- composition: PlasterComposition | None = pyd.Field(default=None, description="", example="Cement")
540
- application_rate: AreaPerVolumeStr | None = pyd.Field(
649
+ composition: PlasterComposition | None = pydantic.Field(default=None, description="", examples=["Cement"])
650
+ application_rate: AreaPerVolumeStr | None = pydantic.Field(
541
651
  default=None,
542
652
  description="Typical or reference amount of material covering a unit of a host surface.",
543
- example="10 m2/l",
653
+ examples=["10 m2/l"],
544
654
  )
545
655
 
546
656
 
@@ -13,7 +13,8 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
  #
16
- from openepd.compat.pydantic import pyd
16
+ import pydantic
17
+
17
18
  from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
18
19
  from openepd.model.specs.enums import (
19
20
  IntumescentFireproofingMaterialType,
@@ -33,7 +34,9 @@ class IntumescentFireproofingV1(BaseOpenEpdHierarchicalSpec):
33
34
  _EXT_VERSION = "1.0"
34
35
 
35
36
  # Own fields:
36
- material_type: IntumescentFireproofingMaterialType | None = pyd.Field(default=None, description="", example="Epoxy")
37
+ material_type: IntumescentFireproofingMaterialType | None = pydantic.Field(
38
+ default=None, description="", examples=["Epoxy"]
39
+ )
37
40
 
38
41
 
39
42
  class SprayFireproofingV1(BaseOpenEpdHierarchicalSpec):
@@ -46,10 +49,10 @@ class SprayFireproofingV1(BaseOpenEpdHierarchicalSpec):
46
49
  _EXT_VERSION = "1.0"
47
50
 
48
51
  # Own fields:
49
- material_type: SprayFireproofingMaterialType | None = pyd.Field(
50
- default=None, description="", example="Gypsum-based"
52
+ material_type: SprayFireproofingMaterialType | None = pydantic.Field(
53
+ default=None, description="", examples=["Gypsum-based"]
51
54
  )
52
- density: SprayFireproofingDensity | None = pyd.Field(default=None, description="", example="Standard")
55
+ density: SprayFireproofingDensity | None = pydantic.Field(default=None, description="", examples=["Standard"])
53
56
 
54
57
 
55
58
  class AppliedFireproofingV1(BaseOpenEpdHierarchicalSpec):
@@ -63,7 +66,7 @@ class AppliedFireproofingV1(BaseOpenEpdHierarchicalSpec):
63
66
  _EXT_VERSION = "1.0"
64
67
 
65
68
  # Own fields:
66
- thickness: LengthMmStr | None = pyd.Field(default=None, description="", example="10 mm")
69
+ thickness: LengthMmStr | None = pydantic.Field(default=None, description="", examples=["10 mm"])
67
70
 
68
71
  # Nested specs:
69
72
  IntumescentFireproofing: IntumescentFireproofingV1 | None = None