Skip to content

Commit eb011d1

Browse files
committed
ENH: work on CLI tool
1 parent 4274eb5 commit eb011d1

File tree

6 files changed

+452
-62
lines changed

6 files changed

+452
-62
lines changed

docs/source/api-reference.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ Synchronous Communication with Save-And-Restore Server
1313

1414
SaveRestoreAPI
1515
SaveRestoreAPI.send_request
16+
SaveRestoreAPI.open
17+
SaveRestoreAPI.close
18+
SaveRestoreAPI.__enter__
19+
SaveRestoreAPI.__exit__
1620

1721
Authentication
1822
**************

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ dependencies = [
2929
]
3030

3131
[project.scripts]
32-
save-and-restore-upload = "save_and_restore_api.tools.upload:main"
32+
save-and-restore = "save_and_restore_api.tools.upload:main"
3333

3434
[project.urls]
3535
Homepage = "https://github.com/dmgav/save-and-restore-api"

src/save_and_restore_api/_api_async.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,27 @@
66

77
class SaveRestoreAPI(_SaveRestoreAPI_Base):
88
def open(self):
9+
# Reusing docstrings from the threaded version
910
self._client = httpx.AsyncClient(base_url=self._base_url, timeout=self._timeout)
1011

1112
async def close(self):
13+
# Reusing docstrings from the threaded version
1214
await self._client.aclose()
1315
self._client = None
1416

1517
async def __aenter__(self):
18+
# Reusing docstrings from the threaded version
1619
self.open()
1720
return self
1821

1922
async def __aexit__(self, exc_type, exc_value, traceback):
23+
# Reusing docstrings from the threaded version
2024
await self.close()
2125

2226
async def send_request(
2327
self, method, url, *, body_json=None, params=None, headers=None, data=None, timeout=None, auth=None
2428
):
29+
# Reusing docstrings from the threaded version
2530
try:
2631
client_response = None
2732
kwargs = self._prepare_request(
@@ -326,6 +331,11 @@ async def structure_path_nodes(self, path):
326331
return await self.send_request(method, url, params=params)
327332

328333

334+
SaveRestoreAPI.open.__doc__ = _SaveRestoreAPI_Threads.open.__doc__
335+
SaveRestoreAPI.close.__doc__ = _SaveRestoreAPI_Threads.close.__doc__
336+
SaveRestoreAPI.__aenter__.__doc__ = _SaveRestoreAPI_Threads.__enter__.__doc__
337+
SaveRestoreAPI.__aexit__.__doc__ = _SaveRestoreAPI_Threads.__exit__.__doc__
338+
329339
SaveRestoreAPI.send_request.__doc__ = _SaveRestoreAPI_Threads.send_request.__doc__
330340

331341
SaveRestoreAPI.info_get.__doc__ = _SaveRestoreAPI_Threads.info_get.__doc__

src/save_and_restore_api/_api_base.py

Lines changed: 57 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
# import getpass
22
import json
3-
from collections.abc import Mapping
43
from urllib.parse import quote
54

65
import httpx
@@ -25,27 +24,16 @@ def __init__(self, msg, request):
2524
super().__init__(msg)
2625

2726

28-
class RequestFailedError(Exception):
29-
def __init__(self, request, response):
30-
msg = response.get("msg", "") if isinstance(response, Mapping) else str(response)
31-
msg = msg or "(no error message)"
32-
msg = f"Request failed: {msg}"
33-
self.request = request
34-
self.response = response
35-
super().__init__(msg)
36-
37-
3827
class _SaveRestoreAPI_Base:
3928
RequestParameterError = RequestParameterError
4029
RequestTimeoutError = RequestTimeoutError
41-
RequestFailedError = RequestFailedError
4230
HTTPRequestError = HTTPRequestError
4331
HTTPClientError = HTTPClientError
4432
HTTPServerError = HTTPServerError
4533

4634
ROOT_NODE_UID = "44bef5de-e8e6-4014-af37-b8f6c8a939a2"
4735

48-
def __init__(self, *, base_url, timeout, request_fail_exceptions=True):
36+
def __init__(self, *, base_url, timeout=5.0):
4937
self._base_url = base_url
5038
self._timeout = timeout
5139
self._client = None
@@ -55,15 +43,67 @@ def __init__(self, *, base_url, timeout, request_fail_exceptions=True):
5543
def auth_gen(username, password):
5644
"""
5745
Generate and return httpx.BasicAuth object based on username and password.
58-
The object can be passed as ``auth`` parameter in API calls.
46+
The object can be passed as a value of ``auth`` parameter in API calls.
47+
Explicitly passing the authentication object may be useful if requests
48+
are made on behalf of multiple users in the same session. If a single user
49+
is authenticated per session, then use ``auth_set()`` to set authentication
50+
once.
51+
52+
Parameters
53+
----------
54+
username : str
55+
Username.
56+
password : str
57+
Password.
58+
59+
Returns
60+
-------
61+
httpx.BasicAuth
62+
Basic authentication object.
63+
64+
Examples
65+
--------
66+
67+
.. code-block:: python
68+
69+
from save_and_restore_api import SaveRestoreAPI
70+
71+
auth = SaveRestoreAPI.auth_gen(username="user", password="userPass")
5972
"""
6073
return httpx.BasicAuth(username=username, password=password)
6174

6275
def auth_set(self, *, username, password):
6376
"""
64-
Configure authentication for the session based on username and password.
65-
If the authentication is configured, there is no need to pass the authentication
66-
object with each API call.
77+
Set authentication for the session. Once the authentication is configured, the
78+
authentication object is automatically passed with each API call. Calling
79+
this function again overwrites the previous authentication. Use ``auth_clear()``
80+
function to clear authentication.
81+
82+
Parameters
83+
----------
84+
username : str
85+
Username.
86+
password : str
87+
Password.
88+
89+
Returns
90+
-------
91+
None
92+
93+
Examples
94+
--------
95+
96+
.. code-block:: python
97+
98+
from save_and_restore_api import SaveRestoreAPI
99+
100+
SR = SaveRestoreAPI(base_url="http://localhost:8080/save-restore")
101+
SR.auth_set(username="user", password="userPass")
102+
# ...........
103+
SR.auth_set(username="admin", password="adminPass")
104+
# ...........
105+
SR.auth_clear()
106+
67107
"""
68108
self._auth = self.auth_gen(username=username, password=password)
69109

src/save_and_restore_api/_api_threads.py

Lines changed: 70 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,78 @@
55

66
class SaveRestoreAPI(_SaveRestoreAPI_Base):
77
def open(self):
8-
self._client = httpx.Client(base_url=self._base_url, timeout=self._timeout)
8+
"""
9+
Open HTTP connection to the server. The function creates the HTTP client
10+
that is used to send requests to the server.
11+
12+
Examples
13+
--------
14+
15+
.. code-block:: python
16+
17+
from save_and_restore_api import SaveRestoreAPI
18+
19+
SR = SaveRestoreAPI(base_url="http://localhost:8080/save-restore")
20+
SR.open()
21+
info = SR.info_get()
22+
print(f"info={info}")
23+
SR.close()
24+
25+
Async version:
26+
27+
.. code-block:: python
28+
29+
from save_and_restore_api.aio import SaveRestoreAPI
30+
31+
SR = SaveRestoreAPI(base_url="http://localhost:8080/save-restore")
32+
await SR.open()
33+
info = await SR.info_get()
34+
print(f"info={info}")
35+
await SR.close()
36+
"""
37+
if self._client is not None:
38+
self._client = httpx.Client(base_url=self._base_url, timeout=self._timeout)
939

1040
def close(self):
11-
self._client.close()
12-
self._client = None
41+
"""
42+
Close HTTP connection to the server. The function closes the HTTP client.
43+
"""
44+
if self._client is not None:
45+
self._client.close()
46+
self._client = None
1347

1448
def __enter__(self):
49+
"""
50+
Support for the context manager protocol.
51+
52+
Examples
53+
--------
54+
55+
.. code-block:: python
56+
57+
from save_and_restore_api import SaveRestoreAPI
58+
59+
with SaveRestoreAPI(base_url="http://localhost:8080/save-restore") as SR:
60+
info = SR.info_get()
61+
print(f"info={info}")
62+
63+
Async version:
64+
65+
.. code-block:: python
66+
67+
from save_and_restore_api.aio import SaveRestoreAPI
68+
69+
async with SaveRestoreAPI(base_url="http://localhost:8080/save-restore") as SR:
70+
info = await SR.info_get()
71+
print(f"info={info}")
72+
"""
1573
self.open()
1674
return self
1775

1876
def __exit__(self, exc_type, exc_value, traceback):
77+
"""
78+
Support for the context manager protocol.
79+
"""
1980
self.close()
2081

2182
def send_request(
@@ -54,10 +115,12 @@ class constructor is used.
54115
55116
Raises
56117
------
57-
SaveRestoreAPI.RequestParameterError, SaveRestoreAPI.RequestTimeoutError,
58-
SaveRestoreAPI.RequestFailedError, SaveRestoreAPI.HTTPRequestError,
59-
SaveRestoreAPI.HTTPClientError, SaveRestoreAPI.HTTPServerError
60-
118+
RequestParameterError
119+
Invalid parameter value or type
120+
RequestTimeoutError
121+
Communication timeout error
122+
HTTPRequestError, HTTPClientError, HTTPServerError
123+
Error while processing the request or communicating with the server.
61124
"""
62125
try:
63126
client_response = None

0 commit comments

Comments
 (0)