Skip to content

Commit c388791

Browse files
author
AndyEveritt
committed
refactor & create api wrapper
1 parent 2f4cc83 commit c388791

7 files changed

Lines changed: 229 additions & 225 deletions

File tree

DuetWebAPI/DuetWebAPI.py

Lines changed: 14 additions & 200 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,22 @@
1212
# Released under The MIT License. Full text available via https://opensource.org/licenses/MIT
1313
#
1414
# Requires Python3
15+
import logging
1516
from typing import Dict, List
17+
1618
import requests
17-
import os
18-
import json
19-
import sys
20-
import datetime
21-
import logging
19+
20+
from DuetWebAPI.api import DSFAPI, DWCAPI, DuetAPI
2221

2322

2423
class DuetWebAPIFactory:
2524
def __init__(self) -> None:
2625
self._creators = {}
27-
26+
2827
def __call__(self, base_url: str) -> DuetAPI:
29-
self.get_api(base_url)
28+
api = self.get_api(base_url)
29+
wrapper = self.create_wrapper(api)
30+
return wrapper(base_url)
3031

3132
def register_api(self, name: str, creator: object, url_suffix: str) -> None:
3233
self._creators[name] = {'creator': creator, 'url_suffix': url_suffix}
@@ -40,206 +41,19 @@ def get_api(self, base_url) -> DuetAPI:
4041
continue
4142
if r.ok:
4243
creator = api['creator']
43-
return creator(base_url)
44+
return creator
4445

4546
logging.error(f'Can not get API for {base_url}')
4647
raise ValueError
4748

49+
def create_wrapper(self, creator: DuetAPI):
50+
class DuetAPIWrapper(creator):
51+
def demo(self):
52+
print('test')
4853

49-
class DuetAPI:
50-
def __init__(self, base_url) -> None:
51-
self._base_url = base_url
52-
53-
def get_model(self):
54-
raise NotImplementedError
55-
56-
def post_code(self, code):
57-
raise NotImplementedError
58-
59-
def get_file(self, filename, path):
60-
raise NotImplementedError
61-
62-
def put_file(self, filename, path):
63-
raise NotImplementedError
64-
65-
def get_fileinfo(self, filename):
66-
raise NotImplementedError
67-
68-
def delete_file(self, filename):
69-
raise NotImplementedError
70-
71-
def move_file(self, from_path, to_path, force=False):
72-
raise NotImplementedError
73-
74-
def get_directory(self, directory):
75-
raise NotImplementedError
76-
77-
def put_directory(self, directory):
78-
raise NotImplementedError
79-
80-
81-
class DWCAPI(DuetAPI):
82-
def get_model(self, key=None) -> Dict:
83-
url = f'{self._base_url}/rr_model'
84-
r = requests.get(url, {'flags': 'd99vn', 'key': key})
85-
if not r.ok:
86-
raise ValueError
87-
j = r.json()
88-
return j['result']
89-
90-
def post_code(self, code) -> Dict:
91-
url = f'{self._base_url}/rr_gcode'
92-
r = requests.get(url, {'gcode': code})
93-
if not r.ok:
94-
raise ValueError
95-
return r.json()
96-
97-
def get_file(self, filename: str, directory: str = 'gcodes') -> str:
98-
"""
99-
filename: name of the file you want to download including extension
100-
directory: the folder that the file is in, options are ['gcodes', 'macros', 'sys']
101-
102-
returns the file as a string
103-
"""
104-
url = f'{self._base_url}/rr_download'
105-
r = requests.get(url, {'name': f'/{directory}/{filename}'})
106-
if not r.ok:
107-
raise ValueError
108-
return r.text
109-
110-
def put_file(self, file: str, directory: str = 'gcodes'):
111-
file = os.path.abspath(file).replace('\\', '/')
112-
filename = file.split('/')[-1]
113-
url = f'{self._base_url}/rr_upload?name=/{directory}/{filename}'
114-
with open(file, 'rb') as f:
115-
r = requests.post(url, data=f)
116-
if not r.ok:
117-
raise ValueError
118-
return r.json()
119-
120-
def get_fileinfo(self, filename: str = None, directory: str = 'gcodes'):
121-
url = f'{self._base_url}/rr_fileinfo'
122-
if filename:
123-
r = requests.get(url, {'name': f'/{directory}/{filename}'})
124-
else:
125-
r = requests.get(url)
126-
if not r.ok:
127-
raise ValueError
128-
return r.json()
129-
130-
def delete_file(self, filename: str, directory: str = 'gcodes'):
131-
url = f'{self._base_url}/rr_delete'
132-
r = requests.get(url, {'name': f'/{directory}/{filename}'})
133-
if not r.ok:
134-
raise ValueError
135-
return r.json()
136-
137-
def move_file(self, from_path, to_path, **_ignored):
138-
url = f'{self._base_url}/rr_move'
139-
r = requests.get(url, {'old': f'{from_path}', 'new': f'{to_path}'})
140-
if not r.ok:
141-
raise ValueError
142-
return r.json()
143-
144-
def get_directory(self, directory) -> List[Dict]:
145-
url = f'{self._base_url}/rr_filelist'
146-
r = requests.get(url, {'dir': f'/{directory}'})
147-
if not r.ok:
148-
raise ValueError
149-
return r.json()['files']
150-
151-
def put_directory(self, directory):
152-
url = f'{self._base_url}/rr_mkdir'
153-
r = requests.get(url, {'dir': f'/{directory}'})
154-
if not r.ok:
155-
raise ValueError
156-
return r.json()
157-
158-
159-
class DSFAPI(DuetAPI):
160-
def get_model(self) -> Dict:
161-
url = f'{self._base_url}/machine/status'
162-
r = requests.get(url)
163-
j = r.json()
164-
return j
165-
166-
def post_code(self, code) -> str:
167-
url = f'{self._base_url}/machine/code'
168-
r = requests.post(url, data=code)
169-
return r.text
170-
171-
def get_file(self, filename: str, directory: str = 'gcodes') -> str:
172-
"""
173-
filename: name of the file you want to download including extension
174-
directory: the folder that the file is in, options are ['gcodes', 'macros', 'sys']
175-
176-
returns the file as a string
177-
"""
178-
url = f'{self._base_url}/machine/file/{directory}/{filename}'
179-
r = requests.get(url)
180-
if not r.ok:
181-
raise ValueError
182-
return r.text
183-
184-
def put_file(self, file: str, directory: str = 'gcodes'):
185-
"""
186-
file: the path to the file you want to upload from your PC
187-
directory: the folder that the file is in, options are ['gcodes', 'macros', 'sys']
188-
189-
returns the file as a string
190-
"""
191-
file = os.path.abspath(file).replace('\\', '/')
192-
filename = file.split('/')[-1]
193-
url = f'{self._base_url}/machine/file/{directory}/{filename}'
194-
with open(file, 'rb') as f:
195-
r = requests.put(url, data=f, headers={'Content-Type': 'application/octet-stream'})
196-
if not r.ok:
197-
raise ValueError
198-
return r.ok
199-
200-
def get_fileinfo(self, filename: str, directory: str = 'gcodes'):
201-
url = f'{self._base_url}/machine/fileinfo/{directory}/{filename}'
202-
r = requests.get(url)
203-
if not r.ok:
204-
raise ValueError
205-
return r.json()
206-
207-
def delete_file(self, filename: str, directory: str = 'gcodes'):
208-
url = f'{self._base_url}/machine/file/{directory}/{filename}'
209-
r = requests.delete(url)
210-
if not r.ok:
211-
raise ValueError
212-
return r.text
213-
214-
def move_file(self, from_path, to_path, force=False):
215-
url = f'{self._base_url}/machine/file/move'
216-
r = requests.post(url, {'from': f'{from_path}', 'to': f'{to_path}', 'force': force})
217-
if not r.ok:
218-
raise ValueError
219-
return r.text
220-
221-
def get_directory(self, directory) -> List[Dict]:
222-
url = f'{self._base_url}/machine/directory/{directory}'
223-
r = requests.get(url)
224-
if not r.ok:
225-
raise ValueError
226-
return r.json()
227-
228-
def put_directory(self, directory):
229-
url = f'{self._base_url}/machine/directory/{directory}'
230-
r = requests.put(url)
231-
if not r.ok:
232-
raise ValueError
233-
return r.text
54+
return DuetAPIWrapper
23455

23556

23657
DuetWebAPI = DuetWebAPIFactory()
23758
DuetWebAPI.register_api('DWC', DWCAPI, '/rr_model')
23859
DuetWebAPI.register_api('DSF', DSFAPI, '/machine/status')
239-
240-
241-
riley = DuetWebAPI('http://riley')
242-
force_rig = DuetWebAPI('http://forcerig')
243-
force_rig.put_file('test.gcode')
244-
riley.put_file('test.gcode')
245-
pass

DuetWebAPI/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
from .DuetWebAPI import DuetWebAPI
1+
from .DuetWebAPI import DuetWebAPI

DuetWebAPI/api/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from .base import DuetAPI
2+
from .dsfapi import DSFAPI
3+
from .dwcapi import DWCAPI

DuetWebAPI/api/base.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
from typing import Dict, List
2+
import requests
3+
import os
4+
import logging
5+
6+
7+
class DuetAPI:
8+
def __init__(self, base_url) -> None:
9+
self._base_url = base_url
10+
11+
def get_model(self):
12+
raise NotImplementedError
13+
14+
def post_code(self, code):
15+
raise NotImplementedError
16+
17+
def get_file(self, filename, path):
18+
raise NotImplementedError
19+
20+
def put_file(self, filename, path):
21+
raise NotImplementedError
22+
23+
def get_fileinfo(self, filename):
24+
raise NotImplementedError
25+
26+
def delete_file(self, filename):
27+
raise NotImplementedError
28+
29+
def move_file(self, from_path, to_path, force=False):
30+
raise NotImplementedError
31+
32+
def get_directory(self, directory):
33+
raise NotImplementedError
34+
35+
def put_directory(self, directory):
36+
raise NotImplementedError

DuetWebAPI/api/dsfapi.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import logging
2+
import os
3+
from typing import Dict, List
4+
5+
import requests
6+
7+
from .base import DuetAPI
8+
9+
10+
class DSFAPI(DuetAPI):
11+
def get_model(self) -> Dict:
12+
url = f'{self._base_url}/machine/status'
13+
r = requests.get(url)
14+
j = r.json()
15+
return j
16+
17+
def post_code(self, code) -> str:
18+
url = f'{self._base_url}/machine/code'
19+
r = requests.post(url, data=code)
20+
return r.text
21+
22+
def get_file(self, filename: str, directory: str = 'gcodes') -> str:
23+
"""
24+
filename: name of the file you want to download including extension
25+
directory: the folder that the file is in, options are ['gcodes', 'macros', 'sys']
26+
27+
returns the file as a string
28+
"""
29+
url = f'{self._base_url}/machine/file/{directory}/{filename}'
30+
r = requests.get(url)
31+
if not r.ok:
32+
raise ValueError
33+
return r.text
34+
35+
def put_file(self, file: str, directory: str = 'gcodes'):
36+
"""
37+
file: the path to the file you want to upload from your PC
38+
directory: the folder that the file is in, options are ['gcodes', 'macros', 'sys']
39+
40+
returns the file as a string
41+
"""
42+
file = os.path.abspath(file).replace('\\', '/')
43+
filename = file.split('/')[-1]
44+
url = f'{self._base_url}/machine/file/{directory}/{filename}'
45+
with open(file, 'rb') as f:
46+
r = requests.put(url, data=f, headers={'Content-Type': 'application/octet-stream'})
47+
if not r.ok:
48+
raise ValueError
49+
return r.ok
50+
51+
def get_fileinfo(self, filename: str, directory: str = 'gcodes'):
52+
url = f'{self._base_url}/machine/fileinfo/{directory}/{filename}'
53+
r = requests.get(url)
54+
if not r.ok:
55+
raise ValueError
56+
return r.json()
57+
58+
def delete_file(self, filename: str, directory: str = 'gcodes'):
59+
url = f'{self._base_url}/machine/file/{directory}/{filename}'
60+
r = requests.delete(url)
61+
if not r.ok:
62+
raise ValueError
63+
return r.text
64+
65+
def move_file(self, from_path, to_path, force=False):
66+
url = f'{self._base_url}/machine/file/move'
67+
r = requests.post(url, {'from': f'{from_path}', 'to': f'{to_path}', 'force': force})
68+
if not r.ok:
69+
raise ValueError
70+
return r.text
71+
72+
def get_directory(self, directory) -> List[Dict]:
73+
url = f'{self._base_url}/machine/directory/{directory}'
74+
r = requests.get(url)
75+
if not r.ok:
76+
raise ValueError
77+
return r.json()
78+
79+
def put_directory(self, directory):
80+
url = f'{self._base_url}/machine/directory/{directory}'
81+
r = requests.put(url)
82+
if not r.ok:
83+
raise ValueError
84+
return r.text

0 commit comments

Comments
 (0)