openepd 6.31.2__tar.gz → 6.32.0__tar.gz
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-6.31.2 → openepd-6.32.0}/PKG-INFO +1 -1
- {openepd-6.31.2 → openepd-6.32.0}/pyproject.toml +1 -1
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/__version__.py +1 -1
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/common.py +24 -1
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/declaration.py +2 -14
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/epd.py +15 -3
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/org.py +10 -14
- {openepd-6.31.2 → openepd-6.32.0}/LICENSE +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/README.md +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/__init__.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/api/__init__.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/api/average_dataset/__init__.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/api/average_dataset/generic_estimate_sync_api.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/api/average_dataset/industry_epd_sync_api.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/api/base_sync_client.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/api/category/__init__.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/api/category/dto.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/api/category/sync_api.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/api/common.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/api/dto/__init__.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/api/dto/base.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/api/dto/common.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/api/dto/meta.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/api/dto/mf.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/api/dto/params.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/api/epd/__init__.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/api/epd/dto.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/api/epd/sync_api.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/api/errors.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/api/org/__init__.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/api/org/sync_api.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/api/pcr/__init__.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/api/pcr/sync_api.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/api/plant/__init__.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/api/plant/sync_api.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/api/standard/__init__.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/api/standard/sync_api.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/api/sync_client.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/api/test/__init__.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/api/utils.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/bundle/__init__.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/bundle/base.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/bundle/model.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/bundle/reader.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/bundle/writer.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/compat/__init__.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/compat/compat_functional_validators.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/compat/pydantic.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/constants/__init__.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/constants/scope_phases.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/m49/__init__.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/m49/const.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/m49/utils.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/__init__.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/base.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/category.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/factory.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/generic_estimate.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/geography.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/industry_epd.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/lcia.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/pcr.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/README.md +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/__init__.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/asphalt.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/base.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/concrete.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/enums.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/__init__.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/accessories.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/aggregates.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/aluminium.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/asphalt.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/bulk_materials.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/cast_decks_and_underlayment.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/cladding.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/cmu.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/concrete.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/conveying_equipment.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/electrical.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/electrical_transmission_and_distribution_equipment.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/electricity.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/exterior_improvements.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/finishes.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/fire_and_smoke_protection.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/furnishings.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/grouting.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/manufacturing_inputs.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/masonry.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/material_handling.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/mechanical.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/mechanical_insulation.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/mixins/__init__.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/mixins/access_flooring_mixin.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/network_infrastructure.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/non_construction.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/openings.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/other_electrical_equipment.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/other_materials.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/plumbing.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/precast_concrete.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/sheathing.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/steel.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/thermal_moisture_protection.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/utility_piping.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/wood.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/wood_joists.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/__init__.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/accessories.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/aggregates.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/aluminium.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/asphalt.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/bulk_materials.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/cast_decks_and_underlayment.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/cladding.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/cmu.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/common.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/concrete.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/conveying_equipment.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/deprecated/__init__.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/deprecated/concrete.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/deprecated/steel.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/electrical.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/electrical_transmission_and_distribution_equipment.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/electricity.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/exterior_improvements.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/finishes.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/fire_and_smoke_protection.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/furnishings.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/grouting.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/manufacturing_inputs.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/masonry.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/material_handling.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/mechanical.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/mechanical_insulation.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/mixins/__init__.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/mixins/access_flooring_mixin.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/mixins/conduit_mixin.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/network_infrastructure.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/non_construction.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/openings.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/other_electrical_equipment.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/other_materials.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/plumbing.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/precast_concrete.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/sheathing.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/steel.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/thermal_moisture_protection.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/utility_piping.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/wood.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/wood_joists.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/standard.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/validation/__init__.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/validation/common.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/validation/enum.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/validation/numbers.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/validation/quantity.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/versioning.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/patch_pydantic.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/py.typed +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/utils/__init__.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/utils/functional.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/utils/mapping/__init__.py +0 -0
- {openepd-6.31.2 → openepd-6.32.0}/src/openepd/utils/mapping/common.py +0 -0
|
@@ -15,8 +15,9 @@
|
|
|
15
15
|
#
|
|
16
16
|
from collections.abc import Callable, Generator
|
|
17
17
|
from enum import StrEnum
|
|
18
|
+
import math
|
|
18
19
|
import re
|
|
19
|
-
from typing import Annotated, Any
|
|
20
|
+
from typing import Annotated, Any, Final
|
|
20
21
|
|
|
21
22
|
from openepd.compat.pydantic import pyd
|
|
22
23
|
from openepd.model.base import BaseOpenEpdSchema
|
|
@@ -31,6 +32,14 @@ in web pages as if they were external resources.
|
|
|
31
32
|
The pattern matches the following format: data:[<media-type>][;base64],<data>
|
|
32
33
|
"""
|
|
33
34
|
|
|
35
|
+
DATA_URL_IMAGE_MAX_LENGTH: Final[int] = math.ceil(32 * 1024 * 4 / 3)
|
|
36
|
+
"""
|
|
37
|
+
Maximum allowed length of a data URL image string to ensure the decoded image is less than 32KB.
|
|
38
|
+
|
|
39
|
+
Base64 encoding overhead (approximately 33%) requires
|
|
40
|
+
limiting the encoded string length to 4/3 of the file size limit.
|
|
41
|
+
"""
|
|
42
|
+
|
|
34
43
|
|
|
35
44
|
class Amount(BaseOpenEpdSchema):
|
|
36
45
|
"""A value-and-unit pairing for amounts that do not have an uncertainty."""
|
|
@@ -336,3 +345,17 @@ class DataUrl(str):
|
|
|
336
345
|
raise ValueError(msg)
|
|
337
346
|
|
|
338
347
|
yield validator
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
def validate_data_url(v: str | None, max_length: int) -> None:
|
|
351
|
+
"""
|
|
352
|
+
Validate max length of data URL.
|
|
353
|
+
|
|
354
|
+
:param v: data URL string.
|
|
355
|
+
:param max_length: maximum allowed length.
|
|
356
|
+
:raises ValueError: if the data URL exceeds the maximum length.
|
|
357
|
+
:return: None
|
|
358
|
+
"""
|
|
359
|
+
if v and len(v) > max_length:
|
|
360
|
+
msg = f"URL must not exceed {max_length} characters"
|
|
361
|
+
raise ValueError(msg)
|
|
@@ -16,12 +16,10 @@
|
|
|
16
16
|
import abc
|
|
17
17
|
import datetime
|
|
18
18
|
from enum import StrEnum
|
|
19
|
-
import math
|
|
20
|
-
from typing import Final
|
|
21
19
|
|
|
22
20
|
from openepd.compat.pydantic import pyd
|
|
23
21
|
from openepd.model.base import BaseOpenEpdSchema, OpenXpdUUID, RootDocument
|
|
24
|
-
from openepd.model.common import Amount, DataUrl
|
|
22
|
+
from openepd.model.common import DATA_URL_IMAGE_MAX_LENGTH, Amount, DataUrl, validate_data_url
|
|
25
23
|
from openepd.model.geography import Geography
|
|
26
24
|
from openepd.model.org import Org
|
|
27
25
|
from openepd.model.pcr import Pcr
|
|
@@ -34,14 +32,6 @@ DEVELOPER_DESCRIPTION = "The organization responsible for the underlying LCA (an
|
|
|
34
32
|
PROGRAM_OPERATOR_DESCRIPTION = "JSON object for program operator Org"
|
|
35
33
|
THIRD_PARTY_VERIFIER_DESCRIPTION = "JSON object for Org that performed a critical review of the EPD data"
|
|
36
34
|
|
|
37
|
-
PRODUCT_IMAGE_MAX_LENGTH: Final[int] = math.ceil(32 * 1024 * 4 / 3)
|
|
38
|
-
"""
|
|
39
|
-
Maximum length for product_image, product_image_small fields.
|
|
40
|
-
|
|
41
|
-
Image file size must be less than 32KB. Base64 encoding overhead (approximately 33%) requires
|
|
42
|
-
limiting the encoded string length to 4/3 of the file size limit.
|
|
43
|
-
"""
|
|
44
|
-
|
|
45
35
|
|
|
46
36
|
class BaseDeclaration(RootDocument, abc.ABC):
|
|
47
37
|
"""Base class for declaration-related documents (EPDs, Industry-wide EPDs, Generic Estimates)."""
|
|
@@ -175,9 +165,7 @@ class BaseDeclaration(RootDocument, abc.ABC):
|
|
|
175
165
|
|
|
176
166
|
@pyd.validator("product_image", "product_image_small")
|
|
177
167
|
def validate_product_image(cls, v: str | None) -> str | None:
|
|
178
|
-
|
|
179
|
-
msg = f"URL must not exceed {PRODUCT_IMAGE_MAX_LENGTH} characters"
|
|
180
|
-
raise ValueError(msg)
|
|
168
|
+
validate_data_url(v, DATA_URL_IMAGE_MAX_LENGTH)
|
|
181
169
|
return v
|
|
182
170
|
|
|
183
171
|
|
|
@@ -16,7 +16,14 @@
|
|
|
16
16
|
|
|
17
17
|
from openepd.compat.pydantic import pyd
|
|
18
18
|
from openepd.model.base import BaseDocumentFactory, OpenEpdDoctypes, OpenEpdExtension
|
|
19
|
-
from openepd.model.common import
|
|
19
|
+
from openepd.model.common import (
|
|
20
|
+
DATA_URL_IMAGE_MAX_LENGTH,
|
|
21
|
+
DataUrl,
|
|
22
|
+
Ingredient,
|
|
23
|
+
WithAltIdsMixin,
|
|
24
|
+
WithAttachmentsMixin,
|
|
25
|
+
validate_data_url,
|
|
26
|
+
)
|
|
20
27
|
from openepd.model.declaration import (
|
|
21
28
|
DEVELOPER_DESCRIPTION,
|
|
22
29
|
PROGRAM_OPERATOR_DESCRIPTION,
|
|
@@ -200,14 +207,14 @@ class EpdPreviewV0(
|
|
|
200
207
|
description="Text description of how product is typically used. Can be used to describe accessories "
|
|
201
208
|
"like fasteners, adhesives, etc. Supports plain text or github flavored markdown.",
|
|
202
209
|
)
|
|
203
|
-
product_usage_image: pyd.AnyUrl | None = pyd.Field(
|
|
210
|
+
product_usage_image: pyd.AnyUrl | None | DataUrl = pyd.Field(
|
|
204
211
|
description="Pointer (url) to image illustrating how the product is used. No more than 10MB.", default=None
|
|
205
212
|
)
|
|
206
213
|
manufacturing_description: str | None = pyd.Field(
|
|
207
214
|
default=None,
|
|
208
215
|
description="Text description of manufacturing process. Supports plain text or github flavored markdown.",
|
|
209
216
|
)
|
|
210
|
-
manufacturing_image: pyd.AnyUrl | None = pyd.Field(
|
|
217
|
+
manufacturing_image: pyd.AnyUrl | None | DataUrl = pyd.Field(
|
|
211
218
|
description="Pointer (url) to an image illustrating the manufacturing process. No more than 10MB.", default=None
|
|
212
219
|
)
|
|
213
220
|
|
|
@@ -235,6 +242,11 @@ class EpdPreviewV0(
|
|
|
235
242
|
msg = "Invalid doctype"
|
|
236
243
|
raise ValueError(msg)
|
|
237
244
|
|
|
245
|
+
@pyd.validator("product_usage_image", "manufacturing_image")
|
|
246
|
+
def validate_product_image(cls, v: str | None) -> str | None:
|
|
247
|
+
validate_data_url(v, DATA_URL_IMAGE_MAX_LENGTH)
|
|
248
|
+
return v
|
|
249
|
+
|
|
238
250
|
|
|
239
251
|
EpdPreview = EpdPreviewV0
|
|
240
252
|
|
|
@@ -13,24 +13,22 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
#
|
|
16
|
-
import
|
|
17
|
-
from typing import Annotated, Final, Optional
|
|
16
|
+
from typing import Annotated, Optional
|
|
18
17
|
|
|
19
18
|
from openlocationcode import openlocationcode
|
|
20
19
|
|
|
21
20
|
from openepd.compat.pydantic import pyd
|
|
22
21
|
from openepd.model.base import BaseOpenEpdSchema
|
|
23
|
-
from openepd.model.common import
|
|
22
|
+
from openepd.model.common import (
|
|
23
|
+
DATA_URL_IMAGE_MAX_LENGTH,
|
|
24
|
+
DataUrl,
|
|
25
|
+
Location,
|
|
26
|
+
WithAltIdsMixin,
|
|
27
|
+
WithAttachmentsMixin,
|
|
28
|
+
validate_data_url,
|
|
29
|
+
)
|
|
24
30
|
from openepd.model.validation.common import ReferenceStr
|
|
25
31
|
|
|
26
|
-
ORG_LOGO_MAX_LENGTH: Final[int] = math.ceil(32 * 1024 * 4 / 3)
|
|
27
|
-
"""
|
|
28
|
-
Maximum length of Org.logo field.
|
|
29
|
-
|
|
30
|
-
Logo file size must be less than 32KB. Base64 encoding overhead (approximately 33%) requires
|
|
31
|
-
limiting the encoded string length to 4/3 of the file size limit.
|
|
32
|
-
"""
|
|
33
|
-
|
|
34
32
|
|
|
35
33
|
class OrgRef(BaseOpenEpdSchema):
|
|
36
34
|
"""Represents Organisation with minimal data."""
|
|
@@ -105,9 +103,7 @@ class Org(WithAttachmentsMixin, WithAltIdsMixin, OrgRef):
|
|
|
105
103
|
|
|
106
104
|
@pyd.validator("logo")
|
|
107
105
|
def validate_logo(cls, v: str | None) -> str | None:
|
|
108
|
-
|
|
109
|
-
msg = f"Logo URL must not exceed {ORG_LOGO_MAX_LENGTH} characters"
|
|
110
|
-
raise ValueError(msg)
|
|
106
|
+
validate_data_url(v, DATA_URL_IMAGE_MAX_LENGTH)
|
|
111
107
|
return v
|
|
112
108
|
|
|
113
109
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openepd-6.31.2 → openepd-6.32.0}/src/openepd/api/average_dataset/generic_estimate_sync_api.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/cast_decks_and_underlayment.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/fire_and_smoke_protection.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/mixins/access_flooring_mixin.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/other_electrical_equipment.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/range/thermal_moisture_protection.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/cast_decks_and_underlayment.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/fire_and_smoke_protection.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/mixins/access_flooring_mixin.py
RENAMED
|
File without changes
|
|
File without changes
|
{openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/network_infrastructure.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/other_electrical_equipment.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openepd-6.31.2 → openepd-6.32.0}/src/openepd/model/specs/singular/thermal_moisture_protection.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|