xpipe_api 0.1.26__py3-none-any.whl → 0.1.28__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
xpipe_api/clients.py CHANGED
@@ -19,7 +19,7 @@ class Client:
19
19
  base_url: str
20
20
  raise_errors: bool
21
21
  session: Optional[str] = None
22
- min_version: Version = Version("10.1-12")
22
+ min_version: Version = Version("15.2")
23
23
 
24
24
  def __init__(
25
25
  self, token: Optional[str] = None, base_url: Optional[str] = None, ptb: bool = False, raise_errors: bool = True
@@ -36,7 +36,7 @@ class Client:
36
36
  except PermissionError:
37
37
  raise NoTokenFoundException("Bad permissions on xpipe_auth: is the daemon running as another user?")
38
38
  except Exception as e:
39
- raise NoTokenFoundException(f"No auth provided and couldn't load xpipe_auth: {e!r}")
39
+ raise NoTokenFoundException(f"No auth provided and couldn't load xpipe_auth: {e!r}. Is the XPipe daemon running?")
40
40
 
41
41
  if not base_url:
42
42
  base_url = "http://127.0.0.1:21722" if ptb else "http://127.0.0.1:21721"
@@ -57,11 +57,12 @@ class Client:
57
57
  session = response.get("sessionToken", None)
58
58
  if session:
59
59
  self.session = session
60
+ daemon_version = self.daemon_version()["version"]
61
+ assert (
62
+ daemon_version == "dev" or Version(daemon_version) >= self.min_version
63
+ ), f"xpipe_api requires XPipe of at least {self.min_version}"
60
64
  else:
61
65
  raise AuthFailedException(json.dumps(response))
62
- assert (
63
- Version(self.daemon_version()["version"]) >= self.min_version
64
- ), f"xpipe_api requires XPipe of at least {self.min_version}"
65
66
 
66
67
  def _post(self, *args, **kwargs) -> requests.Response:
67
68
  if not self.session:
@@ -109,7 +110,7 @@ class Client:
109
110
  def get(self, *args, **kwargs) -> bytes:
110
111
  return self._get(*args, **kwargs).content
111
112
 
112
- def connection_query(self, categories: str = "*", connections: str = "*", types: str = "*") -> List[str]:
113
+ def connection_query(self, categories: str = "**", connections: str = "**", types: str = "*") -> List[str]:
113
114
  endpoint = f"{self.base_url}/connection/query"
114
115
  data = {"categoryFilter": categories, "connectionFilter": connections, "typeFilter": types}
115
116
  response = self.post(endpoint, json=data)
@@ -124,12 +125,20 @@ class Client:
124
125
  response = self.post(endpoint, json=data)
125
126
  return json.loads(response).get("infos", [])
126
127
 
127
- def connection_add(self, name: str, conn_data: dict, validate: bool = False) -> str:
128
+ def connection_add(self, name: str, conn_data: dict, validate: bool = False, category: str = None) -> str:
128
129
  endpoint = f"{self.base_url}/connection/add"
129
130
  data = {"name": name, "data": conn_data, "validate": validate}
131
+ if category:
132
+ data["category"] = category
130
133
  response = self.post(endpoint, json=data)
131
134
  return json.loads(response)["connection"]
132
135
 
136
+ def category_add(self, name: str, parent: str) -> str:
137
+ endpoint = f"{self.base_url}/category/add"
138
+ data = {"name": name, "parent": parent}
139
+ response = self.post(endpoint, json=data)
140
+ return json.loads(response)["category"]
141
+
133
142
  def connection_remove(self, uuids: Union[str, List[str]]):
134
143
  endpoint = f"{self.base_url}/connection/remove"
135
144
  if not isinstance(uuids, list):
@@ -161,7 +170,7 @@ class Client:
161
170
  data = {"connection": connection}
162
171
  self.post(endpoint, json=data)
163
172
 
164
- def get_connections(self, categories: str = "*", connections: str = "*", types: str = "*") -> List[dict]:
173
+ def get_connections(self, categories: str = "**", connections: str = "**", types: str = "*") -> List[dict]:
165
174
  """Convenience method to chain connection/query with connection/info"""
166
175
  uuids = self.connection_query(categories, connections, types)
167
176
  return self.connection_info(uuids) if uuids else []
@@ -237,11 +246,13 @@ class AsyncClient(Client):
237
246
  session_token = parsed.get("sessionToken", None)
238
247
  if session_token:
239
248
  self.session = session_token
249
+ daemon_version = (await self.daemon_version())["version"]
250
+ assert (
251
+ daemon_version == "dev" or Version(daemon_version) >= self.min_version
252
+ ), f"xpipe_api requires XPipe of at least {self.min_version}"
240
253
  else:
241
254
  raise AuthFailedException(json.dumps(parsed))
242
- assert (
243
- Version((await self.daemon_version())["version"]) >= self.min_version
244
- ), f"xpipe_api requires XPipe of at least {self.min_version}"
255
+
245
256
 
246
257
  async def _post(self, *args, **kwargs) -> aiohttp.ClientResponse:
247
258
  if not self.session:
@@ -301,7 +312,7 @@ class AsyncClient(Client):
301
312
  resp = await self._get(*args, **kwargs)
302
313
  return await resp.read()
303
314
 
304
- async def connection_query(self, categories: str = "*", connections: str = "*", types: str = "*") -> List[str]:
315
+ async def connection_query(self, categories: str = "**", connections: str = "**", types: str = "*") -> List[str]:
305
316
  endpoint = f"{self.base_url}/connection/query"
306
317
  data = {"categoryFilter": categories, "connectionFilter": connections, "typeFilter": types}
307
318
  response = await self.post(endpoint, json=data)
@@ -316,12 +327,20 @@ class AsyncClient(Client):
316
327
  response = await self.post(endpoint, json=data)
317
328
  return json.loads(response).get("infos", [])
318
329
 
319
- async def connection_add(self, name: str, conn_data: dict, validate: bool = False) -> str:
330
+ async def connection_add(self, name: str, conn_data: dict, validate: bool = False, category: str = None) -> str:
320
331
  endpoint = f"{self.base_url}/connection/add"
321
332
  data = {"name": name, "data": conn_data, "validate": validate}
333
+ if category:
334
+ data["category"] = category
322
335
  response = await self.post(endpoint, json=data)
323
336
  return json.loads(response)["connection"]
324
337
 
338
+ async def category_add(self, name: str, parent: str) -> str:
339
+ endpoint = f"{self.base_url}/category/add"
340
+ data = {"name": name, "parent": parent}
341
+ response = await self.post(endpoint, json=data)
342
+ return json.loads(response)["category"]
343
+
325
344
  async def connection_remove(self, uuids: Union[str, List[str]]):
326
345
  endpoint = f"{self.base_url}/connection/remove"
327
346
  if not isinstance(uuids, list):
@@ -353,7 +372,7 @@ class AsyncClient(Client):
353
372
  data = {"connection": connection}
354
373
  await self.post(endpoint, json=data)
355
374
 
356
- async def get_connections(self, categories: str = "*", connections: str = "*", types: str = "*") -> List[dict]:
375
+ async def get_connections(self, categories: str = "**", connections: str = "**", types: str = "*") -> List[dict]:
357
376
  uuids = await self.connection_query(categories, connections, types)
358
377
  return (await self.connection_info(uuids)) if uuids else []
359
378
 
@@ -0,0 +1,44 @@
1
+ Metadata-Version: 2.3
2
+ Name: xpipe_api
3
+ Version: 0.1.28
4
+ Summary: Client for the XPipe API
5
+ License: MIT
6
+ Author: Clint Olson
7
+ Author-email: coandco@gmail.com
8
+ Requires-Python: >=3.10,<4.0
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Requires-Dist: aiohttp-requests (>=0.2.4,<0.3.0)
16
+ Requires-Dist: packaging (>=24.1,<25.0)
17
+ Requires-Dist: requests (>=2.32.3,<3.0.0)
18
+ Project-URL: Repository, https://github.com/xpipe-io/xpipe-python-api
19
+ Description-Content-Type: text/markdown
20
+
21
+ # XPipe Python API
22
+
23
+ [![GitHub license](https://img.shields.io/github/license/xpipe-io/xpipe-python-api.svg)](https://github.com/xpipe-io/xpipe-python-api/blob/master/LICENSE)
24
+ [![PyPI version](https://img.shields.io/pypi/v/xpipe_api)](https://pypi.org/project/xpipe_api/)
25
+
26
+ Python client for the XPipe API. This library is a wrapper for the raw [HTTP API](https://github.com/xpipe-io/xpipe/blob/master/openapi.yaml) and intended to make working with it more convenient.
27
+
28
+ ```bash
29
+ python3 -m pip install xpipe_api
30
+ ```
31
+
32
+ You can find the documentation at https://docs.xpipe.io/guide/python-api.
33
+
34
+ ## Development
35
+
36
+ To run the test suite, you'll need to define the XPIPE_APIKEY env var. This will allow the two "log in with the ApiKey
37
+ rather than Local method" tests to work. Here's the recommended method for running the tests with poetry:
38
+
39
+ ```bash
40
+ cd /path/to/xpipe-python-api
41
+ poetry install
42
+ XPIPE_APIKEY=<api_key> poetry run pytest
43
+ ```
44
+
@@ -0,0 +1,7 @@
1
+ xpipe_api/__init__.py,sha256=XLv-a-mt7OcGS9OQbDBHKBsI4mO-4lgWDA13nZ0njFY,108
2
+ xpipe_api/clients.py,sha256=ZbNjpuOSsNtt_ge9XQYxNdYB_zQppBbJOUvg1IFg9Qo,19661
3
+ xpipe_api/exceptions.py,sha256=FdkNKLV1gOH8mOuNM9wH_q3hYNFEdMbQwAEZUX4yZQU,410
4
+ xpipe_api-0.1.28.dist-info/LICENSE,sha256=hWd_i4lSck0lBXcxe-2P4VCUyPAecKW-X1oOiXv21wE,1089
5
+ xpipe_api-0.1.28.dist-info/METADATA,sha256=sOkrtJfXrwEpfYmCW3nsbDI24hUqR8X5tSKH1ZWcKKU,1660
6
+ xpipe_api-0.1.28.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
7
+ xpipe_api-0.1.28.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 1.9.0
2
+ Generator: poetry-core 2.0.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,103 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: xpipe_api
3
- Version: 0.1.26
4
- Summary: Client for the XPipe API
5
- Home-page: https://github.com/xpipe-io/xpipe-python-api
6
- License: MIT
7
- Author: Clint Olson
8
- Author-email: coandco@gmail.com
9
- Requires-Python: >=3.10,<4.0
10
- Classifier: License :: OSI Approved :: MIT License
11
- Classifier: Programming Language :: Python :: 3
12
- Classifier: Programming Language :: Python :: 3.10
13
- Classifier: Programming Language :: Python :: 3.11
14
- Classifier: Programming Language :: Python :: 3.12
15
- Requires-Dist: aiohttp-requests (>=0.2.4,<0.3.0)
16
- Requires-Dist: packaging (>=24.1,<25.0)
17
- Requires-Dist: requests (>=2.32.3,<3.0.0)
18
- Project-URL: Repository, https://github.com/xpipe-io/xpipe-python-api
19
- Description-Content-Type: text/markdown
20
-
21
- # XPipe Python API
22
-
23
- [![GitHub license](https://img.shields.io/github/license/xpipe-io/xpipe-python-api.svg)](https://github.com/coandco/python_xpipe_api/blob/master/LICENSE)
24
- [![PyPI version](https://img.shields.io/pypi/v/xpipe_api)](https://pypi.org/project/xpipe_api/)
25
-
26
- Python client for the XPipe API. This library is a wrapper for the raw [HTTP API](https://github.com/xpipe-io/xpipe/blob/master/openapi.yaml) and intended to make working with it more convenient.
27
-
28
- ## Installation
29
- ```
30
- python3 -m pip install xpipe_api
31
- ```
32
-
33
- ## Usage
34
-
35
- ```python
36
- from xpipe_api import Client
37
-
38
- # By default, Client() will read an access key from the file xpipe_auth on the local filesystem
39
- # and talk to the XPipe HTTP server on localhost. To connect to a remote instance with an API
40
- # key, use Client(token="foo", base_url = "http://servername:21721")
41
- client = Client()
42
-
43
- # connection_query accepts glob-based filters on the category, connection name, and connection type
44
- all_connections = client.connection_query()
45
-
46
- # Each connection includes uuid, category, connection, and type information
47
- first_connection_uuid = all_connections[0]["uuid"]
48
-
49
- # Before any shell commands can be run, a shell session must be started on a connection
50
- client.shell_start(first_connection_uuid)
51
-
52
- # Prints {'exitCode': 0, 'stdout': 'hello world', 'stderr': ''}
53
- print(client.shell_exec(first_connection_uuid, "echo hello world"))
54
-
55
- # Clean up after ourselves by stopping the shell session
56
- client.shell_stop(first_connection_uuid)
57
- ```
58
-
59
- There's also an async version of the client that can be accessed as AsyncClient:
60
-
61
- ```python
62
- import asyncio
63
- from xpipe_api import AsyncClient
64
-
65
-
66
- async def main():
67
- # By default, Client() will read an access key from the file xpipe_auth on the local filesystem
68
- # and talk to the XPipe HTTP server on localhost. To connect to a remote instance with an API
69
- # key, use Client(token="foo", base_url = "http://servername:21721")
70
- client = AsyncClient()
71
-
72
- # connection_query accepts glob-based filters on the category, connection name, and connection type
73
- all_connections = await client.connection_query()
74
-
75
- # Each connection includes uuid, category, connection, and type information
76
- first_connection_uuid = all_connections[0]["uuid"]
77
-
78
- # Before any shell commands can be run, a shell session must be started on a connection
79
- await client.shell_start(first_connection_uuid)
80
-
81
- # Prints {'exitCode': 0, 'stdout': 'hello world', 'stderr': ''}
82
- print(await client.shell_exec(first_connection_uuid, "echo hello world"))
83
-
84
- # Clean up after ourselves by stopping the shell session
85
- await client.shell_stop(first_connection_uuid)
86
-
87
-
88
- if __name__ == "__main__":
89
- asyncio.run(main())
90
- ```
91
-
92
- This is only a short summary of the library. You can find more supported functionalities in the source itself.
93
-
94
- ## Tests
95
-
96
- To run the test suite, you'll need to define the XPIPE_APIKEY env var. This will allow the two "log in with the ApiKey
97
- rather than Local method" tests to work. Here's the recommended method for running the tests with poetry:
98
-
99
- ```commandline
100
- cd /path/to/python_xpipe_api
101
- poetry install
102
- XPIPE_APIKEY=<api_key> poetry run pytest
103
- ```
@@ -1,7 +0,0 @@
1
- xpipe_api/__init__.py,sha256=XLv-a-mt7OcGS9OQbDBHKBsI4mO-4lgWDA13nZ0njFY,108
2
- xpipe_api/clients.py,sha256=Pg0jyrJpjv8bB0Xo4vdQUiqK3RsLdlAmJXorJLNBwhw,18740
3
- xpipe_api/exceptions.py,sha256=FdkNKLV1gOH8mOuNM9wH_q3hYNFEdMbQwAEZUX4yZQU,410
4
- xpipe_api-0.1.26.dist-info/LICENSE,sha256=hWd_i4lSck0lBXcxe-2P4VCUyPAecKW-X1oOiXv21wE,1089
5
- xpipe_api-0.1.26.dist-info/METADATA,sha256=EMi4uQvxYDAw6jGDTK_ViCmUzgb9BNOZVeqyJbwIGvY,3900
6
- xpipe_api-0.1.26.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
7
- xpipe_api-0.1.26.dist-info/RECORD,,