openepd 6.3.1__py3-none-any.whl → 6.4.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 +1 -1
- openepd/model/common.py +13 -1
- openepd/model/epd.py +2 -1
- openepd/model/lcia.py +52 -28
- openepd/model/org.py +10 -2
- openepd/model/specs/enums.py +1 -1
- {openepd-6.3.1.dist-info → openepd-6.4.1.dist-info}/METADATA +1 -1
- {openepd-6.3.1.dist-info → openepd-6.4.1.dist-info}/RECORD +10 -10
- {openepd-6.3.1.dist-info → openepd-6.4.1.dist-info}/LICENSE +0 -0
- {openepd-6.3.1.dist-info → openepd-6.4.1.dist-info}/WHEEL +0 -0
openepd/__version__.py
CHANGED
openepd/model/common.py
CHANGED
@@ -24,7 +24,7 @@ from openepd.model.validation.numbers import RatioFloat
|
|
24
24
|
class Amount(BaseOpenEpdSchema):
|
25
25
|
"""A value-and-unit pairing for amounts that do not have an uncertainty."""
|
26
26
|
|
27
|
-
qty: float | None = pyd.Field(description="How much of this in the amount.", default=None)
|
27
|
+
qty: float | None = pyd.Field(description="How much of this in the amount.", ge=0, default=None)
|
28
28
|
unit: str | None = pyd.Field(description="Which unit. SI units are preferred.", example="kg", default=None)
|
29
29
|
|
30
30
|
@pyd.root_validator
|
@@ -117,6 +117,18 @@ class Ingredient(BaseOpenEpdSchema):
|
|
117
117
|
)
|
118
118
|
citation: str | None = pyd.Field(default=None, description="Text citation describing the data source ")
|
119
119
|
|
120
|
+
@pyd.root_validator(skip_on_failure=True)
|
121
|
+
def _validate_evidence(cls, values: dict[str, Any]) -> dict[str, Any]:
|
122
|
+
# gwp_fraction should be backed by some type of evidence (fraction coming from product EPD etc) to be accounted
|
123
|
+
# for in the calculation of uncertainty
|
124
|
+
if values.get("gwp_fraction"):
|
125
|
+
if not values.get("evidence_type"):
|
126
|
+
raise ValueError("evidence_type is required if gwp_fraction is provided")
|
127
|
+
if not (values.get("citation") or values.get("link")):
|
128
|
+
raise ValueError("link or citation is required if gwp_fraction is provided")
|
129
|
+
|
130
|
+
return values
|
131
|
+
|
120
132
|
|
121
133
|
class LatLng(BaseOpenEpdSchema):
|
122
134
|
"""A latitude and longitude."""
|
openepd/model/epd.py
CHANGED
@@ -38,6 +38,7 @@ MANUFACTURER_DESCRIPTION = (
|
|
38
38
|
'JSON object for declaring Org. Sometimes called the "Declaration Holder" or "Declaration Owner".'
|
39
39
|
)
|
40
40
|
|
41
|
+
PLANT_DESCRIPTION = "List of object(s) for one or more plant(s) that this declaration applies to."
|
41
42
|
|
42
43
|
#
|
43
44
|
# Copyright 2024 by C Change Labs Inc. www.c-change-labs.com
|
@@ -161,7 +162,7 @@ class EpdPreviewV0(
|
|
161
162
|
manufacturer: Org | None = pyd.Field(description=MANUFACTURER_DESCRIPTION)
|
162
163
|
plants: list[Plant] = pyd.Field(
|
163
164
|
max_items=32,
|
164
|
-
description=
|
165
|
+
description=PLANT_DESCRIPTION,
|
165
166
|
default_factory=list,
|
166
167
|
)
|
167
168
|
|
openepd/model/lcia.py
CHANGED
@@ -357,6 +357,30 @@ class ScopeSetDiseaseIncidence(ScopeSet):
|
|
357
357
|
allowed_units = "AnnualPerCapita"
|
358
358
|
|
359
359
|
|
360
|
+
class ScopeSetMass(ScopeSet):
|
361
|
+
"""ScopeSet measuring mass in kg."""
|
362
|
+
|
363
|
+
allowed_units = "kg"
|
364
|
+
|
365
|
+
|
366
|
+
class ScopeSetVolume(ScopeSet):
|
367
|
+
"""ScopeSet measuring mass in kg."""
|
368
|
+
|
369
|
+
allowed_units = "m3"
|
370
|
+
|
371
|
+
|
372
|
+
class ScopeSetMassOrVolume(ScopeSet):
|
373
|
+
"""ScopeSet measuring mass in kg OR volume in m3, example: radioactive waste."""
|
374
|
+
|
375
|
+
allowed_units = ("kg", "m3")
|
376
|
+
|
377
|
+
|
378
|
+
class ScopeSetEnergy(ScopeSet):
|
379
|
+
"""ScopeSet measuring mass in kg."""
|
380
|
+
|
381
|
+
allowed_units = "MJ"
|
382
|
+
|
383
|
+
|
360
384
|
class ImpactSet(ScopesetByNameBase):
|
361
385
|
"""A set of impacts, such as GWP, ODP, AP, EP, POCP, EP-marine, EP-terrestrial, EP-freshwater, etc."""
|
362
386
|
|
@@ -554,71 +578,71 @@ class Impacts(pyd.BaseModel):
|
|
554
578
|
class ResourceUseSet(ScopesetByNameBase):
|
555
579
|
"""A set of resource use indicators, such as RPRec, RPRm, etc."""
|
556
580
|
|
557
|
-
RPRec:
|
581
|
+
RPRec: ScopeSetEnergy | None = pyd.Field(
|
558
582
|
description="Renewable primary resources used as energy carrier (fuel). "
|
559
583
|
"First use bio-based materials used as an energy source. Hydropower, solar and wind power used "
|
560
584
|
"in the technosphere are also included in this indicator",
|
561
585
|
default=None,
|
562
586
|
)
|
563
|
-
RPRm:
|
587
|
+
RPRm: ScopeSetEnergy | None = pyd.Field(
|
564
588
|
description="Renewable primary resources with energy content used as material. "
|
565
589
|
"First use biobased materials used as materials (e.g. wood, hemp, etc.).",
|
566
590
|
default=None,
|
567
591
|
)
|
568
|
-
rpre:
|
592
|
+
rpre: ScopeSetEnergy | None = pyd.Field(
|
569
593
|
description="Renewable primary energy resources as energy",
|
570
594
|
default=None,
|
571
595
|
)
|
572
|
-
nrpre:
|
596
|
+
nrpre: ScopeSetEnergy | None = pyd.Field(
|
573
597
|
description="Non-renewable primary resources as energy (fuel)",
|
574
598
|
default=None,
|
575
599
|
)
|
576
|
-
nrprm:
|
600
|
+
nrprm: ScopeSetEnergy | None = pyd.Field(
|
577
601
|
description="Non-renewable primary resources as material",
|
578
602
|
default=None,
|
579
603
|
)
|
580
|
-
fw:
|
604
|
+
fw: ScopeSetVolume | None = pyd.Field(
|
581
605
|
description="Use of net fresh water",
|
582
606
|
default=None,
|
583
607
|
)
|
584
|
-
sm:
|
608
|
+
sm: ScopeSetMass | None = pyd.Field(
|
585
609
|
description="Use of secondary materials",
|
586
610
|
default=None,
|
587
611
|
)
|
588
|
-
rsf:
|
612
|
+
rsf: ScopeSetEnergy | None = pyd.Field(
|
589
613
|
description="Use of renewable secondary materials",
|
590
614
|
default=None,
|
591
615
|
)
|
592
|
-
nrsf:
|
616
|
+
nrsf: ScopeSetEnergy | None = pyd.Field(
|
593
617
|
description="Use of non-renewable secondary fuels",
|
594
618
|
default=None,
|
595
619
|
)
|
596
|
-
re:
|
620
|
+
re: ScopeSetEnergy | None = pyd.Field(
|
597
621
|
description="Renewable energy resources",
|
598
622
|
default=None,
|
599
623
|
)
|
600
|
-
pere:
|
624
|
+
pere: ScopeSetEnergy | None = pyd.Field(
|
601
625
|
description="Use of renewable primary energy excluding renewable primary energy resources used as raw materials",
|
602
626
|
default=None,
|
603
627
|
)
|
604
|
-
perm:
|
628
|
+
perm: ScopeSetEnergy | None = pyd.Field(
|
605
629
|
description="Use of renewable primary energy resources used as raw materials",
|
606
630
|
default=None,
|
607
631
|
)
|
608
|
-
pert:
|
632
|
+
pert: ScopeSetEnergy | None = pyd.Field(
|
609
633
|
description="Total use of renewable primary energy resources",
|
610
634
|
default=None,
|
611
635
|
)
|
612
|
-
penre:
|
636
|
+
penre: ScopeSetEnergy | None = pyd.Field(
|
613
637
|
description="Use of non-renewable primary energy excluding "
|
614
638
|
"non-renewable primary energy resources used as raw materials",
|
615
639
|
default=None,
|
616
640
|
)
|
617
|
-
penrm:
|
641
|
+
penrm: ScopeSetEnergy | None = pyd.Field(
|
618
642
|
description="Use of non-renewable primary energy resources used as raw materials",
|
619
643
|
default=None,
|
620
644
|
)
|
621
|
-
penrt:
|
645
|
+
penrt: ScopeSetEnergy | None = pyd.Field(
|
622
646
|
description="Total use of non-renewable primary energy resources",
|
623
647
|
default=None,
|
624
648
|
)
|
@@ -627,51 +651,51 @@ class ResourceUseSet(ScopesetByNameBase):
|
|
627
651
|
class OutputFlowSet(ScopesetByNameBase):
|
628
652
|
"""A set of output flows, such as waste, emissions, etc."""
|
629
653
|
|
630
|
-
twd:
|
654
|
+
twd: ScopeSetMass | None = pyd.Field(
|
631
655
|
description="Total waste disposed",
|
632
656
|
default=None,
|
633
657
|
)
|
634
|
-
hwd:
|
658
|
+
hwd: ScopeSetMass | None = pyd.Field(
|
635
659
|
description="Hazardous waste disposed",
|
636
660
|
default=None,
|
637
661
|
)
|
638
|
-
nhwd:
|
662
|
+
nhwd: ScopeSetMass | None = pyd.Field(
|
639
663
|
description="Non-hazardous waste disposed",
|
640
664
|
default=None,
|
641
665
|
)
|
642
|
-
rwd:
|
666
|
+
rwd: ScopeSetMass | None = pyd.Field(
|
643
667
|
description="Radioactive waste disposed",
|
644
668
|
default=None,
|
645
669
|
)
|
646
|
-
hlrw:
|
670
|
+
hlrw: ScopeSetMassOrVolume | None = pyd.Field(
|
647
671
|
description="High level radioactive waste disposed",
|
648
672
|
default=None,
|
649
673
|
)
|
650
|
-
illrw:
|
674
|
+
illrw: ScopeSetMassOrVolume | None = pyd.Field(
|
651
675
|
description="Intermediate level radioactive waste disposed",
|
652
676
|
default=None,
|
653
677
|
)
|
654
|
-
cru:
|
678
|
+
cru: ScopeSetMass | None = pyd.Field(
|
655
679
|
description="Components for re-use",
|
656
680
|
default=None,
|
657
681
|
)
|
658
|
-
mr:
|
682
|
+
mr: ScopeSetMass | None = pyd.Field(
|
659
683
|
description="Recycled materials",
|
660
684
|
default=None,
|
661
685
|
)
|
662
|
-
mfr:
|
686
|
+
mfr: ScopeSetMass | None = pyd.Field(
|
663
687
|
description="Materials for recycling",
|
664
688
|
default=None,
|
665
689
|
)
|
666
|
-
mer:
|
690
|
+
mer: ScopeSetMass | None = pyd.Field(
|
667
691
|
description="Materials for energy recovery",
|
668
692
|
default=None,
|
669
693
|
)
|
670
|
-
ee:
|
694
|
+
ee: ScopeSetEnergy | None = pyd.Field(
|
671
695
|
description="Exported energy",
|
672
696
|
default=None,
|
673
697
|
)
|
674
|
-
eh:
|
698
|
+
eh: ScopeSetEnergy | None = pyd.Field(
|
675
699
|
description="Exported heat",
|
676
700
|
default=None,
|
677
701
|
)
|
openepd/model/org.py
CHANGED
@@ -66,7 +66,6 @@ class Org(WithAttachmentsMixin, WithAltIdsMixin, OrgRef):
|
|
66
66
|
class Plant(WithAttachmentsMixin, WithAltIdsMixin, BaseOpenEpdSchema):
|
67
67
|
"""Represent a manufacturing plant."""
|
68
68
|
|
69
|
-
# TODO: Add proper validator
|
70
69
|
id: str | None = pyd.Field(
|
71
70
|
description="Plus code (aka Open Location Code) of plant's location and "
|
72
71
|
"owner's web domain joined with `.`(dot).",
|
@@ -79,6 +78,12 @@ class Plant(WithAttachmentsMixin, WithAltIdsMixin, BaseOpenEpdSchema):
|
|
79
78
|
deprecated="Pluscode field is deprecated. If users need a pluscode they can obtain it from "
|
80
79
|
"`id` like this: `id.spit('.', maxsplit=1)[0]`",
|
81
80
|
)
|
81
|
+
latitude: float | None = pyd.Field(
|
82
|
+
default=None, description="(deprecated) Latitude of the plant location. Use 'location' fields instead."
|
83
|
+
)
|
84
|
+
longitude: float | None = pyd.Field(
|
85
|
+
default=None, description="(deprecated) Longitude of the plant location. Use 'location' fields instead."
|
86
|
+
)
|
82
87
|
owner: Org | None = pyd.Field(description="Organization that owns the plant", default=None)
|
83
88
|
name: str | None = pyd.Field(
|
84
89
|
max_length=200,
|
@@ -89,12 +94,13 @@ class Plant(WithAttachmentsMixin, WithAltIdsMixin, BaseOpenEpdSchema):
|
|
89
94
|
address: str | None = pyd.Field(
|
90
95
|
max_length=200,
|
91
96
|
default=None,
|
92
|
-
description="Text address, preferably geocoded",
|
97
|
+
description="(deprecated) Text address, preferably geocoded. Use 'location' fields instead",
|
93
98
|
example="1503 Orchard Hill Rd, LaGrange, GA 30240, United States",
|
94
99
|
)
|
95
100
|
contact_email: pyd.EmailStr | None = pyd.Field(
|
96
101
|
description="Email contact", example="info@interface.com", default=None
|
97
102
|
)
|
103
|
+
location: Location | None = pyd.Field(description="Location of the plant", default=None)
|
98
104
|
|
99
105
|
@classmethod
|
100
106
|
def get_asset_type(cls) -> str | None:
|
@@ -103,6 +109,8 @@ class Plant(WithAttachmentsMixin, WithAltIdsMixin, BaseOpenEpdSchema):
|
|
103
109
|
|
104
110
|
@pyd.validator("id")
|
105
111
|
def _validate_id(cls, v: str) -> str:
|
112
|
+
if not v:
|
113
|
+
return v
|
106
114
|
try:
|
107
115
|
pluscode, web_domain = v.split(".", maxsplit=1)
|
108
116
|
except ValueError as e:
|
openepd/model/specs/enums.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
openepd/__init__.py,sha256=Shkfh0Kun0YRhmRDw7LkUj2eQL3X-HnP55u2THOEALw,794
|
2
|
-
openepd/__version__.py,sha256=
|
2
|
+
openepd/__version__.py,sha256=ynbiHC7WrNYOSyzyrd2Hj7jVjQQIObp13PMqmGs_IDQ,638
|
3
3
|
openepd/api/__init__.py,sha256=UGmZGEyMnASrYwEBPHuXmVzHiuCUskUsJEPoHTIo-lg,620
|
4
4
|
openepd/api/average_dataset/__init__.py,sha256=UGmZGEyMnASrYwEBPHuXmVzHiuCUskUsJEPoHTIo-lg,620
|
5
5
|
openepd/api/average_dataset/generic_estimate_sync_api.py,sha256=mxWwDokEGMe87Px8C_aHvIdVKZVHrEAuVtaSA1zJchU,7953
|
@@ -35,22 +35,22 @@ openepd/compat/pydantic.py,sha256=DOjSixsylLqMtFAIARu50sGcT4VPXN_c473q_2JwZQ0,11
|
|
35
35
|
openepd/model/__init__.py,sha256=UGmZGEyMnASrYwEBPHuXmVzHiuCUskUsJEPoHTIo-lg,620
|
36
36
|
openepd/model/base.py,sha256=OEYNFUTL4BivBNAt_LGowTlDuUjvKMHgf5U5ZBncZwQ,9805
|
37
37
|
openepd/model/category.py,sha256=IQXNGQFQmFZ_H9PRONloX_UOSf1sTMDq1rM1yz8JR0Y,1639
|
38
|
-
openepd/model/common.py,sha256=
|
38
|
+
openepd/model/common.py,sha256=4iZAdmQy5UvLKrtmO8OnXsH1HD8jl20c6cv8MUZKW-M,10356
|
39
39
|
openepd/model/declaration.py,sha256=oBJ_v_ESoQhybQIH5S5tmYVkgkoX3gwe3nvFyPqb4uk,13832
|
40
|
-
openepd/model/epd.py,sha256=
|
40
|
+
openepd/model/epd.py,sha256=6G-5cpwaXx5BC6gQns2qlbqmsiEuXrsNmIK4mk1aJaQ,12108
|
41
41
|
openepd/model/factory.py,sha256=XP7eeQNW5tqwX_4hfuEb3lK6BFQDb4KB0fSN0r8-lCU,2656
|
42
42
|
openepd/model/generic_estimate.py,sha256=bbU0cR4izSqjZcfxUHNbdO4pllqqd8OaUFikrEgCFoA,3992
|
43
43
|
openepd/model/geography.py,sha256=G3Oz3QBw5n-RiSCAv-vAGxrOZBhwIT5rASnPlo9dkcs,42095
|
44
44
|
openepd/model/industry_epd.py,sha256=rgXhCUDAgzZ9eGio7ExqE3ymP3zTXnrrwcIDvg5YP1A,3285
|
45
|
-
openepd/model/lcia.py,sha256=
|
46
|
-
openepd/model/org.py,sha256=
|
45
|
+
openepd/model/lcia.py,sha256=NTUoPv8Yy-f_MCiezEKvB4gx18r0In5vl2e2SuLqQjY,25012
|
46
|
+
openepd/model/org.py,sha256=PtG4-EgjKvNSt7446lV60HhDC3YyRx2E-yJ8MMs5raE,5049
|
47
47
|
openepd/model/pcr.py,sha256=QknLtTn6Y14JORWKQ1qBqGgKnZpbKgqNiYF3Axl4U4c,5494
|
48
48
|
openepd/model/specs/README.md,sha256=UGhSiFJ9hOxT1mZl-5ZrhkOrPKf1W_gcu5CI9hzV7LU,2430
|
49
49
|
openepd/model/specs/__init__.py,sha256=IAevXqqYrCWlTH4z4Fy9o77vaOLinX56G05iIJJfm0M,3094
|
50
50
|
openepd/model/specs/asphalt.py,sha256=V-N7NbrxyNnjgNXQbJPj17ZFM3Q-qxTxxjqpx61wEfA,3350
|
51
51
|
openepd/model/specs/base.py,sha256=JgXvfy8K1Jpcai1eCUDZ-ndsLYkL-dcDyH2hQls6Znw,2652
|
52
52
|
openepd/model/specs/concrete.py,sha256=spMvijIv79c87PXT_YV7coG851AkJ1ILl9EHCxN2-6E,9593
|
53
|
-
openepd/model/specs/enums.py,sha256=
|
53
|
+
openepd/model/specs/enums.py,sha256=r7Ik8tgL60McK_5ACQn0qhIUTmxjnCQlGvHtFE6m8xM,63602
|
54
54
|
openepd/model/specs/range/__init__.py,sha256=LmBClxzTNpWzGwS1zvFoAxbKILrMRMz22mJXKYu2u8I,4502
|
55
55
|
openepd/model/specs/range/accessories.py,sha256=T3z-5jLoIVIIGeQi2cc5fMP3a7uGgvoW2E_SVmr3c30,2498
|
56
56
|
openepd/model/specs/range/aggregates.py,sha256=nxk6iZHzs0CIoUMWSw4IfB-D4tGd4prh9O2HXnC9u70,2549
|
@@ -133,7 +133,7 @@ openepd/model/validation/quantity.py,sha256=UP6x2nUj1nP7G8e2rpi-HigHx9rwKeCuIDh_
|
|
133
133
|
openepd/model/versioning.py,sha256=R_zm6rCrgF3vlJQYbpyWhirdS_Oek16cv_mvZmpuE8I,4473
|
134
134
|
openepd/patch_pydantic.py,sha256=xrkzblatmU9HBzukWkp1cPq9ZSuohoz1p0pQqVKSlKs,4122
|
135
135
|
openepd/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
136
|
-
openepd-6.
|
137
|
-
openepd-6.
|
138
|
-
openepd-6.
|
139
|
-
openepd-6.
|
136
|
+
openepd-6.4.1.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
137
|
+
openepd-6.4.1.dist-info/METADATA,sha256=YqnvdbcllbapVDL63YMJA-0UJozK9OH5TGhnicVv95I,9038
|
138
|
+
openepd-6.4.1.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
|
139
|
+
openepd-6.4.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|