11"""Client.py
22Client is the Python public API for TerminusDB"""
3+ import base64
34import copy
45import gzip
56import json
@@ -269,19 +270,16 @@ def ref(self):
269270 return self ._ref
270271
271272 @ref .setter
272- def ref (self , value ):
273- if isinstance ( value , str ) :
273+ def ref (self , value : Optional [ str ] ):
274+ if value is not None :
274275 value = value .lower ()
275- if value in ["local" , "remote" , None ]:
276- self ._ref = value
277- else :
278- raise ValueError ("ref can only be 'local' or 'remote'" )
276+ self ._ref = value
279277
280278 def connect (
281279 self ,
282280 team : str = "admin" ,
283281 db : Optional [str ] = None ,
284- remote_auth : str = None ,
282+ remote_auth : Optional [ dict ] = None ,
285283 use_token : bool = False ,
286284 jwt_token : Optional [str ] = None ,
287285 api_token : Optional [str ] = None ,
@@ -302,7 +300,7 @@ def connect(
302300 Name of the team, default to be "admin"
303301 db: optional, str
304302 Name of the database connected
305- remote_auth: optional, str
303+ remote_auth: optional, dict
306304 Remote Auth setting
307305 key: optional, str
308306 API key for connecting, default to be "root"
@@ -331,10 +329,13 @@ def connect(
331329
332330 self .team = team
333331 self .db = db
334- self ._remote_auth = remote_auth
332+ self ._remote_auth_dict = remote_auth
335333 self ._key = key
336334 self .user = user
337- self ._use_token = use_token
335+ if api_token :
336+ self ._use_token = True
337+ else :
338+ self ._use_token = use_token
338339 self ._jwt_token = jwt_token
339340 self ._api_token = api_token
340341 self .branch = branch
@@ -623,7 +624,7 @@ def set_db(self, dbid: str, team: Optional[str] = None) -> str:
623624 return self .connect (
624625 team = team ,
625626 db = dbid ,
626- remote_auth = self ._remote_auth ,
627+ remote_auth = self ._remote_auth_dict ,
627628 key = self ._key ,
628629 user = self .user ,
629630 branch = self .branch ,
@@ -1674,7 +1675,9 @@ def pull(
16741675
16751676 return json .loads (_finish_response (result ))
16761677
1677- def fetch (self , remote_id : str ) -> dict :
1678+ def fetch (self , remote_id : str ,
1679+ remote_auth : Optional [dict ] = None ,
1680+ ) -> dict :
16781681 """Fatch the brach from a remote
16791682
16801683 Parameters
@@ -1702,6 +1705,7 @@ def push(
17021705 remote_branch : Optional [str ] = None ,
17031706 message : Optional [str ] = None ,
17041707 author : Optional [str ] = None ,
1708+ remote_auth : Optional [dict ] = None ,
17051709 ) -> dict :
17061710 """Push changes from a branch to a remote repo
17071711
@@ -1715,6 +1719,8 @@ def push(
17151719 optional commit message
17161720 author: str, optional
17171721 option to overide the author of the operation
1722+ remote_auth: dict, optional
1723+ optional remote authorization (uses client remote auth otherwise)
17181724
17191725 Raises
17201726 ------
@@ -1744,10 +1750,13 @@ def push(
17441750 "author" : author ,
17451751 "message" : message ,
17461752 }
1753+ if self ._remote_auth_dict or remote_auth :
1754+ headers = {'Authorization-Remote' : self ._generate_remote_header (remote_auth ) if remote_auth else self ._remote_auth ()}
1755+ headers .update (self ._default_headers )
17471756
17481757 result = self ._session .post (
17491758 self ._push_url (),
1750- headers = self . _default_headers ,
1759+ headers = headers ,
17511760 json = rc_args ,
17521761 auth = self ._auth (),
17531762 )
@@ -2232,7 +2241,8 @@ def patch_resource(
22322241 return json .loads (result )
22332242
22342243 def clonedb (
2235- self , clone_source : str , newid : str , description : Optional [str ] = None
2244+ self , clone_source : str , newid : str , description : Optional [str ] = None ,
2245+ remote_auth : Optional [dict ] = None
22362246 ) -> None :
22372247 """Clone a remote repository and create a local copy.
22382248
@@ -2244,6 +2254,8 @@ def clonedb(
22442254 Identifier of the new repository to create.
22452255 Description : str, optional
22462256 Optional description about the cloned database.
2257+ remote_auth : str, optional
2258+ Optional remote authorization (uses client remote auth otherwise)
22472259
22482260 Raises
22492261 ------
@@ -2255,15 +2267,19 @@ def clonedb(
22552267 >>> client = Client("http://127.0.0.1:6363/")
22562268 >>> client.clonedb("http://terminusdb.com/some_user/test_db", "my_test_db")
22572269 """
2258- self ._check_connection ()
2270+ self ._check_connection (check_db = False )
22592271 if description is None :
22602272 description = f"New database { newid } "
2273+
2274+ if self ._remote_auth_dict or remote_auth :
2275+ headers = {'Authorization-Remote' : self ._generate_remote_header (remote_auth ) if remote_auth else self ._remote_auth ()}
2276+ headers .update (self ._default_headers )
22612277 rc_args = {"remote_url" : clone_source , "label" : newid , "comment" : description }
22622278
22632279 _finish_response (
22642280 self ._session .post (
22652281 self ._clone_url (newid ),
2266- headers = self . _default_headers ,
2282+ headers = headers ,
22672283 json = rc_args ,
22682284 auth = self ._auth (),
22692285 )
@@ -2312,7 +2328,25 @@ def _auth(self):
23122328 return APITokenAuth (os .environ ["TERMINUSDB_ACCESS_TOKEN" ])
23132329 else :
23142330 raise RuntimeError ("Client not connected." )
2315- # TODO: remote_auth
2331+
2332+ def _remote_auth (self ):
2333+ if self ._remote_auth_dict :
2334+ return self ._generate_remote_header (self ._remote_auth_dict )
2335+ elif "TERMINUSDB_REMOTE_ACCESS_TOKEN" in os .environ :
2336+ token = os .environ ["TERMINUSDB_REMOTE_ACCESS_TOKEN" ]
2337+ return f"Token { token } "
2338+
2339+ def _generate_remote_header (self , remote_auth : dict ):
2340+ key_type = remote_auth ['type' ]
2341+ key = remote_auth ['key' ]
2342+ if key_type == 'http_basic' :
2343+ username = remote_auth ['username' ]
2344+ http_basic_creds = base64 .b64encode (f"{ username } :{ key } " .encode ('utf-8' ))
2345+ return f"Basic { http_basic_creds } "
2346+ elif key_type == 'token' :
2347+ return f"Token { key } "
2348+ # JWT is the only key type remaining
2349+ return f"Bearer { key } "
23162350
23172351 def create_organization (self , org : str ) -> Optional [dict ]:
23182352 """
0 commit comments