Skip to content

Commit 1fdf9ec

Browse files
committed
Add support for environment context
1 parent 5da8186 commit 1fdf9ec

4 files changed

Lines changed: 93 additions & 0 deletions

File tree

‎pyiceberg/environment_context.py‎

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
18+
from importlib.metadata import version
19+
20+
21+
class EnvironmentContext:
22+
_PROPERTIES: dict[str, str] = {
23+
"engine-name": "pyiceberg",
24+
"engine-version": version("pyiceberg"),
25+
}
26+
27+
def __init__(self) -> None:
28+
raise NotImplementedError("EnvironmentContext is a utility class and cannot be instantiated.")
29+
30+
@classmethod
31+
def get(cls) -> dict[str, str]:
32+
"""Return a read-only copy of all properties."""
33+
return cls._PROPERTIES.copy()
34+
35+
@classmethod
36+
def put(cls, key: str, value: str) -> None:
37+
"""Will add the given key/value pair in a global properties map."""
38+
cls._PROPERTIES[key] = value
39+
40+
@classmethod
41+
def remove(cls, key: str) -> str | None:
42+
"""Remove the key from the global properties map."""
43+
return cls._PROPERTIES.pop(key, None)

‎pyiceberg/table/snapshots.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
from pydantic import Field, PrivateAttr, model_serializer
2727

28+
from pyiceberg.environment_context import EnvironmentContext
2829
from pyiceberg.io import FileIO
2930
from pyiceberg.manifest import DataFile, DataFileContent, ManifestFile, _manifests
3031
from pyiceberg.partitioning import UNPARTITIONED_PARTITION_SPEC, PartitionSpec
@@ -402,6 +403,9 @@ def _update_totals(total_property: str, added_property: str, removed_property: s
402403
removed_property=REMOVED_EQUALITY_DELETES,
403404
)
404405

406+
for key, value in EnvironmentContext.get().items():
407+
summary.__setitem__(key, value)
408+
405409
return summary
406410

407411

‎tests/table/test_snapshots.py‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import pytest
2121

22+
from pyiceberg.environment_context import EnvironmentContext
2223
from pyiceberg.manifest import DataFile, DataFileContent, ManifestContent, ManifestFile
2324
from pyiceberg.partitioning import PartitionField, PartitionSpec
2425
from pyiceberg.schema import Schema
@@ -315,6 +316,8 @@ def test_merge_snapshot_summaries_empty() -> None:
315316
"total-files-size": "0",
316317
"total-position-deletes": "0",
317318
"total-equality-deletes": "0",
319+
"engine-name": "pyiceberg",
320+
"engine-version": EnvironmentContext.get().get("engine-version"),
318321
},
319322
)
320323

@@ -349,6 +352,8 @@ def test_merge_snapshot_summaries_new_summary() -> None:
349352
"total-files-size": "4",
350353
"total-position-deletes": "5",
351354
"total-equality-deletes": "3",
355+
"engine-name": "pyiceberg",
356+
"engine-version": EnvironmentContext.get().get("engine-version"),
352357
},
353358
)
354359

@@ -391,6 +396,8 @@ def test_merge_snapshot_summaries_overwrite_summary() -> None:
391396
"total-files-size": "5",
392397
"total-position-deletes": "6",
393398
"total-equality-deletes": "4",
399+
"engine-name": "pyiceberg",
400+
"engine-version": EnvironmentContext.get().get("engine-version"),
394401
}
395402

396403
assert actual.additional_properties == expected

‎tests/test_environment_context.py‎

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
import tomllib
18+
19+
from pyiceberg.environment_context import EnvironmentContext
20+
21+
22+
def test_default_value() -> None:
23+
actual = EnvironmentContext.get()
24+
expected = {"engine-name": "pyiceberg", "engine-version": _project_version()}
25+
assert actual == expected
26+
27+
28+
def test_put_and_remove() -> None:
29+
EnvironmentContext.put("test-key", "test-value")
30+
assert EnvironmentContext.get()["test-key"] == "test-value"
31+
32+
EnvironmentContext.remove("test-key")
33+
assert "test-key" not in EnvironmentContext.get()
34+
35+
36+
def _project_version() -> str:
37+
with open("pyproject.toml", "rb") as f:
38+
data = tomllib.load(f)
39+
return data["project"]["version"]

0 commit comments

Comments
 (0)