openepd 4.9.0__py3-none-any.whl → 4.10.1__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.
openepd/__version__.py CHANGED
@@ -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 = "4.9.0"
16
+ VERSION = "4.10.1"
openepd/model/base.py CHANGED
@@ -37,6 +37,7 @@ class OpenEpdDoctypes(StrEnum):
37
37
 
38
38
  Epd = "openEPD"
39
39
  GenericEstimate = "openGenericEstimate"
40
+ IndustryEpd = "openIndustryEpd"
40
41
 
41
42
 
42
43
  def modify_pydantic_schema(schema_dict: dict, cls: type) -> dict:
@@ -17,10 +17,17 @@ import abc
17
17
  import datetime
18
18
 
19
19
  from openepd.compat.pydantic import pyd
20
- from openepd.model.base import RootDocument
20
+ from openepd.model.base import BaseOpenEpdSchema, RootDocument
21
21
  from openepd.model.common import Amount
22
+ from openepd.model.geography import Geography
23
+ from openepd.model.org import Org
22
24
  from openepd.model.pcr import Pcr
23
25
  from openepd.model.standard import Standard
26
+ from openepd.model.validation.common import ReferenceStr
27
+
28
+ DEVELOPER_DESCRIPTION = "The organization responsible for the underlying LCA (and subsequent summarization as EPD)."
29
+ PROGRAM_OPERATOR_DESCRIPTION = "JSON object for program operator Org"
30
+ THIRD_PARTY_VERIFIER_DESCRIPTION = "JSON object for Org that performed a critical review of the EPD data"
24
31
 
25
32
 
26
33
  class BaseDeclaration(RootDocument, abc.ABC):
@@ -50,7 +57,7 @@ class BaseDeclaration(RootDocument, abc.ABC):
50
57
  kg_per_declared_unit: Amount | None = pyd.Field(
51
58
  default=None,
52
59
  description="Mass of the product, in kilograms, per declared unit",
53
- example=Amount(qty=12.5, unit="kg"),
60
+ example=Amount(qty=12.5, unit="kg").to_serializable(exclude_unset=True),
54
61
  )
55
62
  compliance: list[Standard] = pyd.Field(
56
63
  description="Standard(s) to which this document is compliant.", default_factory=list
@@ -111,3 +118,76 @@ class BaseDeclaration(RootDocument, abc.ABC):
111
118
  In the absence of primary data, cleaning assumptions shall be documented.
112
119
  """,
113
120
  )
121
+
122
+
123
+ class AverageDatasetMixin(pyd.BaseModel, title="Average Dataset"):
124
+ """Fields common for average dataset (Industry-wide EPDs, Generic Estimates)."""
125
+
126
+ description: str | None = pyd.Field(
127
+ max_length=2000,
128
+ description="1-paragraph description of the average dataset. Supports plain text or github flavored markdown.",
129
+ )
130
+
131
+ geography: list[Geography] | None = pyd.Field(
132
+ description="Jurisdiction(s) in which the LCA result is applicable. An empty array, or absent properties, "
133
+ "implies global applicability.",
134
+ )
135
+
136
+
137
+ class WithProgramOperatorMixin(pyd.BaseModel):
138
+ """Object which has a connection to ProgramOperator."""
139
+
140
+ program_operator: Org | None = pyd.Field(description=PROGRAM_OPERATOR_DESCRIPTION)
141
+ program_operator_doc_id: str | None = pyd.Field(
142
+ max_length=200, description="Document identifier from Program Operator.", example="123-456.789/b"
143
+ )
144
+ program_operator_version: str | None = pyd.Field(
145
+ max_length=200, description="Document version number from Program Operator.", example="4.3.0"
146
+ )
147
+
148
+
149
+ class WithVerifierMixin(pyd.BaseModel):
150
+ """Set of fields related to verifier."""
151
+
152
+ third_party_verifier: Org | None = pyd.Field(description=THIRD_PARTY_VERIFIER_DESCRIPTION)
153
+ third_party_verification_url: pyd.AnyUrl | None = pyd.Field(
154
+ description="Optional link to a verification statement.",
155
+ example="https://we-verify-epds.com/en/letters/123-456.789b.pdf",
156
+ )
157
+ third_party_verifier_email: pyd.EmailStr | None = pyd.Field(
158
+ description="Email address of the third party verifier", example="john.doe@example.com", default=None
159
+ )
160
+
161
+
162
+ class WithEpdDeveloperMixin(pyd.BaseModel):
163
+ """Set of fields related to EPD Developer."""
164
+
165
+ epd_developer: Org | None = pyd.Field(
166
+ description=DEVELOPER_DESCRIPTION,
167
+ default=None,
168
+ )
169
+ epd_developer_email: pyd.EmailStr | None = pyd.Field(
170
+ default=None,
171
+ example="john.doe@we-do-lca.com",
172
+ description="Email contact for inquiries about development of this EPD. "
173
+ "This must be an email which can be publicly shared.",
174
+ )
175
+
176
+
177
+ class RefBase(BaseOpenEpdSchema, title="Ref Object"):
178
+ """Base class for reference-style objects."""
179
+
180
+ id: str | None = pyd.Field(
181
+ description="The unique ID for this object. To ensure global uniqueness, should be registered at "
182
+ "open-xpd-uuid.cqd.io/register or a coordinating registry.",
183
+ example="1u7zsed8",
184
+ default=None,
185
+ )
186
+
187
+ name: str | None = pyd.Field(max_length=200, description="Name of the object", default=None)
188
+
189
+ ref: ReferenceStr | None = pyd.Field(
190
+ default=None,
191
+ example="https://openepd.buildingtransparency.org/api/generic_estimates/EC300001",
192
+ description="Reference to this JSON object",
193
+ )
openepd/model/epd.py CHANGED
@@ -18,7 +18,15 @@ from typing import Annotated
18
18
  from openepd.compat.pydantic import pyd
19
19
  from openepd.model.base import BaseDocumentFactory, OpenEpdDoctypes
20
20
  from openepd.model.common import Amount, Ingredient, WithAltIdsMixin, WithAttachmentsMixin
21
- from openepd.model.declaration import BaseDeclaration
21
+ from openepd.model.declaration import (
22
+ DEVELOPER_DESCRIPTION,
23
+ PROGRAM_OPERATOR_DESCRIPTION,
24
+ THIRD_PARTY_VERIFIER_DESCRIPTION,
25
+ BaseDeclaration,
26
+ WithEpdDeveloperMixin,
27
+ WithProgramOperatorMixin,
28
+ WithVerifierMixin,
29
+ )
22
30
  from openepd.model.lcia import WithLciaMixin
23
31
  from openepd.model.org import Org, Plant
24
32
  from openepd.model.specs import Specs
@@ -27,12 +35,17 @@ from openepd.model.versioning import OpenEpdVersions, Version
27
35
  MANUFACTURER_DESCRIPTION = (
28
36
  'JSON object for declaring Org. Sometimes called the "Declaration Holder" or "Declaration Owner".'
29
37
  )
30
- DEVELOPER_DESCRIPTION = "The organization responsible for the underlying LCA (and subsequent summarization as EPD)."
31
- PROGRAM_OPERATOR_DESCRIPTION = "JSON object for program operator Org"
32
- THIRD_PARTY_VERIFIER_DESCRIPTION = "JSON object for Org that performed a critical review of the EPD data"
33
38
 
34
39
 
35
- class EpdPreviewV0(WithAttachmentsMixin, WithAltIdsMixin, BaseDeclaration, title="EPD (Preview)"):
40
+ class EpdPreviewV0(
41
+ WithAttachmentsMixin,
42
+ WithProgramOperatorMixin,
43
+ WithEpdDeveloperMixin,
44
+ WithVerifierMixin,
45
+ WithAltIdsMixin,
46
+ BaseDeclaration,
47
+ title="EPD (Preview)",
48
+ ):
36
49
  """
37
50
  EPD preview, used in API list responses and where there is no need for a full object.
38
51
 
@@ -67,36 +80,11 @@ class EpdPreviewV0(WithAttachmentsMixin, WithAltIdsMixin, BaseDeclaration, title
67
80
  example="https://epd-online.com/EmbeddedEpdList/Download/6029",
68
81
  )
69
82
  manufacturer: Org | None = pyd.Field(description=MANUFACTURER_DESCRIPTION)
70
- epd_developer: Org | None = pyd.Field(
71
- description=DEVELOPER_DESCRIPTION,
72
- default=None,
73
- )
74
- epd_developer_email: pyd.EmailStr | None = pyd.Field(
75
- default=None,
76
- example="john.doe@we-do-lca.com",
77
- description="Email contact for inquiries about development of this EPD. "
78
- "This must be an email which can be publicly shared.",
79
- )
80
83
  plants: list[Plant] = pyd.Field(
81
84
  max_items=32,
82
85
  description="List of object(s) for one or more plant(s) that this declaration applies to.",
83
86
  default_factory=list,
84
87
  )
85
- program_operator: Org | None = pyd.Field(description=PROGRAM_OPERATOR_DESCRIPTION)
86
- program_operator_doc_id: str | None = pyd.Field(
87
- max_length=200, description="Document identifier from Program Operator.", example="123-456.789/b"
88
- )
89
- program_operator_version: str | None = pyd.Field(
90
- max_length=200, description="Document version number from Program Operator.", example="4.3.0"
91
- )
92
- third_party_verifier: Org | None = pyd.Field(description=THIRD_PARTY_VERIFIER_DESCRIPTION)
93
- third_party_verification_url: pyd.AnyUrl | None = pyd.Field(
94
- description="Optional link to a verification statement.",
95
- example="https://we-verify-epds.com/en/letters/123-456.789b.pdf",
96
- )
97
- third_party_verifier_email: pyd.EmailStr | None = pyd.Field(
98
- description="Email address of the third party verifier", example="john.doe@example.com", default=None
99
- )
100
88
  kg_C_per_declared_unit: Amount | None = pyd.Field(
101
89
  default=None,
102
90
  description="Mass of elemental carbon, per declared unit, contained in the product itself at the manufacturing "
openepd/model/factory.py CHANGED
@@ -16,6 +16,7 @@
16
16
  from openepd.model.base import BaseDocumentFactory, OpenEpdDoctypes, RootDocument
17
17
  from openepd.model.epd import EpdFactory
18
18
  from openepd.model.generic_estimate import GenericEstimateFactory
19
+ from openepd.model.industry_epd import IndustryEpdFactory
19
20
 
20
21
 
21
22
  class DocumentFactory:
@@ -24,6 +25,7 @@ class DocumentFactory:
24
25
  DOCTYPE_TO_FACTORY: dict[OpenEpdDoctypes, type[BaseDocumentFactory]] = {
25
26
  OpenEpdDoctypes.Epd: EpdFactory,
26
27
  OpenEpdDoctypes.GenericEstimate: GenericEstimateFactory,
28
+ OpenEpdDoctypes.IndustryEpd: IndustryEpdFactory,
27
29
  }
28
30
 
29
31
  @classmethod
@@ -16,13 +16,11 @@
16
16
  from enum import StrEnum
17
17
 
18
18
  from openepd.compat.pydantic import pyd
19
- from openepd.model.base import BaseDocumentFactory, BaseOpenEpdSchema, OpenEpdDoctypes
19
+ from openepd.model.base import BaseDocumentFactory, OpenEpdDoctypes
20
20
  from openepd.model.common import WithAltIdsMixin, WithAttachmentsMixin
21
- from openepd.model.declaration import BaseDeclaration
22
- from openepd.model.geography import Geography
21
+ from openepd.model.declaration import AverageDatasetMixin, BaseDeclaration, RefBase
23
22
  from openepd.model.lcia import WithLciaMixin
24
23
  from openepd.model.org import Org
25
- from openepd.model.validation.common import ReferenceStr
26
24
  from openepd.model.versioning import OpenEpdVersions, Version
27
25
 
28
26
 
@@ -47,27 +45,12 @@ class LicenseTerms(StrEnum):
47
45
  """
48
46
 
49
47
 
50
- class GenericEstimateRef(BaseOpenEpdSchema, title="Generic Estimate (Ref)"):
48
+ class GenericEstimateRef(RefBase, title="Generic Estimate (Ref)"):
51
49
  """Reference (short) version of Generic Estimate object."""
52
50
 
53
- id: str | None = pyd.Field(
54
- description="The unique ID for this document. To ensure global uniqueness, should be registered at "
55
- "open-xpd-uuid.cqd.io/register or a coordinating registry.",
56
- example="1u7zsed8",
57
- default=None,
58
- )
59
-
60
- name: str | None = pyd.Field(max_length=200, description="Name of the generic estimate", default=None)
61
-
62
- ref: ReferenceStr | None = pyd.Field(
63
- default=None,
64
- example="https://openepd.buildingtransparency.org/api/generic_estimates/EC300001",
65
- description="Reference to this GenericEstimate JSON object",
66
- )
67
-
68
51
 
69
52
  class GenericEstimatePreviewV0(
70
- WithAttachmentsMixin, GenericEstimateRef, BaseDeclaration, title="Generic Estimate (preview)"
53
+ WithAttachmentsMixin, AverageDatasetMixin, GenericEstimateRef, BaseDeclaration, title="Generic Estimate (preview)"
71
54
  ):
72
55
  """
73
56
  Generic Estimate preview, used in API list responses and where there is no need for a full object.
@@ -80,20 +63,13 @@ class GenericEstimatePreviewV0(
80
63
  default="openGenericEstimate",
81
64
  )
82
65
 
83
- description: str | None = pyd.Field(
84
- max_length=2000,
85
- description="1-paragraph description of the Generic Estimate. Supports plain text or github flavored markdown.",
86
- )
87
-
88
66
  publisher: Org | None = pyd.Field(description="Organization that published the LCA results.")
67
+ reviewer: Org | None = pyd.Field(description="Org that performed a critical review of the LCA.")
89
68
  reviewer_email: pyd.EmailStr | None = pyd.Field(
90
69
  description="Email address of the third party verifier", example="john.doe@example.com", default=None
91
70
  )
92
- reviewer: Org | None = pyd.Field(description="Org that performed a critical review of the LCA.")
71
+
93
72
  license_terms: LicenseTerms | None = pyd.Field(description="The license terms for use of the data.")
94
- geography: list[Geography] | None = pyd.Field(
95
- "Jurisdiction(s) in which the LCA result is applicable. An empty array, or absent properties, implies global applicability."
96
- )
97
73
  model_repository: pyd.AnyUrl | None = pyd.Field(
98
74
  default=None, description="A link to the shared git repository containing the LCA model used for this estimate."
99
75
  )
@@ -103,13 +79,7 @@ GenericEstimatePreview = GenericEstimatePreviewV0
103
79
 
104
80
 
105
81
  class GenericEstimateV0(GenericEstimatePreviewV0, WithLciaMixin, WithAltIdsMixin, title="Generic Estimate (Full)"):
106
- """
107
- Represent a full Generic Estimate object.
108
-
109
- This is considered the most complete valid openEPD object for GenericEstimate. In addition to it, several related
110
- models are defined, either with fewer fields (to be used in APIs for list requests) or with more relaxed structure
111
- to support related entities matching.
112
- """
82
+ """Full Generic Estimate object."""
113
83
 
114
84
  _FORMAT_VERSION = OpenEpdVersions.Version0.as_str()
115
85
 
@@ -122,10 +92,6 @@ class GenericEstimateWithDepsV0(GenericEstimateV0, title="Generic Estimate (with
122
92
  Expanded version of the GenericEstimate.
123
93
 
124
94
  Contains related entities - orgs - with full fields, to support object matching in implementations.
125
-
126
- For now the implementation matches the above GenericEstimate entity, but they will diverge as normal GE would have
127
- some required fields in Org (like web_domain), and WithDeps would not.
128
-
129
95
  """
130
96
 
131
97
  publisher: Org | None = pyd.Field(description="Organization that published the LCA results.")
@@ -356,6 +356,7 @@ class Geography(StrEnum):
356
356
  See https://unstats.un.org/unsd/methodology/m49/overview/
357
357
 
358
358
  * m49_001: Global
359
+ * m49_003: North America. The continent of North America (numerical code 003) comprises Northern America (numerical code 021), Caribbean (numerical code 029), and Central America (numerical code 013).
359
360
  * m49_002: Africa
360
361
  * m49_015: Northern Africa
361
362
  * m49_202: Sub-Saharan Africa
@@ -957,277 +958,278 @@ class Geography(StrEnum):
957
958
  US_WY = "US-WY"
958
959
 
959
960
  # m49 codification
960
- m49_001 = "001"
961
- m49_002 = "002"
962
- m49_015 = "015"
963
- m49_202 = "202"
964
- m49_019 = "019"
965
- m49_419 = "419"
966
- m49_021 = "021"
967
- m49_142 = "142"
968
- m49_143 = "143"
969
- m49_030 = "030"
970
- m49_035 = "035"
971
- m49_034 = "034"
972
- m49_145 = "145"
973
- m49_150 = "150"
974
- m49_151 = "151"
975
- m49_154 = "154"
976
- m49_039 = "039"
977
- m49_155 = "155"
978
- m49_009 = "009"
979
- m49_053 = "053"
980
- m49_054 = "054"
981
- m49_057 = "057"
982
- m49_061 = "061"
983
- m49_012 = "012"
984
- m49_818 = "818"
985
- m49_434 = "434"
986
- m49_504 = "504"
987
- m49_729 = "729"
988
- m49_788 = "788"
989
- m49_732 = "732"
990
- m49_086 = "086"
991
- m49_108 = "108"
992
- m49_174 = "174"
993
- m49_262 = "262"
994
- m49_232 = "232"
995
- m49_231 = "231"
996
- m49_260 = "260"
997
- m49_404 = "404"
998
- m49_450 = "450"
999
- m49_454 = "454"
1000
- m49_480 = "480"
1001
- m49_175 = "175"
1002
- m49_508 = "508"
1003
- m49_638 = "638"
1004
- m49_646 = "646"
1005
- m49_690 = "690"
1006
- m49_706 = "706"
1007
- m49_728 = "728"
1008
- m49_800 = "800"
1009
- m49_834 = "834"
1010
- m49_894 = "894"
1011
- m49_716 = "716"
1012
- m49_024 = "024"
1013
- m49_120 = "120"
1014
- m49_140 = "140"
1015
- m49_148 = "148"
1016
- m49_178 = "178"
1017
- m49_180 = "180"
1018
- m49_226 = "226"
1019
- m49_266 = "266"
1020
- m49_678 = "678"
1021
- m49_072 = "072"
1022
- m49_748 = "748"
1023
- m49_426 = "426"
1024
- m49_516 = "516"
1025
- m49_710 = "710"
1026
- m49_204 = "204"
1027
- m49_854 = "854"
1028
- m49_132 = "132"
1029
- m49_384 = "384"
1030
- m49_270 = "270"
1031
- m49_288 = "288"
1032
- m49_324 = "324"
1033
- m49_624 = "624"
1034
- m49_430 = "430"
1035
- m49_466 = "466"
1036
- m49_478 = "478"
1037
- m49_562 = "562"
1038
- m49_566 = "566"
1039
- m49_654 = "654"
1040
- m49_686 = "686"
1041
- m49_694 = "694"
1042
- m49_768 = "768"
1043
- m49_660 = "660"
1044
- m49_028 = "028"
1045
- m49_533 = "533"
1046
- m49_044 = "044"
1047
- m49_052 = "052"
1048
- m49_535 = "535"
1049
- m49_092 = "092"
1050
- m49_136 = "136"
1051
- m49_192 = "192"
1052
- m49_531 = "531"
1053
- m49_212 = "212"
1054
- m49_214 = "214"
1055
- m49_308 = "308"
1056
- m49_312 = "312"
1057
- m49_332 = "332"
1058
- m49_388 = "388"
1059
- m49_474 = "474"
1060
- m49_500 = "500"
1061
- m49_630 = "630"
1062
- m49_652 = "652"
1063
- m49_659 = "659"
1064
- m49_662 = "662"
1065
- m49_663 = "663"
1066
- m49_670 = "670"
1067
- m49_534 = "534"
1068
- m49_780 = "780"
1069
- m49_796 = "796"
1070
- m49_850 = "850"
1071
- m49_084 = "084"
1072
- m49_188 = "188"
1073
- m49_222 = "222"
1074
- m49_320 = "320"
1075
- m49_340 = "340"
1076
- m49_484 = "484"
1077
- m49_558 = "558"
1078
- m49_591 = "591"
1079
- m49_032 = "032"
1080
- m49_068 = "068"
1081
- m49_074 = "074"
1082
- m49_076 = "076"
1083
- m49_152 = "152"
1084
- m49_170 = "170"
1085
- m49_218 = "218"
1086
- m49_238 = "238"
1087
- m49_254 = "254"
1088
- m49_328 = "328"
1089
- m49_600 = "600"
1090
- m49_604 = "604"
1091
- m49_239 = "239"
1092
- m49_740 = "740"
1093
- m49_858 = "858"
1094
- m49_862 = "862"
1095
- m49_060 = "060"
1096
- m49_124 = "124"
1097
- m49_304 = "304"
1098
- m49_666 = "666"
1099
- m49_840 = "840"
1100
- m49_010 = "010"
1101
- m49_398 = "398"
1102
- m49_417 = "417"
1103
- m49_762 = "762"
1104
- m49_795 = "795"
1105
- m49_860 = "860"
1106
- m49_156 = "156"
1107
- m49_344 = "344"
1108
- m49_446 = "446"
1109
- m49_408 = "408"
1110
- m49_392 = "392"
1111
- m49_496 = "496"
1112
- m49_410 = "410"
1113
- m49_096 = "096"
1114
- m49_116 = "116"
1115
- m49_360 = "360"
1116
- m49_418 = "418"
1117
- m49_458 = "458"
1118
- m49_104 = "104"
1119
- m49_608 = "608"
1120
- m49_702 = "702"
1121
- m49_764 = "764"
1122
- m49_626 = "626"
1123
- m49_704 = "704"
1124
- m49_004 = "004"
1125
- m49_050 = "050"
1126
- m49_064 = "064"
1127
- m49_356 = "356"
1128
- m49_364 = "364"
1129
- m49_462 = "462"
1130
- m49_524 = "524"
1131
- m49_586 = "586"
1132
- m49_144 = "144"
1133
- m49_051 = "051"
1134
- m49_031 = "031"
1135
- m49_048 = "048"
1136
- m49_196 = "196"
1137
- m49_268 = "268"
1138
- m49_368 = "368"
1139
- m49_376 = "376"
1140
- m49_400 = "400"
1141
- m49_414 = "414"
1142
- m49_422 = "422"
1143
- m49_512 = "512"
1144
- m49_634 = "634"
1145
- m49_682 = "682"
1146
- m49_275 = "275"
1147
- m49_760 = "760"
1148
- m49_792 = "792"
1149
- m49_784 = "784"
1150
- m49_887 = "887"
1151
- m49_112 = "112"
1152
- m49_100 = "100"
1153
- m49_203 = "203"
1154
- m49_348 = "348"
1155
- m49_616 = "616"
1156
- m49_498 = "498"
1157
- m49_642 = "642"
1158
- m49_643 = "643"
1159
- m49_703 = "703"
1160
- m49_804 = "804"
1161
- m49_248 = "248"
1162
- m49_208 = "208"
1163
- m49_233 = "233"
1164
- m49_234 = "234"
1165
- m49_246 = "246"
1166
- m49_831 = "831"
1167
- m49_352 = "352"
1168
- m49_372 = "372"
1169
- m49_833 = "833"
1170
- m49_832 = "832"
1171
- m49_428 = "428"
1172
- m49_440 = "440"
1173
- m49_578 = "578"
1174
- m49_744 = "744"
1175
- m49_752 = "752"
1176
- m49_826 = "826"
1177
- m49_008 = "008"
1178
- m49_020 = "020"
1179
- m49_070 = "070"
1180
- m49_191 = "191"
1181
- m49_292 = "292"
1182
- m49_300 = "300"
1183
- m49_336 = "336"
1184
- m49_380 = "380"
1185
- m49_470 = "470"
1186
- m49_499 = "499"
1187
- m49_807 = "807"
1188
- m49_620 = "620"
1189
- m49_674 = "674"
1190
- m49_688 = "688"
1191
- m49_705 = "705"
1192
- m49_724 = "724"
1193
- m49_040 = "040"
1194
- m49_056 = "056"
1195
- m49_250 = "250"
1196
- m49_276 = "276"
1197
- m49_438 = "438"
1198
- m49_442 = "442"
1199
- m49_492 = "492"
1200
- m49_528 = "528"
1201
- m49_756 = "756"
1202
- m49_036 = "036"
1203
- m49_162 = "162"
1204
- m49_166 = "166"
1205
- m49_334 = "334"
1206
- m49_554 = "554"
1207
- m49_574 = "574"
1208
- m49_242 = "242"
1209
- m49_540 = "540"
1210
- m49_598 = "598"
1211
- m49_090 = "090"
1212
- m49_548 = "548"
1213
- m49_316 = "316"
1214
- m49_296 = "296"
1215
- m49_584 = "584"
1216
- m49_583 = "583"
1217
- m49_520 = "520"
1218
- m49_580 = "580"
1219
- m49_585 = "585"
1220
- m49_581 = "581"
1221
- m49_016 = "016"
1222
- m49_184 = "184"
1223
- m49_258 = "258"
1224
- m49_570 = "570"
1225
- m49_612 = "612"
1226
- m49_882 = "882"
1227
- m49_772 = "772"
1228
- m49_776 = "776"
1229
- m49_798 = "798"
1230
- m49_876 = "876"
961
+ m49_001 = "001" # Global
962
+ m49_003 = "003" # North America. The continent of North America (numerical code 003) comprises Northern America (numerical code 021), Caribbean (numerical code 029), and Central America (numerical code 013).
963
+ m49_002 = "002" # Africa
964
+ m49_015 = "015" # Northern Africa
965
+ m49_202 = "202" # Sub-Saharan Africa
966
+ m49_019 = "019" # Americas
967
+ m49_419 = "419" # Latin America and the Caribbean
968
+ m49_021 = "021" # Northern America
969
+ m49_142 = "142" # Asia
970
+ m49_143 = "143" # Central Asia
971
+ m49_030 = "030" # Eastern Asia
972
+ m49_035 = "035" # South-eastern Asia
973
+ m49_034 = "034" # Southern Asia
974
+ m49_145 = "145" # Western Asia
975
+ m49_150 = "150" # Europe
976
+ m49_151 = "151" # Eastern Europe
977
+ m49_154 = "154" # Northern Europe
978
+ m49_039 = "039" # Southern Europe
979
+ m49_155 = "155" # Western Europe
980
+ m49_009 = "009" # Oceania
981
+ m49_053 = "053" # Australia and New Zealand
982
+ m49_054 = "054" # Melanesia
983
+ m49_057 = "057" # Micronesia
984
+ m49_061 = "061" # Polynesia
985
+ m49_012 = "012" # Algeria
986
+ m49_818 = "818" # Egypt
987
+ m49_434 = "434" # Libya
988
+ m49_504 = "504" # Morocco
989
+ m49_729 = "729" # Sudan
990
+ m49_788 = "788" # Tunisia
991
+ m49_732 = "732" # Western Sahara
992
+ m49_086 = "086" # British Indian Ocean Territory
993
+ m49_108 = "108" # Burundi
994
+ m49_174 = "174" # Comoros
995
+ m49_262 = "262" # Djibouti
996
+ m49_232 = "232" # Eritrea
997
+ m49_231 = "231" # Ethiopia
998
+ m49_260 = "260" # French Southern Territories
999
+ m49_404 = "404" # Kenya
1000
+ m49_450 = "450" # Madagascar
1001
+ m49_454 = "454" # Malawi
1002
+ m49_480 = "480" # Mauritius
1003
+ m49_175 = "175" # Mayotte
1004
+ m49_508 = "508" # Mozambique
1005
+ m49_638 = "638" # Réunion
1006
+ m49_646 = "646" # Rwanda
1007
+ m49_690 = "690" # Seychelles
1008
+ m49_706 = "706" # Somalia
1009
+ m49_728 = "728" # South Sudan
1010
+ m49_800 = "800" # Uganda
1011
+ m49_834 = "834" # United Republic of Tanzania
1012
+ m49_894 = "894" # Zambia
1013
+ m49_716 = "716" # Zimbabwe
1014
+ m49_024 = "024" # Angola
1015
+ m49_120 = "120" # Cameroon
1016
+ m49_140 = "140" # Central African Republic
1017
+ m49_148 = "148" # Chad
1018
+ m49_178 = "178" # Congo
1019
+ m49_180 = "180" # Democratic Republic of the Congo
1020
+ m49_226 = "226" # Equatorial Guinea
1021
+ m49_266 = "266" # Gabon
1022
+ m49_678 = "678" # Sao Tome and Principe
1023
+ m49_072 = "072" # Botswana
1024
+ m49_748 = "748" # Eswatini
1025
+ m49_426 = "426" # Lesotho
1026
+ m49_516 = "516" # Namibia
1027
+ m49_710 = "710" # South Africa
1028
+ m49_204 = "204" # Benin
1029
+ m49_854 = "854" # Burkina Faso
1030
+ m49_132 = "132" # Cabo Verde
1031
+ m49_384 = "384" # Côte d’Ivoire
1032
+ m49_270 = "270" # Gambia
1033
+ m49_288 = "288" # Ghana
1034
+ m49_324 = "324" # Guinea
1035
+ m49_624 = "624" # Guinea-Bissau
1036
+ m49_430 = "430" # Liberia
1037
+ m49_466 = "466" # Mali
1038
+ m49_478 = "478" # Mauritania
1039
+ m49_562 = "562" # Niger
1040
+ m49_566 = "566" # Nigeria
1041
+ m49_654 = "654" # Saint Helena
1042
+ m49_686 = "686" # Senegal
1043
+ m49_694 = "694" # Sierra Leone
1044
+ m49_768 = "768" # Togo
1045
+ m49_660 = "660" # Anguilla
1046
+ m49_028 = "028" # Antigua and Barbuda
1047
+ m49_533 = "533" # Aruba
1048
+ m49_044 = "044" # Bahamas
1049
+ m49_052 = "052" # Barbados
1050
+ m49_535 = "535" # Bonaire, Sint Eustatius and Saba
1051
+ m49_092 = "092" # British Virgin Islands
1052
+ m49_136 = "136" # Cayman Islands
1053
+ m49_192 = "192" # Cuba
1054
+ m49_531 = "531" # Curaçao
1055
+ m49_212 = "212" # Dominica
1056
+ m49_214 = "214" # Dominican Republic
1057
+ m49_308 = "308" # Grenada
1058
+ m49_312 = "312" # Guadeloupe
1059
+ m49_332 = "332" # Haiti
1060
+ m49_388 = "388" # Jamaica
1061
+ m49_474 = "474" # Martinique
1062
+ m49_500 = "500" # Montserrat
1063
+ m49_630 = "630" # Puerto Rico
1064
+ m49_652 = "652" # Saint Barthélemy
1065
+ m49_659 = "659" # Saint Kitts and Nevis
1066
+ m49_662 = "662" # Saint Lucia
1067
+ m49_663 = "663" # Saint Martin (French Part)
1068
+ m49_670 = "670" # Saint Vincent and the Grenadines
1069
+ m49_534 = "534" # Sint Maarten (Dutch part)
1070
+ m49_780 = "780" # Trinidad and Tobago
1071
+ m49_796 = "796" # Turks and Caicos Islands
1072
+ m49_850 = "850" # United States Virgin Islands
1073
+ m49_084 = "084" # Belize
1074
+ m49_188 = "188" # Costa Rica
1075
+ m49_222 = "222" # El Salvador
1076
+ m49_320 = "320" # Guatemala
1077
+ m49_340 = "340" # Honduras
1078
+ m49_484 = "484" # Mexico
1079
+ m49_558 = "558" # Nicaragua
1080
+ m49_591 = "591" # Panama
1081
+ m49_032 = "032" # Argentina
1082
+ m49_068 = "068" # Bolivia (Plurinational State of)
1083
+ m49_074 = "074" # Bouvet Island
1084
+ m49_076 = "076" # Brazil
1085
+ m49_152 = "152" # Chile
1086
+ m49_170 = "170" # Colombia
1087
+ m49_218 = "218" # Ecuador
1088
+ m49_238 = "238" # Falkland Islands (Malvinas)
1089
+ m49_254 = "254" # French Guiana
1090
+ m49_328 = "328" # Guyana
1091
+ m49_600 = "600" # Paraguay
1092
+ m49_604 = "604" # Peru
1093
+ m49_239 = "239" # South Georgia and the South Sandwich Islands
1094
+ m49_740 = "740" # Suriname
1095
+ m49_858 = "858" # Uruguay
1096
+ m49_862 = "862" # Venezuela (Bolivarian Republic of)
1097
+ m49_060 = "060" # Bermuda
1098
+ m49_124 = "124" # Canada
1099
+ m49_304 = "304" # Greenland
1100
+ m49_666 = "666" # Saint Pierre and Miquelon
1101
+ m49_840 = "840" # United States of America
1102
+ m49_010 = "010" # Antarctica
1103
+ m49_398 = "398" # Kazakhstan
1104
+ m49_417 = "417" # Kyrgyzstan
1105
+ m49_762 = "762" # Tajikistan
1106
+ m49_795 = "795" # Turkmenistan
1107
+ m49_860 = "860" # Uzbekistan
1108
+ m49_156 = "156" # China
1109
+ m49_344 = "344" # China, Hong Kong Special Administrative Region
1110
+ m49_446 = "446" # China, Macao Special Administrative Region
1111
+ m49_408 = "408" # Democratic People's Republic of Korea
1112
+ m49_392 = "392" # Japan
1113
+ m49_496 = "496" # Mongolia
1114
+ m49_410 = "410" # Republic of Korea
1115
+ m49_096 = "096" # Brunei Darussalam
1116
+ m49_116 = "116" # Cambodia
1117
+ m49_360 = "360" # Indonesia
1118
+ m49_418 = "418" # Lao People's Democratic Republic
1119
+ m49_458 = "458" # Malaysia
1120
+ m49_104 = "104" # Myanmar
1121
+ m49_608 = "608" # Philippines
1122
+ m49_702 = "702" # Singapore
1123
+ m49_764 = "764" # Thailand
1124
+ m49_626 = "626" # Timor-Leste
1125
+ m49_704 = "704" # Viet Nam
1126
+ m49_004 = "004" # Afghanistan
1127
+ m49_050 = "050" # Bangladesh
1128
+ m49_064 = "064" # Bhutan
1129
+ m49_356 = "356" # India
1130
+ m49_364 = "364" # Iran (Islamic Republic of)
1131
+ m49_462 = "462" # Maldives
1132
+ m49_524 = "524" # Nepal
1133
+ m49_586 = "586" # Pakistan
1134
+ m49_144 = "144" # Sri Lanka
1135
+ m49_051 = "051" # Armenia
1136
+ m49_031 = "031" # Azerbaijan
1137
+ m49_048 = "048" # Bahrain
1138
+ m49_196 = "196" # Cyprus
1139
+ m49_268 = "268" # Georgia
1140
+ m49_368 = "368" # Iraq
1141
+ m49_376 = "376" # Israel
1142
+ m49_400 = "400" # Jordan
1143
+ m49_414 = "414" # Kuwait
1144
+ m49_422 = "422" # Lebanon
1145
+ m49_512 = "512" # Oman
1146
+ m49_634 = "634" # Qatar
1147
+ m49_682 = "682" # Saudi Arabia
1148
+ m49_275 = "275" # State of Palestine
1149
+ m49_760 = "760" # Syrian Arab Republic
1150
+ m49_792 = "792" # Türkiye
1151
+ m49_784 = "784" # United Arab Emirates
1152
+ m49_887 = "887" # Yemen
1153
+ m49_112 = "112" # Belarus
1154
+ m49_100 = "100" # Bulgaria
1155
+ m49_203 = "203" # Czechia
1156
+ m49_348 = "348" # Hungary
1157
+ m49_616 = "616" # Poland
1158
+ m49_498 = "498" # Republic of Moldova
1159
+ m49_642 = "642" # Romania
1160
+ m49_643 = "643" # Russian Federation
1161
+ m49_703 = "703" # Slovakia
1162
+ m49_804 = "804" # Ukraine
1163
+ m49_248 = "248" # Åland Islands
1164
+ m49_208 = "208" # Denmark
1165
+ m49_233 = "233" # Estonia
1166
+ m49_234 = "234" # Faroe Islands
1167
+ m49_246 = "246" # Finland
1168
+ m49_831 = "831" # Guernsey
1169
+ m49_352 = "352" # Iceland
1170
+ m49_372 = "372" # Ireland
1171
+ m49_833 = "833" # Isle of Man
1172
+ m49_832 = "832" # Jersey
1173
+ m49_428 = "428" # Latvia
1174
+ m49_440 = "440" # Lithuania
1175
+ m49_578 = "578" # Norway
1176
+ m49_744 = "744" # Svalbard and Jan Mayen Islands
1177
+ m49_752 = "752" # Sweden
1178
+ m49_826 = "826" # United Kingdom of Great Britain and Northern Ireland
1179
+ m49_008 = "008" # Albania
1180
+ m49_020 = "020" # Andorra
1181
+ m49_070 = "070" # Bosnia and Herzegovina
1182
+ m49_191 = "191" # Croatia
1183
+ m49_292 = "292" # Gibraltar
1184
+ m49_300 = "300" # Greece
1185
+ m49_336 = "336" # Holy See
1186
+ m49_380 = "380" # Italy
1187
+ m49_470 = "470" # Malta
1188
+ m49_499 = "499" # Montenegro
1189
+ m49_807 = "807" # North Macedonia
1190
+ m49_620 = "620" # Portugal
1191
+ m49_674 = "674" # San Marino
1192
+ m49_688 = "688" # Serbia
1193
+ m49_705 = "705" # Slovenia
1194
+ m49_724 = "724" # Spain
1195
+ m49_040 = "040" # Austria
1196
+ m49_056 = "056" # Belgium
1197
+ m49_250 = "250" # France
1198
+ m49_276 = "276" # Germany
1199
+ m49_438 = "438" # Liechtenstein
1200
+ m49_442 = "442" # Luxembourg
1201
+ m49_492 = "492" # Monaco
1202
+ m49_528 = "528" # Netherlands (Kingdom of the)
1203
+ m49_756 = "756" # Switzerland
1204
+ m49_036 = "036" # Australia
1205
+ m49_162 = "162" # Christmas Island
1206
+ m49_166 = "166" # Cocos (Keeling) Islands
1207
+ m49_334 = "334" # Heard Island and McDonald Islands
1208
+ m49_554 = "554" # New Zealand
1209
+ m49_574 = "574" # Norfolk Island
1210
+ m49_242 = "242" # Fiji
1211
+ m49_540 = "540" # New Caledonia
1212
+ m49_598 = "598" # Papua New Guinea
1213
+ m49_090 = "090" # Solomon Islands
1214
+ m49_548 = "548" # Vanuatu
1215
+ m49_316 = "316" # Guam
1216
+ m49_296 = "296" # Kiribati
1217
+ m49_584 = "584" # Marshall Islands
1218
+ m49_583 = "583" # Micronesia (Federated States of)
1219
+ m49_520 = "520" # Nauru
1220
+ m49_580 = "580" # Northern Mariana Islands
1221
+ m49_585 = "585" # Palau
1222
+ m49_581 = "581" # United States Minor Outlying Islands
1223
+ m49_016 = "016" # American Samoa
1224
+ m49_184 = "184" # Cook Islands
1225
+ m49_258 = "258" # French Polynesia
1226
+ m49_570 = "570" # Niue
1227
+ m49_612 = "612" # Pitcairn
1228
+ m49_882 = "882" # Samoa
1229
+ m49_772 = "772" # Tokelau
1230
+ m49_776 = "776" # Tonga
1231
+ m49_798 = "798" # Tuvalu
1232
+ m49_876 = "876" # Wallis and Futuna Islands
1231
1233
 
1232
1234
 
1233
1235
  class Country(StrEnum):
@@ -0,0 +1,98 @@
1
+ #
2
+ # Copyright 2024 by C Change Labs Inc. www.c-change-labs.com
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+ from openepd.compat.pydantic import pyd
17
+ from openepd.model.base import BaseDocumentFactory, OpenEpdDoctypes
18
+ from openepd.model.common import WithAltIdsMixin, WithAttachmentsMixin
19
+ from openepd.model.declaration import (
20
+ AverageDatasetMixin,
21
+ BaseDeclaration,
22
+ RefBase,
23
+ WithEpdDeveloperMixin,
24
+ WithProgramOperatorMixin,
25
+ WithVerifierMixin,
26
+ )
27
+ from openepd.model.lcia import WithLciaMixin
28
+ from openepd.model.org import Org
29
+ from openepd.model.versioning import OpenEpdVersions, Version
30
+
31
+
32
+ class IndustryEpdRef(RefBase, title="Industry EPD (Ref)"):
33
+ """Reference (short) version of Industry average EPD object."""
34
+
35
+
36
+ class IndustryEpdPreviewV0(
37
+ WithAttachmentsMixin,
38
+ AverageDatasetMixin,
39
+ WithEpdDeveloperMixin,
40
+ WithVerifierMixin,
41
+ WithProgramOperatorMixin,
42
+ IndustryEpdRef,
43
+ BaseDeclaration,
44
+ title="Industry EPD (preview)",
45
+ ):
46
+ """
47
+ Industry EPD Preview object.
48
+
49
+ Used in lists and other cases where full LCIA data is not required.
50
+ """
51
+
52
+ doctype: str = pyd.Field(
53
+ description='Describes the type and schema of the document. Must always be "openIndustryEpd"',
54
+ default="openIndustryEpd",
55
+ )
56
+
57
+ publishers: list[Org] | None = pyd.Field(description="")
58
+ manufacturers: list[Org] | None = pyd.Field(description="Participating manufacturers")
59
+
60
+
61
+ IndustryEpdPreview = IndustryEpdPreviewV0
62
+
63
+
64
+ class IndustryEpdV0(IndustryEpdPreviewV0, WithLciaMixin, WithAltIdsMixin, title="Industry EPD (Full)"):
65
+ """
66
+ Full Industry EPD object.
67
+
68
+ This is considered the most complete valid openEPD object for IndustryEpd. In addition to it, several related
69
+ models are defined, either with fewer fields (to be used in APIs for list requests) or with more relaxed structure
70
+ to support related entities matching.
71
+ """
72
+
73
+ _FORMAT_VERSION = OpenEpdVersions.Version0.as_str()
74
+
75
+
76
+ IndustryEpd = IndustryEpdV0
77
+
78
+
79
+ class IndustryEpdWithDepsV0(IndustryEpdV0, title="Industry EPD (with Dependencies)"):
80
+ """
81
+ Expanded version of the IndustryEpd.
82
+
83
+ Contains related entities - orgs - with full fields, to support object matching in implementations.
84
+
85
+ For now the implementation matches the above Industry Epd entity, but they will diverge as normal GE would have
86
+ some required fields in Org (like web_domain), and WithDeps would not.
87
+
88
+ """
89
+
90
+
91
+ IndustryEpdWithDeps = IndustryEpdWithDepsV0
92
+
93
+
94
+ class IndustryEpdFactory(BaseDocumentFactory[IndustryEpd]):
95
+ """Factory for EPD objects."""
96
+
97
+ DOCTYPE_CONSTRAINT = OpenEpdDoctypes.IndustryEpd
98
+ VERSION_MAP: dict[Version, type[IndustryEpd]] = {OpenEpdVersions.Version0: IndustryEpdV0}
openepd/model/lcia.py CHANGED
@@ -322,6 +322,16 @@ class LCIAMethod(StrEnum):
322
322
  class Impacts(pyd.BaseModel):
323
323
  """List of environmental impacts, compiled per one of the standard Impact Assessment methods."""
324
324
 
325
+ class Config:
326
+ # pydantic schema generator gets lost in this structure, so we need to re-establish it manually for openapi
327
+ schema_extra = {
328
+ "properties": {
329
+ str(lm): {"description": str(lm), "allOf": [{"$ref": "#/components/schemas/ImpactSet"}]}
330
+ for lm in LCIAMethod
331
+ },
332
+ "additionalProperties": None,
333
+ }
334
+
325
335
  __root__: dict[LCIAMethod, ImpactSet]
326
336
 
327
337
  def set_unknown_lcia(self, impact_set: ImpactSet):
@@ -16,6 +16,7 @@
16
16
  from openepd.compat.pydantic import pyd
17
17
  from openepd.model.specs.base import BaseOpenEpdHierarchicalSpec
18
18
  from openepd.model.specs.generated.enums import CableTraysMaterial, EnergySource, RacewaysMaterial
19
+ from openepd.model.specs.generated.mixins.conduit_mixin import ConduitMixin
19
20
  from openepd.model.validation.quantity import (
20
21
  ColorTemperatureStr,
21
22
  LengthMmStr,
@@ -290,10 +291,10 @@ class LightingV1(BaseOpenEpdHierarchicalSpec):
290
291
  TaskLighting: TaskLightingV1 | None = None
291
292
 
292
293
 
293
- class ElectricalConduitV1(BaseOpenEpdHierarchicalSpec):
294
+ class ElectricalConduitV1(BaseOpenEpdHierarchicalSpec, ConduitMixin):
294
295
  """Tubing used to protect and route electrical wiring in a building or structure."""
295
296
 
296
- _EXT_VERSION = "1.0"
297
+ _EXT_VERSION = "1.1"
297
298
 
298
299
 
299
300
  class ElectricalV1(BaseOpenEpdHierarchicalSpec):
@@ -2491,3 +2491,27 @@ class PlasterComposition(StrEnum):
2491
2491
  ACRYLIC = "Acrylic"
2492
2492
  LIME = "Lime"
2493
2493
  OTHER = "Other"
2494
+
2495
+
2496
+ class ConduitMaterial(StrEnum):
2497
+ """
2498
+ Material of the conduit.
2499
+
2500
+ - PVC: Polyvinyl chloride piping
2501
+ - PEX: Cross-linked polethylene piping
2502
+ - HDPE: High density polyethylene piping
2503
+ - PP: Polypropylene
2504
+ - Stainless Steel: Stainless steel conduit
2505
+ - Galvanized Steel: Galvanized steel conduit
2506
+ - Aluminum: Aluminum conduit
2507
+ - Other: Other piping material
2508
+ """
2509
+
2510
+ PVC = "PVC"
2511
+ PEX = "PEX"
2512
+ HDPE = "HDPE"
2513
+ PP = "PP"
2514
+ STAINLESS_STEEL = "Stainless Steel"
2515
+ GALVANIZED_STEEL = "Galvanized Steel"
2516
+ ALUMINUM = "Aluminum"
2517
+ OTHER = "Other"
@@ -0,0 +1,15 @@
1
+ #
2
+ # Copyright 2024 by C Change Labs Inc. www.c-change-labs.com
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
@@ -0,0 +1,50 @@
1
+ #
2
+ # Copyright 2024 by C Change Labs Inc. www.c-change-labs.com
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+ __all__ = ["ConduitMixin"]
17
+
18
+ from openepd.compat.pydantic import pyd
19
+ from openepd.model.specs.base import BaseOpenEpdSpec
20
+ from openepd.model.specs.generated.enums import ConduitMaterial
21
+ from openepd.model.validation.quantity import LengthMmStr
22
+
23
+
24
+ class ConduitMixin(BaseOpenEpdSpec):
25
+ """
26
+ Properties of a conduit.
27
+
28
+ Those properties are the same for communication and electrical conduits.
29
+ """
30
+
31
+ nominal_diameter: LengthMmStr | None = pyd.Field(
32
+ default=None,
33
+ description="Nominal Diameter is also known as the mean or average outside diameter.",
34
+ example="100 mm",
35
+ )
36
+ outer_diameter: LengthMmStr | None = pyd.Field(
37
+ default=None,
38
+ description="The measurement of the distance of a straight line between points on the outer walls of the pipe.",
39
+ example="100 mm",
40
+ )
41
+ inner_diameter: LengthMmStr | None = pyd.Field(
42
+ default=None,
43
+ description="The measurement of the distance of a straight line between points on the inner walls of the pipe.",
44
+ example="100 mm",
45
+ )
46
+ wall_thickness: LengthMmStr | None = pyd.Field(
47
+ default=None, description="Conduit wall thickness.", example="100 mm"
48
+ )
49
+
50
+ material: ConduitMaterial | None = pyd.Field(default=None, description="Material of the conduit.", example="PVC")
@@ -27,6 +27,7 @@ from openepd.model.specs.generated.enums import (
27
27
  RacewaysMaterial,
28
28
  RackType,
29
29
  )
30
+ from openepd.model.specs.generated.mixins.conduit_mixin import ConduitMixin
30
31
  from openepd.model.validation.quantity import ElectricalCurrentStr, LengthMmStr, MassKgStr, validate_unit_factory
31
32
 
32
33
 
@@ -166,10 +167,10 @@ class NetworkingRacewaysV1(BaseOpenEpdHierarchicalSpec):
166
167
  raceways_material: RacewaysMaterial | None = pyd.Field(default=None, description="", example="Aluminum")
167
168
 
168
169
 
169
- class CommunicationsConduitV1(BaseOpenEpdHierarchicalSpec):
170
+ class CommunicationsConduitV1(BaseOpenEpdHierarchicalSpec, ConduitMixin):
170
171
  """Tubing used to protect and route communications wiring in a building or structure."""
171
172
 
172
- _EXT_VERSION = "1.0"
173
+ _EXT_VERSION = "1.1"
173
174
 
174
175
 
175
176
  class NetworkInfrastructureV1(BaseOpenEpdHierarchicalSpec):
@@ -243,7 +243,10 @@ class SteelV1(BaseOpenEpdHierarchicalSpec):
243
243
 
244
244
  # Own fields:
245
245
  yield_tensile_str: PressureMPaStr | None = pyd.Field(
246
- default=None, description="Yield Tensile strength (Mpa) per unit area", example="100 MPa"
246
+ default=None,
247
+ description="Yield Tensile strength (Mpa) per unit area. Yield strength is the point at which a material "
248
+ "begins to permanently deform or change shape due to applied stress.",
249
+ example="100 MPa",
247
250
  )
248
251
  bar_elongation: float | None = pyd.Field(
249
252
  default=None, description="Increase in length at break, in percent. Typically 10%-20%", example=0.2
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: openepd
3
- Version: 4.9.0
3
+ Version: 4.10.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,5 +1,5 @@
1
1
  openepd/__init__.py,sha256=Shkfh0Kun0YRhmRDw7LkUj2eQL3X-HnP55u2THOEALw,794
2
- openepd/__version__.py,sha256=A3iFx_kUtK0dkVs7itV9wiL0foJSKpYp8kZwKq3fk2I,638
2
+ openepd/__version__.py,sha256=KzFp1gnpC3_rR0ckYMYd34Zk_3-GVjuHpo3hjsuUjP4,639
3
3
  openepd/api/__init__.py,sha256=UGmZGEyMnASrYwEBPHuXmVzHiuCUskUsJEPoHTIo-lg,620
4
4
  openepd/api/base_sync_client.py,sha256=jviqtQgsOVdRq5x7_Yh_Tg8zIdWtVTIUqNCgebf6YDg,20925
5
5
  openepd/api/category/__init__.py,sha256=UGmZGEyMnASrYwEBPHuXmVzHiuCUskUsJEPoHTIo-lg,620
@@ -30,15 +30,16 @@ openepd/compat/__init__.py,sha256=UGmZGEyMnASrYwEBPHuXmVzHiuCUskUsJEPoHTIo-lg,62
30
30
  openepd/compat/compat_functional_validators.py,sha256=yz6DfWeg7knBHEN_enpCGGTLRknEsecXfpzD1FDlywY,834
31
31
  openepd/compat/pydantic.py,sha256=DOjSixsylLqMtFAIARu50sGcT4VPXN_c473q_2JwZQ0,1146
32
32
  openepd/model/__init__.py,sha256=UGmZGEyMnASrYwEBPHuXmVzHiuCUskUsJEPoHTIo-lg,620
33
- openepd/model/base.py,sha256=Uy2Fh7Z9nPzrXrOn2aHPoJjktQfVOQ7UBCXiATkPfEQ,9008
33
+ openepd/model/base.py,sha256=o6miTbb4d2BRQ6epN5Jn8mIMkAeoAucd_3op7aEMELc,9044
34
34
  openepd/model/category.py,sha256=IQXNGQFQmFZ_H9PRONloX_UOSf1sTMDq1rM1yz8JR0Y,1639
35
35
  openepd/model/common.py,sha256=aa_bfotPybPoYyzHtwj5E5X1T-fCEyznMfVUWvpUhiM,5460
36
- openepd/model/declaration.py,sha256=5mzX24KpsezqBuGFAr-InsgB4FFNqI7HPJeDHQ93ZCI,5322
37
- openepd/model/epd.py,sha256=bhmPNWQQ28uhaoxE7sW8_mxyswSCEvGovQ2tH69jzUo,10324
38
- openepd/model/factory.py,sha256=StQUH7GNmRqskMnnRYkr_PLCl5X5sSLEPiYZOIQI9eo,2541
39
- openepd/model/generic_estimate.py,sha256=cAgZDiYjqNaGXKc6fR8o9380zqgQMB38F0YTQJo__Lo,5508
40
- openepd/model/geography.py,sha256=OngHXz-Dkg-NrVPIwNPP53xu4-HkQ_fnEfX5fYIVEfA,37417
41
- openepd/model/lcia.py,sha256=sDZIxyggqHIISCUocgvIEgkmqPLGNSEA3-zUd7TEgsw,18430
36
+ openepd/model/declaration.py,sha256=w-wC5G8QmO8JxnUyMKfrKARer3VIMbs_vQr3SP_BdCE,8638
37
+ openepd/model/epd.py,sha256=RtUeDq1869JJe5fUu-aP31jl_HRAO21NXcLQvRYmQLs,9030
38
+ openepd/model/factory.py,sha256=XP7eeQNW5tqwX_4hfuEb3lK6BFQDb4KB0fSN0r8-lCU,2656
39
+ openepd/model/generic_estimate.py,sha256=0bS3IXJliheYLBhN6aeSpe-rkKYFCegvwUiBzElCLC0,3938
40
+ openepd/model/geography.py,sha256=G3Oz3QBw5n-RiSCAv-vAGxrOZBhwIT5rASnPlo9dkcs,42095
41
+ openepd/model/industry_epd.py,sha256=t6s9JrfHJVJo_egQt6RdyE9u3t8rZi32efM-MoaV8ag,3234
42
+ openepd/model/lcia.py,sha256=bnDVsEo429Go_EneVOkXYIxDu2soxrgxyfzU4OhDR3Q,18827
42
43
  openepd/model/org.py,sha256=FHcYh2WOOQrCMyzm0Ow-iP79jMTBPcneidjH6NXIklA,3760
43
44
  openepd/model/pcr.py,sha256=SwqLWMj9k_jqIzxz5mh6ttqvtLCspKSpywF5YTBOMsA,5397
44
45
  openepd/model/specs/README.md,sha256=W5LSMpZuW5x36cKS4HRfeFsClsRf8J9yHMMICghdc0s,862
@@ -58,10 +59,10 @@ openepd/model/specs/generated/cmu.py,sha256=Vv-aiT4Q7Zl5XTkSCnTeGOpE_ufTy63zt2Z5
58
59
  openepd/model/specs/generated/common.py,sha256=iNeJmVYZURVQWewx3zskwnwy7DBuaggCHFWQBThtY2A,1048
59
60
  openepd/model/specs/generated/concrete.py,sha256=wnR656XxF6b26aBP4TRijMJf5CdLUzbZtSLXsbE3Yxw,6987
60
61
  openepd/model/specs/generated/conveying_equipment.py,sha256=sQSnFccpTIw8sNGywW0KajE1lCHzbVBCISKyrYFW02U,3052
61
- openepd/model/specs/generated/electrical.py,sha256=571-26lGYG3z5ecmZyxawxO70USatWSzn7_vEXeVAE0,10985
62
+ openepd/model/specs/generated/electrical.py,sha256=kM9lkNq4762VHUesWBPQ7P9RqMELxaaFH6yzZCEgUhA,11075
62
63
  openepd/model/specs/generated/electrical_transmission_and_distribution_equipment.py,sha256=h6UQixACOHrquhQ2GFqqYWel_zqOXT-vAkI0o_RLf0A,1978
63
64
  openepd/model/specs/generated/electricity.py,sha256=iGtN21K1MRVwoRfO6friVgiXc2b6cVdITbvnXqLmW3k,823
64
- openepd/model/specs/generated/enums.py,sha256=9JA9hay6s76kStmcAvpmF8NLgsYZA3IkNMRh-TMK2qY,60938
65
+ openepd/model/specs/generated/enums.py,sha256=DD9eQbkSVkV4b8F10rn6_2k8Sn8H01mZmZX5aBnPtuc,61524
65
66
  openepd/model/specs/generated/finishes.py,sha256=Sq_jh3xnPlvLAiS6z7AIvWXIz31_bzW4SM_auXSxALE,22421
66
67
  openepd/model/specs/generated/fire_and_smoke_protection.py,sha256=zkOlnNCnAZ9MUWk2sDqUX14YxNEDU3MGfUlePG3su0Q,3068
67
68
  openepd/model/specs/generated/furnishings.py,sha256=QY_FDsFZaqjCiw2xHsD3kmyBGJA7jCHlSIvaw4TmqXI,2581
@@ -71,14 +72,16 @@ openepd/model/specs/generated/masonry.py,sha256=35yUySGoRCApdZSYWbCjZ_rTR7WRPssz
71
72
  openepd/model/specs/generated/material_handling.py,sha256=hx8fisNcFw6GXC7uMfW-4wkGUS8xJA9gTk_WpZGHkqY,1274
72
73
  openepd/model/specs/generated/mechanical.py,sha256=qRKvOqRqn2DoyTCOnNwHClyoby0pa4YN8vXuE6CtY8A,9872
73
74
  openepd/model/specs/generated/mechanical_insulation.py,sha256=sbXTXT4xOOgvyDeLN4HZ3xCIwKkaPEjoQlRyCrq4tlM,1617
74
- openepd/model/specs/generated/network_infrastructure.py,sha256=C4y2PKvC-0QXNDz5qFUgMMcK3n8b_9GsLotSWBDaxms,8403
75
+ openepd/model/specs/generated/mixins/__init__.py,sha256=UGmZGEyMnASrYwEBPHuXmVzHiuCUskUsJEPoHTIo-lg,620
76
+ openepd/model/specs/generated/mixins/conduit_mixin.py,sha256=ONH8wZ19xqnIDH-mbRpa4m00LqkYVwdr6-tuSR7TgHE,1938
77
+ openepd/model/specs/generated/network_infrastructure.py,sha256=k1sW_STLQZd9S-f687_KYeBLaPAnsCiyBxMeuvEycb4,8493
75
78
  openepd/model/specs/generated/openings.py,sha256=cpJr0Qk9FTLktM5hQAOsPBFL36CRP2sKpe_1v1EOVG4,18818
76
79
  openepd/model/specs/generated/other_electrical_equipment.py,sha256=HUOI_NfCXn_pmon0KEy11hBrILA5QYtpnme0YqWoEfk,814
77
80
  openepd/model/specs/generated/other_materials.py,sha256=ztaZHOr2HbiSpKdz4M1b2jsm_11fMDqZduEYWT1Q_rI,3498
78
81
  openepd/model/specs/generated/plumbing.py,sha256=2bd5K2V0BspEfymb_47nYzdP-6OpBgaRc4Oul8OS8jo,4578
79
82
  openepd/model/specs/generated/precast_concrete.py,sha256=Qwnm49sCXXmPoIckIUwldDvUq760FzTVaYnFOV6XOEY,7327
80
83
  openepd/model/specs/generated/sheathing.py,sha256=06Y9Dy7_9Iy3VfA6fQGr6AUq30u1K_4cIQOe36BCiOs,3636
81
- openepd/model/specs/generated/steel.py,sha256=nqkGivvAg5rll2NhClhKE6UCORsvPaVgHiuhirKP3Js,9901
84
+ openepd/model/specs/generated/steel.py,sha256=k-zb_3DkS6SOY4B9nqRGLnVOrc69PttOPZjrDnqR9eM,10046
82
85
  openepd/model/specs/generated/thermal_moisture_protection.py,sha256=px1GPZyumr1w0r0ikKO1FefHNK66cxYp1PpmZvpTzPU,8205
83
86
  openepd/model/specs/generated/utility_piping.py,sha256=X0cHq5kQP41RH1iGWrkwUdFX0PI4V00WzxH9BA-i7SY,2493
84
87
  openepd/model/specs/generated/wood.py,sha256=RMNoPRS9K3XF2aXCbvRN3awpO23_5ugYhRCrnvCvI20,6341
@@ -91,7 +94,7 @@ openepd/model/validation/quantity.py,sha256=kzug0MZ3Ao0zeVzN-aleyxUg5hA_7D5tNOOe
91
94
  openepd/model/versioning.py,sha256=R_zm6rCrgF3vlJQYbpyWhirdS_Oek16cv_mvZmpuE8I,4473
92
95
  openepd/patch_pydantic.py,sha256=xrkzblatmU9HBzukWkp1cPq9ZSuohoz1p0pQqVKSlKs,4122
93
96
  openepd/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
94
- openepd-4.9.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
95
- openepd-4.9.0.dist-info/METADATA,sha256=pgDKp3QMBRUOSfTtKsczMpMjOO7n_OEuFwaOz0LR6JI,8534
96
- openepd-4.9.0.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
97
- openepd-4.9.0.dist-info/RECORD,,
97
+ openepd-4.10.1.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
98
+ openepd-4.10.1.dist-info/METADATA,sha256=VGCrT0N2HBiCDYtXUnqW1BFWZ_KycJKBuhlz4f8QzX8,8535
99
+ openepd-4.10.1.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
100
+ openepd-4.10.1.dist-info/RECORD,,