Compare commits

...

10 commits

Author SHA1 Message Date
da271dcd52 Deleted deletion of modules 2017-05-31 15:30:45 +02:00
4bc9d7bd9b Version Bump 2017-05-31 15:23:26 +02:00
0c69977e61 Fixed store actions on 'false'
Send empty lines to frontend, if empty lines are sent
Emptied sys.modules when the module is executed
2017-05-31 00:24:55 +02:00
63e8059e94 Fixed groups inside subparsers 2017-05-30 19:22:25 +02:00
b589dd70f3 Fixed actions in subparsers 2017-05-30 19:17:48 +02:00
c0d0e11591 fixed setup.py 2017-05-29 14:56:59 +02:00
de5549e43c Version 0.1.1
Default values are now shown in HTML-Form
2017-05-29 14:55:11 +02:00
f7fcde3100 Preparing for PyPI release 2017-05-29 12:11:04 +02:00
cef9c04dc3 Updated README to new name 2017-05-29 12:00:41 +02:00
4d11bc4917 Renamed repository to warped due to naming conflicts in PyPI 2017-05-29 11:59:01 +02:00
316 changed files with 173 additions and 46 deletions

View file

@ -1,2 +1,2 @@
recursive-include warp/templates *
recursive-include warp/static *
recursive-include warped/templates *
recursive-include warped/static *

View file

@ -1,6 +1,6 @@
# WARP - a Webbased frontend for ARgparser in Python
# WARPED - a Webbased frontend for ARgparser in Python
`warp` can be used to execute single Python file and Python modules. It captures
`warped` can be used to execute single Python file and Python modules. It captures
calls to the `argparse` module of Python and renders a web GUI based on the
options and arguments defined. It also displays the output of the program inside
the web GUI and allows you to stop, pause and resume the program, as well as
@ -11,14 +11,14 @@ downloading the output.
Either get a stable version from PyPI, or install the current version from git
# Installation from PyPI
pip install warp
pip install warped
# Installation from git
pip install git+https://git.k-fortytwo.de/christofsteel/warp/
pip install git+https://git.k-fortytwo.de/christofsteel/warped/
## Usage
warp [-h] [--port PORT] [--host HOST] [--module] file
warped [-h] [--port PORT] [--host HOST] [--module] file
a Webbased frontend for ARgparse in Python
@ -33,25 +33,25 @@ Either get a stable version from PyPI, or install the current version from git
## Sample
To test the capabilities of `warp` an example module was included. You can run
To test the capabilities of `warped` an example module was included. You can run
it like this:
warp -m warp.samples.hooked
warped -m warped.samples.hooked
Since `warp` also makes use of the argparse module, `warp` itself can be //warped//.
Since `warped` also makes use of the argparse module, `warped` itself can be //warped//.
warp -m warp.hook
warped -m warped.hook
## How does it work?
When `warp` is executed, it starts a flask webserver. The javascript of the
When `warped` is executed, it starts a flask webserver. The javascript of the
website reads the `/arguments` resource of the server, where the configuration
of the argparser returned. In a seperate process the given program is executed
using the `runpy` library, redirecting `sys.stdin` and `sys.stdout` to a
`multiprocessing.Queue`, which can be read by the warp process to display it
via the web GUI.
Additionally, `warp` adds an entry for `argparse` in the `sys.modules` list. Python
Additionally, `warped` adds an entry for `argparse` in the `sys.modules` list. Python
looks first looks at this list, everytime a module is imported, to avoid
importing a module multiple times. This custom `argparse` module behaves similar
to the original `argparse` module. In fact with the exception of the

77
README.rst Normal file
View file

@ -0,0 +1,77 @@
WARPED - a Webbased frontend for ARgparser in Python
====================================================
``warped`` can be used to execute single Python file and Python modules.
It captures calls to the ``argparse`` module of Python and renders a web
GUI based on the options and arguments defined. It also displays the
output of the program inside the web GUI and allows you to stop, pause
and resume the program, as well as downloading the output.
Install
-------
Either get a stable version from PyPI, or install the current version
from git
::
# Installation from PyPI
pip install warped
# Installation from git
pip install git+https://git.k-fortytwo.de/christofsteel/warped/
Usage
-----
::
warped [-h] [--port PORT] [--host HOST] [--module] file
a Webbased frontend for ARgparse in Python
positional arguments:
file File to run
optional arguments:
-h, --help show this help message and exit
--port PORT, -p PORT The port to listen on (default 5000)
--host HOST The host to bind to (default 0.0.0.0)
--module, -m If set, loads a module instead of a file
Sample
------
To test the capabilities of ``warped`` an example module was included.
You can run it like this:
::
warped -m warped.samples.hooked
Since ``warped`` also makes use of the argparse module, ``warped``
itself can be //warped//.
::
warped -m warped.hook
How does it work?
-----------------
When ``warped`` is executed, it starts a flask webserver. The javascript
of the website reads the ``/arguments`` resource of the server, where
the configuration of the argparser returned. In a seperate process the
given program is executed using the ``runpy`` library, redirecting
``sys.stdin`` and ``sys.stdout`` to a ``multiprocessing.Queue``, which
can be read by the warp process to display it via the web GUI.
Additionally, ``warped`` adds an entry for ``argparse`` in the
``sys.modules`` list. Python looks first looks at this list, everytime a
module is imported, to avoid importing a module multiple times. This
custom ``argparse`` module behaves similar to the original ``argparse``
module. In fact with the exception of the
``ArgumentParser.parse_args()`` method, it works exactly like the
original. Once the program calls the ``parse_args()`` method, it blocks
and waits for user interaction via the web GUI. Once the user submits
the data, the process continues.

2
setup.cfg Normal file
View file

@ -0,0 +1,2 @@
[metadata]
description-file = README.md

View file

@ -1,17 +1,20 @@
from setuptools import setup, find_packages
version = "0.1.2"
setup(
name='warp',
version='0.0.1',
name='warped',
version=version,
packages=find_packages(),
url='https://git.k-fortytwo.de/christofsteel/warp',
download_url = 'https://git.k-fortytwo.de/christofsteel/warped/archive/%s.tar.gz' % version,
license='MIT',
author='Christoph Stahl',
author_email='christoph.stahl@uni-dortmund.de',
description='A webbased wrapper for the argument parser in Python',
entry_points={
'console_scripts': [
"warp = warp.hook:main"
"warped = warped.hook:main"
]
},
include_package_data = True,

View file

@ -43,6 +43,7 @@ class Action():
internal_dict['dest'] = self.dest
internal_dict['desc'] = self.desc
internal_dict['checked'] = self.on_none if self.on_none is True or self.on_none is False else None
internal_dict['default'] = self.on_none if type(self.on_none) == str else None
internal_dict['optional'] = self.optional
internal_dict['is_const'] = self.const is not None
internal_dict['type'] = self.type_function.__name__
@ -89,7 +90,7 @@ class ActionContainer():
internal_dict = {}
internal_dict['uuid'] = str(self.uuid)
internal_dict['actions'] = [action.as_dict() for action in self.actions]
internal_dict['groups'] = [[action.as_dict() for action in group] for group in self.groups]
internal_dict['groups'] = [group.as_dict() for group in self.groups]
return internal_dict
class StoreAction(Action):
@ -97,6 +98,8 @@ class StoreAction(Action):
class StoreConstAction(Action):
def store_type_function(self, x):
if x == 'false':
x = None
return self.const if x is not None else self.on_none
def __init__(self, action, **kwargs):
@ -109,4 +112,4 @@ class MutuallyExclusiveGroup(ActionContainer):
super().__init__()
def __repr__(self):
return "Group Object: ( Actions: {}, Groups: {} )".format(self.actions, self.mutex_groups)
return "Group Object: ( Actions: {}, Groups: {} )".format(self.actions, self.groups)

View file

@ -73,8 +73,6 @@ def argParserGenerator(actionQueue, namespaceQueue):
actions, mutex_groups = self.get_actions()
print(actions, file=sys.__stdout__)
self.actionQueue.put((mutex_groups, actions, name, desc))
namespace = self.namespaceQueue.get()
return namespace

View file

@ -4,11 +4,10 @@ import runpy
from traceback import print_exc
from contextlib import redirect_stdout, redirect_stderr
from multiprocessing import Process
class Context(Process):
def __init__(self, name, path, stdout, stderr, arguments=[], is_module = False, overwritten_modules={}):
def __init__(self, name, path, stdout, stderr, arguments=[], is_module = False, overwritten_modules={}, original_modules=None):
super().__init__()
self.name = name
self.stdout = stdout
@ -17,12 +16,17 @@ class Context(Process):
self.is_module = is_module
self.arguments = arguments
self.overwritten_modules = overwritten_modules
self.original_modules = original_modules
def run(self):
if self.arguments is not None:
sys.argv = [''] + self.arguments
else:
sys.argv = ['']
# if not self.original_modules is None:
# sys.modules.clear()
# sys.modules.update(self.original_modules)
sys.modules.update(self.overwritten_modules)
with redirect_stdout(self.stdout):
with redirect_stderr(self.stderr):
@ -41,10 +45,5 @@ if __name__ == "__main__":
parser.add_argument("--is-module", "-m", default=False, action="store_true", dest="is_module")
args = parser.parse_args()
#newModule = ModuleType('argparse', 'Argument Parser')
#newModule.__dict__.update(argparse.__dict__)
#newModule.__dict__['ArgumentParser'].parse_args = f
print(args)
context = Context("test", args.path, sys.stdout, sys.stderr, None if args.arguments is None else [args.arguments], args.is_module)
context.start()

View file

@ -1,3 +1,4 @@
from . import savemodules
import sys
import io
@ -24,9 +25,15 @@ class QueuedOut(io.StringIO):
lines = b.split('\n')
for line in lines[:-1]:
super().write(line)
self.flush()
self.explflush()
super().write(lines[-1])
def explflush(self):
value = self.getvalue()
self.queue.put((self.name, value))
self.seek(0)
self.truncate(0)
def flush(self):
value = self.getvalue()
if len(value) > 1:
@ -99,7 +106,8 @@ def start_module(name, is_module):
ioout,
ioerr,
overwritten_modules={'argparse': argparser},
is_module = is_module
is_module = is_module,
original_modules = savemodules.savedmodules
)
views.app.module_process.start()
views.app.output.start()
@ -111,6 +119,7 @@ def start_module(name, is_module):
views.app.output.stop()
ioerr.write("Process stopped ({})\n".format(views.app.module_process.exitcode))
views.app.output.queue.put(("sig", "stop"))
views.app.restart.wait()

View file

@ -21,7 +21,7 @@ def main():
group3 = group2.add_mutually_exclusive_group()
group3.add_argument('--three')
group3.add_argument('--four')
bla.add_argument('--test', '-t', help="Blubb")
bla.add_argument('--test', '-t', help="Blubb", default="Blabla")
bla.add_argument('--bla', action="store_true", default=True)
bla.add_argument('--blubb', action="store_true")
bla.add_argument('-f', action="append")

View file

@ -11,3 +11,4 @@ if __name__ == "__main__":
args = parser.parse_args()
print("Subparser %s was selected" % args.command)
print(args)

2
warped/savemodules.py Normal file
View file

@ -0,0 +1,2 @@
import sys
savedmodules = dict(sys.modules)

View file

@ -7,6 +7,15 @@
display: block;
}
.checkbox {
height:100%;
}
input[type=checkbox] {
width: 2em;
height: 2em;
-moz-appearance: none;
}
#output {
flex:1;
@ -15,7 +24,7 @@
font-weight: bold;
font-family: "Lucida Console", Monaco, monospace;
white-space:pre;
overflow-y: scroll;
overflow-y: auto;
height: 100%;
}
@ -62,7 +71,7 @@ li.subparser {
#arguments {
padding: 0px;
overflow: scroll;
overflow-y: auto;
}
.tabs-panel {

View file

Before

Width:  |  Height:  |  Size: 147 KiB

After

Width:  |  Height:  |  Size: 147 KiB

View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

Before

Width:  |  Height:  |  Size: 921 B

After

Width:  |  Height:  |  Size: 921 B

View file

Before

Width:  |  Height:  |  Size: 919 B

After

Width:  |  Height:  |  Size: 919 B

View file

Before

Width:  |  Height:  |  Size: 922 B

After

Width:  |  Height:  |  Size: 922 B

View file

Before

Width:  |  Height:  |  Size: 921 B

After

Width:  |  Height:  |  Size: 921 B

View file

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View file

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View file

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

View file

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

Before

Width:  |  Height:  |  Size: 984 B

After

Width:  |  Height:  |  Size: 984 B

View file

Before

Width:  |  Height:  |  Size: 876 B

After

Width:  |  Height:  |  Size: 876 B

View file

Before

Width:  |  Height:  |  Size: 937 B

After

Width:  |  Height:  |  Size: 937 B

View file

Before

Width:  |  Height:  |  Size: 956 B

After

Width:  |  Height:  |  Size: 956 B

View file

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

Before

Width:  |  Height:  |  Size: 976 B

After

Width:  |  Height:  |  Size: 976 B

View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

Before

Width:  |  Height:  |  Size: 896 B

After

Width:  |  Height:  |  Size: 896 B

View file

Before

Width:  |  Height:  |  Size: 760 B

After

Width:  |  Height:  |  Size: 760 B

View file

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View file

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 1 KiB

View file

Before

Width:  |  Height:  |  Size: 941 B

After

Width:  |  Height:  |  Size: 941 B

View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View file

Before

Width:  |  Height:  |  Size: 2 KiB

After

Width:  |  Height:  |  Size: 2 KiB

View file

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

Before

Width:  |  Height:  |  Size: 2 KiB

After

Width:  |  Height:  |  Size: 2 KiB

View file

Before

Width:  |  Height:  |  Size: 869 B

After

Width:  |  Height:  |  Size: 869 B

View file

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View file

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 1 KiB

View file

Before

Width:  |  Height:  |  Size: 822 B

After

Width:  |  Height:  |  Size: 822 B

View file

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

Before

Width:  |  Height:  |  Size: 756 B

After

Width:  |  Height:  |  Size: 756 B

View file

Before

Width:  |  Height:  |  Size: 986 B

After

Width:  |  Height:  |  Size: 986 B

View file

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

Before

Width:  |  Height:  |  Size: 929 B

After

Width:  |  Height:  |  Size: 929 B

View file

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

Before

Width:  |  Height:  |  Size: 881 B

After

Width:  |  Height:  |  Size: 881 B

View file

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 1 KiB

View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View file

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View file

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View file

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

Before

Width:  |  Height:  |  Size: 984 B

After

Width:  |  Height:  |  Size: 984 B

View file

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 1 KiB

Some files were not shown because too many files have changed in this diff Show more