Skip to content

Commit ebef5ce

Browse files
authored
Merge pull request #7 from dmgav/docs-devel
Docstrings for API functions
2 parents 254c6bd + 6a7da09 commit ebef5ce

File tree

5 files changed

+676
-68
lines changed

5 files changed

+676
-68
lines changed

docs/source/usage.rst

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,170 @@
11
=====
22
Usage
33
=====
4+
5+
The **save-and-restore-api** package provides a Python API library and **save-and-restore**
6+
CLI tool. The library is Python developer-friendly interface for communication with
7+
Save-and-Restore service via REST API. The **save-and-restore** CLI tool allows to perform
8+
some operations on Save-and-Restore nodes from the command line and can be used in Bash
9+
scripts.
10+
11+
'save-and-restore-api' Python library
12+
=====================================
13+
14+
**save-and-restore-api** is a Python library for communicating with Save-and-Restore service
15+
(CS Studio Phoebus). The package provides syncronous (thread-based) and asynchronous (asyncio)
16+
versions of the API classes. The synchronous ``SaveRestoreAPI`` class is located in the
17+
``save_and_restore_api`` module and the asynchronous counterpart is located in the
18+
``save_and_restore_api.aio`` module. Both classes provide the same set of methods and properties.
19+
The library is built on top of the **httpx** package.
20+
21+
All API requests to Save-and-Restore service except GET requests require authentication.
22+
There are two ways to set authentication credentials. The first way is to call the ``auth_set()``
23+
method of the API class instance. The method sets credentials for all subsequent API calls.
24+
Repeatedly calling the method overwrites previously set credentials. The second way is to
25+
generate the authentication object by calling the ``auth_gen()`` method and pass the returned
26+
object to the ``auth`` parameter of the API methods. This method may be useful if the application
27+
simultaneously supports multiple users with different credentials.
28+
29+
The ``SaveRestoreAPI`` class supports context manager protocol. The class can be used with
30+
and without context manager. The choice depends on the application architecture. The context
31+
manager automatically opens and closes the underlying HTTP socket:
32+
33+
.. code-block:: python
34+
35+
from save_and_restore_api import SaveRestoreAPI
36+
37+
with SaveRestoreAPI(base_url="http://localhost:8080/save-restore") as SR:
38+
39+
# < Set authentication if necessary >
40+
SR.auth_set(username="user", password="user_password")
41+
42+
# < The code that communicates with Save-and-Restore service using SR object>
43+
44+
If using the class without context manager, the application is responsible for opening
45+
and closing the HTTP socket:
46+
47+
.. code-block:: python
48+
49+
try:
50+
SR = SaveRestoreAPI(base_url="http://localhost:8080/save-restore")
51+
SR.open()
52+
53+
# < Set authentication if necessary >
54+
SR.auth_set(username="user", password="user_password")
55+
56+
# < The code that communicates with Save-and-Restore service using SR object>
57+
58+
finally:
59+
SR.close()
60+
61+
62+
Examples
63+
========
64+
65+
The following example code creates a folder node named "My Folder" under the root node:
66+
67+
.. code-block:: python
68+
69+
from save_and_restore_api import SaveRestoreAPI
70+
71+
with SaveRestoreAPI(base_url="http://localhost:8080/save-restore") as SR:
72+
SR.auth_set(username="user", password="user_password")
73+
74+
root_folder_uid = SR.ROOT_NODE_UID
75+
node={"name": "My Folder", "nodeType": "FOLDER"}
76+
77+
folder = SR.node_add(root_folder_uid, node=node)
78+
79+
print(f"Created folder metadata: {folder}")
80+
81+
Here is an async version of the same code:
82+
83+
.. code-block:: python
84+
85+
from save_and_restore_api.aio import SaveRestoreAPI
86+
87+
async with SaveRestoreAPI(base_url="http://localhost:8080/save-restore") as SR:
88+
await SR.auth_set(username="user", password="user_password")
89+
90+
root_folder_uid = SR.ROOT_NODE_UID
91+
node={"name": "My Folder", "nodeType": "FOLDER"}
92+
93+
folder = await SR.node_add(root_folder_uid, node=node)
94+
print(f"Created folder metadata: {folder}")
95+
96+
'save-and-restore' CLI tool
97+
===========================
98+
99+
**save-and-restore** CLI tool is installed with the package. The tool allows performing
100+
a limited set of basic operations on the nodes of the Save-and-Restore service.
101+
The currently selected set of operations:
102+
103+
- **LOGIN**: test login credentials;
104+
105+
- **CONFIG ADD**: create configuration node based on a list of PVs read from a file;
106+
107+
- **CONFIG UPDATE**: update an existing configuration node based on a list of PVs read from a file;
108+
109+
- **CONFIG GET**: get information about an existing configuration node, including the list of PVs.
110+
111+
The tool was primarily developed for adding snapshot configurations to Save-and-Restore
112+
based on lists of PVs loaded from local files. Typical use case is to create a configuration
113+
based on a list of PVs read from an autosave (``.sav``) file saved by an IOC. Currently only
114+
autosave files are supported, but support for other formats can be added if needed.
115+
The list of supported functions can also be extended.
116+
117+
There are multiple ways to pass authentication credentials to the tool. The credentials include
118+
user name and password. The user name can be passed using the ``--user-name`` command line
119+
parameter. The tool interactively prompts for the password of the operation requires
120+
authentication. If the user name is not specified, then the tool also prompts for it.
121+
Alternatively, the user name and/or password can be passed using environment variables.
122+
123+
The following environment variables are supported:
124+
125+
- ``SAVE_AND_RESTORE_API_BASE_URL``: host URL (see '--base-url' parameter)
126+
- ``SAVE_AND_RESTORE_API_USER_NAME``: user name (see '--user-name' parameter);
127+
- ``SAVE_AND_RESTORE_API_USER_PASSWORD``: user password.
128+
129+
Examples of using 'save-and-restore' CLI tool
130+
=============================================
131+
132+
Check login credentials. User password is requested interactively. Alternatively, the
133+
password can be passed using environment variable ``SAVE_AND_RESTORE_API_USER_PASSWORD``.
134+
135+
.. code-block:: bash
136+
137+
save-and-restore --base-url http://localhost:8080/save-restore --user-name=user LOGIN
138+
139+
Read the configuration node named 'eiger_config'. Print the full configuration data
140+
(the list of PVs):
141+
142+
.. code-block:: bash
143+
144+
save-and-restore --base-url http://localhost:8080/save-restore \
145+
CONFIG GET --config-name /detectors/imaging/eiger_config --show-data=ON
146+
147+
Create a new configuration node named 'eiger_config'. Load the list of PVs from
148+
file ``eiger_pvs.sav``. Automatically create any missing parent folders in
149+
the path:
150+
151+
.. code-block:: bash
152+
153+
save-and-restore --base-url=http://localhost:8080/save-restore --user-name=user \
154+
--create-folders=ON CONFIG ADD --config-name=/detectors/imaging/eiger_config \
155+
--file-name=eiger_pvs.sav --file-format=autosave
156+
157+
Update an existing configuration node named 'eiger_config'. Load the list of PVs
158+
from the file ``eiger_pvs.sav``:
159+
160+
.. code-block:: bash
161+
162+
save-and-restore --base-url http://localhost:8080/save-restore --user-name=user \
163+
CONFIG UPDATE --config-name /detectors/imaging/eiger_config \
164+
--file-name eiger_pvs.sav --file-format autosave
165+
166+
Print full list of options:
167+
168+
.. code-block:: bash
169+
170+
save-and-restore -h

src/save_and_restore_api/_api_base.py

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -442,35 +442,3 @@ def _prepare_structure_path_nodes(self, *, path):
442442
method, url = "GET", "/path"
443443
params = {"path": path}
444444
return method, url, params
445-
446-
# =============================================================================================
447-
448-
# def create_config(self, parent_node_uid, name, pv_list):
449-
# config_dict = {
450-
# "configurationNode": {
451-
# "name": name,
452-
# "nodeType": "CONFIGURATION",
453-
# "userName": self._username,
454-
# },
455-
# "configurationData": {
456-
# "pvList": pv_list,
457-
# },
458-
# }
459-
# print(f"config_dict=\n{pprint.pformat(config_dict)}")
460-
# return self.send_request("PUT", f"/config?parentNodeId={parent_node_uid}", body_json=config_dict)
461-
462-
# def update_config(self, node_uid, name, pv_list):
463-
# config_dict = {
464-
# "configurationNode": {
465-
# "name": name,
466-
# "nodeType": "CONFIGURATION",
467-
# "userName": self._username,
468-
# "uniqueId": node_uid,
469-
# },
470-
# "configurationData": {
471-
# "pvList": pv_list,
472-
# },
473-
# }
474-
# print(f"config_dict=\n{pprint.pformat(config_dict)}")
475-
# # return self.send_request("POST", f"/config/{node_uid}", body_json=config_dict)
476-
# return self.send_request("POST", "/config", body_json=config_dict)

0 commit comments

Comments
 (0)