Skip to content

Commit fd5bf7a

Browse files
committed
Update based on libtiledb latest
1 parent ee33075 commit fd5bf7a

File tree

6 files changed

+140
-64
lines changed

6 files changed

+140
-64
lines changed

tiledb/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
from .current_domain import CurrentDomain
2626
from .ndrectangle import NDRectangle
2727

28-
if libtiledb_version()[0] == 2 and libtiledb_version()[1] >= 28:
28+
if libtiledb_version()[0] == 2 and libtiledb_version()[1] >= 29:
2929
from .profile import Profile
3030

3131
del libtiledb_version # no longer needed

tiledb/ctx.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,24 @@ class Config(lt.Config):
5050
5151
:param dict params: Set parameter values from dict like object
5252
:param str path: Set parameter values from persisted Config parameter file
53+
:param str profile_name: Set the profile name to use for this Config object
54+
:param str profile_dir: Set the profile directory to use for this Config object
5355
"""
5456

55-
def __init__(self, params: dict = None, path: str = None):
57+
def __init__(
58+
self,
59+
params: dict = None,
60+
path: str = None,
61+
profile_name: str = None,
62+
profile_dir: str = None,
63+
):
5664
super().__init__()
5765
if path is not None:
5866
self.load(path)
5967
if params is not None:
6068
self.update(params)
69+
if profile_name is not None or profile_dir is not None:
70+
self._set_profile(profile_name, profile_dir)
6171

6272
@staticmethod
6373
def load(uri: str):
@@ -293,6 +303,17 @@ def save(self, uri: str):
293303
"""
294304
self.save_to_file(uri)
295305

306+
def set_profile(self, profile_name: str = None, profile_dir: str = None):
307+
"""
308+
Sets the profile to use for the current Config object.
309+
:param profile_name: The name of the profile to use. If not provided,
310+
the default profile will be used.
311+
:param profile_dir: The directory where the profile is located. If not
312+
provided, the home directory will be used.
313+
:raises tiledb.TileDBError: If the profile cannot be found or loaded.
314+
"""
315+
self._set_profile(profile_name, profile_dir)
316+
296317
def __reduce__(self):
297318
"""
298319
Customize the pickling process by defining how to serialize

tiledb/libtiledb/context.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,13 @@ void init_config(py::module& m) {
5353
})
5454

5555
.def("save_to_file", &Config::save_to_file)
56+
57+
.def(
58+
"_set_profile",
59+
&Config::set_profile,
60+
py::arg("profile_name") = std::nullopt,
61+
py::arg("profile_dir") = std::nullopt)
62+
5663
.def("__eq__", &Config::operator==)
5764
.def("__ne__", &Config::operator!=)
5865
//.def("_ptr", &Config::ptr) // TBD should this be capsule?

tiledb/libtiledb/profile.cc

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,19 @@ using namespace tiledbpy::common;
1414
namespace py = pybind11;
1515

1616
void init_profile(py::module& m) {
17+
#if TILEDB_VERSION_MAJOR >= 2 && TILEDB_VERSION_MINOR >= 29
1718
py::class_<tiledb::Profile>(m, "Profile")
1819

1920
.def(
2021
py::init<std::optional<std::string>, std::optional<std::string>>(),
21-
py::keep_alive<1, 2>())
22+
py::arg("name") = std::nullopt,
23+
py::arg("dir") = std::nullopt)
2224

2325
.def(py::init<Profile>())
2426

25-
.def_property_readonly("_name", &tiledb::Profile::get_name)
27+
.def_property_readonly("_name", &tiledb::Profile::name)
2628

27-
.def_property_readonly("_homedir", &tiledb::Profile::get_homedir)
29+
.def_property_readonly("_dir", &tiledb::Profile::dir)
2830

2931
.def(
3032
"_set_param",
@@ -42,11 +44,12 @@ void init_profile(py::module& m) {
4244
std::optional<std::string>,
4345
std::optional<std::string>>(&tiledb::Profile::load),
4446
py::arg("name") = std::nullopt,
45-
py::arg("homedir") = std::nullopt)
47+
py::arg("dir") = std::nullopt)
4648

4749
.def("_remove", &tiledb::Profile::remove)
4850

4951
.def("_dump", &tiledb::Profile::dump);
52+
#endif
5053
}
5154

5255
} // namespace libtiledbcpp

tiledb/profile.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ class Profile(lt.Profile):
66
Represents a TileDB profile.
77
"""
88

9-
def __init__(self, name: str = None, homedir: str = None):
9+
def __init__(self, name: str = None, dir: str = None):
1010
"""Class representing a TileDB profile.
1111
1212
:param name: The name of the profile.
13-
:param homedir: The home directory of the profile.
13+
:param dir: The directory of the profile.
1414
:raises tiledb.TileDBError:
1515
"""
16-
super().__init__(name, homedir)
16+
super().__init__(name, dir)
1717

1818
@property
1919
def name(self):
@@ -24,12 +24,12 @@ def name(self):
2424
return self._name
2525

2626
@property
27-
def homedir(self):
28-
"""The home directory of the profile.
27+
def dir(self):
28+
"""The directory of the profile.
2929
3030
:rtype: str
3131
"""
32-
return self._homedir
32+
return self._dir
3333

3434
def __repr__(self):
3535
"""String representation of the profile.
@@ -63,18 +63,18 @@ def save(self):
6363
self._save()
6464

6565
@classmethod
66-
def load(cls, name: str = None, homedir: str = None) -> "Profile":
66+
def load(cls, name: str = None, dir: str = None) -> "Profile":
6767
"""Loads a profile from storage.
6868
6969
:param name: The name of the profile.
70-
:param homedir: The home directory of the profile.
70+
:param dir: The directory of the profile.
7171
:return: The loaded profile.
7272
:rtype: tiledb.Profile
7373
:raises tiledb.TileDBError:
7474
"""
7575
# This is a workaround for the from_pybind11 method due to the fact
7676
# that this class does not inherit from CtxMixin, as is commonly done.
77-
lt_obj = lt.Profile._load(name, homedir)
77+
lt_obj = lt.Profile._load(name, dir)
7878
py_obj = cls.__new__(cls)
7979
lt.Profile.__init__(py_obj, lt_obj)
8080
return py_obj

tiledb/tests/test_profile.py

Lines changed: 94 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import json
12
from pathlib import Path
23

34
import pytest
@@ -7,82 +8,126 @@
78

89
from .common import DiskTestCase
910

10-
if not (lt.version()[0] == 2 and lt.version()[1] >= 28):
11+
if not (lt.version()[0] == 2 and lt.version()[1] >= 29):
1112
pytest.skip(
12-
"Profile is only available in TileDB 2.28 and later",
13+
"Profile is only available in TileDB 2.29 and later",
1314
allow_module_level=True,
1415
)
1516

17+
"""
18+
Due to the nature of Profiles, they are touching the filesystem,
19+
so we need to be careful and not affect the user's Profiles.
20+
Thus we use DiskTestCase to create temporary directories.
21+
"""
22+
1623

1724
class ProfileTestCase(DiskTestCase):
1825
def setup_method(self):
1926
super().setup_method()
20-
self.profile1 = tiledb.Profile() # default profile
21-
self.profile2 = tiledb.Profile("test_profile") # named profile
22-
self.profile3 = tiledb.Profile(
23-
homedir=self.path("profile3_dir")
24-
) # profile with custom home directory
25-
self.profile4 = tiledb.Profile(
26-
"test_profile", self.path("profile4_dir")
27-
) # named profile with custom home directory
27+
self.profile1 = tiledb.Profile(
28+
dir=self.path("profile1_dir")
29+
) # profile with custom directory
30+
self.profile2 = tiledb.Profile(
31+
"profile2_name", self.path("profile2_dir")
32+
) # named profile with custom directory
2833

2934

3035
class ProfileTest(ProfileTestCase):
3136
def test_profile_name(self):
3237
assert self.profile1.name == "default"
33-
assert self.profile2.name == "test_profile"
34-
assert self.profile3.name == "default"
35-
assert self.profile4.name == "test_profile"
38+
assert self.profile2.name == "profile2_name"
3639

37-
def test_profile_homedir(self):
38-
assert Path(self.profile1.homedir) == Path.home()
39-
assert Path(self.profile2.homedir) == Path.home()
40-
assert Path(self.profile3.homedir) == Path(self.path("profile3_dir"))
41-
assert Path(self.profile4.homedir) == Path(self.path("profile4_dir"))
40+
def test_profile_dir(self):
41+
assert Path(self.profile1.dir) == Path(self.path("profile1_dir"))
42+
assert Path(self.profile2.dir) == Path(self.path("profile2_dir"))
4243

4344
def test_profile_set_get_param(self):
44-
self.profile1["rest.username"] = "my_username"
45-
assert self.profile1["rest.username"] == "my_username"
45+
username = "my_username"
46+
server_address = "https://myaddress.com"
4647

47-
self.profile3["rest.server_address"] = "https://myaddress.com"
48-
assert self.profile3["rest.server_address"] == "https://myaddress.com"
48+
self.profile1["rest.username"] = username
49+
assert self.profile1["rest.username"] == username
4950

50-
def test_profile_repr(self):
51-
self.profile1["rest.password"] = "testing_the_password"
52-
self.profile1["rest.payer_namespace"] = "testing_the_namespace"
53-
self.profile1["rest.server_address"] = "https://testing_the_address.com"
54-
self.profile1["rest.token"] = "testing_the_token"
55-
self.profile1["rest.username"] = "testing_the_username"
51+
self.profile1["rest.server_address"] = server_address
52+
assert self.profile1["rest.server_address"] == server_address
5653

57-
import json
54+
def test_profile_repr(self):
55+
password = "testing_the_password"
56+
payer_namespace = "testing_the_namespace"
57+
server_address = "https://testing_the_address.com"
58+
token = "testing_the_token"
59+
username = "testing_the_username"
60+
61+
self.profile1["rest.password"] = password
62+
self.profile1["rest.payer_namespace"] = payer_namespace
63+
self.profile1["rest.server_address"] = server_address
64+
self.profile1["rest.token"] = token
65+
self.profile1["rest.username"] = username
5866

5967
goal_dict = {
6068
"default": {
61-
"rest.password": "testing_the_password",
62-
"rest.payer_namespace": "testing_the_namespace",
63-
"rest.server_address": "https://testing_the_address.com",
64-
"rest.token": "testing_the_token",
65-
"rest.username": "testing_the_username",
69+
"rest.password": password,
70+
"rest.payer_namespace": payer_namespace,
71+
"rest.server_address": server_address,
72+
"rest.token": token,
73+
"rest.username": username,
6674
}
6775
}
6876

6977
assert goal_dict == json.loads(repr(self.profile1))
7078

7179
def test_profile_set_save_load_get(self):
72-
self.profile4["rest.token"] = "testing_the_token_for_profile4"
73-
self.profile4["rest.payer_namespace"] = "testing_the_namespace_for_profile4"
80+
token = "testing_the_token_for_profile2"
81+
payer_namespace = "testing_the_namespace_for_profile2"
82+
default_server_address = "https://api.tiledb.com"
83+
84+
self.profile2["rest.token"] = token
85+
self.profile2["rest.payer_namespace"] = payer_namespace
7486

7587
# save the profile
76-
self.profile4.save()
77-
78-
# load
79-
new_profile = tiledb.Profile.load("test_profile", self.path("profile4_dir"))
80-
assert new_profile.name == "test_profile"
81-
assert new_profile.homedir == self.path("profile4_dir")
82-
assert new_profile["rest.username"] == ""
83-
assert new_profile["rest.password"] == ""
84-
assert new_profile["rest.server_address"] == "https://api.tiledb.com"
85-
assert new_profile["rest.token"] == "testing_the_token_for_profile4"
86-
assert (
87-
new_profile["rest.payer_namespace"] == "testing_the_namespace_for_profile4"
88-
)
88+
self.profile2.save()
89+
90+
# load the profile
91+
loaded_profile = tiledb.Profile.load("profile2_name", self.path("profile2_dir"))
92+
assert loaded_profile.name == "profile2_name"
93+
assert loaded_profile.dir == self.path("profile2_dir")
94+
assert loaded_profile["rest.username"] == ""
95+
assert loaded_profile["rest.password"] == ""
96+
assert loaded_profile["rest.server_address"] == default_server_address
97+
assert loaded_profile["rest.token"] == token
98+
assert loaded_profile["rest.payer_namespace"] == payer_namespace
99+
100+
101+
class ConfigWithProfileTest(ProfileTestCase):
102+
def test_config_with_profile(self):
103+
username = "username_coming_from_profile"
104+
password = "password_coming_from_profile"
105+
server_address = "https://profile_address.com"
106+
107+
# Create a profile and set some parameters
108+
profile = tiledb.Profile(dir=self.path("profile_with_config_dir"))
109+
profile["rest.username"] = username
110+
profile["rest.password"] = password
111+
profile["rest.server_address"] = server_address
112+
113+
# Save the profile
114+
profile.save()
115+
116+
# -----
117+
# The above is done only once, so we can use the same profile later
118+
# -----
119+
120+
# Create a config and set the profile
121+
config = tiledb.Config()
122+
config.set_profile(profile_dir=self.path("profile_with_config_dir"))
123+
# Test that the config parameters are set correctly
124+
assert config["rest.username"] == username
125+
assert config["rest.password"] == password
126+
assert config["rest.server_address"] == server_address
127+
128+
# Alternatively, we can set the profile details directly in the Config constructor
129+
config2 = tiledb.Config(profile_dir=self.path("profile_with_config_dir"))
130+
# Test that the config parameters are set correctly
131+
assert config2["rest.username"] == username
132+
assert config2["rest.password"] == password
133+
assert config2["rest.server_address"] == server_address

0 commit comments

Comments
 (0)