pywebexec 2.1.18__py3-none-any.whl → 2.2.0__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.
pywebexec/pywebexec.py CHANGED
@@ -1038,15 +1038,12 @@ def swagger_yaml():
1038
1038
  swagger_spec = yaml.safe_load(swagger_spec_str)
1039
1039
  # Update existing POST /commands enum if present
1040
1040
  executables = get_executables()
1041
- post_cmd = swagger_spec.get('paths', {}).get('/commands', {}).get('post')
1042
- if post_cmd:
1043
- params_list = post_cmd.get('parameters', [])
1044
- for param in params_list:
1045
- if param.get('in') == 'body' and 'schema' in param:
1046
- props = param['schema'].get('properties', {})
1047
- if 'command' in props:
1048
- props['command']['enum'] = [e['command'] for e in executables]
1049
- # Add dynamic paths for each
1041
+ post_cmd = swagger_spec.get('paths', {}).get('/commands', {}).get('post', {})
1042
+ if post_cmd and 'requestBody' in post_cmd:
1043
+ schema = post_cmd['requestBody'].get('content', {}).get('application/json', {}).get('schema', {})
1044
+ if 'properties' in schema and 'command' in schema['properties']:
1045
+ schema['properties']['command']['enum'] = [e['command'] for e in executables]
1046
+
1050
1047
  # Add dynamic paths for each executable:
1051
1048
  for exe in executables:
1052
1049
  dynamic_path = "/commands/" + exe["command"]
@@ -1065,28 +1062,32 @@ def swagger_yaml():
1065
1062
  "parallel": {"type": "integer", "description": 'nb parallel jobs', "default": 1, "required": True, "minimum": 1, "maximum": 100},
1066
1063
  "delay": {"type": "number", "description": "initial delay in s between jobs", "default": 10, "required": True, "minimum": 0, "maximum": 600},
1067
1064
  })
1065
+
1068
1066
  swagger_spec.setdefault("paths", {})[dynamic_path] = {
1069
1067
  "post": {
1070
1068
  "summary": f"Run command {exe['command']}",
1071
1069
  "tags": ["run_commands"],
1072
1070
  "description": f"{exe['help']}",
1073
- "consumes": ["application/json"],
1074
- "produces": ["application/json"],
1075
- "parameters": [
1076
- {
1077
- "in": "body",
1078
- "name": "requestBody",
1079
- "schema": cmd_schema
1071
+ "requestBody": {
1072
+ "required": True,
1073
+ "content": {
1074
+ "application/json": {
1075
+ "schema": cmd_schema
1076
+ }
1080
1077
  }
1081
- ],
1078
+ },
1082
1079
  "responses": {
1083
1080
  "200": {
1084
1081
  "description": "Command started",
1085
- "schema": {
1086
- "type": "object",
1087
- "properties": {
1088
- "message": {"type": "string"},
1089
- "command_id": {"type": "string"}
1082
+ "content": {
1083
+ "application/json": {
1084
+ "schema": {
1085
+ "type": "object",
1086
+ "properties": {
1087
+ "message": {"type": "string"},
1088
+ "command_id": {"type": "string"}
1089
+ }
1090
+ }
1090
1091
  }
1091
1092
  }
1092
1093
  }
@@ -1,5 +1,5 @@
1
1
 
2
- .markdown, .swagger-ui .markdown {
2
+ .markdown, .swagger-ui .markdown, .swagger-ui .renderedMarkdown {
3
3
  /* background-color: #e0e0ff; */
4
4
  border: 1px solid #ccc;
5
5
  padding: 0px 8px 8px 8px;
@@ -449,6 +449,7 @@ body.dimmed * {
449
449
  .command-line:hover {
450
450
  text-overflow: unset;
451
451
  max-width: unset;
452
+ white-space: pre;
452
453
  }
453
454
  .nbrunning {
454
455
  display: inline-block;
@@ -301,7 +301,7 @@ paramsInput.addEventListener('focus', () => {
301
301
  console.log('Error running command:', error);
302
302
  }
303
303
  }
304
- }, currentCmd.toString());
304
+ }, currentCmd);
305
305
  setHelpDivPosition();
306
306
  paramsContainer.style.display = 'block';
307
307
  const input1 = schemaFormPW.querySelector('input, select, textarea');
@@ -1,6 +1,6 @@
1
1
  const maxScrollback = 99999;
2
2
  const maxSize = 10485760; // 10MB
3
- let fontSize = 14;
3
+ let fontSize = +localStorage.getItem('popupFontSize') || 14;
4
4
  let terminal = new Terminal({
5
5
  cursorBlink: false,
6
6
  cursorInactiveStyle: 'none',
@@ -75,8 +75,8 @@ let slider = null;
75
75
  let isPaused = false;
76
76
  let cols = 0;
77
77
  let rows = 0;
78
- let fitWindow = false;
79
-
78
+ let fitWindow = localStorage.getItem('popupFitWindow') === 'false' ? false : true;
79
+ console.log(localStorage.getItem('popupFitWindow'));
80
80
  const toggleButton = document.getElementById('toggleFetch');
81
81
  const pausedMessage = document.getElementById('pausedMessage');
82
82
  const toggleFitButton = document.getElementById('toggleFit');
@@ -169,9 +169,13 @@ async function viewOutput(command_id) {
169
169
  }
170
170
  const data = await response.json();
171
171
  const commandInfo = document.getElementById('commandInfo');
172
- const command = `${data.command.replace(/^\.\//, '')} ${data.params.join(' ')}`;
172
+ if (data.command.endsWith('/run-para')) {
173
+ command = `${data.params.join(' ').replace(/^.* -- run .\//, 'batch ')}`;
174
+ } else {
175
+ command = `${data.command.replace(/^\.\//, '')} ${data.params.join(' ')}`;
176
+ }
173
177
  setCommandStatus(data.status);
174
- commandInfo.innerText = command;
178
+ commandInfo.innerHTML = command;
175
179
  commandInfo.setAttribute('title', command);
176
180
  document.title = `${data.command} ${data.params.join(' ')} - [${data.status}]`;
177
181
  if (data.command == 'term')
@@ -232,21 +236,31 @@ function toggleFetchOutput() {
232
236
  }
233
237
  isPaused = !isPaused;
234
238
  }
235
- function toggleFit() {
236
- fitWindow = ! fitWindow;
239
+ function setFitIcon()
240
+ {
241
+ console.log(fitWindow);
237
242
  if (fitWindow) {
243
+ toggleFitButton.classList.remove('fit-window');
238
244
  toggleFitButton.classList.add('fit-tty');
239
245
  toggleFitButton.setAttribute('title', 'terminal fit tty');
240
246
  } else {
241
247
  toggleFitButton.classList.remove('fit-tty');
248
+ toggleFitButton.classList.add('fit-window');
242
249
  toggleFitButton.setAttribute('title', 'terminal fit window');
243
- }
250
+ }
251
+ }
252
+
253
+ function toggleFit() {
254
+ fitWindow = ! fitWindow;
255
+ setFitIcon();
256
+ localStorage.setItem('popupFitWindow', fitWindow);
244
257
  autoFit();
245
258
  viewOutput(currentCommandId);
246
259
  }
247
260
 
248
261
  toggleButton.addEventListener('click', toggleFetchOutput);
249
262
  toggleFitButton.addEventListener('click', toggleFit);
263
+ setFitIcon();
250
264
  window.addEventListener('resize', adjustOutputHeight);
251
265
  window.addEventListener('load', () => {
252
266
  slider = document.getElementById('outputSlider');
@@ -259,11 +273,13 @@ window.addEventListener('load', () => {
259
273
  document.getElementById('decreaseFontSize').addEventListener('click', () => {
260
274
  fontSize = Math.max(8, fontSize - 1);
261
275
  terminal.options.fontSize = fontSize;
276
+ localStorage.setItem('popupFontSize', fontSize);
262
277
  autoFit();
263
278
  });
264
279
 
265
280
  document.getElementById('increaseFontSize').addEventListener('click', () => {
266
281
  fontSize = Math.min(32, fontSize + 1);
267
282
  terminal.options.fontSize = fontSize;
283
+ localStorage.setItem('popupFontSize', fontSize);
268
284
  autoFit();
269
285
  });
@@ -11,7 +11,7 @@ function adjustInputWidth(input) {
11
11
  function formInputHandle() {
12
12
  schemaForm.querySelectorAll('input[type="text"], input[type="number"]').forEach(input => {
13
13
  if (! inputHandlers.includes(input)) {
14
- val = input.value || input.placeholder;
14
+ val = input.placeholder;
15
15
  if (val) {
16
16
  size = Math.max(val.length, 2)
17
17
  if (input.type== 'number') {
@@ -35,16 +35,17 @@ function extractKeysAndPlaceholders(obj, formoptions, prefix = '') {
35
35
  let result = [];
36
36
 
37
37
  for (let key in obj.properties) {
38
+ k = prefix ? `${prefix}.${key}` : key;
38
39
  if (obj.properties[key].type === 'object' && obj.properties[key].properties) {
39
- result = result.concat(extractKeysAndPlaceholders(obj.properties[key], formoptions, prefix ? `${prefix}.${key}` : key));
40
+ result = result.concat(extractKeysAndPlaceholders(obj.properties[key], formoptions, k));
40
41
  } else {
41
- if (formoptions[`${prefix}.${key}`]) {
42
- foptions = formoptions[`${prefix}.${key}`];
42
+ if (formoptions[k]) {
43
+ foptions = formoptions[k];
43
44
  } else {
44
45
  foptions = {};
45
46
  }
46
47
  result.push({
47
- key: prefix ? `${prefix}.${key}` : key,
48
+ key: k,
48
49
  placeholder: obj.properties[key].example || null,
49
50
  ... foptions
50
51
  });
@@ -52,7 +53,7 @@ function extractKeysAndPlaceholders(obj, formoptions, prefix = '') {
52
53
  }
53
54
  return result;
54
55
  }
55
- let schemaValues = {};
56
+
56
57
  function createSchemaForm(form, schema, onSubmit, schemaName) {
57
58
  if (schemaValues[schemaName]) {
58
59
  value = schemaValues[schemaName];
@@ -167,16 +168,22 @@ function createSchemaForm(form, schema, onSubmit, schemaName) {
167
168
  txt.setAttribute("spellcheck", "false");
168
169
  txt.addEventListener("input", () => adjustTxtHeight(txt));
169
170
  });
171
+
170
172
  form[0].addEventListener('input', () => {
171
173
  schemaValues[schemaName] = jsform.root.getFormValues();
172
- // localStorage.setItem('schemaValues', JSON.stringify(schemaValues));
174
+ localStorage.setItem('schemaValues', JSON.stringify(schemaValues));
173
175
  });
174
176
 
175
177
  return jsform;
176
178
  }
177
179
  function adjustTxtHeight(txt) {
180
+ if (txt.value.includes('\n')) {
181
+ delta = 2;
182
+ } else {
183
+ delta = 0;
184
+ }
178
185
  txt.style.height = "0";
179
- txt.style.height = txt.scrollHeight + "px";
186
+ txt.style.height = `${txt.scrollHeight+delta}px`;
180
187
  }
181
188
  async function getSwaggerSpec() {
182
189
  const response = await fetch('/swagger.yaml');
@@ -209,5 +216,6 @@ async function getPostParametersSchema() {
209
216
 
210
217
  let schemaForm;
211
218
  let inputHandlers = [];
219
+ let schemaValues = JSON.parse(localStorage.getItem('schemaValues')) || {};
212
220
 
213
221
 
@@ -7,11 +7,11 @@ let fullOutput = '';
7
7
  let outputLength = 0;
8
8
  const maxScrollback = 99999;
9
9
  const maxSize = 10485760; // 10MB
10
- let fontSize = 14;
10
+ let fontSize = +localStorage.getItem('fontSize') || 14;
11
11
  let isPaused = false;
12
12
  let showRunningOnly = false;
13
13
  let hiddenCommandIds = [];
14
- let fitWindow = false;
14
+ let fitWindow = localStorage.getItem('fitWindow') === 'false' ? false : true;
15
15
  let cols = 0;
16
16
  let rows = 0;
17
17
 
@@ -260,7 +260,12 @@ async function viewOutput(command_id) {
260
260
  }
261
261
  const data = await response.json();
262
262
  const commandInfo = document.getElementById('commandInfo');
263
- const command = `${data.command.replace(/^\.\//, '')} ${data.params.join(' ')}`;
263
+ if (data.command.endsWith('/run-para')) {
264
+ command = `${data.params.join(' ').replace(/^.* -- run .\//, 'batch ')}`;
265
+ } else {
266
+ command = `${data.command.replace(/^\.\//, '')} ${data.params.join(' ')}`;
267
+ }
268
+ console.log(command);
264
269
  setCommandStatus(data.status)
265
270
  commandInfo.innerHTML = command;
266
271
  commandInfo.setAttribute('title', command);
@@ -415,12 +420,14 @@ slider.addEventListener('input', sliderUpdateOutput);
415
420
  document.getElementById('decreaseFontSize').addEventListener('click', () => {
416
421
  fontSize = Math.max(8, fontSize - 1);
417
422
  terminal.options.fontSize = fontSize;
423
+ localStorage.setItem('fontSize', fontSize);
418
424
  autoFit();
419
425
  });
420
426
 
421
427
  document.getElementById('increaseFontSize').addEventListener('click', () => {
422
428
  fontSize = Math.min(32, fontSize + 1);
423
429
  terminal.options.fontSize = fontSize;
430
+ localStorage.setItem('fontSize', fontSize);
424
431
  autoFit();
425
432
  });
426
433
 
@@ -451,21 +458,31 @@ function toggleFetchOutput() {
451
458
  }
452
459
  isPaused = !isPaused;
453
460
  }
454
- function toggleFit() {
455
- fitWindow = ! fitWindow;
461
+
462
+ function setFitIcon()
463
+ {
456
464
  if (fitWindow) {
465
+ toggleFitButton.classList.remove('fit-window');
457
466
  toggleFitButton.classList.add('fit-tty');
458
467
  toggleFitButton.setAttribute('title', 'terminal fit tty');
459
468
  } else {
460
469
  toggleFitButton.classList.remove('fit-tty');
470
+ toggleFitButton.classList.add('fit-window');
461
471
  toggleFitButton.setAttribute('title', 'terminal fit window');
462
- }
472
+ }
473
+ }
474
+
475
+ function toggleFit() {
476
+ fitWindow = ! fitWindow;
477
+ setFitIcon();
478
+ localStorage.setItem('fitWindow', fitWindow);
463
479
  autoFit();
464
480
  viewOutput(currentCommandId);
465
481
  }
466
482
 
467
483
  toggleButton.addEventListener('click', toggleFetchOutput);
468
484
  toggleFitButton.addEventListener('click', toggleFit);
485
+ setFitIcon();
469
486
 
470
487
  document.getElementById('thStatus').addEventListener('click', () => {
471
488
  showRunningOnly = !showRunningOnly;
@@ -26,6 +26,28 @@ function addFormInputListener(textArea, jsform){
26
26
  };
27
27
  }
28
28
 
29
+ async function getPostParametersSchema() {
30
+ const swaggerSpec = await getSwaggerSpec();
31
+ const result = {};
32
+ for (const path in swaggerSpec.paths) {
33
+ const pathItem = swaggerSpec.paths[path];
34
+ if (pathItem.post) {
35
+ const postDef = pathItem.post;
36
+ // Look for requestBody with JSON schema in OpenAPI 3.0
37
+ if (postDef.requestBody && postDef.requestBody.content && postDef.requestBody.content['application/json']) {
38
+ result[path] = postDef.requestBody.content['application/json'].schema;
39
+ } else {
40
+ result[path] = null;
41
+ }
42
+ }
43
+ }
44
+ return result;
45
+ }
46
+ function adjustTxtHeight2(paramtext) {
47
+ paramtext.style.height = "0";
48
+ paramtext.style.height = `${paramtext.scrollHeight+2}px`;
49
+ }
50
+
29
51
  window.onload = function() {
30
52
  ui = SwaggerUIBundle({
31
53
  url: "/swagger.yaml",
@@ -69,29 +91,25 @@ window.onload = function() {
69
91
  const observer = new MutationObserver((mutations) => {
70
92
  mutations.forEach(mutation => {
71
93
  mutation.addedNodes.forEach(node => {
72
- if (node.classList && (node.classList.contains("highlight-code") ||
73
- node.classList.contains("body-param__text"))) {
74
- // Retrieve the data-path attribute from the first opblock-summary-path element
75
- const routePath = $(node).closest('.opblock').find('.opblock-summary-path').first().attr('data-path');
76
- const routePathId = `schemaForm${routePath.replaceAll("/", "_")}`;
77
- const prevForm = node.parentNode.querySelector(`#${routePathId}`)
78
- if (prevForm) {
79
- prevForm.remove();
80
- }
81
- if (node.classList.contains("body-param__text")) {
82
- node.addEventListener("input", (e) => {
83
- e.target.style.height = "0"
84
- e.target.style.height = e.target.scrollHeight + "px";
85
- });
86
- node.style.height = "0"
87
- node.style.height = node.scrollHeight + "px";
94
+ if (node.nodeType === Node.ELEMENT_NODE) {
95
+ const paramtext = node.querySelector(".body-param__text");
96
+ if (paramtext) {
97
+ // Retrieve the data-path attribute from the first opblock-summary-path element
98
+ const routePath = $(node).closest('.opblock').find('.opblock-summary-path').first().attr('data-path');
99
+ const routePathId = `schemaForm${routePath.replaceAll("/", "_")}`;
100
+ const prevForm = paramtext.parentNode.querySelector(`#${routePathId}`)
101
+ if (prevForm) {
102
+ prevForm.remove();
103
+ }
104
+ paramtext.addEventListener("input", () => adjustTxtHeight2(paramtext));
105
+ setTimeout(() => adjustTxtHeight2(paramtext), 100);
88
106
  const form = document.createElement("form");
89
107
  form.id = routePathId;
90
108
  form.classList.add("schema-form");
91
109
  jsform = createSchemaForm($(form), swaggerSchemas[routePath], null, routePath);
92
110
  // form.addEventListener("input", formInput(node, jsform));
93
- form.addEventListener("input", addFormInputListener(node, jsform));
94
- node.parentNode.insertBefore(form, node.nextSibling);
111
+ form.addEventListener("input", addFormInputListener(paramtext, jsform));
112
+ paramtext.parentNode.insertBefore(form, paramtext.nextSibling);
95
113
  item1 = form.querySelector("input, select, textarea");
96
114
  if (item1) {
97
115
  item1.focus();
pywebexec/swagger.yaml CHANGED
@@ -1,4 +1,4 @@
1
- swagger: "2.0"
1
+ openapi: "3.0.0"
2
2
  info:
3
3
  title: PyWebExec API
4
4
  version: "1.0"
@@ -11,77 +11,80 @@ paths:
11
11
  responses:
12
12
  "200":
13
13
  description: "List of all commands status"
14
- schema:
15
- type: object
16
- properties:
17
- commands:
18
- type: array
19
- items:
20
- type: object
21
- properties:
22
- command_id:
23
- type: string
24
- command:
25
- type: string
26
- status:
27
- type: string
28
- start_time:
29
- type: string
30
- format: date-time
31
- end_time:
32
- type: string
33
- format: date-time
34
- exit_code:
35
- type: integer
36
- last_output_line:
37
- type: string
38
- user:
39
- type: string
14
+ content:
15
+ application/json:
16
+ schema:
17
+ type: object
18
+ properties:
19
+ commands:
20
+ type: array
21
+ items:
22
+ type: object
23
+ properties:
24
+ command_id:
25
+ type: string
26
+ command:
27
+ type: string
28
+ status:
29
+ type: string
30
+ start_time:
31
+ type: string
32
+ format: date-time
33
+ end_time:
34
+ type: string
35
+ format: date-time
36
+ exit_code:
37
+ type: integer
38
+ last_output_line:
39
+ type: string
40
+ user:
41
+ type: string
40
42
  post:
41
43
  summary: "Run a command"
42
44
  tags:
43
45
  - commands
44
- consumes:
45
- - application/json
46
- produces:
47
- - application/json
48
- parameters:
49
- - in: body
50
- name: requestBody
51
- schema:
52
- type: object
53
- properties:
54
- command:
55
- type: string
56
- description: "Command to run"
57
- # Enum will be added dynamically by the APIs
58
- default: commandName
59
- params:
60
- type: array
61
- description: "Command parameters"
62
- items:
46
+ requestBody:
47
+ required: true
48
+ content:
49
+ application/json:
50
+ schema:
51
+ type: object
52
+ properties:
53
+ command:
63
54
  type: string
64
- default: []
65
- rows:
66
- type: integer
67
- description: "tty nb rows"
68
- default: 24
69
- cols:
70
- type: integer
71
- description: "tty nb columns"
72
- default: 125
73
- required:
74
- - command
55
+ description: "Command to run"
56
+ # Enum will be added dynamically by the APIs
57
+ default: commandName
58
+ required: true
59
+ params:
60
+ type: array
61
+ description: "Command parameters"
62
+ items:
63
+ type: string
64
+ default: []
65
+ rows:
66
+ type: integer
67
+ description: "tty nb rows"
68
+ default: 24
69
+ cols:
70
+ type: integer
71
+ description: "tty nb columns"
72
+ default: 125
73
+ required:
74
+ - command
75
75
  responses:
76
76
  "200":
77
77
  description: "Command started"
78
- schema:
79
- type: object
80
- properties:
81
- command_id:
82
- type: string
83
- message:
84
- type: string
78
+ content:
79
+ application/json:
80
+ schema:
81
+ type: object
82
+ properties:
83
+ command_id:
84
+ type: string
85
+ message:
86
+ type: string
87
+
85
88
  /commands/{command_id}:
86
89
  get:
87
90
  summary: "Get command status"
@@ -91,43 +94,46 @@ paths:
91
94
  - in: path
92
95
  name: command_id
93
96
  required: true
94
- type: string
97
+ schema:
98
+ type: string
95
99
  responses:
96
100
  "200":
97
101
  description: "Command status returned"
98
- schema:
99
- type: object
100
- properties:
101
- command_id:
102
- type: string
103
- command:
104
- type: string
105
- params:
106
- type: array
107
- items:
108
- type: string
109
- status:
110
- type: string
111
- start_time:
112
- type: string
113
- format: date-time
114
- end_time:
115
- type: string
116
- format: date-time
117
- exit_code:
118
- type: integer
119
- last_output_line:
120
- type: string
121
- cols:
122
- type: integer
123
- rows:
124
- type: integer
125
- user:
126
- type: string
127
- from:
128
- type: string
129
- pid:
130
- type: integer
102
+ content:
103
+ application/json:
104
+ schema:
105
+ type: object
106
+ properties:
107
+ command_id:
108
+ type: string
109
+ command:
110
+ type: string
111
+ params:
112
+ type: array
113
+ items:
114
+ type: string
115
+ status:
116
+ type: string
117
+ start_time:
118
+ type: string
119
+ format: date-time
120
+ end_time:
121
+ type: string
122
+ format: date-time
123
+ exit_code:
124
+ type: integer
125
+ last_output_line:
126
+ type: string
127
+ cols:
128
+ type: integer
129
+ rows:
130
+ type: integer
131
+ user:
132
+ type: string
133
+ from:
134
+ type: string
135
+ pid:
136
+ type: integer
131
137
 
132
138
  /commands/{command_id}/output:
133
139
  get:
@@ -138,44 +144,49 @@ paths:
138
144
  - in: path
139
145
  name: command_id
140
146
  required: true
141
- type: string
147
+ schema:
148
+ type: string
142
149
  - in: query
143
150
  name: offset
144
- type: integer
145
- default: 0
151
+ schema:
152
+ type: integer
153
+ default: 0
146
154
  - in: query
147
155
  name: maxsize
148
- type: integer
149
- default: 10485760
156
+ schema:
157
+ type: integer
158
+ default: 10485760
150
159
  - in: query
151
160
  name: maxlines
152
- type: integer
153
- default: 5000
154
- consumes:
155
- - application/json
156
- produces:
157
- - application/json
158
- - text/plain
161
+ schema:
162
+ type: integer
163
+ default: 5000
159
164
  responses:
160
165
  "200":
161
166
  description: "Command output returned"
162
- schema:
163
- type: object
164
- properties:
165
- output:
166
- type: string
167
- status:
168
- type: string
169
- rows:
170
- type: integer
171
- cols:
172
- type: integer
173
- links:
167
+ content:
168
+ application/json:
169
+ schema:
174
170
  type: object
175
171
  properties:
176
- next:
172
+ output:
177
173
  type: string
178
- format: uri
174
+ status:
175
+ type: string
176
+ rows:
177
+ type: integer
178
+ cols:
179
+ type: integer
180
+ links:
181
+ type: object
182
+ properties:
183
+ next:
184
+ type: string
185
+ format: uri
186
+ text/plain:
187
+ schema:
188
+ type: string
189
+
179
190
  /commands/{command_id}/stop:
180
191
  patch:
181
192
  summary: "Stop a running command"
@@ -185,15 +196,19 @@ paths:
185
196
  - in: path
186
197
  name: command_id
187
198
  required: true
188
- type: string
199
+ schema:
200
+ type: string
189
201
  responses:
190
202
  "200":
191
203
  description: "Command stopped successfully"
192
- schema:
193
- type: object
194
- properties:
195
- message:
196
- type: string
204
+ content:
205
+ application/json:
206
+ schema:
207
+ type: object
208
+ properties:
209
+ message:
210
+ type: string
211
+
197
212
  /commands/{command_id}/run:
198
213
  post:
199
214
  summary: "Relaunch a command"
@@ -203,56 +218,61 @@ paths:
203
218
  - in: path
204
219
  name: command_id
205
220
  required: true
206
- type: string
207
- - in: body
208
- name: requestBody
209
221
  schema:
210
- type: object
211
- properties:
212
- rows:
213
- type: integer
214
- description: "tty nb rows"
215
- default: 24
216
- cols:
217
- type: integer
218
- description: "tty nb columns"
219
- default: 125
222
+ type: string
223
+ requestBody:
224
+ required: true
225
+ content:
226
+ application/json:
227
+ schema:
228
+ type: object
229
+ properties:
230
+ rows:
231
+ type: integer
232
+ description: "tty nb rows"
233
+ default: 24
234
+ cols:
235
+ type: integer
236
+ description: "tty nb columns"
237
+ default: 125
220
238
  responses:
221
239
  "200":
222
240
  description: "Command relaunched"
223
- schema:
224
- type: object
225
- properties:
226
- message:
227
- type: string
228
- command_id:
229
- type: string
241
+ content:
242
+ application/json:
243
+ schema:
244
+ type: object
245
+ properties:
246
+ message:
247
+ type: string
248
+ command_id:
249
+ type: string
250
+
230
251
  /commands/exposed:
231
252
  get:
232
253
  summary: "List available executable commands"
233
254
  tags:
234
255
  - commands
235
- produces:
236
- - application/json
237
256
  responses:
238
257
  "200":
239
258
  description: "List of commands with markdown help"
240
- schema:
241
- type: object
242
- properties:
243
- commands:
244
- type: array
245
- items:
246
- type: object
247
- properties:
248
- command:
249
- type: string
250
- help:
251
- type: string
252
- examples:
259
+ content:
253
260
  application/json:
254
- commands:
255
- - command: ls
256
- help: "List directory contents \n**params**:\n* `<ls_params>`"
257
- - command: cat
258
- help: "Concatenate and display files \n**params**:\n* `<cat_params>`"
261
+ schema:
262
+ type: object
263
+ properties:
264
+ commands:
265
+ type: array
266
+ items:
267
+ type: object
268
+ properties:
269
+ command:
270
+ type: string
271
+ help:
272
+ type: string
273
+ example:
274
+ commands:
275
+ - command: ls
276
+ help: "List directory contents \n**params**:\n* `<ls_params>`"
277
+ - command: cat
278
+ help: "Concatenate and display files \n**params**:\n* `<cat_params>`"
pywebexec/version.py CHANGED
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '2.1.18'
21
- __version_tuple__ = version_tuple = (2, 1, 18)
20
+ __version__ = version = '2.2.0'
21
+ __version_tuple__ = version_tuple = (2, 2, 0)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pywebexec
3
- Version: 2.1.18
3
+ Version: 2.2.0
4
4
  Summary: Simple Python HTTP Exec Server
5
5
  Home-page: https://github.com/joknarf/pywebexec
6
6
  Author: Franck Jouvanceau
@@ -1,11 +1,11 @@
1
1
  pywebexec/__init__.py,sha256=197fHJy0UDBwTTpGCGortZRr-w2kTaD7MxqdbVmTEi0,61
2
2
  pywebexec/host_ip.py,sha256=Ud_HTflWVQ8789aoQ2RZdT1wGI-ccvrwSWGz_c7T3TI,1241
3
- pywebexec/pywebexec.py,sha256=kufip6m7MWjCIjtheUYuFUZgnNS5_W3kC5gVFVSUVX8,45662
4
- pywebexec/swagger.yaml,sha256=zP_Nz69vZx0iwbKTwiQgSs8rJRUTiGKRyIkWzMPANOE,6688
5
- pywebexec/version.py,sha256=jKhjDDPkXCuEk44GYAoeIIRStFXiStBmbDX_bJM8XTI,513
3
+ pywebexec/pywebexec.py,sha256=R-jp9BiUMJZW7m9N9kQC6dpIueUgFVDo4n9_GFb1rOs,45734
4
+ pywebexec/swagger.yaml,sha256=I_oLpp7Hqel8SDEEykvpmCT-Gv3ytGlziq9bvQOrtZY,7598
5
+ pywebexec/version.py,sha256=wdFcRBeaWRZXknL-E8RTk9hV9M-OMto6dfJ90sc1i9A,511
6
6
  pywebexec/static/css/form.css,sha256=eApJskeJ3MCzC7_p4gXgoIbvbG5s8m4bP1O4KHHqeiA,5293
7
- pywebexec/static/css/markdown.css,sha256=3RzUnpVBdF6cQuB_NXV7hMTc0quYU8sfyuZcpsREj6A,1939
8
- pywebexec/static/css/style.css,sha256=ynccbEDzK07rurLm-UirUs5j_hVfXlIgaHeUIq9WvA0,9969
7
+ pywebexec/static/css/markdown.css,sha256=br4-iK9wigTs54N2KHtjgZ4KLH0THVSvJo-XZAdMHiE,1970
8
+ pywebexec/static/css/style.css,sha256=R1VOPNV2ztROKy9Fgf3tvUrtuKagY027tFJ8C866yWU,9991
9
9
  pywebexec/static/css/swagger-ui.css,sha256=xhXN8fnUaIACGHuPIEIr9-qmyYr6Zx0k2wv4Qy7Bg1Y,154985
10
10
  pywebexec/static/css/swagger-ui.css.map,sha256=dJy-xBn_htK4BNupTMIl33ddse7BXsrCdDJWlTJodnw,258842
11
11
  pywebexec/static/css/xterm.css,sha256=uo5phWaUiJgcz0DAzv46uoByLLbJLeetYosL1xf68rY,5559
@@ -33,11 +33,11 @@ pywebexec/static/images/resume.svg,sha256=99LP1Ya2JXakRCO9kW8JMuT_4a_CannF65Eiuw
33
33
  pywebexec/static/images/running.svg,sha256=fBCYwYb2O9K4N3waC2nURP25NRwZlqR4PbDZy6JQMww,610
34
34
  pywebexec/static/images/success.svg,sha256=NVwezvVMplt46ElW798vqGfrL21Mw_DWHUp_qiD_FU8,489
35
35
  pywebexec/static/images/swagger-ui.svg,sha256=FR0yeOVwe4zCYKZAjCGcT_m0Mf25NexIVaSXifIkoU0,2117
36
- pywebexec/static/js/executables.js,sha256=V9SUmRQP9M69jYbahNrsV4_oI0ASZv_F6Ax9wj0S0Ww,12171
37
- pywebexec/static/js/popup.js,sha256=0fr3pp4j9D2fXEVnHyQrx2bPWFHfgbb336dbewgH1d8,9023
38
- pywebexec/static/js/schemaform.js,sha256=Kt5E7ic6PMY3lBrxMJZ5-KHHBgaQGDs8hWvWLO-Ei8g,6406
39
- pywebexec/static/js/script.js,sha256=KrtLF77vKvKomKAIy0rix-T1hx4VTgjkQunHvgs-jaA,17631
40
- pywebexec/static/js/swagger-form.js,sha256=o2ovbTpqwy6H2yubV1NIi7VBQfAqW7seZWQ6O78ACb8,3837
36
+ pywebexec/static/js/executables.js,sha256=2ZSlsEMbfATr1EwUJMEAoS5G_wSUuWgT6AVQijawvtE,12160
37
+ pywebexec/static/js/popup.js,sha256=O3DEWnyb5yGW9tjODYycc-ujWndyAfnJMxulaQeogtc,9700
38
+ pywebexec/static/js/schemaform.js,sha256=GtIfd5YBaEr-KC1vXvZPFa5sYWRqdcjvP0Ozl7mr0YQ,6474
39
+ pywebexec/static/js/script.js,sha256=sMOwgeRi59X0QyTTI58SqC4Sp_F7pK5JfozCkJMOHjs,18234
40
+ pywebexec/static/js/swagger-form.js,sha256=sW7cUYJnd1ZZSMaMqaB2LCkjB1tfvSkdcAr-eW6UpZU,4430
41
41
  pywebexec/static/js/js-yaml/LICENSE,sha256=oHvCRGi5ZUznalR9R6LbKC0HcztxXbTHOpi9Y5YflVA,1084
42
42
  pywebexec/static/js/js-yaml/js-yaml.min.js,sha256=Rdw90D3AegZwWiwpibjH9wkBPwS9U4bjJ51ORH8H69c,39430
43
43
  pywebexec/static/js/marked/LICENSE.md,sha256=jjo_gvWaYJWPVsoI9EVkfDKkcz3HymwsRvbriYRxq5w,2942
@@ -67,9 +67,9 @@ pywebexec/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
67
67
  pywebexec/templates/index.html,sha256=w18O2plH_yS8bqlPsu5hwFFmCj9H2hWLSV8B6ADcSwU,3900
68
68
  pywebexec/templates/popup.html,sha256=3kpMccKD_OLLhJ4Y9KRw6Ny8wQWjVaRrUfV9y5-bDiQ,1580
69
69
  pywebexec/templates/swagger_ui.html,sha256=9ngyldkyEdLonBjl97mbIZUlVk-jxwcHrvFzMSrveyU,1067
70
- pywebexec-2.1.18.dist-info/LICENSE,sha256=gRJf0JPT_wsZJsUGlWPTS8Vypfl9vQ1qjp6sNbKykuA,1064
71
- pywebexec-2.1.18.dist-info/METADATA,sha256=upqvKlbMXuOQ-yC3reYNyrS9eufIXXonIxmlTVGBLnQ,12811
72
- pywebexec-2.1.18.dist-info/WHEEL,sha256=beeZ86-EfXScwlR_HKu4SllMC9wUEj_8Z_4FJ3egI2w,91
73
- pywebexec-2.1.18.dist-info/entry_points.txt,sha256=l52GBkPCXRkmlHfEyoVauyfBdg8o-CAtC8qQpOIjJK0,55
74
- pywebexec-2.1.18.dist-info/top_level.txt,sha256=vHoHyzngrfGdm_nM7Xn_5iLmaCrf10XO1EhldgNLEQ8,10
75
- pywebexec-2.1.18.dist-info/RECORD,,
70
+ pywebexec-2.2.0.dist-info/LICENSE,sha256=gRJf0JPT_wsZJsUGlWPTS8Vypfl9vQ1qjp6sNbKykuA,1064
71
+ pywebexec-2.2.0.dist-info/METADATA,sha256=PdGpfSzOG74LxsHEY8AUmPw5l_gsGIjChSTJIAKjxIk,12810
72
+ pywebexec-2.2.0.dist-info/WHEEL,sha256=beeZ86-EfXScwlR_HKu4SllMC9wUEj_8Z_4FJ3egI2w,91
73
+ pywebexec-2.2.0.dist-info/entry_points.txt,sha256=l52GBkPCXRkmlHfEyoVauyfBdg8o-CAtC8qQpOIjJK0,55
74
+ pywebexec-2.2.0.dist-info/top_level.txt,sha256=vHoHyzngrfGdm_nM7Xn_5iLmaCrf10XO1EhldgNLEQ8,10
75
+ pywebexec-2.2.0.dist-info/RECORD,,