dsf-python 3.6.0b2__py3-none-any.whl → 3.6.0b2.post3__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.
dsf/__init__.py CHANGED
@@ -1,3 +1,5 @@
1
+ __version__ = "3.6.0-b2.post3"
2
+
1
3
  # path to unix socket file
2
4
  SOCKET_FILE = "/run/dsf/dcs.sock"
3
5
 
dsf/commands/plugins.py CHANGED
@@ -21,7 +21,7 @@ def reload_plugin(plugin: str):
21
21
  return BaseCommand("ReloadPlugin", **{"plugin": plugin})
22
22
 
23
23
 
24
- def set_plugin_data(plugin: str, key: str, value: str):
24
+ def set_plugin_data(plugin: str, key: str, value):
25
25
  """
26
26
  Update custom plugin data in the object model
27
27
  May be used to update only the own plugin data unless the plugin has the ManagePlugins permission.
@@ -34,10 +34,8 @@ def set_plugin_data(plugin: str, key: str, value: str):
34
34
  raise TypeError("plugin must be a string")
35
35
  if not isinstance(key, str) or not key:
36
36
  raise TypeError("key must be a string")
37
- if not isinstance(value, str):
38
- raise TypeError("value must be a string")
39
37
  return BaseCommand(
40
- "SetPluginData", **{"Plugin": plugin, "key": key, "value": value}
38
+ "SetPluginData", **{"plugin": plugin, "key": key, "value": value}
41
39
  )
42
40
 
43
41
 
dsf/http.py CHANGED
@@ -1,5 +1,8 @@
1
1
  import asyncio
2
2
  import json
3
+ import socket
4
+ import stat
5
+ import errno
3
6
  import os
4
7
  from concurrent.futures import ThreadPoolExecutor
5
8
  from enum import Enum
@@ -11,10 +14,11 @@ from .object_model import HttpEndpointType
11
14
  class HttpResponseType(str, Enum):
12
15
  """Enumeration of supported HTTP responses"""
13
16
 
14
- StatusCode = "StatusCode"
15
- PlainText = "PlainText"
16
- JSON = "JSON"
17
- File = "File"
17
+ StatusCode = "statuscode"
18
+ PlainText = "plainText"
19
+ JSON = "json"
20
+ File = "file"
21
+ URI = "uri"
18
22
 
19
23
 
20
24
  class ReceivedHttpRequest:
@@ -47,7 +51,7 @@ class HttpEndpointConnection:
47
51
  """Close the connection"""
48
52
  self.writer.close()
49
53
 
50
- async def read_request(self):
54
+ async def read_request(self) -> ReceivedHttpRequest:
51
55
  """
52
56
  Read information about the last HTTP request.
53
57
  Note that a call to this method may fail!
@@ -67,9 +71,9 @@ class HttpEndpointConnection:
67
71
  try:
68
72
  await self.send(
69
73
  {
70
- "StatusCode": status_code,
71
- "Response": response,
72
- "ResponseType": response_type,
74
+ "statusCode": status_code,
75
+ "response": response,
76
+ "responseType": response_type,
73
77
  }
74
78
  )
75
79
  finally:
@@ -149,11 +153,47 @@ class HttpEndpointUnixSocket:
149
153
  """Set the handler to handle client connections"""
150
154
  self.handler = handler
151
155
 
156
+ def _create_socket(self, path: str):
157
+ path = os.fspath(path)
158
+ sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
159
+
160
+ # Check for abstract socket. `str` and `bytes` paths are supported.
161
+ if path[0] not in (0, '\x00'):
162
+ try:
163
+ if stat.S_ISSOCK(os.stat(path).st_mode):
164
+ os.remove(path)
165
+ except FileNotFoundError:
166
+ pass
167
+ except OSError as err:
168
+ # Directory may have permissions only to create socket.
169
+ # logger.error('Unable to check or remove stale UNIX socket '
170
+ # '%r: %r', path, err)
171
+ pass
172
+
173
+ try:
174
+ sock.bind(path)
175
+ os.chmod(path, os.stat(path).st_mode | stat.S_IWGRP | stat.S_IRGRP)
176
+ except OSError as exc:
177
+ sock.close()
178
+ if exc.errno == errno.EADDRINUSE:
179
+ # Let's improve the error message by adding
180
+ # with what exact address it occurs.
181
+ msg = f'Address {path!r} is already in use'
182
+ raise OSError(errno.EADDRINUSE, msg) from None
183
+ else:
184
+ raise
185
+ except:
186
+ sock.close()
187
+ raise
188
+
189
+ return sock
190
+
152
191
  def start_connection_listener(self):
153
192
  try:
154
193
  self._loop = asyncio.new_event_loop()
194
+ sock = self._create_socket(self.socket_file)
155
195
  self._server = asyncio.start_unix_server(
156
- self.handle_connection, self.socket_file, backlog=self.backlog
196
+ self.handle_connection, sock=sock, backlog=self.backlog
157
197
  )
158
198
  self._loop.create_task(self._server)
159
199
  self._loop.run_forever()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dsf-python
3
- Version: 3.6.0b2
3
+ Version: 3.6.0b2.post3
4
4
  Summary: Python interface to access DuetSoftwareFramework
5
5
  Home-page: https://github.com/Duet3D/dsf-python
6
6
  Author: Duet3D Ltd.
@@ -1,6 +1,6 @@
1
- dsf/__init__.py,sha256=9EA8iGOVjKYNIW7dikfDMqcH3t6Mj-0Hx9tIG_PEU0g,222
1
+ dsf/__init__.py,sha256=U7DYDaYF0GThefa06ZcAU5GdqaVgrLolsWdXUpTL1Ww,254
2
2
  dsf/exceptions.py,sha256=TIF-e0wAprfodFTfRD9chP6JZ97yA04dlaHN90mgGVI,93
3
- dsf/http.py,sha256=ZOz0dRGWyxgWDoS-1c3DqQkNmyAZuhPi9y6vtano-mU,5829
3
+ dsf/http.py,sha256=x3vPh4eZXYoBI0UVFZVGxc1p-fzN7vHhOpqPJ7Usl_w,7221
4
4
  dsf/utils.py,sha256=9GfGUu0sbeoJBJ6RuRIpI-BZ-1PKIMWaemWliknt1v0,2571
5
5
  dsf/commands/__init__.py,sha256=O4_mLIDnLnN3zLxvH8_3mx3Yx2rU4f2Ha3cm9PmFaS4,198
6
6
  dsf/commands/base_command.py,sha256=rwjaXeZ38yayAH7gYBm9Nf1xpYsg38Ul6oMexSkuCIo,378
@@ -17,7 +17,7 @@ dsf/commands/http_endpoints.py,sha256=CevsLjAh_9GG6MQkAL7aFZKsuyRvYgNkiSCc5-jGv7
17
17
  dsf/commands/model_subscription.py,sha256=Dq4M7EfRjkHUcIbTrLjJRAxhAhMiawowLbEFS11NMEc,224
18
18
  dsf/commands/object_model.py,sha256=QDtxBbkJA7AozjicUtMAhBq9uGkB9_OHcZQIr8koJG4,2522
19
19
  dsf/commands/packages.py,sha256=e7LObfz7xNygMPGi2A5o_F6OG1yFhN5fYO--U0tf5WM,712
20
- dsf/commands/plugins.py,sha256=w_7YlIxj95w046vO89qGbAXyVzOBw_o-dlMuaqFE-JA,3020
20
+ dsf/commands/plugins.py,sha256=noLoiQTXuHxjFgXnk2LxgdoNZnhZXXIY-IIJcEQr_Zk,2930
21
21
  dsf/commands/responses.py,sha256=Q6jZwEKbmKkph96EepUdgD6LfY2VAX41MAaj6aJ1-XQ,1755
22
22
  dsf/commands/user_sessions.py,sha256=qFN_NfS8n2gVXqfdN0_kA3--kvtrX0ELYKtkxT1U7-E,1312
23
23
  dsf/connections/__init__.py,sha256=83E9M8yOZfdQqm196fnOaR7Wy4_IDYVhFwIl9BltsxI,1898
@@ -172,8 +172,8 @@ dsf/object_model/tools/tools.py,sha256=2wOEZlXswUnVBa0cuhyGYHz1z2R-mF25fi0a7WY3W
172
172
  dsf/object_model/volumes/__init__.py,sha256=XuRDty30gqn8jshASvclpxVTachXeAeJyo2-iHKEsKc,50
173
173
  dsf/object_model/volumes/volumes.py,sha256=gqbo5kUQo037A7Wv49vxnnaBhGlNjilJydjW8V2sKZ4,3073
174
174
  dsf/utility/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
175
- dsf_python-3.6.0b2.dist-info/LICENSE,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
176
- dsf_python-3.6.0b2.dist-info/METADATA,sha256=BwSRQmLS4RsuytQ4UH9CUUZYgfHcE4uByQaxIGXKdDU,2054
177
- dsf_python-3.6.0b2.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
178
- dsf_python-3.6.0b2.dist-info/top_level.txt,sha256=hrm-wnKtms7vAmVuHX6jIj3C6G5p3uKCiXZH4HwJ4LA,4
179
- dsf_python-3.6.0b2.dist-info/RECORD,,
175
+ dsf_python-3.6.0b2.post3.dist-info/LICENSE,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
176
+ dsf_python-3.6.0b2.post3.dist-info/METADATA,sha256=9cm9octK6ubgXD6IKbq7iuHiMv2Aj992k9cTFuSG85c,2060
177
+ dsf_python-3.6.0b2.post3.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
178
+ dsf_python-3.6.0b2.post3.dist-info/top_level.txt,sha256=hrm-wnKtms7vAmVuHX6jIj3C6G5p3uKCiXZH4HwJ4LA,4
179
+ dsf_python-3.6.0b2.post3.dist-info/RECORD,,