wexample-app 0.0.4__tar.gz
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.
- wexample-app-0.0.4/PKG-INFO +16 -0
- wexample-app-0.0.4/README.md +3 -0
- wexample-app-0.0.4/setup.cfg +4 -0
- wexample-app-0.0.4/setup.py +26 -0
- wexample-app-0.0.4/wexample_app/__init__.py +0 -0
- wexample-app-0.0.4/wexample_app/const/__init__.py +0 -0
- wexample-app-0.0.4/wexample_app/const/types.py +1 -0
- wexample-app-0.0.4/wexample_app/exception/__init__.py +0 -0
- wexample-app-0.0.4/wexample_app/exception/kernel_exception.py +2 -0
- wexample-app-0.0.4/wexample_app/response/__init__.py +0 -0
- wexample-app-0.0.4/wexample_app/response/abstract_response.py +14 -0
- wexample-app-0.0.4/wexample_app/response/default_response.py +13 -0
- wexample-app-0.0.4/wexample_app/utils/__init__.py +0 -0
- wexample-app-0.0.4/wexample_app/utils/abstract_command_resolver.py +25 -0
- wexample-app-0.0.4/wexample_app/utils/abstract_kernel.py +99 -0
- wexample-app-0.0.4/wexample_app/utils/abstract_kernel_child.py +11 -0
- wexample-app-0.0.4/wexample_app/utils/command.py +13 -0
- wexample-app-0.0.4/wexample_app/utils/command_request.py +44 -0
- wexample-app-0.0.4/wexample_app/utils/file/__init__.py +0 -0
- wexample-app-0.0.4/wexample_app/utils/mixins/__init__.py +0 -0
- wexample-app-0.0.4/wexample_app/utils/mixins/command_line_kernel.py +74 -0
- wexample-app-0.0.4/wexample_app/utils/runner/__init__.py +0 -0
- wexample-app-0.0.4/wexample_app/utils/runner/abstract_command_runner.py +24 -0
- wexample-app-0.0.4/wexample_app/utils/runner/python_command_runner.py +48 -0
- wexample-app-0.0.4/wexample_app.egg-info/PKG-INFO +16 -0
- wexample-app-0.0.4/wexample_app.egg-info/SOURCES.txt +28 -0
- wexample-app-0.0.4/wexample_app.egg-info/__init__.py +0 -0
- wexample-app-0.0.4/wexample_app.egg-info/dependency_links.txt +1 -0
- wexample-app-0.0.4/wexample_app.egg-info/requires.txt +5 -0
- wexample-app-0.0.4/wexample_app.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: wexample-app
|
|
3
|
+
Version: 0.0.4
|
|
4
|
+
Summary: Helpers for building Python app or cli.
|
|
5
|
+
Home-page: https://github.com/wexample/python-app
|
|
6
|
+
Author: weeger
|
|
7
|
+
Author-email: contact@wexample.com
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.6
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
|
|
14
|
+
# app
|
|
15
|
+
|
|
16
|
+
Helpers for building Python app or cli.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
setup(
|
|
4
|
+
name='wexample-app',
|
|
5
|
+
version=open('version.txt').read(),
|
|
6
|
+
author='weeger',
|
|
7
|
+
author_email='contact@wexample.com',
|
|
8
|
+
description='Helpers for building Python app or cli.',
|
|
9
|
+
long_description=open('README.md').read(),
|
|
10
|
+
long_description_content_type='text/markdown',
|
|
11
|
+
url='https://github.com/wexample/python-app',
|
|
12
|
+
packages=find_packages(),
|
|
13
|
+
classifiers=[
|
|
14
|
+
'Programming Language :: Python :: 3',
|
|
15
|
+
'License :: OSI Approved :: MIT License',
|
|
16
|
+
'Operating System :: OS Independent',
|
|
17
|
+
],
|
|
18
|
+
install_requires=[
|
|
19
|
+
'python-dotenv',
|
|
20
|
+
'pydantic',
|
|
21
|
+
'wexample-filestate',
|
|
22
|
+
'wexample-helpers',
|
|
23
|
+
'wexample-prompt',
|
|
24
|
+
],
|
|
25
|
+
python_requires='>=3.6',
|
|
26
|
+
)
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
CommandLineArgumentsList = list[str]
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from abc import abstractmethod
|
|
2
|
+
|
|
3
|
+
from wexample_app.utils.abstract_kernel_child import AbstractKernelChild
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class AbstractResponse(AbstractKernelChild):
|
|
7
|
+
@abstractmethod
|
|
8
|
+
def print(self) -> str:
|
|
9
|
+
# For now, simple placeholder.
|
|
10
|
+
pass
|
|
11
|
+
|
|
12
|
+
# Enforce importing for rebuild
|
|
13
|
+
from wexample_app.utils.abstract_kernel import AbstractKernel
|
|
14
|
+
AbstractResponse.model_rebuild()
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
from wexample_app.response.abstract_response import AbstractResponse
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class DefaultResponse(AbstractResponse):
|
|
7
|
+
content: Any
|
|
8
|
+
|
|
9
|
+
def print(self) -> str:
|
|
10
|
+
# For now consider every output as a string
|
|
11
|
+
return str(self.content)
|
|
12
|
+
|
|
13
|
+
DefaultResponse.model_rebuild()
|
|
File without changes
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from abc import abstractmethod
|
|
2
|
+
|
|
3
|
+
from wexample_app.utils.abstract_kernel_child import AbstractKernelChild
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING, Optional
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from wexample_app.utils.command_request import CommandRequest
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class AbstractCommandResolver(AbstractKernelChild):
|
|
12
|
+
@classmethod
|
|
13
|
+
@abstractmethod
|
|
14
|
+
def get_type(cls) -> str:
|
|
15
|
+
pass
|
|
16
|
+
|
|
17
|
+
def supports(self, request: "CommandRequest") -> bool:
|
|
18
|
+
# By default, resolver match with every command.
|
|
19
|
+
return True
|
|
20
|
+
|
|
21
|
+
def build_command_path(self, request: "CommandRequest") -> Optional[str]:
|
|
22
|
+
return None
|
|
23
|
+
|
|
24
|
+
def build_command_function_name(self, request: "CommandRequest") -> None:
|
|
25
|
+
return None
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
from typing import Any, Optional, Dict, Type
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, Field
|
|
4
|
+
from wexample_helpers.const.types import StringsList
|
|
5
|
+
from wexample_app.exception.kernel_exception import KernelException
|
|
6
|
+
from wexample_prompt.io_manager import IOManager
|
|
7
|
+
from wexample_filestate.file_state_manager import FileStateManager
|
|
8
|
+
from wexample_app.utils.abstract_command_resolver import AbstractCommandResolver
|
|
9
|
+
from wexample_app.utils.runner.abstract_command_runner import AbstractCommandRunner
|
|
10
|
+
from wexample_prompt.utils.prompt_response import PromptResponse
|
|
11
|
+
from wexample_app.utils.command_request import CommandRequest
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class AbstractKernel(BaseModel):
|
|
15
|
+
io: Optional[IOManager] = None
|
|
16
|
+
entrypoint_path: str = Field(description="The main file placed at application root directory")
|
|
17
|
+
resolvers: Dict[str, "AbstractCommandResolver"] = None
|
|
18
|
+
runners: Dict[str, "AbstractCommandRunner"] = None
|
|
19
|
+
env_config: Dict[str, Optional[str]] = None
|
|
20
|
+
expected_env_items: Optional[StringsList] = [
|
|
21
|
+
"APP_ENV"
|
|
22
|
+
]
|
|
23
|
+
workdir: FileStateManager = None
|
|
24
|
+
|
|
25
|
+
def __init__(self, /, **data: Any) -> None:
|
|
26
|
+
super().__init__(**data)
|
|
27
|
+
|
|
28
|
+
self.io = IOManager()
|
|
29
|
+
|
|
30
|
+
self._init_workdir()
|
|
31
|
+
self._init_env_values()
|
|
32
|
+
self._init_resolvers()
|
|
33
|
+
self._init_runners()
|
|
34
|
+
|
|
35
|
+
# Validate configuration.
|
|
36
|
+
self._check_env_values()
|
|
37
|
+
|
|
38
|
+
def _init_env_values(self):
|
|
39
|
+
from dotenv import dotenv_values
|
|
40
|
+
|
|
41
|
+
self.env_config = dotenv_values(f"{self.workdir.get_resolved()}{self._get_dotenv_file_name()}")
|
|
42
|
+
|
|
43
|
+
def _get_dotenv_file_name(self) -> str:
|
|
44
|
+
from wexample_helpers.const.globals import FILE_NAME_ENV
|
|
45
|
+
return FILE_NAME_ENV
|
|
46
|
+
|
|
47
|
+
def _init_workdir(self):
|
|
48
|
+
self.workdir = (self._get_workdir_state_manager_class()).create_from_path(
|
|
49
|
+
path=self.entrypoint_path,
|
|
50
|
+
config={},
|
|
51
|
+
io=self.io
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
def _init_resolvers(self):
|
|
55
|
+
self.resolvers = {
|
|
56
|
+
class_definition.get_type(): class_definition(kernel=self)
|
|
57
|
+
for class_definition in self._get_command_resolvers()
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
def _init_runners(self):
|
|
61
|
+
self.runners = {
|
|
62
|
+
class_definition.get_runner_name(): class_definition(kernel=self)
|
|
63
|
+
for class_definition in self._get_command_runners()
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
def _get_workdir_state_manager_class(self) -> Type[FileStateManager]:
|
|
67
|
+
return FileStateManager
|
|
68
|
+
|
|
69
|
+
def _get_command_request_class(self) -> Type["CommandRequest"]:
|
|
70
|
+
from wexample_app.utils.command_request import CommandRequest
|
|
71
|
+
|
|
72
|
+
return CommandRequest
|
|
73
|
+
|
|
74
|
+
def _check_env_values(self):
|
|
75
|
+
from wexample_helpers.helpers.dict_helper import dict_get_first_missing_key
|
|
76
|
+
first_missing_key = dict_get_first_missing_key(self.env_config, self.expected_env_items)
|
|
77
|
+
if first_missing_key:
|
|
78
|
+
raise KernelException(f"Missing {self._get_dotenv_file_name()} configuration {first_missing_key}")
|
|
79
|
+
|
|
80
|
+
def _get_core_configuration_arguments(self) -> list[dict[str, Any]]:
|
|
81
|
+
return []
|
|
82
|
+
|
|
83
|
+
def _get_command_resolvers(self) -> list[Type["AbstractCommandResolver"]]:
|
|
84
|
+
return []
|
|
85
|
+
|
|
86
|
+
def _get_command_runners(self) -> list[Type["AbstractCommandRunner"]]:
|
|
87
|
+
from wexample_app.utils.runner.python_command_runner import PythonCommandRunner
|
|
88
|
+
|
|
89
|
+
return [
|
|
90
|
+
# Default runner.
|
|
91
|
+
PythonCommandRunner
|
|
92
|
+
]
|
|
93
|
+
|
|
94
|
+
def execute_kernel_command(self, request: "CommandRequest") -> PromptResponse:
|
|
95
|
+
return request.execute()
|
|
96
|
+
|
|
97
|
+
from wexample_app.utils.command import Command
|
|
98
|
+
Command.model_rebuild()
|
|
99
|
+
CommandRequest.model_rebuild()
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from typing import Callable, Any
|
|
2
|
+
|
|
3
|
+
from wexample_app.utils.abstract_kernel_child import AbstractKernelChild
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Command(AbstractKernelChild):
|
|
7
|
+
function: Callable[..., Any] = None
|
|
8
|
+
|
|
9
|
+
def execute(self, arguments):
|
|
10
|
+
return self.function(
|
|
11
|
+
kernel=self.kernel,
|
|
12
|
+
arguments=arguments
|
|
13
|
+
)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
from wexample_app.utils.abstract_kernel_child import AbstractKernelChild
|
|
2
|
+
from typing import TYPE_CHECKING, Optional, Any, List, Union
|
|
3
|
+
|
|
4
|
+
if TYPE_CHECKING:
|
|
5
|
+
from wexample_prompt.utils.prompt_response import PromptResponse
|
|
6
|
+
from wexample_app.utils.abstract_command_resolver import AbstractCommandResolver
|
|
7
|
+
from wexample_app.utils.runner.abstract_command_runner import AbstractCommandRunner
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class CommandRequest(AbstractKernelChild):
|
|
11
|
+
name: str
|
|
12
|
+
arguments: List[Union[str | int]] = []
|
|
13
|
+
path: Optional[str] = None
|
|
14
|
+
type: Optional[str] = None
|
|
15
|
+
resolver: Optional["AbstractCommandResolver"] = None
|
|
16
|
+
runner: Optional["AbstractCommandRunner"] = None
|
|
17
|
+
|
|
18
|
+
def __init__(self, /, **data: Any) -> None:
|
|
19
|
+
super().__init__(**data)
|
|
20
|
+
|
|
21
|
+
self.type = self.guess_type()
|
|
22
|
+
self.path = self.get_resolver().build_command_path(self)
|
|
23
|
+
self.resolver = self.get_resolver()
|
|
24
|
+
self.runner = self.guess_runner()
|
|
25
|
+
|
|
26
|
+
def execute(self) -> "PromptResponse":
|
|
27
|
+
command = self.runner.build_command(request=self)
|
|
28
|
+
|
|
29
|
+
return command.execute(self.arguments)
|
|
30
|
+
|
|
31
|
+
def get_resolver(self) -> Optional["AbstractCommandResolver"]:
|
|
32
|
+
return self.kernel.resolvers[self.type]
|
|
33
|
+
|
|
34
|
+
def guess_runner(self) -> Optional["AbstractCommandRunner"]:
|
|
35
|
+
for runner_type in self.kernel.runners:
|
|
36
|
+
if self.kernel.runners[runner_type].will_run(self):
|
|
37
|
+
return self.kernel.runners[runner_type]
|
|
38
|
+
return None
|
|
39
|
+
|
|
40
|
+
def guess_type(self) -> Optional[str]:
|
|
41
|
+
for resolver_type in self.kernel.resolvers:
|
|
42
|
+
if self.kernel.resolvers[resolver_type].supports(self):
|
|
43
|
+
return resolver_type
|
|
44
|
+
return None
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from wexample_helpers.helpers.args_helper import args_shift_one
|
|
4
|
+
from wexample_app.const.types import CommandLineArgumentsList
|
|
5
|
+
from wexample_app.utils.command_request import CommandRequest
|
|
6
|
+
from wexample_app.response.abstract_response import AbstractResponse
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class CommandLineKernel:
|
|
10
|
+
_sys_argv: list[str]
|
|
11
|
+
_sys_argv_start_index: int | None = 1
|
|
12
|
+
_sys_argv_end_index: int | None = None
|
|
13
|
+
_core_argv: list[str]
|
|
14
|
+
|
|
15
|
+
def _init_command_line_kernel(self):
|
|
16
|
+
import sys
|
|
17
|
+
|
|
18
|
+
self._sys_argv: list[str] = sys.argv.copy()
|
|
19
|
+
|
|
20
|
+
self._handle_core_args()
|
|
21
|
+
|
|
22
|
+
def _get_core_args(self):
|
|
23
|
+
return {}
|
|
24
|
+
|
|
25
|
+
def _handle_core_args(self):
|
|
26
|
+
for arg_config in self._get_core_args():
|
|
27
|
+
if args_shift_one(self._sys_argv, arg_config["arg"], True) is not None:
|
|
28
|
+
setattr(self, arg_config["attr"], arg_config["value"])
|
|
29
|
+
|
|
30
|
+
def exec_argv(self):
|
|
31
|
+
"""
|
|
32
|
+
Main entrypoint from command line calls.
|
|
33
|
+
May not be called by an internal script.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
command_requests = self._build_command_requests_from_arguments(
|
|
37
|
+
self._sys_argv[self._sys_argv_start_index:self._sys_argv_end_index]
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
responses: list[AbstractResponse] = []
|
|
41
|
+
for command_request in command_requests:
|
|
42
|
+
responses.append(self.execute_kernel_command(command_request))
|
|
43
|
+
|
|
44
|
+
self.render_responses_to_prompt(responses)
|
|
45
|
+
|
|
46
|
+
def exec_single_command(self, command_request):
|
|
47
|
+
self.render_responses_to_prompt([
|
|
48
|
+
self.execute_kernel_command(command_request)
|
|
49
|
+
])
|
|
50
|
+
|
|
51
|
+
def render_responses_to_prompt(self, responses: list[AbstractResponse]):
|
|
52
|
+
prompt_responses = []
|
|
53
|
+
from wexample_prompt.utils.prompt_response import PromptResponse
|
|
54
|
+
|
|
55
|
+
for response in responses:
|
|
56
|
+
prompt_responses.append(
|
|
57
|
+
# For now consider every output as a string
|
|
58
|
+
PromptResponse.from_multiline_message(
|
|
59
|
+
response.print()
|
|
60
|
+
)
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
self.io.print_responses(prompt_responses)
|
|
64
|
+
|
|
65
|
+
def _build_command_requests_from_arguments(self, arguments: CommandLineArgumentsList) -> list[CommandRequest]:
|
|
66
|
+
return []
|
|
67
|
+
|
|
68
|
+
def _build_single_command_request_from_arguments(self, arguments: CommandLineArgumentsList):
|
|
69
|
+
return [
|
|
70
|
+
(self._get_command_request_class())(
|
|
71
|
+
kernel=self,
|
|
72
|
+
name=arguments[0],
|
|
73
|
+
arguments=arguments[1:])
|
|
74
|
+
]
|
|
File without changes
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from abc import abstractmethod
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
from wexample_app.utils.abstract_kernel_child import AbstractKernelChild
|
|
5
|
+
|
|
6
|
+
from typing import TYPE_CHECKING
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from wexample_app.utils.command import Command
|
|
10
|
+
from wexample_app.utils.command_request import CommandRequest
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class AbstractCommandRunner(AbstractKernelChild):
|
|
14
|
+
@classmethod
|
|
15
|
+
@abstractmethod
|
|
16
|
+
def get_runner_name(cls) -> str:
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
@abstractmethod
|
|
20
|
+
def build_command(self, request: "CommandRequest") -> Optional["Command"]:
|
|
21
|
+
pass
|
|
22
|
+
|
|
23
|
+
def will_run(self, request: "CommandRequest") -> bool:
|
|
24
|
+
return False
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import os.path
|
|
2
|
+
from typing import Optional
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
from wexample_app.utils.runner.abstract_command_runner import AbstractCommandRunner
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from wexample_app.utils.command import Command
|
|
9
|
+
from wexample_app.utils.command_request import CommandRequest
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class PythonCommandRunner(AbstractCommandRunner):
|
|
13
|
+
@classmethod
|
|
14
|
+
def get_runner_name(cls) -> str:
|
|
15
|
+
return "python"
|
|
16
|
+
|
|
17
|
+
def will_run(self, request: "CommandRequest") -> bool:
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
from wexample_helpers.const.globals import FILE_EXTENSION_PYTHON
|
|
20
|
+
|
|
21
|
+
file_path = Path(request.resolver.build_command_path(request))
|
|
22
|
+
file_extension = file_path.suffix.lower()
|
|
23
|
+
|
|
24
|
+
return file_extension == f".{FILE_EXTENSION_PYTHON}"
|
|
25
|
+
|
|
26
|
+
def build_command(self, request: "CommandRequest") -> Optional["Command"]:
|
|
27
|
+
import importlib.util
|
|
28
|
+
from wexample_app.utils.command import Command
|
|
29
|
+
|
|
30
|
+
path = request.resolver.build_command_path(request)
|
|
31
|
+
|
|
32
|
+
if not os.path.exists(path):
|
|
33
|
+
return None
|
|
34
|
+
|
|
35
|
+
# Import module and load function.
|
|
36
|
+
spec = importlib.util.spec_from_file_location(path, path)
|
|
37
|
+
|
|
38
|
+
if not spec or not spec.loader:
|
|
39
|
+
return None
|
|
40
|
+
|
|
41
|
+
module = importlib.util.module_from_spec(spec)
|
|
42
|
+
spec.loader.exec_module(module)
|
|
43
|
+
function = getattr(module, request.resolver.build_command_function_name(request), None)
|
|
44
|
+
|
|
45
|
+
return Command(
|
|
46
|
+
kernel=self.kernel,
|
|
47
|
+
function=function
|
|
48
|
+
) if function is not None else None
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: wexample-app
|
|
3
|
+
Version: 0.0.4
|
|
4
|
+
Summary: Helpers for building Python app or cli.
|
|
5
|
+
Home-page: https://github.com/wexample/python-app
|
|
6
|
+
Author: weeger
|
|
7
|
+
Author-email: contact@wexample.com
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.6
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
|
|
14
|
+
# app
|
|
15
|
+
|
|
16
|
+
Helpers for building Python app or cli.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
setup.py
|
|
3
|
+
wexample_app/__init__.py
|
|
4
|
+
wexample_app.egg-info/PKG-INFO
|
|
5
|
+
wexample_app.egg-info/SOURCES.txt
|
|
6
|
+
wexample_app.egg-info/__init__.py
|
|
7
|
+
wexample_app.egg-info/dependency_links.txt
|
|
8
|
+
wexample_app.egg-info/requires.txt
|
|
9
|
+
wexample_app.egg-info/top_level.txt
|
|
10
|
+
wexample_app/const/__init__.py
|
|
11
|
+
wexample_app/const/types.py
|
|
12
|
+
wexample_app/exception/__init__.py
|
|
13
|
+
wexample_app/exception/kernel_exception.py
|
|
14
|
+
wexample_app/response/__init__.py
|
|
15
|
+
wexample_app/response/abstract_response.py
|
|
16
|
+
wexample_app/response/default_response.py
|
|
17
|
+
wexample_app/utils/__init__.py
|
|
18
|
+
wexample_app/utils/abstract_command_resolver.py
|
|
19
|
+
wexample_app/utils/abstract_kernel.py
|
|
20
|
+
wexample_app/utils/abstract_kernel_child.py
|
|
21
|
+
wexample_app/utils/command.py
|
|
22
|
+
wexample_app/utils/command_request.py
|
|
23
|
+
wexample_app/utils/file/__init__.py
|
|
24
|
+
wexample_app/utils/mixins/__init__.py
|
|
25
|
+
wexample_app/utils/mixins/command_line_kernel.py
|
|
26
|
+
wexample_app/utils/runner/__init__.py
|
|
27
|
+
wexample_app/utils/runner/abstract_command_runner.py
|
|
28
|
+
wexample_app/utils/runner/python_command_runner.py
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
wexample_app
|