rapidframework-lib 1.0.9__py3-none-any.whl → 1.1.1__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.
- rapidframework/config.py +24 -19
- rapidframework/configs/managers.json +12 -13
- rapidframework/frameworks/django.py +4 -4
- rapidframework/frameworks/fastapi.py +1 -2
- rapidframework/main.py +13 -18
- rapidframework/template.py +42 -50
- {rapidframework_lib-1.0.9.dist-info → rapidframework_lib-1.1.1.dist-info}/METADATA +2 -2
- {rapidframework_lib-1.0.9.dist-info → rapidframework_lib-1.1.1.dist-info}/RECORD +12 -12
- {rapidframework_lib-1.0.9.dist-info → rapidframework_lib-1.1.1.dist-info}/WHEEL +0 -0
- {rapidframework_lib-1.0.9.dist-info → rapidframework_lib-1.1.1.dist-info}/entry_points.txt +0 -0
- {rapidframework_lib-1.0.9.dist-info → rapidframework_lib-1.1.1.dist-info}/licenses/LICENSE +0 -0
- {rapidframework_lib-1.0.9.dist-info → rapidframework_lib-1.1.1.dist-info}/top_level.txt +0 -0
rapidframework/config.py
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
from
|
2
|
-
from typing import Self, Dict
|
1
|
+
from pathlib import Path
|
2
|
+
from typing import Optional, Self, Dict, List
|
3
3
|
import pkgutil
|
4
|
-
from msgspec import json, Struct,
|
5
|
-
from subprocess import run
|
4
|
+
from msgspec import json, Struct, DecodeError
|
5
|
+
from subprocess import run, CalledProcessError
|
6
6
|
from importlib.metadata import distribution
|
7
7
|
from re import sub
|
8
8
|
|
@@ -17,9 +17,9 @@ class Config:
|
|
17
17
|
|
18
18
|
def __init__(self) -> None:
|
19
19
|
if not hasattr(self, "_initialized"):
|
20
|
-
self.source_dir =
|
21
|
-
self.
|
22
|
-
self.
|
20
|
+
self.source_dir = Path.cwd()
|
21
|
+
self.source_files = self.source_dir.iterdir()
|
22
|
+
self.project_name = Path(self.source_dir).name
|
23
23
|
self.dirs_to_create = [
|
24
24
|
"tests",
|
25
25
|
"templates",
|
@@ -28,27 +28,28 @@ class Config:
|
|
28
28
|
"static/js",
|
29
29
|
"static/images",
|
30
30
|
]
|
31
|
-
|
32
|
-
self.
|
31
|
+
manager = AutoManager()
|
32
|
+
self.install = manager.get_config_managers()
|
33
|
+
self.pkg_manager = manager.get_pkg_manager()
|
33
34
|
self._initialized = True
|
34
35
|
|
35
36
|
|
36
|
-
def create_dirs(self,
|
37
|
+
def create_dirs(self, _dirs_to_create: Optional[List[str]] = None) -> None:
|
37
38
|
dirs_to_create: list = self.dirs_to_create.copy()
|
38
|
-
|
39
|
+
if _dirs_to_create:
|
40
|
+
dirs_to_create.extend(_dirs_to_create)
|
39
41
|
#
|
40
42
|
for _dir in dirs_to_create:
|
41
|
-
|
43
|
+
(self.source_dir / _dir).mkdir(exist_ok=True)
|
42
44
|
|
43
|
-
def create_files(self,
|
44
|
-
for
|
45
|
-
with open(
|
45
|
+
def create_files(self, relative_file_paths: List[str]) -> None:
|
46
|
+
for _relative_path in relative_file_paths:
|
47
|
+
with open(self.source_dir / _relative_path, "w"): ...
|
46
48
|
|
47
49
|
|
48
50
|
class _ConfigCommands(Struct):
|
49
51
|
install: str
|
50
52
|
uninstall: str
|
51
|
-
list_: str = field(name="list")
|
52
53
|
|
53
54
|
class _ConfigFormat(Struct):
|
54
55
|
managers: Dict[str, _ConfigCommands]
|
@@ -57,12 +58,12 @@ class AutoManager:
|
|
57
58
|
_instance = None
|
58
59
|
_decoder = json.Decoder(type=_ConfigFormat, strict=True)
|
59
60
|
|
60
|
-
def __new__(cls
|
61
|
+
def __new__(cls) -> Self:
|
61
62
|
if cls._instance is None:
|
62
63
|
cls._instance = super().__new__(cls)
|
63
64
|
return cls._instance
|
64
65
|
|
65
|
-
def __init__(self, config_name: str = "managers.json"):
|
66
|
+
def __init__(self, config_name: str = "managers.json") -> None:
|
66
67
|
if not hasattr(self, "_initialized"):
|
67
68
|
self.config_name = config_name
|
68
69
|
self._ConfigFormat = _ConfigFormat
|
@@ -87,7 +88,11 @@ class AutoManager:
|
|
87
88
|
pkg = self.get_pkg_manager()
|
88
89
|
if pkg not in managers:
|
89
90
|
raise ValueError(f"Package manager '{pkg}' not found in configuration.")
|
90
|
-
|
91
|
+
try:
|
92
|
+
run([pkg, managers[pkg].install] + libs, check=True)
|
93
|
+
except CalledProcessError as e:
|
94
|
+
print(f"Failed to install packages: {e}")
|
95
|
+
|
91
96
|
|
92
97
|
if __name__ == "__main__":
|
93
98
|
# Example usage of AutoManager singleton
|
@@ -2,28 +2,27 @@
|
|
2
2
|
"managers": {
|
3
3
|
"pip": {
|
4
4
|
"install": "install",
|
5
|
-
"uninstall": "uninstall"
|
6
|
-
|
5
|
+
"uninstall": "uninstall"
|
6
|
+
},
|
7
|
+
"pipx": {
|
8
|
+
"install": "install",
|
9
|
+
"uninstall": "uninstall"
|
10
|
+
},
|
11
|
+
"pyenv": {
|
12
|
+
"install": "install",
|
13
|
+
"uninstall": "uninstall"
|
7
14
|
},
|
8
15
|
"conda": {
|
9
16
|
"install": "install",
|
10
|
-
"uninstall": "uninstall"
|
11
|
-
"list": "list"
|
17
|
+
"uninstall": "uninstall"
|
12
18
|
},
|
13
19
|
"uv": {
|
14
20
|
"install": "add",
|
15
|
-
"uninstall": "remove"
|
16
|
-
"list": "pip list"
|
17
|
-
},
|
18
|
-
"pyenv": {
|
19
|
-
"install": "install",
|
20
|
-
"uninstall": "uninstall",
|
21
|
-
"list": "versions"
|
21
|
+
"uninstall": "remove"
|
22
22
|
},
|
23
23
|
"poetry": {
|
24
24
|
"install": "add",
|
25
|
-
"uninstall": "remove"
|
26
|
-
"list": "show"
|
25
|
+
"uninstall": "remove"
|
27
26
|
}
|
28
27
|
}
|
29
28
|
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from ..template import Template
|
2
|
-
import
|
3
|
-
import
|
2
|
+
from os import path
|
3
|
+
from pathlib import Path
|
4
4
|
from subprocess import run
|
5
5
|
|
6
6
|
|
@@ -11,8 +11,8 @@ class DjangoManager(Template):
|
|
11
11
|
example = True
|
12
12
|
|
13
13
|
def create_example(self, example_id) -> None:
|
14
|
-
package_dir =
|
14
|
+
package_dir = Path(__file__).resolve().parent
|
15
15
|
example_folder_path = package_dir / "examples" / f"{self.framework_name}_{example_id}"
|
16
16
|
|
17
|
-
if
|
17
|
+
if path.isdir(example_folder_path):
|
18
18
|
run(["django-admin", "startproject", f"--template={example_folder_path}", self.name])
|
@@ -3,11 +3,10 @@ from ..template import Template
|
|
3
3
|
class FastapiManager(Template):
|
4
4
|
extra_libs = ["sqlalchemy", "python-multipart", "databases", "python-multipart", "aiofiles", "uvicorn", "jinja2", "bcrypt"]
|
5
5
|
extra_dirs = ["db"]
|
6
|
-
example =
|
6
|
+
example = True
|
7
7
|
|
8
8
|
class StarletteManager(FastapiManager):
|
9
9
|
extra_libs = ["aiomysql"]
|
10
10
|
|
11
11
|
class LitestarManager(StarletteManager):
|
12
12
|
extra_libs = ["msgspec", "starlette", "httpx"]
|
13
|
-
example = True
|
rapidframework/main.py
CHANGED
@@ -1,31 +1,26 @@
|
|
1
1
|
import argparse
|
2
2
|
from pathlib import Path
|
3
3
|
from . import Template
|
4
|
-
#
|
5
|
-
import gc
|
6
4
|
|
7
|
-
def all_subclasses(cls):
|
5
|
+
def all_subclasses(cls) -> list[type]:
|
8
6
|
subclasses = cls.__subclasses__()
|
9
7
|
for subclass in subclasses:
|
10
8
|
subclasses += all_subclasses(subclass)
|
11
9
|
return subclasses
|
12
10
|
|
13
|
-
def find_manager_class(base_name: str):
|
14
|
-
base_name_lower = base_name.lower()
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
if isinstance(obj, type):
|
19
|
-
cls_name = obj.__name__
|
20
|
-
if cls_name.lower() == base_name_lower + target_suffix:
|
21
|
-
return obj
|
11
|
+
def find_manager_class(base_name: str) -> type:
|
12
|
+
base_name_lower = base_name.lower() + "manager"
|
13
|
+
for cls in all_subclasses(Template):
|
14
|
+
if cls.__name__.lower() == base_name_lower:
|
15
|
+
return cls
|
22
16
|
raise Exception(f"Manager class for '{base_name}' not found. Ensure it is defined and imported correctly.")
|
23
17
|
|
18
|
+
|
24
19
|
FRAMEWORKS_PATH = Path(__file__).parent / "frameworks"
|
25
20
|
|
26
21
|
|
27
22
|
class Main:
|
28
|
-
def __init__(self):
|
23
|
+
def __init__(self) -> None:
|
29
24
|
#
|
30
25
|
self.available_frameworks = self._discover_frameworks()
|
31
26
|
#
|
@@ -45,18 +40,18 @@ class Main:
|
|
45
40
|
#
|
46
41
|
self.framework_manager: type = find_manager_class(self.args.framework)
|
47
42
|
|
48
|
-
def _discover_frameworks(self):
|
43
|
+
def _discover_frameworks(self) -> list[str]:
|
49
44
|
return sorted(set([cls.__name__.removesuffix("Manager").lower() for cls in all_subclasses(Template)]))
|
50
45
|
|
51
|
-
def run(self):
|
46
|
+
def run(self) -> None:
|
52
47
|
framework = self.framework_manager(self.args.name)
|
53
48
|
#
|
54
49
|
if hasattr(self.framework_manager, "install_framework"):
|
55
|
-
framework.install_framework(
|
50
|
+
framework.install_framework(_version=self.args.version)
|
56
51
|
if hasattr(self.framework_manager, "create_example"):
|
57
|
-
framework.create_example(
|
52
|
+
framework.create_example(self.args.example or 1)
|
58
53
|
|
59
|
-
def main_entry_point():
|
54
|
+
def main_entry_point() -> None:
|
60
55
|
Main().run()
|
61
56
|
|
62
57
|
|
rapidframework/template.py
CHANGED
@@ -1,29 +1,34 @@
|
|
1
|
-
from
|
1
|
+
from pathlib import Path
|
2
2
|
from .config import AutoManager
|
3
3
|
from .config import Config
|
4
4
|
from typing import Optional, List
|
5
|
+
from copy import deepcopy
|
6
|
+
|
5
7
|
|
6
8
|
cfg = Config()
|
7
9
|
|
8
10
|
class Template:
|
9
|
-
extra_libs: List[str]
|
10
|
-
extra_dirs: List[str]
|
11
|
-
extra_files: List[str]
|
11
|
+
extra_libs: List[str]
|
12
|
+
extra_dirs: List[str]
|
13
|
+
extra_files: List[str]
|
12
14
|
example: bool = True
|
13
15
|
|
14
|
-
def __init_subclass__(cls, **kwargs):
|
16
|
+
def __init_subclass__(cls, **kwargs) -> None:
|
15
17
|
super().__init_subclass__(**kwargs)
|
16
|
-
cls.framework_name = cls.__name__.lower().
|
18
|
+
cls.framework_name = cls.__name__.lower().removesuffix("manager")
|
17
19
|
|
18
20
|
bases = [base for base in cls.__mro__[1:] if issubclass(base, Template)]
|
19
21
|
|
22
|
+
fields = ["extra_libs", "extra_dirs", "extra_files"]
|
23
|
+
|
20
24
|
seen = set()
|
21
|
-
for attr in
|
22
|
-
values = [
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
25
|
+
for attr in fields:
|
26
|
+
values = [
|
27
|
+
item
|
28
|
+
for base in reversed(bases)
|
29
|
+
if base not in seen and not seen.add(base)
|
30
|
+
for item in getattr(base, attr, [])
|
31
|
+
]
|
27
32
|
values += getattr(cls, attr, [])
|
28
33
|
setattr(cls, attr, values)
|
29
34
|
|
@@ -34,55 +39,42 @@ class Template:
|
|
34
39
|
self,
|
35
40
|
name: str,
|
36
41
|
framework_name: Optional[str] = None,
|
37
|
-
source_dir =
|
38
|
-
project_name =
|
42
|
+
source_dir: Optional[str] = None,
|
43
|
+
project_name: Optional[str] = None
|
39
44
|
):
|
40
45
|
self.name = name
|
46
|
+
self.source_dir = source_dir or cfg.source_dir
|
47
|
+
self.project_name = project_name or cfg.project_name
|
41
48
|
self.framework_name = framework_name or self.__class__.framework_name
|
42
|
-
self.source_dir = source_dir
|
43
|
-
self.project_name = project_name
|
44
49
|
self.AutoManager = AutoManager()
|
45
|
-
|
46
|
-
self.
|
47
|
-
self.
|
50
|
+
#
|
51
|
+
self.extra_libs = deepcopy(self.__class__.extra_libs)
|
52
|
+
self.extra_dirs = deepcopy(self.__class__.extra_dirs)
|
53
|
+
self.extra_files = deepcopy(self.__class__.extra_files)
|
48
54
|
self.example = self.__class__.example
|
49
55
|
|
50
|
-
def install_framework(self,
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
libs_to_install.extend(self.extra_libs)
|
56
|
-
#
|
57
|
-
self.AutoManager.install_libs(libs_to_install)
|
58
|
-
#
|
59
|
-
self.setup_framework()
|
56
|
+
def install_framework(self, _version: Optional[str] = None) -> None:
|
57
|
+
self.AutoManager.install_libs(
|
58
|
+
[f"{self.framework_name}=={_version}"] if _version else [self.framework_name]
|
59
|
+
+ self.extra_libs)
|
60
|
+
self._setup_framework()
|
60
61
|
|
61
|
-
def
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
#
|
67
|
-
if dirs:
|
68
|
-
cfg.create_dirs(source_dir, dirs)
|
69
|
-
if files:
|
70
|
-
cfg.create_files(files)
|
62
|
+
def _setup_framework(self) -> None:
|
63
|
+
if self.extra_dirs:
|
64
|
+
cfg.create_dirs(self.extra_dirs)
|
65
|
+
if self.extra_files:
|
66
|
+
cfg.create_files(self.extra_files)
|
71
67
|
|
72
68
|
def create_example(self, example_id) -> None:
|
73
69
|
if self.example:
|
74
70
|
from pkgutil import get_data
|
75
71
|
|
76
|
-
example_code = get_data(
|
77
|
-
"rapidframework",
|
78
|
-
f"frameworks/examples/{self.framework_name}_{example_id}.py",
|
79
|
-
)
|
80
|
-
if not example_code:
|
81
|
-
raise Exception(f"Example {example_id} not found for {self.framework_name} framework.")
|
72
|
+
example_code = get_data("rapidframework", f"frameworks/examples/{self.framework_name}_{example_id}.py")
|
82
73
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
74
|
+
if example_code is None:
|
75
|
+
raise FileNotFoundError(f"Example {example_id} not found for {self.framework_name} framework.")
|
76
|
+
|
77
|
+
with open(Path(self.source_dir) / f"{self.name}.py", "w", encoding="utf-8") as f:
|
78
|
+
f.write(example_code.decode("utf-8"))
|
87
79
|
else:
|
88
|
-
raise
|
80
|
+
raise NotImplementedError(f"Example creation is not implemented for {self.framework_name} framework.")
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: rapidframework-lib
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.1.1
|
4
4
|
Description-Content-Type: text/markdown
|
5
5
|
License-File: LICENSE
|
6
6
|
Requires-Dist: msgspec
|
@@ -13,7 +13,7 @@ Dynamic: requires-dist
|
|
13
13
|
|
14
14
|
> **RapidFramework** is a Python library for quickly creating and setting up projects from templates.
|
15
15
|
|
16
|
-
## https://pypi.org/project/rapidframework-lib/1.
|
16
|
+
## https://pypi.org/project/rapidframework-lib/1.1.1/
|
17
17
|
|
18
18
|
## Installation
|
19
19
|
|
@@ -1,12 +1,12 @@
|
|
1
1
|
rapidframework/__init__.py,sha256=0f6S18Vy0QQs3VW9m4A6sNDfHoYGvf9Dzk32xlZ5RNs,151
|
2
|
-
rapidframework/config.py,sha256=
|
3
|
-
rapidframework/main.py,sha256=
|
4
|
-
rapidframework/template.py,sha256
|
2
|
+
rapidframework/config.py,sha256=xjPI8DIxkd9sbAlSsIUIYYfoDHqFPxQshOGVzxXldmY,3657
|
3
|
+
rapidframework/main.py,sha256=xY7c4YaUG1YtN-V1LOV8maMRTGueLYptOGSuWN3DPc0,2045
|
4
|
+
rapidframework/template.py,sha256=-_cugFwyhyxz6SPvT95fThzK83x361Rkr51_yK6LpSY,2864
|
5
5
|
rapidframework/__pycache__/main.cpython-313.pyc,sha256=J3Y41E5fOwmGEQtwgTq-NBUl0s0VxCvDC5KUnCGvIdU,3891
|
6
|
-
rapidframework/configs/managers.json,sha256=
|
6
|
+
rapidframework/configs/managers.json,sha256=xTBE-UB7atZ5VgLEtK78SdVkimQ762E025rtMR_gjsM,614
|
7
7
|
rapidframework/frameworks/__init__.py,sha256=CJETvRzO000nPloWwKFd-AnLmR5PM9SSZUyB-C4M8a4,464
|
8
|
-
rapidframework/frameworks/django.py,sha256=
|
9
|
-
rapidframework/frameworks/fastapi.py,sha256=
|
8
|
+
rapidframework/frameworks/django.py,sha256=DCdQvmyLeBjVfMAAZIVSgIWVplcTL0pIfnFsY3eKSTU,801
|
9
|
+
rapidframework/frameworks/fastapi.py,sha256=k24ECko0eRfYYJNUueE0506DMoc1R5C8_JZ_OxRG24I,408
|
10
10
|
rapidframework/frameworks/simple_frameworks.py,sha256=9PEu-ZvA17pT7QLQTnfQ_2PGjCDbi8ECaaSO1MPp2Lg,1023
|
11
11
|
rapidframework/frameworks/examples/__init__.py,sha256=ovguP4wzQEDNguczwiZnhMm4dRRVcvnzmHrfQtlRCNQ,15
|
12
12
|
rapidframework/frameworks/examples/bottle_1.py,sha256=AhEqgse_IinZ0jx211y0ybyxB0dknGI-x6zhIOQ4Qos,118
|
@@ -32,9 +32,9 @@ rapidframework/frameworks/examples/django_1/project_name/users/admin.py-tpl,sha2
|
|
32
32
|
rapidframework/frameworks/examples/django_1/project_name/users/models.py-tpl,sha256=BDqPNCqoqDWPRTQJZjyRQSk9zwPVV14HLKtjS-qtKz8,89
|
33
33
|
rapidframework/frameworks/examples/django_1/project_name/users/migrations/0001_initial.py-tpl,sha256=V-yCkAE_F0oWEAG4xcSLPOjxnbD3sPble_On_Ny49kA,2931
|
34
34
|
rapidframework/frameworks/examples/django_1/project_name/users/migrations/__init__.py-tpl,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
35
|
-
rapidframework_lib-1.
|
36
|
-
rapidframework_lib-1.
|
37
|
-
rapidframework_lib-1.
|
38
|
-
rapidframework_lib-1.
|
39
|
-
rapidframework_lib-1.
|
40
|
-
rapidframework_lib-1.
|
35
|
+
rapidframework_lib-1.1.1.dist-info/licenses/LICENSE,sha256=lXsPzvyEfL6vjzMMCRYi7gpsIjpSUYUsDF-MvMHyhc0,1070
|
36
|
+
rapidframework_lib-1.1.1.dist-info/METADATA,sha256=wSaoLzQcZXxq8Pns1bwrNIEEpApHtjQMCtejpg8C42c,1242
|
37
|
+
rapidframework_lib-1.1.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
38
|
+
rapidframework_lib-1.1.1.dist-info/entry_points.txt,sha256=UaOaGJ-BDCxtmNoPp-u_TnXXLbnXtrB13PYr5BgqmHA,72
|
39
|
+
rapidframework_lib-1.1.1.dist-info/top_level.txt,sha256=7PXDkFZsYowz4aB2xVaSso4qD45jd2kHn6x3xxhMMNs,15
|
40
|
+
rapidframework_lib-1.1.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|