openepd 3.1.1__py3-none-any.whl → 3.1.3__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 (34) hide show
  1. openepd/__version__.py +1 -1
  2. openepd/compat/compat_functional_validators.py +29 -0
  3. openepd/compat/pydantic.py +6 -1
  4. openepd/model/specs/concrete.py +1 -157
  5. openepd/model/specs/generated/asphalt.py +1 -11
  6. openepd/model/specs/generated/cladding.py +4 -16
  7. openepd/model/specs/generated/cmu.py +1 -8
  8. openepd/model/specs/generated/concrete.py +59 -33
  9. openepd/model/specs/generated/conveying_equipment.py +2 -12
  10. openepd/model/specs/generated/electrical.py +9 -12
  11. openepd/model/specs/generated/enums.py +26 -20
  12. openepd/model/specs/generated/finishes.py +2 -36
  13. openepd/model/specs/generated/fire_and_smoke_protection.py +1 -3
  14. openepd/model/specs/generated/furnishings.py +1 -3
  15. openepd/model/specs/generated/masonry.py +5 -4
  16. openepd/model/specs/generated/mechanical.py +25 -93
  17. openepd/model/specs/generated/mechanical_insulation.py +1 -5
  18. openepd/model/specs/generated/network_infrastructure.py +2 -12
  19. openepd/model/specs/generated/openings.py +209 -91
  20. openepd/model/specs/generated/plumbing.py +3 -19
  21. openepd/model/specs/generated/precast_concrete.py +1 -5
  22. openepd/model/specs/generated/steel.py +117 -53
  23. openepd/model/specs/generated/thermal_moisture_protection.py +1 -15
  24. openepd/model/specs/generated/utility_piping.py +2 -10
  25. openepd/model/specs/generated/wood.py +1 -5
  26. openepd/model/validation/quantity.py +158 -16
  27. {openepd-3.1.1.dist-info → openepd-3.1.3.dist-info}/METADATA +2 -1
  28. {openepd-3.1.1.dist-info → openepd-3.1.3.dist-info}/RECORD +30 -33
  29. openepd/model/specs/aluminium.py +0 -67
  30. openepd/model/specs/glass.py +0 -360
  31. openepd/model/specs/steel.py +0 -184
  32. openepd/model/specs/wood.py +0 -130
  33. {openepd-3.1.1.dist-info → openepd-3.1.3.dist-info}/LICENSE +0 -0
  34. {openepd-3.1.1.dist-info → openepd-3.1.3.dist-info}/WHEEL +0 -0
@@ -18,14 +18,22 @@
18
18
  # Find out more at www.BuildingTransparency.org
19
19
  #
20
20
  from openepd.compat.pydantic import pyd
21
+ from openepd.model.base import BaseOpenEpdSchema
21
22
  from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec, BaseOpenEpdSpec
22
23
  from openepd.model.specs.generated.enums import SteelComposition, SteelRebarGrade
23
- from openepd.model.specs.steel import SteelMakingRoute
24
24
  from openepd.model.standard import Standard
25
25
  from openepd.model.validation.numbers import RatioFloat
26
26
  from openepd.model.validation.quantity import LengthMmStr, PressureMPaStr, validate_unit_factory
27
27
 
28
28
 
29
+ class SteelMakingRoute(BaseOpenEpdSchema):
30
+ """Steel making route."""
31
+
32
+ bof: bool | None = pyd.Field(default=None, description="Basic oxygen furnace")
33
+ eaf: bool | None = pyd.Field(default=None, description="Electric arc furnace")
34
+ ohf: bool | None = pyd.Field(default=None, description="Open hearth furnace")
35
+
36
+
29
37
  class SteelFabricatedMixin(BaseOpenEpdSpec):
30
38
  """Class with fabricated property used in different parts of steel hierarchy."""
31
39
 
@@ -33,41 +41,51 @@ class SteelFabricatedMixin(BaseOpenEpdSpec):
33
41
 
34
42
 
35
43
  class ColdFormedFramingV1(BaseOpenEpdHierarchicalSpec):
36
- """Cold formed framing performance specification."""
44
+ """
45
+ Cold Formed Framing performance specification.
46
+
47
+ Cold formed steel elements such as studs and framing, typically made from coil or sheet steel and used
48
+ within walls and ceilings.
49
+ """
37
50
 
38
51
  _EXT_VERSION = "1.0"
39
52
 
40
53
 
41
54
  class DeckingSteelV1(BaseOpenEpdHierarchicalSpec):
42
- """Cold Formed Steel Decking."""
55
+ """Corrugated Decking made from cold-formed sheet steel. Often filled with concrete."""
43
56
 
44
57
  _EXT_VERSION = "1.0"
45
58
 
46
59
 
47
60
  class SteelSuspensionAssemblyV1(BaseOpenEpdHierarchicalSpec):
48
- """Steel suspension assembly performance specification."""
61
+ """Steel suspension assemblies for suspended (e.g. acoustical) ceiling systems."""
49
62
 
50
63
  _EXT_VERSION = "1.0"
51
64
 
52
65
 
53
66
  class HollowSectionsV1(BaseOpenEpdHierarchicalSpec, SteelFabricatedMixin):
54
- """Hollow sections performance specification."""
67
+ """Hollow cross section steel shape, typically referred to as hollow structural section (HSS)."""
55
68
 
56
69
  _EXT_VERSION = "1.0"
57
70
 
58
- # Own fields:
59
-
60
71
 
61
72
  class HotRolledSectionsV1(BaseOpenEpdHierarchicalSpec, SteelFabricatedMixin):
62
- """Hot rolled sections performance specification."""
73
+ """
74
+ Hot rolled sections performance specification.
63
75
 
64
- _EXT_VERSION = "1.0"
76
+ Steel shapes, such as angles, wide flange beams and I-beams, produced using a high temperature
77
+ mill process.
78
+ """
65
79
 
66
- # Own fields:
80
+ _EXT_VERSION = "1.0"
67
81
 
68
82
 
69
83
  class PlateSteelV1(BaseOpenEpdHierarchicalSpec, SteelFabricatedMixin):
70
- """Plate Steels."""
84
+ """Plate Steels.
85
+
86
+ Flat hot-rolled steel, typically thicker than 'sheet', made by compressing multiple steel
87
+ layers together into one.
88
+ """
71
89
 
72
90
  _EXT_VERSION = "1.0"
73
91
 
@@ -75,43 +93,66 @@ class PlateSteelV1(BaseOpenEpdHierarchicalSpec, SteelFabricatedMixin):
75
93
 
76
94
 
77
95
  class MetalRailingsV1(BaseOpenEpdHierarchicalSpec):
78
- """Metal railings performance specification."""
96
+ """Metal Railings including pipe and tube railings."""
79
97
 
80
98
  _EXT_VERSION = "1.0"
81
99
 
82
100
 
83
101
  class MetalStairsV1(BaseOpenEpdHierarchicalSpec):
84
- """Metal stairs performance specification."""
102
+ """
103
+ Metal stairs.
104
+
105
+ Includes: metal pan stairs, metal floor plate stairs, grating stairs, fire escapes,
106
+ ladders, and walkways/catwalks/ramps/platforms.
107
+ """
85
108
 
86
109
  _EXT_VERSION = "1.0"
87
110
 
88
111
 
89
112
  class MiscMetalFabricationV1(BaseOpenEpdHierarchicalSpec):
90
- """Misc metal fabrication performance specification."""
113
+ """Prefabricated steel assemblies not included in another category."""
91
114
 
92
115
  _EXT_VERSION = "1.0"
93
116
 
94
117
 
95
118
  class OpenWebMembranesV1(BaseOpenEpdHierarchicalSpec):
96
- """Open web membranes performance specification."""
119
+ """
120
+ Open web membranes performance specification.
121
+
122
+ Lightweight steel truss, typically made of parallel chords and a triangulated web system,
123
+ "proportioned to span between bearing points.
124
+ """
97
125
 
98
126
  _EXT_VERSION = "1.0"
99
127
 
100
128
 
101
129
  class MBQSteelV1(BaseOpenEpdHierarchicalSpec):
102
- """M b q steel performance specification."""
130
+ """
131
+ Merchant Bar Quality (MBQ) steel.
132
+
133
+ Used as feedstock to steel construction products, but also includes rounds, angles, and light structural shapes.
134
+ """
103
135
 
104
136
  _EXT_VERSION = "1.0"
105
137
 
106
138
 
107
139
  class CoilSteelV1(BaseOpenEpdHierarchicalSpec):
108
- """Coil steel performance specification."""
140
+ """
141
+ Sheet or strip steel, sold in rolls.
142
+
143
+ Typically, coil steel is cold-formed into light gauge products.
144
+ """
109
145
 
110
146
  _EXT_VERSION = "1.0"
111
147
 
112
148
 
113
149
  class ColdFormedSteelV1(BaseOpenEpdHierarchicalSpec):
114
- """Cold Formed Structural Steel."""
150
+ """
151
+ Cold Formed Steel Products.
152
+
153
+ All types of cold formed steel products. These products are made from hot-rolled steel coils and
154
+ sheets and are cold formed into products such as studs, decking, panels, and other accessories.
155
+ """
115
156
 
116
157
  _EXT_VERSION = "1.0"
117
158
 
@@ -122,18 +163,31 @@ class ColdFormedSteelV1(BaseOpenEpdHierarchicalSpec):
122
163
 
123
164
 
124
165
  class StructuralSteelV1(BaseOpenEpdHierarchicalSpec):
125
- """Structural Steel."""
166
+ """
167
+ Structural Steel.
168
+
169
+ Hot rolled steel shapes, Hollow Sections, pipes, and similar hot-worked structural steels.
170
+ """
126
171
 
127
172
  _EXT_VERSION = "1.0"
128
173
 
129
174
  # Own fields:
130
- modulus_of_elasticity: PressureMPaStr | None = pyd.Field(default=None, description="", example="1.0 MPa")
131
- thermal_expansion: str | None = pyd.Field(default=None, description="", example="1 / K")
132
- thermal_conductivity: str | None = pyd.Field(default=None, description="", example="1 W / (m * K)")
133
-
134
- _steel_modulus_of_elasticity_is_quantity_validator = pyd.validator("modulus_of_elasticity", allow_reuse=True)(
135
- validate_unit_factory("MPa")
175
+ modulus_of_elasticity: PressureMPaStr | None = pyd.Field(
176
+ default=None,
177
+ description="Modulus of Elasticity, https://en.wikipedia.org/wiki/Elastic_modulus ",
178
+ example="193 GPa",
179
+ )
180
+ thermal_expansion: str | None = pyd.Field(
181
+ default=None,
182
+ description="Thermal Expansion, https://en.wikipedia.org/wiki/Thermal_expansion",
183
+ example="1.11E-5 / K",
136
184
  )
185
+ thermal_conductivity: str | None = pyd.Field(
186
+ default=None,
187
+ description="Thermal Conductivity, https://en.wikipedia.org/wiki/Thermal_conductivity_and_resistivity",
188
+ example="1.45E-5 W / (m * K)",
189
+ )
190
+
137
191
  _steel_thermal_expansion_is_quantity_validator = pyd.validator("thermal_expansion", allow_reuse=True)(
138
192
  validate_unit_factory("1 / K")
139
193
  )
@@ -148,7 +202,7 @@ class StructuralSteelV1(BaseOpenEpdHierarchicalSpec):
148
202
 
149
203
 
150
204
  class PrefabricatedSteelAssembliesV1(BaseOpenEpdHierarchicalSpec):
151
- """Prefabricated steel assemblies performance specification."""
205
+ """Prefabricated assemblies made primarily of steel."""
152
206
 
153
207
  _EXT_VERSION = "1.0"
154
208
 
@@ -160,26 +214,24 @@ class PrefabricatedSteelAssembliesV1(BaseOpenEpdHierarchicalSpec):
160
214
 
161
215
 
162
216
  class PostTensioningSteelV1(BaseOpenEpdHierarchicalSpec):
163
- """Post-Tensioning Steels, per https://www.concretenetwork.com/post-tension/industry.html."""
217
+ """Steel tensioning cables or tendons for compression of prestressed concrete."""
164
218
 
165
219
  _EXT_VERSION = "1.0"
166
220
 
167
221
 
168
222
  class RebarSteelV1(BaseOpenEpdHierarchicalSpec, SteelFabricatedMixin):
169
- """Bar steels, such as rebar for concrete reinforcement."""
223
+ """Reinforcing bar used together with concrete."""
170
224
 
171
225
  _EXT_VERSION = "1.0"
172
226
 
173
227
  # Own fields:
174
- grade: SteelRebarGrade | None = pyd.Field(default=None, description="", example="60 ksi")
175
- diameter_min: LengthMmStr | None = pyd.Field(default=None, description="", example="8 mm")
176
- bending_pin_max: float | None = pyd.Field(default=None, description="", example=2.3)
177
- ts_ys_ratio_max: float | None = pyd.Field(default=None, description="", example=2.3)
178
- epoxy_coated: bool | None = pyd.Field(default=None, description="", example=True)
179
-
180
- _steel_rebar_diameter_min_is_quantity_validator = pyd.validator("diameter_min", allow_reuse=True)(
181
- validate_unit_factory("m")
228
+ grade: SteelRebarGrade | None = pyd.Field(default=None, example="60 ksi")
229
+ diameter_min: LengthMmStr | None = pyd.Field(default=None, description="Minimal diameter", example="8 mm")
230
+ bending_pin_max: float | None = pyd.Field(default=None, example=2.3)
231
+ ts_ys_ratio_max: float | None = pyd.Field(
232
+ default=None, description="Max ratio of ultimate tensile to yield tensile strength", example=2.3
182
233
  )
234
+ epoxy_coated: bool | None = pyd.Field(default=None, example=True)
183
235
 
184
236
 
185
237
  class WireMeshSteelV1(BaseOpenEpdHierarchicalSpec, SteelFabricatedMixin):
@@ -189,29 +241,41 @@ class WireMeshSteelV1(BaseOpenEpdHierarchicalSpec, SteelFabricatedMixin):
189
241
 
190
242
 
191
243
  class SteelV1(BaseOpenEpdHierarchicalSpec):
192
- """Steel performance specification."""
244
+ """Broad category for construction materials made from steel and its alloys."""
193
245
 
194
246
  _EXT_VERSION = "1.0"
195
247
 
196
248
  # Own fields:
197
- yield_tensile_str: PressureMPaStr | None = pyd.Field(default=None, description="", example="1 MPa")
198
- bar_elongation: float | None = pyd.Field(default=None, description="", example=2.3)
249
+ yield_tensile_str: PressureMPaStr | None = pyd.Field(
250
+ default=None, description="Yield Tensile strength (Mpa) per unit area", example="100 MPa"
251
+ )
252
+ bar_elongation: float | None = pyd.Field(
253
+ default=None, description="Increase in length at break, in percent. Typically 10%-20%", example=0.2
254
+ )
199
255
  recycled_content: RatioFloat | None = pyd.Field(default=None, description="", example=0.5, ge=0, le=1)
200
- post_consumer_recycled_content: RatioFloat | None = pyd.Field(default=None, description="", example=0.5, ge=0, le=1)
201
- astm_marking: str | None = pyd.Field(default=None, description="")
202
- euro_marking: str | None = pyd.Field(default=None, description="")
203
- composition: SteelComposition | None = pyd.Field(default=None, description="", example="Carbon")
204
- cold_finished: bool | None = pyd.Field(default=None, description="", example=True)
205
- galvanized: bool | None = pyd.Field(default=None, description="", example=True)
206
- stainless: bool | None = pyd.Field(default=None, description="", example=True)
207
- making_route: SteelMakingRoute | None = pyd.Field(default=None)
208
- astm_standards: list[Standard] | None = pyd.Field(default=None, description="")
209
- sae_standards: list[Standard] | None = pyd.Field(default=None, description="")
210
- en_standards: list[Standard] | None = pyd.Field(default=None, description="")
211
-
212
- _steel_yield_tensile_str_is_quantity_validator = pyd.validator("yield_tensile_str", allow_reuse=True)(
213
- validate_unit_factory("MPa")
256
+ post_consumer_recycled_content: RatioFloat | None = pyd.Field(
257
+ default=None,
258
+ description="Should be a number between zero and the Recycled Content (steel_recycled_content)",
259
+ example=0.5,
260
+ ge=0,
261
+ le=1,
262
+ )
263
+ astm_marking: str | None = pyd.Field(
264
+ default=None, description="The marking to be expected on the product.", example="S4S60"
214
265
  )
266
+ euro_marking: str | None = pyd.Field(
267
+ default=None, description="The marking to be expected on the product.", examples="S4S60"
268
+ )
269
+ composition: SteelComposition | None = pyd.Field(
270
+ default=None, description="Basic chemical composition", example="Carbon"
271
+ )
272
+ cold_finished: bool | None = pyd.Field(default=None, example=True)
273
+ galvanized: bool | None = pyd.Field(default=None, example=True)
274
+ stainless: bool | None = pyd.Field(default=None, example=True)
275
+ making_route: SteelMakingRoute | None = pyd.Field(default=None)
276
+ astm_standards: list[Standard] | None = pyd.Field(default=None, description="List of ASTM standards")
277
+ sae_standards: list[Standard] | None = pyd.Field(default=None, description="List of SAE standards")
278
+ en_standards: list[Standard] | None = pyd.Field(default=None, description="List of EN standards")
215
279
 
216
280
  # Nested specs:
217
281
  MBQSteel: MBQSteelV1 | None = None
@@ -28,7 +28,7 @@ from openepd.model.specs.generated.enums import (
28
28
  RoofCoverBoardsMaterial,
29
29
  )
30
30
  from openepd.model.validation.numbers import RatioFloat
31
- from openepd.model.validation.quantity import LengthMmStr, PressureMPaStr, validate_unit_factory
31
+ from openepd.model.validation.quantity import LengthMmStr, PressureMPaStr
32
32
 
33
33
 
34
34
  class BituminousRoofingV1(BaseOpenEpdHierarchicalSpec):
@@ -93,10 +93,6 @@ class BoardInsulationV1(BaseOpenEpdHierarchicalSpec):
93
93
  # Own fields:
94
94
  compressive_strength: PressureMPaStr | None = pyd.Field(default=None, description="", example="1 MPa")
95
95
 
96
- _compressive_strength_is_quantity_validator = pyd.validator("compressive_strength", allow_reuse=True)(
97
- validate_unit_factory("MPa")
98
- )
99
-
100
96
 
101
97
  class FoamedInPlaceV1(BaseOpenEpdHierarchicalSpec):
102
98
  """Foamed in place performance specification."""
@@ -134,8 +130,6 @@ class MembraneRoofingV1(BaseOpenEpdHierarchicalSpec):
134
130
  nsf347: bool | None = pyd.Field(default=None, description="", example=True)
135
131
  vantage_vinyl: bool | None = pyd.Field(default=None, description="", example=True)
136
132
 
137
- _thickness_is_quantity_validator = pyd.validator("thickness", allow_reuse=True)(validate_unit_factory("m"))
138
-
139
133
  # Nested specs:
140
134
  BituminousRoofing: BituminousRoofingV1 | None = None
141
135
  SinglePlyEPDM: SinglePlyEPDMV1 | None = None
@@ -159,10 +153,6 @@ class InsulationV1(BaseOpenEpdHierarchicalSpec):
159
153
  )
160
154
  thickness_per_declared_unit: LengthMmStr | None = pyd.Field(default=None, description="", example="10 mm")
161
155
 
162
- _thickness_per_declared_unit_is_quantity_validator = pyd.validator("thickness_per_declared_unit", allow_reuse=True)(
163
- validate_unit_factory("m")
164
- )
165
-
166
156
  # Nested specs:
167
157
  BlanketInsulation: BlanketInsulationV1 | None = None
168
158
  BlownInsulation: BlownInsulationV1 | None = None
@@ -199,10 +189,6 @@ class RoofCoverBoardsV1(BaseOpenEpdHierarchicalSpec):
199
189
  facing: list[RoofCoverBoardsFacing] | None = pyd.Field(default=None, description="", example=["Paper"])
200
190
  thickness: LengthMmStr | None = pyd.Field(default=None, description="", example="1 m")
201
191
 
202
- _roof_cover_boards_thickness_is_quantity_validator = pyd.validator("thickness", allow_reuse=True)(
203
- validate_unit_factory("m")
204
- )
205
-
206
192
 
207
193
  class SteepSlopeRoofingV1(BaseOpenEpdHierarchicalSpec):
208
194
  """Steep slope roofing performance specification."""
@@ -20,7 +20,7 @@
20
20
  from openepd.compat.pydantic import pyd
21
21
  from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
22
22
  from openepd.model.specs.generated.enums import BuriedPipingType, PipingAnsiSchedule, UtilityPipingMaterial
23
- from openepd.model.validation.quantity import LengthMmStr, validate_unit_factory
23
+ from openepd.model.validation.quantity import LengthMmStr, MassPerLengthStr
24
24
 
25
25
 
26
26
  class BuildingHeatingPipingV1(BaseOpenEpdHierarchicalSpec):
@@ -48,18 +48,10 @@ class UtilityPipingV1(BaseOpenEpdHierarchicalSpec):
48
48
  # Own fields:
49
49
  thickness: LengthMmStr | None = pyd.Field(default=None, description="", example="6 m")
50
50
  piping_diameter: LengthMmStr | None = pyd.Field(default=None, description="", example="200 mm")
51
- mass_per_unit_length: str | None = pyd.Field(default=None, description="", example="1 kg / m")
51
+ mass_per_unit_length: MassPerLengthStr | None = pyd.Field(default=None, description="", example="1 kg / m")
52
52
  piping_ansi_schedule: PipingAnsiSchedule | None = pyd.Field(default=None, description="", example="5")
53
53
  utility_piping_material: UtilityPipingMaterial | None = pyd.Field(default=None, description="", example="PVC")
54
54
 
55
- _thickness_is_quantity_validator = pyd.validator("thickness", allow_reuse=True)(validate_unit_factory("m"))
56
- _piping_diameter_is_quantity_validator = pyd.validator("piping_diameter", allow_reuse=True)(
57
- validate_unit_factory("m")
58
- )
59
- _mass_per_unit_length_is_quantity_validator = pyd.validator("mass_per_unit_length", allow_reuse=True)(
60
- validate_unit_factory("kg / m")
61
- )
62
-
63
55
  # Nested specs:
64
56
  BuildingHeatingPiping: BuildingHeatingPipingV1 | None = None
65
57
  BuriedPiping: BuriedPipingV1 | None = None
@@ -31,7 +31,7 @@ from openepd.model.specs.generated.enums import (
31
31
  SheathingPanelsFabrication,
32
32
  )
33
33
  from openepd.model.validation.numbers import RatioFloat
34
- from openepd.model.validation.quantity import LengthMmStr, validate_unit_factory
34
+ from openepd.model.validation.quantity import LengthMmStr
35
35
 
36
36
 
37
37
  class WoodDeckingV1(BaseOpenEpdHierarchicalSpec):
@@ -119,10 +119,6 @@ class SheathingPanelsV1(BaseOpenEpdHierarchicalSpec):
119
119
  wood_board_thickness: LengthMmStr | None = pyd.Field(default=None, description="", example="10 mm")
120
120
  timber_species: EngineeredTimberSpecies | None = pyd.Field(default=None, description="", example="Alaska Cedar")
121
121
 
122
- _wood_board_thickness_is_quantity_validator = pyd.validator("wood_board_thickness", allow_reuse=True)(
123
- validate_unit_factory("m")
124
- )
125
-
126
122
 
127
123
  class UnfinishedWoodV1(BaseOpenEpdHierarchicalSpec):
128
124
  """Unfinished or 'green' timber."""
@@ -18,9 +18,8 @@
18
18
  # Find out more at www.BuildingTransparency.org
19
19
  #
20
20
  from abc import ABC, abstractmethod
21
- from typing import TYPE_CHECKING, Annotated, Callable, TypeAlias
21
+ from typing import TYPE_CHECKING, Callable, ClassVar
22
22
 
23
- from openepd.compat.pydantic import pyd
24
23
  from openepd.model.common import OpenEPDUnit
25
24
 
26
25
  if TYPE_CHECKING:
@@ -116,17 +115,160 @@ def validate_quantity_le_factory(max_value: str) -> "QuantityValidatorType":
116
115
  return validator
117
116
 
118
117
 
119
- # todo with the migration to Pydantic 2 we will be able to use pydantic.funcational_validators.AfterDecorator
120
- # this will let us bind the validator not to the model or the field, but to the type itself.
121
-
122
- # for abitrary non-standard quantity
123
- QuantityStr: TypeAlias = Annotated[str, pyd.Field()]
124
- PressureMPaStr: TypeAlias = Annotated[str, pyd.Field(example="30 MPa")]
125
- MassKgStr: TypeAlias = Annotated[str, pyd.Field(example="30 kg")]
126
- AreaM2Str: TypeAlias = Annotated[str, pyd.Field(example="12 m2", gt=0)]
127
- LengthMStr: TypeAlias = Annotated[str, pyd.Field(example="30 m", gt=0)]
128
- LengthMmStr: TypeAlias = Annotated[str, pyd.Field(example="30 mm", gt=0)]
129
- LengthInchStr: TypeAlias = Annotated[str, pyd.Field(example="30 m", gt=0)]
130
- TemperatureCStr: TypeAlias = Annotated[str, pyd.Field(example="45 C")]
131
- HeatConductanceUCIStr: TypeAlias = Annotated[str, pyd.Field(example="0.3 U")]
132
- GwpKgCo2eStr: TypeAlias = Annotated[str, pyd.Field(example="300 kgCO2e")]
118
+ def validate_quantity_for_new_validator(max_value: str) -> Callable:
119
+ """Create validator to check that quantity is less than or equal to max_value."""
120
+
121
+ def validator(value: str) -> str:
122
+ cls = BaseOpenEpdHierarchicalSpec
123
+ if hasattr(cls, "_QUANTITY_VALIDATOR") and cls._QUANTITY_VALIDATOR is not None:
124
+ cls._QUANTITY_VALIDATOR.validate_quantity_less_or_equal(value, max_value)
125
+ return value
126
+
127
+ return validator
128
+
129
+
130
+ # for arbitrary non-standard quantity
131
+ # todo these types should be replaced by Annotated[str, AfterValidator...] as we move completely to pydantic 2
132
+
133
+
134
+ class QuantityStr(str):
135
+ """
136
+ Quantity string type.
137
+
138
+ Should be used in models where the physical value (quantity) is expected.
139
+
140
+ Checks for dimensionality and for the fact that value is greater than zero.
141
+ """
142
+
143
+ unit: ClassVar[str]
144
+
145
+ @classmethod
146
+ def __get_validators__(cls):
147
+ yield validate_unit_factory(cls.unit)
148
+ yield validate_quantity_ge_factory(f"0 {cls.unit}")
149
+
150
+ @classmethod
151
+ def __modify_schema__(cls, field_schema):
152
+ field_schema.update(
153
+ examples=[f"1 {cls.unit}"],
154
+ )
155
+
156
+
157
+ class PressureMPaStr(QuantityStr):
158
+ """Pressure quantity type."""
159
+
160
+ unit = OpenEPDUnit.MPa
161
+
162
+
163
+ class MassKgStr(QuantityStr):
164
+ """Mass quantity type."""
165
+
166
+ unit = OpenEPDUnit.kg
167
+
168
+
169
+ class AreaM2Str(QuantityStr):
170
+ """Area quantity type."""
171
+
172
+ unit = OpenEPDUnit.m2
173
+
174
+
175
+ class LengthMStr(QuantityStr):
176
+ """Length (m) quantity type."""
177
+
178
+ unit = OpenEPDUnit.m
179
+
180
+
181
+ class LengthMmStr(QuantityStr):
182
+ """Length (mm) quantity type."""
183
+
184
+ unit = OpenEPDUnit.m
185
+
186
+ @classmethod
187
+ def __modify_schema__(cls, field_schema):
188
+ field_schema.update(
189
+ examples=["6 mm"],
190
+ )
191
+
192
+
193
+ class LengthInchStr(QuantityStr):
194
+ """Length (inch) quantity type."""
195
+
196
+ unit = OpenEPDUnit.m
197
+
198
+ @classmethod
199
+ def __modify_schema__(cls, field_schema):
200
+ field_schema.update(
201
+ examples=["2.5 inch"],
202
+ )
203
+
204
+
205
+ class TemperatureCStr(QuantityStr):
206
+ """Temperature celsius quantity type."""
207
+
208
+ unit = OpenEPDUnit.degree_c
209
+
210
+
211
+ class GwpKgCo2eStr(QuantityStr):
212
+ """GWP intensity quantity type."""
213
+
214
+ unit = OpenEPDUnit.kg_co2
215
+
216
+
217
+ class RValueStr(QuantityStr):
218
+ """R-Value quantity type."""
219
+
220
+ unit = "K * m2 / W"
221
+
222
+
223
+ class SpeedStr(QuantityStr):
224
+ """Speed quantity type."""
225
+
226
+ unit = "m / s"
227
+
228
+
229
+ class ColorTemperatureStr(QuantityStr):
230
+ """Color temp quantity type."""
231
+
232
+ unit = "K"
233
+
234
+
235
+ class LuminosityStr(QuantityStr):
236
+ """Luminosity quantity type."""
237
+
238
+ unit = "lumen"
239
+
240
+
241
+ class PowerStr(QuantityStr):
242
+ """Power quantity type."""
243
+
244
+ unit = "W"
245
+
246
+
247
+ class ElectricalCurrentStr(QuantityStr):
248
+ """Current quantity type."""
249
+
250
+ unit = "A"
251
+
252
+
253
+ class VolumeStr(QuantityStr):
254
+ """Volume quantity type."""
255
+
256
+ unit = "m3"
257
+
258
+
259
+ class AirflowStr(QuantityStr):
260
+ """Air flow quantity type."""
261
+
262
+ unit = "m3 / s"
263
+
264
+
265
+ class FlowRateStr(QuantityStr):
266
+ """Liquid flow rate quantity type."""
267
+
268
+ unit = "l / min"
269
+
270
+
271
+ class MassPerLengthStr(QuantityStr):
272
+ """Mass per unit of length quantity type."""
273
+
274
+ unit = "kg / m"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: openepd
3
- Version: 3.1.1
3
+ Version: 3.1.3
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
@@ -18,6 +18,7 @@ Classifier: Programming Language :: Python :: 3.11
18
18
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
19
  Provides-Extra: api-client
20
20
  Requires-Dist: email-validator (>=1.3.1)
21
+ Requires-Dist: idna (>=3.7)
21
22
  Requires-Dist: pydantic (>=1.10,<3.0)
22
23
  Requires-Dist: requests (>=2.0) ; extra == "api-client"
23
24
  Project-URL: Repository, https://github.com/cchangelabs/openepd