openepd 5.2.0__tar.gz → 5.3.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.
Files changed (140) hide show
  1. {openepd-5.2.0 → openepd-5.3.0}/PKG-INFO +1 -1
  2. {openepd-5.2.0 → openepd-5.3.0}/pyproject.toml +1 -1
  3. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/__version__.py +1 -1
  4. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/api/average_dataset/generic_estimate_sync_api.py +12 -5
  5. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/api/epd/sync_api.py +14 -5
  6. openepd-5.3.0/src/openepd/api/utils.py +68 -0
  7. openepd-5.2.0/src/openepd/api/utils.py +0 -28
  8. {openepd-5.2.0 → openepd-5.3.0}/LICENSE +0 -0
  9. {openepd-5.2.0 → openepd-5.3.0}/README.md +0 -0
  10. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/__init__.py +0 -0
  11. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/api/__init__.py +0 -0
  12. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/api/average_dataset/__init__.py +0 -0
  13. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/api/average_dataset/industry_epd_sync_api.py +0 -0
  14. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/api/base_sync_client.py +0 -0
  15. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/api/category/__init__.py +0 -0
  16. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/api/category/dto.py +0 -0
  17. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/api/category/sync_api.py +0 -0
  18. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/api/common.py +0 -0
  19. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/api/dto/__init__.py +0 -0
  20. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/api/dto/base.py +0 -0
  21. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/api/dto/common.py +0 -0
  22. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/api/dto/meta.py +0 -0
  23. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/api/dto/mf.py +0 -0
  24. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/api/dto/params.py +0 -0
  25. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/api/epd/__init__.py +0 -0
  26. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/api/epd/dto.py +0 -0
  27. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/api/errors.py +0 -0
  28. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/api/pcr/__init__.py +0 -0
  29. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/api/pcr/sync_api.py +0 -0
  30. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/api/sync_client.py +0 -0
  31. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/api/test/__init__.py +0 -0
  32. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/bundle/__init__.py +0 -0
  33. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/bundle/base.py +0 -0
  34. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/bundle/model.py +0 -0
  35. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/bundle/reader.py +0 -0
  36. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/bundle/writer.py +0 -0
  37. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/compat/__init__.py +0 -0
  38. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/compat/compat_functional_validators.py +0 -0
  39. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/compat/pydantic.py +0 -0
  40. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/__init__.py +0 -0
  41. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/base.py +0 -0
  42. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/category.py +0 -0
  43. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/common.py +0 -0
  44. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/declaration.py +0 -0
  45. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/epd.py +0 -0
  46. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/factory.py +0 -0
  47. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/generic_estimate.py +0 -0
  48. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/geography.py +0 -0
  49. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/industry_epd.py +0 -0
  50. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/lcia.py +0 -0
  51. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/org.py +0 -0
  52. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/pcr.py +0 -0
  53. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/README.md +0 -0
  54. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/__init__.py +0 -0
  55. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/asphalt.py +0 -0
  56. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/base.py +0 -0
  57. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/concrete.py +0 -0
  58. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/__init__.py +0 -0
  59. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/accessories.py +0 -0
  60. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/aggregates.py +0 -0
  61. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/aluminium.py +0 -0
  62. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/asphalt.py +0 -0
  63. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/bulk_materials.py +0 -0
  64. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/cast_decks_and_underlayment.py +0 -0
  65. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/cladding.py +0 -0
  66. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/cmu.py +0 -0
  67. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/common.py +0 -0
  68. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/concrete.py +0 -0
  69. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/conveying_equipment.py +0 -0
  70. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/electrical.py +0 -0
  71. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/electrical_transmission_and_distribution_equipment.py +0 -0
  72. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/electricity.py +0 -0
  73. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/enums.py +0 -0
  74. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/finishes.py +0 -0
  75. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/fire_and_smoke_protection.py +0 -0
  76. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/furnishings.py +0 -0
  77. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/grouting.py +0 -0
  78. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/manufacturing_inputs.py +0 -0
  79. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/masonry.py +0 -0
  80. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/material_handling.py +0 -0
  81. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/mechanical.py +0 -0
  82. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/mechanical_insulation.py +0 -0
  83. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/mixins/__init__.py +0 -0
  84. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/mixins/conduit_mixin.py +0 -0
  85. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/network_infrastructure.py +0 -0
  86. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/openings.py +0 -0
  87. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/other_electrical_equipment.py +0 -0
  88. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/other_materials.py +0 -0
  89. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/plumbing.py +0 -0
  90. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/precast_concrete.py +0 -0
  91. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/sheathing.py +0 -0
  92. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/steel.py +0 -0
  93. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/thermal_moisture_protection.py +0 -0
  94. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/utility_piping.py +0 -0
  95. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/wood.py +0 -0
  96. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/generated/wood_joists.py +0 -0
  97. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/__init__.py +0 -0
  98. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/accessories.py +0 -0
  99. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/aggregates.py +0 -0
  100. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/aluminium.py +0 -0
  101. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/asphalt.py +0 -0
  102. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/bulk_materials.py +0 -0
  103. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/cast_decks_and_underlayment.py +0 -0
  104. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/cladding.py +0 -0
  105. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/cmu.py +0 -0
  106. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/concrete.py +0 -0
  107. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/conveying_equipment.py +0 -0
  108. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/electrical.py +0 -0
  109. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/electrical_transmission_and_distribution_equipment.py +0 -0
  110. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/electricity.py +0 -0
  111. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/finishes.py +0 -0
  112. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/fire_and_smoke_protection.py +0 -0
  113. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/furnishings.py +0 -0
  114. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/grouting.py +0 -0
  115. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/manufacturing_inputs.py +0 -0
  116. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/masonry.py +0 -0
  117. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/material_handling.py +0 -0
  118. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/mechanical.py +0 -0
  119. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/mechanical_insulation.py +0 -0
  120. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/network_infrastructure.py +0 -0
  121. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/openings.py +0 -0
  122. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/other_electrical_equipment.py +0 -0
  123. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/other_materials.py +0 -0
  124. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/plumbing.py +0 -0
  125. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/precast_concrete.py +0 -0
  126. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/sheathing.py +0 -0
  127. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/steel.py +0 -0
  128. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/thermal_moisture_protection.py +0 -0
  129. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/utility_piping.py +0 -0
  130. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/wood.py +0 -0
  131. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/specs/range/wood_joists.py +0 -0
  132. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/standard.py +0 -0
  133. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/validation/__init__.py +0 -0
  134. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/validation/common.py +0 -0
  135. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/validation/enum.py +0 -0
  136. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/validation/numbers.py +0 -0
  137. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/validation/quantity.py +0 -0
  138. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/model/versioning.py +0 -0
  139. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/patch_pydantic.py +0 -0
  140. {openepd-5.2.0 → openepd-5.3.0}/src/openepd/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: openepd
3
- Version: 5.2.0
3
+ Version: 5.3.0
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,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "openepd"
3
- version = "5.2.0"
3
+ version = "5.3.0"
4
4
  license = "Apache-2.0"
5
5
  description = "Python library to work with OpenEPD format"
6
6
  authors = ["C-Change Labs <support@c-change-labs.com>"]
@@ -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 = "5.2.0"
16
+ VERSION = "5.3.0"
@@ -21,7 +21,7 @@ from openepd.api.base_sync_client import BaseApiMethodGroup
21
21
  from openepd.api.common import StreamingListResponse, paging_meta_from_v1_api
22
22
  from openepd.api.dto.common import BaseMeta, OpenEpdApiResponse
23
23
  from openepd.api.dto.meta import PagingMetaMixin
24
- from openepd.api.utils import encode_path_param
24
+ from openepd.api.utils import encode_path_param, remove_none_id_fields
25
25
  from openepd.model.generic_estimate import (
26
26
  GenericEstimate,
27
27
  GenericEstimatePreview,
@@ -57,26 +57,33 @@ class GenericEstimateApi(BaseApiMethodGroup):
57
57
 
58
58
  @overload
59
59
  def post_with_refs(
60
- self, ge: GenericEstimateWithDeps, with_response: Literal[True]
60
+ self, ge: GenericEstimateWithDeps, with_response: Literal[True], exclude_defaults: bool = True
61
61
  ) -> tuple[GenericEstimate, Response]: ...
62
62
 
63
63
  @overload
64
- def post_with_refs(self, ge: GenericEstimateWithDeps, with_response: Literal[False] = False) -> GenericEstimate: ...
64
+ def post_with_refs(
65
+ self, ge: GenericEstimateWithDeps, with_response: Literal[False] = False, exclude_defaults: bool = True
66
+ ) -> GenericEstimate: ...
65
67
 
66
68
  def post_with_refs(
67
- self, ge: GenericEstimateWithDeps, with_response: bool = False
69
+ self, ge: GenericEstimateWithDeps, with_response: bool = False, exclude_defaults: bool = True
68
70
  ) -> GenericEstimate | tuple[GenericEstimate, Response]:
69
71
  """
70
72
  Post an GenericEstimate with references.
71
73
 
72
74
  :param ge: GenericEstimate
73
75
  :param with_response: return the response object togather with the GenericEstimate
76
+ :param exclude_defaults: If True, fields with default values are excluded from the payload
74
77
  :return: GenericEstimate alone, or GenericEstimate with HTTP Response object depending on parameter
75
78
  """
79
+ data = ge.to_serializable(exclude_unset=True, exclude_defaults=exclude_defaults, by_alias=True)
80
+ if exclude_defaults is False:
81
+ # Remove 'id' fields with None values, as 'id' cannot be None
82
+ data = remove_none_id_fields(data)
76
83
  response = self._client.do_request(
77
84
  "patch",
78
85
  "/generic_estimates/post_with_refs",
79
- json=ge.to_serializable(exclude_unset=True, exclude_defaults=True, by_alias=True),
86
+ json=data,
80
87
  )
81
88
  content = response.json()
82
89
  if with_response:
@@ -20,7 +20,7 @@ from requests import Response
20
20
  from openepd.api.base_sync_client import BaseApiMethodGroup
21
21
  from openepd.api.common import StreamingListResponse
22
22
  from openepd.api.epd.dto import EpdSearchResponse, EpdStatisticsResponse, StatisticsDto
23
- from openepd.api.utils import encode_path_param
23
+ from openepd.api.utils import encode_path_param, remove_none_id_fields
24
24
  from openepd.model.epd import Epd
25
25
 
26
26
 
@@ -106,23 +106,32 @@ class EpdApi(BaseApiMethodGroup):
106
106
  return self.get_statistics_raw(omf).payload
107
107
 
108
108
  @overload
109
- def post_with_refs(self, epd: Epd, with_response: Literal[True]) -> tuple[Epd, Response]: ...
109
+ def post_with_refs(
110
+ self, epd: Epd, with_response: Literal[True], exclude_defaults: bool = True
111
+ ) -> tuple[Epd, Response]: ...
110
112
 
111
113
  @overload
112
- def post_with_refs(self, epd: Epd, with_response: Literal[False] = False) -> Epd: ...
114
+ def post_with_refs(self, epd: Epd, with_response: Literal[False] = False, exclude_defaults: bool = True) -> Epd: ...
113
115
 
114
- def post_with_refs(self, epd: Epd, with_response: bool = False) -> Epd | tuple[Epd, Response]:
116
+ def post_with_refs(
117
+ self, epd: Epd, with_response: bool = False, exclude_defaults: bool = True
118
+ ) -> Epd | tuple[Epd, Response]:
115
119
  """
116
120
  Post an EPD with references.
117
121
 
118
122
  :param epd: EPD
119
123
  :param with_response: return the response object togather with the EPD
124
+ :param exclude_defaults: If True, fields with default values are excluded from the payload
120
125
  :return: EPD or EPD with HTTP Response object depending on parameter
121
126
  """
127
+ epd_data = epd.to_serializable(exclude_unset=True, exclude_defaults=exclude_defaults, by_alias=True)
128
+ if exclude_defaults is False:
129
+ # Remove 'id' fields with None values, as 'id' cannot be None
130
+ epd_data = remove_none_id_fields(epd_data)
122
131
  response = self._client.do_request(
123
132
  "patch",
124
133
  "/epds/post-with-refs",
125
- json=epd.to_serializable(exclude_unset=True, exclude_defaults=True, by_alias=True),
134
+ json=epd_data,
126
135
  )
127
136
  content = response.json()
128
137
  if with_response:
@@ -0,0 +1,68 @@
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__ = ("encode_path_param",)
17
+
18
+ from urllib.parse import quote
19
+
20
+
21
+ def encode_path_param(value: str) -> str:
22
+ """
23
+ Encode a path parameter value.
24
+
25
+ :param value: parameter value
26
+ :return: encoded value
27
+ """
28
+ return quote(value, safe="")
29
+
30
+
31
+ def remove_none_id_fields(d: dict) -> dict:
32
+ """
33
+ Remove any key 'id' with a None value from the dictionary, including nested dicts.
34
+
35
+ :param d: the dict which may contain 'id' keys with None values.
36
+ :return: a new dict with 'id' keys that have None values removed.
37
+
38
+ :note:
39
+ - This function does not modify the original dictionary (no side effects).
40
+ - It returns a new dictionary with the necessary modifications applied.
41
+
42
+ :example:
43
+ >>> data = {
44
+ ... "id": None,
45
+ ... "name": "item1",
46
+ ... "details": {
47
+ ... "id": None,
48
+ ... "category": "tools",
49
+ ... "nested": {
50
+ ... "id": None,
51
+ ... "value": 42
52
+ ... }
53
+ ... }
54
+ ... }
55
+ >>> remove_none_id_fields(data)
56
+ {'name': 'item1', 'details': {'category': 'tools', 'nested': {'value': 42}}}
57
+ """
58
+ if not isinstance(d, dict):
59
+ return d
60
+
61
+ cleaned_dict = {}
62
+ for k, v in d.items():
63
+ if isinstance(v, dict):
64
+ v = remove_none_id_fields(v)
65
+ if not (k == "id" and v is None):
66
+ cleaned_dict[k] = v
67
+
68
+ return cleaned_dict
@@ -1,28 +0,0 @@
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__ = ("encode_path_param",)
17
-
18
- from urllib.parse import quote
19
-
20
-
21
- def encode_path_param(value: str) -> str:
22
- """
23
- Encode a path parameter value.
24
-
25
- :param value: parameter value
26
- :return: encoded value
27
- """
28
- return quote(value, safe="")
File without changes
File without changes
File without changes
File without changes