openepd 0.1.3__py3-none-any.whl → 0.3.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.
- openepd/__version__.py +1 -1
- openepd/model/base.py +27 -0
- openepd/model/common.py +4 -15
- openepd/model/epd.py +38 -2
- openepd/model/org.py +3 -5
- openepd/model/pcr.py +2 -2
- openepd/model/specs/__init__.py +29 -0
- openepd/model/specs/concrete.py +83 -0
- openepd/model/standard.py +34 -0
- {openepd-0.1.3.dist-info → openepd-0.3.0.dist-info}/METADATA +1 -1
- openepd-0.3.0.dist-info/RECORD +17 -0
- openepd-0.1.3.dist-info/RECORD +0 -14
- {openepd-0.1.3.dist-info → openepd-0.3.0.dist-info}/LICENSE +0 -0
- {openepd-0.1.3.dist-info → openepd-0.3.0.dist-info}/WHEEL +0 -0
openepd/__version__.py
CHANGED
openepd/model/base.py
CHANGED
@@ -20,20 +20,47 @@
|
|
20
20
|
import pydantic
|
21
21
|
from pydantic.generics import GenericModel
|
22
22
|
|
23
|
+
AnySerializable = int | str | bool | float | list | dict | pydantic.BaseModel | None
|
24
|
+
|
23
25
|
|
24
26
|
class BaseOpenEpdSchema(pydantic.BaseModel):
|
25
27
|
"""Base class for all OpenEPD models."""
|
26
28
|
|
29
|
+
ext: dict[str, AnySerializable] | None = pydantic.Field(alias="ext", default=None)
|
30
|
+
|
27
31
|
class Config:
|
28
32
|
allow_mutation = True
|
29
33
|
validate_assignment = False
|
34
|
+
allow_population_by_field_name = True
|
35
|
+
use_enum_values = True
|
30
36
|
|
31
37
|
def has_values(self) -> bool:
|
32
38
|
"""Return True if the model has any values."""
|
33
39
|
return len(self.dict(exclude_unset=True, exclude_none=True)) > 0
|
34
40
|
|
41
|
+
@classmethod
|
42
|
+
def is_allowed_field_name(cls, field_name: str) -> bool:
|
43
|
+
"""
|
44
|
+
Return True if the field name is defined in the module.
|
45
|
+
|
46
|
+
Both property name and aliases are checked.
|
47
|
+
"""
|
48
|
+
if field_name in cls.__fields__:
|
49
|
+
return True
|
50
|
+
else:
|
51
|
+
for x in cls.__fields__.values():
|
52
|
+
if x.alias == field_name:
|
53
|
+
return True
|
54
|
+
return False
|
55
|
+
|
35
56
|
|
36
57
|
class BaseOpenEpdGenericSchema(GenericModel, BaseOpenEpdSchema):
|
37
58
|
"""Base class for all OpenEPD generic models."""
|
38
59
|
|
39
60
|
pass
|
61
|
+
|
62
|
+
|
63
|
+
class BaseOpenEpdSpec(BaseOpenEpdSchema):
|
64
|
+
"""Base class for all OpenEPD specs."""
|
65
|
+
|
66
|
+
pass
|
openepd/model/common.py
CHANGED
@@ -36,21 +36,10 @@ class Measurement(BaseOpenEpdSchema):
|
|
36
36
|
|
37
37
|
mean: float = pyd.Field(description="Mean (expected) value of the measurement")
|
38
38
|
unit: str = pyd.Field(description="Measurement unit")
|
39
|
-
rsd: pyd.PositiveFloat = pyd.Field(
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
class ExternalIdentification(BaseOpenEpdSchema): # TODO: NEW Object, not in the spec
|
44
|
-
"""Represent an external identification of an object."""
|
45
|
-
|
46
|
-
id: str
|
47
|
-
version: str | None
|
48
|
-
|
49
|
-
|
50
|
-
class ExternallyIdentifiableMixin: # TODO: NEW Object, not in the spec
|
51
|
-
"""Mixin for objects that can be identified externally."""
|
52
|
-
|
53
|
-
identified: dict[str, ExternalIdentification] = pyd.Field(description="The external identification of the object.")
|
39
|
+
rsd: pyd.PositiveFloat | None = pyd.Field(
|
40
|
+
description="Relative standard deviation, i.e. standard_deviation/mean", default=None
|
41
|
+
)
|
42
|
+
dist: str | None = pyd.Field(description="Statistical distribution of the measurement error.", default=None)
|
54
43
|
|
55
44
|
|
56
45
|
class WithAttachmentsMixin:
|
openepd/model/epd.py
CHANGED
@@ -23,12 +23,14 @@ from typing import Literal
|
|
23
23
|
import pydantic as pyd
|
24
24
|
|
25
25
|
from openepd.model.base import BaseOpenEpdSchema
|
26
|
-
from openepd.model.common import Amount
|
26
|
+
from openepd.model.common import Amount
|
27
27
|
from openepd.model.lcia import ImpactSet, OutputFlowSet, ResourceUseSet
|
28
28
|
from openepd.model.org import Org, Plant
|
29
|
+
from openepd.model.specs import Specs
|
30
|
+
from openepd.model.standard import Standard
|
29
31
|
|
30
32
|
|
31
|
-
class Epd(
|
33
|
+
class Epd(BaseOpenEpdSchema):
|
32
34
|
"""Represent an EPD."""
|
33
35
|
|
34
36
|
# TODO: Add validator for open-xpd-uuid on this field
|
@@ -120,3 +122,37 @@ class Epd(ExternallyIdentifiableMixin, BaseOpenEpdSchema):
|
|
120
122
|
description="Set of Waste and Output Flow indicators which describe the waste categories "
|
121
123
|
"and other material output flows derived from the LCI."
|
122
124
|
)
|
125
|
+
compliance: list[Standard] = pyd.Field(
|
126
|
+
description="Standard(s) to which this declaration is compliant.", default_factory=list
|
127
|
+
)
|
128
|
+
specs: Specs = pyd.Field(
|
129
|
+
default_factory=Specs,
|
130
|
+
description="Data structure(s) describing performance specs of product. Unique for each material type.",
|
131
|
+
)
|
132
|
+
lca_discussion: str | None = pyd.Field(
|
133
|
+
max_length=20000,
|
134
|
+
description="""A rich text description containing information for experts reviewing the EPD contents.
|
135
|
+
Text descriptions required by ISO 14025, ISO 21930, EN 15804,, relevant PCRs, or program instructions and which do not
|
136
|
+
have specific openEPD fields should be entered here. This field may be large, and may contain multiple sections
|
137
|
+
separated by github flavored markdown formatting.""",
|
138
|
+
example="""# Packaging
|
139
|
+
|
140
|
+
Information on product-specific packaging: type, composition and possible reuse of packaging materials (paper,
|
141
|
+
strapping, pallets, foils, drums, etc.) shall be included in this Section. The EPD shall describe specific packaging
|
142
|
+
scenario assumptions, including disposition pathways for each packaging material by reuse, recycling, or landfill
|
143
|
+
disposal based on packaging type.*
|
144
|
+
|
145
|
+
# Product Installation
|
146
|
+
|
147
|
+
A description of the type of processing, machinery, tools, dust extraction equipment, auxiliary materials, etc.
|
148
|
+
to be used during installation shall be included. Information on industrial and environmental protection may be
|
149
|
+
included in this section. Any waste treatment included within the system boundary of installation waste should be
|
150
|
+
specified.
|
151
|
+
|
152
|
+
# Use Conditions
|
153
|
+
|
154
|
+
Use-stage environmental impacts of flooring products during building operations depend on product cleaning assumptions.
|
155
|
+
Information on cleaning frequency and cleaning products shall be provided based on the manufacturer’s recommendations.
|
156
|
+
In the absence of primary data, cleaning assumptions shall be documented.
|
157
|
+
""",
|
158
|
+
)
|
openepd/model/org.py
CHANGED
@@ -22,7 +22,7 @@ from typing import Annotated, Optional
|
|
22
22
|
import pydantic as pyd
|
23
23
|
|
24
24
|
from openepd.model.base import BaseOpenEpdSchema
|
25
|
-
from openepd.model.common import
|
25
|
+
from openepd.model.common import WithAttachmentsMixin
|
26
26
|
|
27
27
|
|
28
28
|
class Contact(BaseOpenEpdSchema): # TODO: NEW Object, not in the spec
|
@@ -35,9 +35,7 @@ class Contact(BaseOpenEpdSchema): # TODO: NEW Object, not in the spec
|
|
35
35
|
)
|
36
36
|
|
37
37
|
|
38
|
-
class Org(
|
39
|
-
ExternallyIdentifiableMixin, WithAttachmentsMixin, BaseOpenEpdSchema
|
40
|
-
): # TODO: NEW Identifiable field, not in the spec
|
38
|
+
class Org(WithAttachmentsMixin, BaseOpenEpdSchema): # TODO: NEW Identifiable field, not in the spec
|
41
39
|
"""Represent an organization."""
|
42
40
|
|
43
41
|
web_domain: str = pyd.Field(
|
@@ -59,7 +57,7 @@ class Org(
|
|
59
57
|
)
|
60
58
|
|
61
59
|
|
62
|
-
class Plant(
|
60
|
+
class Plant(WithAttachmentsMixin, BaseOpenEpdSchema):
|
63
61
|
"""Represent a manufacturing plant."""
|
64
62
|
|
65
63
|
# TODO: Add proper validator
|
openepd/model/pcr.py
CHANGED
@@ -23,11 +23,11 @@ from typing import Optional
|
|
23
23
|
import pydantic as pyd
|
24
24
|
|
25
25
|
from openepd.model.base import BaseOpenEpdSchema
|
26
|
-
from openepd.model.common import
|
26
|
+
from openepd.model.common import WithAttachmentsMixin
|
27
27
|
from openepd.model.org import Org
|
28
28
|
|
29
29
|
|
30
|
-
class Pcr(
|
30
|
+
class Pcr(WithAttachmentsMixin, BaseOpenEpdSchema):
|
31
31
|
"""Represent a PCR (Product Category Rules)."""
|
32
32
|
|
33
33
|
id: str = pyd.Field(
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2023 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
|
+
# This software was developed with support from the Skanska USA,
|
17
|
+
# Charles Pankow Foundation, Microsoft Sustainability Fund, Interface, MKA Foundation, and others.
|
18
|
+
# Find out more at www.BuildingTransparency.org
|
19
|
+
#
|
20
|
+
import pydantic as pyd
|
21
|
+
|
22
|
+
from openepd.model.base import BaseOpenEpdSchema
|
23
|
+
from openepd.model.specs.concrete import CmuSpec
|
24
|
+
|
25
|
+
|
26
|
+
class Specs(BaseOpenEpdSchema):
|
27
|
+
"""Material specific specs."""
|
28
|
+
|
29
|
+
cmu: CmuSpec | None = pyd.Field(default=None, description="Concrete Masonry Unit-specific (CMU) specs")
|
@@ -0,0 +1,83 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2023 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
|
+
# This software was developed with support from the Skanska USA,
|
17
|
+
# Charles Pankow Foundation, Microsoft Sustainability Fund, Interface, MKA Foundation, and others.
|
18
|
+
# Find out more at www.BuildingTransparency.org
|
19
|
+
#
|
20
|
+
from enum import StrEnum
|
21
|
+
|
22
|
+
import pydantic as pyd
|
23
|
+
|
24
|
+
from openepd.model.base import BaseOpenEpdSpec
|
25
|
+
|
26
|
+
|
27
|
+
class CmuWeightClassification(StrEnum):
|
28
|
+
"""Concrete Masonry Unit weight classification."""
|
29
|
+
|
30
|
+
Normal = "Normal"
|
31
|
+
"""Normal weight CMU has a density of 125 lbs/cu. ft."""
|
32
|
+
Medium = "Medium"
|
33
|
+
"""Medium weight CMU has a density of 105-125 lbs/cu. ft."""
|
34
|
+
Light = "Light"
|
35
|
+
"""Lightweight CMU has a density less than 105 lbs/cu. ft."""
|
36
|
+
|
37
|
+
|
38
|
+
class CmuOptions(BaseOpenEpdSpec):
|
39
|
+
"""Concrete Masonry Unit options."""
|
40
|
+
|
41
|
+
load_bearing: bool | None = pyd.Field(
|
42
|
+
description="Load-Bearing. CMUs intended to be loadbearing, rather than simply cosmetic",
|
43
|
+
example=True,
|
44
|
+
default=None,
|
45
|
+
)
|
46
|
+
aerated_concrete: bool | None = pyd.Field(
|
47
|
+
description="AAC Aerated Concrete. Aerated Autoclaved Concrete, a foam concrete.", example=True, default=None
|
48
|
+
)
|
49
|
+
insulated: bool | None = pyd.Field(
|
50
|
+
description="Insulated. CMUs with integral insulation", example=True, default=None
|
51
|
+
)
|
52
|
+
sound_absorbing: bool | None = pyd.Field(
|
53
|
+
description="Sound Absorbing. CMUs structured for sound absorbtion", example=True, default=None
|
54
|
+
)
|
55
|
+
white: bool | None = pyd.Field(
|
56
|
+
description="White. CMU using white cement and light-colored aggregate", example=True, default=None
|
57
|
+
)
|
58
|
+
recycled_aggregate: bool | None = pyd.Field(
|
59
|
+
description="Recycled aggregate. CMU using primarily reycled aggregates", example=True, default=None
|
60
|
+
)
|
61
|
+
groundface: bool | None = pyd.Field(
|
62
|
+
description="Ground Face. Ground or Honed facing, typically for improved appearance", example=True, default=None
|
63
|
+
)
|
64
|
+
splitface: bool | None = pyd.Field(
|
65
|
+
description="Splitface. Rough surface texture via splitting; aggregate can be seen", example=True, default=None
|
66
|
+
)
|
67
|
+
smoothface: bool | None = pyd.Field(
|
68
|
+
description="Smooth Face. Standard smooth-faced blocks", example=True, default=None
|
69
|
+
)
|
70
|
+
slumpstone: bool | None = pyd.Field(
|
71
|
+
description="Slumpstone. A slightly rounded, random distortion with the look of rustic adobe.",
|
72
|
+
example=True,
|
73
|
+
default=None,
|
74
|
+
)
|
75
|
+
|
76
|
+
|
77
|
+
class CmuSpec(BaseOpenEpdSpec):
|
78
|
+
"""Standardized Concrete Masonry Unit-specific extension for OpenEPD."""
|
79
|
+
|
80
|
+
strength: str = pyd.Field(description="Compressive strength", example="4000 psi")
|
81
|
+
options: CmuOptions = pyd.Field(
|
82
|
+
description="Options for CMU. List of true/false properties", default_factory=CmuOptions
|
83
|
+
)
|
@@ -0,0 +1,34 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2023 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
|
+
# This software was developed with support from the Skanska USA,
|
17
|
+
# Charles Pankow Foundation, Microsoft Sustainability Fund, Interface, MKA Foundation, and others.
|
18
|
+
# Find out more at www.BuildingTransparency.org
|
19
|
+
#
|
20
|
+
import pydantic as pyd
|
21
|
+
|
22
|
+
from openepd.model.base import BaseOpenEpdSchema
|
23
|
+
from openepd.model.org import Org
|
24
|
+
|
25
|
+
|
26
|
+
class Standard(BaseOpenEpdSchema):
|
27
|
+
"""A standard, such as EN 15804, ISO 14044, ISO 14024:2018, etc."""
|
28
|
+
|
29
|
+
short_name: str = pyd.Field(description="Short-form of name of standard. Must be unique. Case-insensitive")
|
30
|
+
name: str | None = pyd.Field(description="Full document name. Must be unique. Case-insensitive", default=None)
|
31
|
+
link: pyd.AnyUrl | None = pyd.Field(
|
32
|
+
description="Link to the exact standard (including version) referred to", default=None
|
33
|
+
)
|
34
|
+
issuer: Org | None = pyd.Field(description="Org that issued this standard", default=None)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
openepd/__init__.py,sha256=7_QNx3x9RCC7Lj9fHDD3nzgq6wV4Fmou7OJNWkCPnEw,837
|
2
|
+
openepd/__version__.py,sha256=M9l7ZzgmpFsB59avClU0_PB_PUhypOp28sEbL1pAGQU,855
|
3
|
+
openepd/model/__init__.py,sha256=7_QNx3x9RCC7Lj9fHDD3nzgq6wV4Fmou7OJNWkCPnEw,837
|
4
|
+
openepd/model/base.py,sha256=Dpc8YeGf70gHahGrLbCC2e4MFCI6BHoByNSGdN3Ul7c,2155
|
5
|
+
openepd/model/common.py,sha256=DomuW6IRVyOpbo-wJbrPpWa7ig65OzAncSzA63Imyy8,2178
|
6
|
+
openepd/model/epd.py,sha256=_BZoLHOz8uDL0lDqHAYgPxOiJ39hHfWCbVAdXqIhWWk,7763
|
7
|
+
openepd/model/lcia.py,sha256=N_2TukAXKCz5ztWHRdOrw2UVmAhLn9WN9x9y6_BJ6Uw,8887
|
8
|
+
openepd/model/org.py,sha256=kQyaCi6pRzaThJ_13o4ymEfNoSBXXZP0wVoZA7mse6o,3690
|
9
|
+
openepd/model/pcr.py,sha256=RmOB9YLkNJIU1RAvHSDzOOIL3ux3FmJo60oCkXXu_08,2855
|
10
|
+
openepd/model/specs/__init__.py,sha256=JmbvfzwO0QmNcrxGqYE_KjvYHBmc2bnDm7cyZsaMG78,1137
|
11
|
+
openepd/model/specs/concrete.py,sha256=v9Jyi6NiaoMA2ELX_wMckgTAtRplEOaIkZrd2qEdiN4,3342
|
12
|
+
openepd/model/standard.py,sha256=Nv_H3Lhu79y4waWzzKpwODCPPGrlWwRIl6eZBMSc9Qg,1519
|
13
|
+
openepd/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
14
|
+
openepd-0.3.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
15
|
+
openepd-0.3.0.dist-info/METADATA,sha256=ASVre0j0f1CKolSXk10wzB6FmSros-KnUoiw3IbVvuM,3723
|
16
|
+
openepd-0.3.0.dist-info/WHEEL,sha256=WGfLGfLX43Ei_YORXSnT54hxFygu34kMpcQdmgmEwCQ,88
|
17
|
+
openepd-0.3.0.dist-info/RECORD,,
|
openepd-0.1.3.dist-info/RECORD
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
openepd/__init__.py,sha256=7_QNx3x9RCC7Lj9fHDD3nzgq6wV4Fmou7OJNWkCPnEw,837
|
2
|
-
openepd/__version__.py,sha256=T87cqTOIorCpfwNyvo0jvQ5LS27mv02hQMmtN92zYkU,855
|
3
|
-
openepd/model/__init__.py,sha256=7_QNx3x9RCC7Lj9fHDD3nzgq6wV4Fmou7OJNWkCPnEw,837
|
4
|
-
openepd/model/base.py,sha256=2kaIyTze9V0ItX-yNFFHGRIF3ewDuoF_GGbYbfAT_iI,1366
|
5
|
-
openepd/model/common.py,sha256=_Vn2ysWrJFYHZKBe8cxnPhV45RR3KzIPjfKXLPJOTVA,2573
|
6
|
-
openepd/model/epd.py,sha256=5KvTvG3uX5hhVyp9iuDhjz_8fgVV8IC4wextNToVoiU,5740
|
7
|
-
openepd/model/lcia.py,sha256=N_2TukAXKCz5ztWHRdOrw2UVmAhLn9WN9x9y6_BJ6Uw,8887
|
8
|
-
openepd/model/org.py,sha256=k3fpFwVPnN80UIJJFu-kPUCIyD2iIavtDeTCKwGTFIg,3783
|
9
|
-
openepd/model/pcr.py,sha256=vEwd2V6IFau1vXC8MC8Ptx6YXySrFgOuiho_J1ZxhJg,2913
|
10
|
-
openepd/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
11
|
-
openepd-0.1.3.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
12
|
-
openepd-0.1.3.dist-info/METADATA,sha256=H_SXczzF5ijpPxydL3XQ5FGEVuLAWVfkNcz5onAu4ig,3723
|
13
|
-
openepd-0.1.3.dist-info/WHEEL,sha256=WGfLGfLX43Ei_YORXSnT54hxFygu34kMpcQdmgmEwCQ,88
|
14
|
-
openepd-0.1.3.dist-info/RECORD,,
|
File without changes
|
File without changes
|