pywebexec 1.2.0__py3-none-any.whl → 1.4.12__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.
@@ -5,17 +5,23 @@
5
5
  <link rel="icon" href="/static/images/favicon.svg" type="image/svg+xml">
6
6
  <title>{{ title }}</title>
7
7
  <link rel="stylesheet" href="/static/css/style.css">
8
+ <link rel="stylesheet" href="/static/css/xterm.css">
8
9
  </head>
9
10
  <body>
10
11
  <div id="dimmer" class="dimmer">
11
- <div class="dimmer-text">Server not reachable</div>
12
+ <div class="dimmer-text">Server not available</div>
12
13
  </div>
13
14
  <h2><span class="status-icon title-icon"></span>{{ title }}</h2>
14
- <form id="launchForm">
15
+ <form id="launchForm" class="form-inline">
15
16
  <label for="commandName">Command</label>
16
- <select id="commandName" name="commandName"></select>
17
- <label for="params">Params</label>
18
- <input type="text" id="params" name="params">
17
+ <div class="input-group">
18
+ <input type="text" id="commandName" name="commandName" size=5 autocomplete="off" style="width: 100px;" autofocus>
19
+ <div id="showCommandListButton" class="show-command-list-button">
20
+ <span class="arrow">&#9660;</span>
21
+ </div>
22
+ <select id="commandList" class="command-list" size="20"></select>
23
+ <input type="text" id="params" name="params" oninput="this.style.width = ((this.value.length + 1) * 8) + 'px';">
24
+ </div>
19
25
  <button type="submit">Run</button>
20
26
  </form>
21
27
  <div class="table-container" id="tableContainer">
@@ -26,7 +32,6 @@
26
32
  <th>Start Time</th>
27
33
  <th>Duration</th>
28
34
  <th>Command</th>
29
- <th>Exit</th>
30
35
  <th>Status</th>
31
36
  <th>Action</th>
32
37
  <th>Output</th>
@@ -39,6 +44,14 @@
39
44
  <div class="resizer" id="resizer"></div>
40
45
  </div>
41
46
  <div id="output" class="output"></div>
47
+ <div class="slider-container">
48
+ <input type="range" id="outputSlider" min="0" max="100" value="100">
49
+ <label for="outputSlider"><span id="outputPercentage">100%</span></label>
50
+ </div>
51
+ <script src="/static/js/xterm/ansi_up.min.js"></script>
52
+ <script src="/static/js/xterm/xterm.js"></script>
53
+ <script src="/static/js/xterm/xterm-addon-fit.js"></script>
42
54
  <script type="text/javascript" src="/static/js/script.js"></script>
55
+ <script type="text/javascript" src="/static/js/commands.js"></script>
43
56
  </body>
44
57
  </html>
@@ -0,0 +1,24 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <link rel="icon" href="/static/images/favicon.svg" type="image/svg+xml">
6
+ <title id="outputTitle">Command Output</title>
7
+ <link rel="stylesheet" href="/static/css/style.css">
8
+ <link rel="stylesheet" href="/static/css/xterm.css">
9
+ </head>
10
+ <body>
11
+ <div id="dimmer" class="dimmer">
12
+ <div class="dimmer-text">Server not available</div>
13
+ </div>
14
+ <div id="output" class="output"></div>
15
+ <div class="slider-container">
16
+ <input type="range" id="outputSlider" min="0" max="100" value="100">
17
+ <label for="outputSlider"><span id="outputPercentage">100%</span></label>
18
+ </div>
19
+ <script src="/static/js/xterm/ansi_up.min.js"></script>
20
+ <script src="/static/js/xterm/xterm.js"></script>
21
+ <script src="/static/js/xterm/xterm-addon-fit.js"></script>
22
+ <script type="text/javascript" src="/static/js/popup.js"></script>
23
+ </body>
24
+ </html>
pywebexec/version.py CHANGED
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '1.2.0'
16
- __version_tuple__ = version_tuple = (1, 2, 0)
15
+ __version__ = version = '1.4.12'
16
+ __version_tuple__ = version_tuple = (1, 4, 12)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pywebexec
3
- Version: 1.2.0
3
+ Version: 1.4.12
4
4
  Summary: Simple Python HTTP Exec Server
5
5
  Home-page: https://github.com/joknarf/pywebexec
6
6
  Author: Franck Jouvanceau
@@ -36,7 +36,6 @@ Classifier: Intended Audience :: System Administrators
36
36
  Classifier: License :: OSI Approved :: MIT License
37
37
  Classifier: Operating System :: POSIX
38
38
  Classifier: Operating System :: Unix
39
- Classifier: Operating System :: Microsoft :: Windows
40
39
  Classifier: Operating System :: MacOS
41
40
  Classifier: Programming Language :: Python
42
41
  Classifier: Programming Language :: Python :: 3
@@ -57,6 +56,7 @@ Requires-Dist: python-daemon>=2.3.2
57
56
  Requires-Dist: cryptography>=40.0.2
58
57
  Requires-Dist: Flask>=2.0.3
59
58
  Requires-Dist: Flask-HTTPAuth>=4.8.0
59
+ Requires-Dist: pexpect>=4.9.0
60
60
  Requires-Dist: gunicorn>=21.2.0
61
61
  Requires-Dist: ldap3>=2.9.1
62
62
 
@@ -67,7 +67,7 @@ Requires-Dist: ldap3>=2.9.1
67
67
  [![Python versions](https://img.shields.io/badge/python-3.6+-blue.svg)](https://shields.io/)
68
68
 
69
69
  # pywebexec
70
- Simple Python HTTP(S) API/Web Command Launcher
70
+ Simple Python HTTP(S) API/Web Command Launcher and Terminal sharing
71
71
 
72
72
  ## Install
73
73
  ```
@@ -79,11 +79,13 @@ $ pip install pywebexec
79
79
  * put in a directory the scripts/commands/links to commands you want to expose
80
80
  * start http server serving current directory executables listening on 0.0.0.0 port 8080
81
81
  ```shell
82
- $ pywebexec
82
+ $ pywebexec -d <dir>
83
83
  ```
84
84
 
85
85
  * Launch commands with params/view live output/Status using browser
86
- ![pywebexecnew2](https://github.com/user-attachments/assets/c69e14a3-9624-49b0-81b7-134111b71d2d)
86
+ * Share your terminal output using `pywebexec -d <dir> term`
87
+
88
+ ![pywebexecnew9](https://github.com/user-attachments/assets/a57864ab-c5ee-4301-addd-cc68abc90f15)
87
89
 
88
90
  all commands output / statuses are available in the executables directory in subdirectory `.web_status`
89
91
 
@@ -91,13 +93,16 @@ all commands output / statuses are available in the executables directory in sub
91
93
 
92
94
  * Serve executables in a directory
93
95
  * Launch commands with params from web browser or API call
96
+ * multiple share terminal output
94
97
  * Follow live output
98
+ * Replay terminal history
95
99
  * Stop command
96
100
  * Relaunch command
97
101
  * HTTPS support
98
102
  * HTTPS self-signed certificate generator
99
103
  * Basic Auth
100
- * LDAP(S)
104
+ * LDAP(S) password check/group member
105
+ * Safe url token generation
101
106
  * Can be started as a daemon (POSIX)
102
107
  * Uses gunicorn to serve http/https
103
108
  * Linux/MacOS compatible
@@ -108,7 +113,30 @@ $ pywebexec --dir ~/myscripts --listen 0.0.0.0 --port 8080 --title myscripts
108
113
  $ pywebexec -d ~/myscripts -l 0.0.0.0 -p 8080 -t myscripts
109
114
  ```
110
115
 
111
- ## Basic auth
116
+ ## Sharing terminals
117
+
118
+ * start server and share tty in one command
119
+ ```shell
120
+ $ pywebexec -d ~/webshare shareterm
121
+ ```
122
+ * share tty with an already pywebexec server started
123
+ ```shell
124
+ $ pywebexec -d ~/webshare term
125
+ ```
126
+ if another user need to share his terminal, he need to have write permission on `<dir>/.web_status` directory.
127
+
128
+ ## Safe url token
129
+
130
+ * generate safe url, use the url to access the server
131
+ ```shell
132
+ $ pywebexec -T
133
+ $ pywebexec --tokenurl
134
+ Starting server:
135
+ http://<host>:8080?token=jSTWiNgEVkddeEJ7I97x2ekOeaiXs2mErRSKNxm3DP0
136
+ http://x.x.x.x:8080?token=jSTWiNgEVkddeEJ7I97x2ekOeaiXs2mErRSKNxm3DP0
137
+ ```
138
+
139
+ ## Basic auth
112
140
 
113
141
  * single user/password
114
142
  ```shell
@@ -131,14 +159,14 @@ $ pywebexec
131
159
 
132
160
  * Generate auto-signed certificate and start https server
133
161
  ```shell
134
- $ pywebfs --gencert
135
- $ pywebfs --g
162
+ $ pywebexec --gencert
163
+ $ pywebexec --g
136
164
  ```
137
165
 
138
166
  * Start https server using existing certificate
139
167
  ```shell
140
- $ pywebfs --cert /pathto/host.cert --key /pathto/host.key
141
- $ pywebfs -c /pathto/host.cert -k /pathto/host.key
168
+ $ pywebexec --cert /pathto/host.cert --key /pathto/host.key
169
+ $ pywebexec -c /pathto/host.cert -k /pathto/host.key
142
170
  ```
143
171
 
144
172
  ## Launch server as a daemon
@@ -153,7 +181,7 @@ $ pywebexec stop
153
181
  ## Launch command through API
154
182
 
155
183
  ```shell
156
- $ curl http://myhost:8080/run_script -H 'Content-Type: application/json' -X POST -d '{ "script_name":"myscript", "params":["param1", ...]}
184
+ $ curl http://myhost:8080/run_command -H 'Content-Type: application/json' -X POST -d '{ "command":"myscript", "params":["param1", ...]}'
157
185
  $ curl http://myhost:8080/command_status/<command_id>
158
186
  $ curl http://myhost:8080/command_output/<command_id> -H "Accept: text/plain"
159
187
  ```
@@ -166,6 +194,6 @@ $ curl http://myhost:8080/command_output/<command_id> -H "Accept: text/plain"
166
194
  | POST | /run_command | command: str<br>params: array[str] | command_id: uuid<br>message: str |
167
195
  | POST | /stop_command/command_id | | message: str |
168
196
  | GET | /command_status/command_id | | command_id: uuid<br>command: str<br>params: array[str]<br>start_time: isotime<br>end_time: isotime<br>status: str<br>exit_code: int<br>last_output_line: str |
169
- | GET | /command_output/command_id | | output: str<br>status: str |
197
+ | GET | /command_output/command_id | offset: int | output: str<br>status: str<br>links: { next: str } |
170
198
  | GET | /commands | | array of<br>command_id: uuid<br>command: str<br>start_time: isotime<br>end_time: isotime<br>status: str<br>exit_code: int<br>last_output_line: str |
171
199
  | GET | /executables | | array of str |
@@ -0,0 +1,31 @@
1
+ pywebexec/__init__.py,sha256=4spIsVaF8RJt8S58AG_wWoORRNkws9Iwqprj27C3ljM,99
2
+ pywebexec/pywebexec.py,sha256=bo_rh0wsEkcOXltOZMiZlojqABCAQqDM33cJGUUmnrU,26922
3
+ pywebexec/version.py,sha256=Zv4TpC5V6FOmlNNowuZivqOrr2E0lJ1Gpdzj7o5gDYw,413
4
+ pywebexec/static/css/Consolas NF.ttf,sha256=DJEOzF0eqZ-kxu3Gs_VE8X0NJqiobBzmxWDGpdgGRxI,1313900
5
+ pywebexec/static/css/style.css,sha256=sDBhZ-csW5THIKfTDsHqxCSg6rIJ91Oh15sjw_HjJo4,5702
6
+ pywebexec/static/css/xterm.css,sha256=gy8_LGA7Q61DUf8ElwFQzHqHMBQnbbEmpgZcbdgeSHI,5383
7
+ pywebexec/static/images/aborted.svg,sha256=_mP43hU5QdRLFZIknBgjx-dIXrHgQG23-QV27ApXK2A,381
8
+ pywebexec/static/images/copy.svg,sha256=d9OwtGh5GzzZHzYcDrLfNxZYLth1Q64x7bRyYxu4Px0,622
9
+ pywebexec/static/images/copy_ok.svg,sha256=mEqUVUhSq8xaJK2msQkxRawnz_KwlCZ-tok8QS6hJ3g,451
10
+ pywebexec/static/images/down-arrow.svg,sha256=4TclEmntMvKk_F_ADXgTpGtviYo826EDmmZiGE7HQBI,121
11
+ pywebexec/static/images/failed.svg,sha256=ADZ7IKrUyOXtqpivnz3VcH0-Wru-I5MOi3OJAkI3hxk,1439
12
+ pywebexec/static/images/favicon.svg,sha256=9gSN5Oak1zTWhTCyutlupPBKUxcbdoVt7dvhk8xvEug,1224
13
+ pywebexec/static/images/popup.svg,sha256=0Bl9A_v5cBsMPn6FnOlVWlAQKgd2zqiWQbhjcL9BDzI,559
14
+ pywebexec/static/images/running.gif,sha256=iYuzQGkMxrakSIwt6gPieKCImGZoSAHmU5MUNZa7cpw,25696
15
+ pywebexec/static/images/success.svg,sha256=PJDcCSTevJh7rkfSFLtc7P0pbeh8PVQBS8DaOLQemmc,489
16
+ pywebexec/static/js/commands.js,sha256=8JDb3Q55EJOYf2Q9Uy6qEuqAnn1oGjM0RndgQ4aOjqo,7725
17
+ pywebexec/static/js/popup.js,sha256=i7BPBh6oS0Q6H528DwP6KwJ8CKh7ULwm1rLHSbyvDhk,4656
18
+ pywebexec/static/js/script.js,sha256=QlYuIdvolTwxkJtgp7-X1IRM9Hr8D08iQCyCzZjv3hk,12255
19
+ pywebexec/static/js/xterm/LICENSE,sha256=EU1P4eXTull-_T9I80VuwnJXubB-zLzUl3xpEYj2T1M,1083
20
+ pywebexec/static/js/xterm/ansi_up.min.js,sha256=KNGV0vEr30hNqKQimTAvGVy-icD5A1JqMQTtvYtKR2Y,13203
21
+ pywebexec/static/js/xterm/xterm-addon-fit.js,sha256=Pprm9pZe4SadVXS5Bc8b9VnC9Ex4QlWwA0pxOH53Gck,1460
22
+ pywebexec/static/js/xterm/xterm.js,sha256=Bzka76jZwEhVt_LlS0e0qMw7ryGa1p5qfxFyeohphBo,283371
23
+ pywebexec/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
+ pywebexec/templates/index.html,sha256=DYtT555wSNhnFtzzHhPMWJireynCJNnAuTytpoORQeE,2321
25
+ pywebexec/templates/popup.html,sha256=T6_tAOUoA58sA1oxB5pb8i42RenoMdCsH8T86Gccb6Q,945
26
+ pywebexec-1.4.12.dist-info/LICENSE,sha256=gRJf0JPT_wsZJsUGlWPTS8Vypfl9vQ1qjp6sNbKykuA,1064
27
+ pywebexec-1.4.12.dist-info/METADATA,sha256=cCiJmWvh3DHBVJa0uRdM6-oMEBFyU3g0nSNxrhz5Y1I,7724
28
+ pywebexec-1.4.12.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
29
+ pywebexec-1.4.12.dist-info/entry_points.txt,sha256=l52GBkPCXRkmlHfEyoVauyfBdg8o-CAtC8qQpOIjJK0,55
30
+ pywebexec-1.4.12.dist-info/top_level.txt,sha256=vHoHyzngrfGdm_nM7Xn_5iLmaCrf10XO1EhldgNLEQ8,10
31
+ pywebexec-1.4.12.dist-info/RECORD,,
@@ -1,20 +0,0 @@
1
- pywebexec/__init__.py,sha256=4spIsVaF8RJt8S58AG_wWoORRNkws9Iwqprj27C3ljM,99
2
- pywebexec/pywebexec.py,sha256=TTTF2mueOTDEv-FZHoIx5dMbIQyhsafOMQ-YzkDFIXk,22564
3
- pywebexec/version.py,sha256=zMnMemknXglcJs59xkicNzeEJTVgYd1omSfLWj76yWw,411
4
- pywebexec/static/css/style.css,sha256=rvnWRZQ__-J2EPSKdjPnVaA1oJ7auy0IdsNgxx07WAc,3403
5
- pywebexec/static/images/aborted.svg,sha256=_mP43hU5QdRLFZIknBgjx-dIXrHgQG23-QV27ApXK2A,381
6
- pywebexec/static/images/copy.svg,sha256=d9OwtGh5GzzZHzYcDrLfNxZYLth1Q64x7bRyYxu4Px0,622
7
- pywebexec/static/images/copy_ok.svg,sha256=mEqUVUhSq8xaJK2msQkxRawnz_KwlCZ-tok8QS6hJ3g,451
8
- pywebexec/static/images/failed.svg,sha256=ADZ7IKrUyOXtqpivnz3VcH0-Wru-I5MOi3OJAkI3hxk,1439
9
- pywebexec/static/images/favicon.svg,sha256=ti80IfuDZwIvQcmJxkOeUaB1iMsiyOPmQmVO-h0y1IU,1126
10
- pywebexec/static/images/running.gif,sha256=iYuzQGkMxrakSIwt6gPieKCImGZoSAHmU5MUNZa7cpw,25696
11
- pywebexec/static/images/success.svg,sha256=PJDcCSTevJh7rkfSFLtc7P0pbeh8PVQBS8DaOLQemmc,489
12
- pywebexec/static/js/script.js,sha256=Vg_UZiiTDi79tke6-EpZGQOxPVxXMaAT6qRMpMHGGNU,9380
13
- pywebexec/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
- pywebexec/templates/index.html,sha256=BzTEL60RhPyKi-EAhr4HFgPfJnBSkdQJNFjdkjetZHs,1454
15
- pywebexec-1.2.0.dist-info/LICENSE,sha256=gRJf0JPT_wsZJsUGlWPTS8Vypfl9vQ1qjp6sNbKykuA,1064
16
- pywebexec-1.2.0.dist-info/METADATA,sha256=-V_Ta6Z11TvUc6EVbQ_U1fZ2OnhuJNeoklBU1ynF9R4,6906
17
- pywebexec-1.2.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
18
- pywebexec-1.2.0.dist-info/entry_points.txt,sha256=l52GBkPCXRkmlHfEyoVauyfBdg8o-CAtC8qQpOIjJK0,55
19
- pywebexec-1.2.0.dist-info/top_level.txt,sha256=vHoHyzngrfGdm_nM7Xn_5iLmaCrf10XO1EhldgNLEQ8,10
20
- pywebexec-1.2.0.dist-info/RECORD,,