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 CHANGED
@@ -1,8 +1,8 @@
1
- from os import getcwd, listdir, path, makedirs
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, field, DecodeError
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 = getcwd()
21
- self.project_name = path.basename(self.source_dir)
22
- self.source_files = listdir()
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
- self.install = AutoManager().get_config_managers()
32
- self.pkg_manager = AutoManager().get_pkg_manager()
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, app_path, extra_dirs=[]) -> None:
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
- dirs_to_create.extend(extra_dirs)
39
+ if _dirs_to_create:
40
+ dirs_to_create.extend(_dirs_to_create)
39
41
  #
40
42
  for _dir in dirs_to_create:
41
- makedirs(path.join(app_path, _dir), exist_ok=True)
43
+ (self.source_dir / _dir).mkdir(exist_ok=True)
42
44
 
43
- def create_files(self, file_paths) -> None:
44
- for file_path in file_paths:
45
- with open(path.join(self.source_dir, file_path), "w"): ...
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, config_name: str = "managers.json") -> Self:
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
- run([pkg, managers[pkg].install] + libs)
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
- "list": "freeze"
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 os
3
- import pathlib
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 = pathlib.Path(__file__).resolve().parent
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 os.path.isdir(example_folder_path):
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 = False
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
- target_suffix = "manager"
16
-
17
- for obj in gc.get_objects():
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(version=self.args.version)
50
+ framework.install_framework(_version=self.args.version)
56
51
  if hasattr(self.framework_manager, "create_example"):
57
- framework.create_example(1 if self.args.example is None else self.args.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
 
@@ -1,29 +1,34 @@
1
- from os import path
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().replace("manager", "")
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 ["extra_libs", "extra_dirs", "extra_files"]:
22
- values = []
23
- for base in reversed(bases):
24
- if base not in seen:
25
- seen.add(base)
26
- values += getattr(base, attr, [])
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 = cfg.source_dir,
38
- project_name = cfg.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
- self.extra_libs = self.__class__.extra_libs
46
- self.extra_dirs = self.__class__.extra_dirs
47
- self.extra_files = self.__class__.extra_files
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, **kwargs):
51
- version = f"=={kwargs.get('version')}" if kwargs.get('version') else ""
52
- libs_to_install: list = kwargs.get("libs") or []
53
- #
54
- libs_to_install.extend([f"{self.framework_name}{version}"])
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 setup_framework(self, _source_dir: Optional[str] = None, extra_dirs: Optional[list] = None, extra_files: Optional[list] = None):
62
- source_dir: str = _source_dir or self.source_dir
63
- #
64
- dirs = (extra_dirs or []) + self.extra_dirs
65
- files = (extra_files or []) + self.extra_files
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
- with open(
84
- path.join(self.source_dir, self.name + ".py"), "w", encoding="utf-8"
85
- ) as example_file:
86
- example_file.write(example_code.decode("utf-8"))
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 Exception("Example method is'n allowed for this framework !")
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.0.9
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.0.9/
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=xfsmdtMfmOSe6LXLMkDWbTiPdRHPSRhLkICvvk2I0Ug,3470
3
- rapidframework/main.py,sha256=9c-iaW4QAnVFLgHVBz6oYqhx8-QnlPOI6XBt9yrNoqU,2129
4
- rapidframework/template.py,sha256=Km9hI435jh_GjZmjWjqRA-DdE0QxBBF20IuFcQTUC4c,3148
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=EEBDjTVQuNXGIF_oIXuNVpXK4kTk2HsRb2aPrbmUjo4,664
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=eG69Sdn4ALn0fAXeY1TknJgTvcut8TArDybluPjF_Jo,792
9
- rapidframework/frameworks/fastapi.py,sha256=vZ06QrsTJqzasnt1q7Bph59F3CcoKz_xuAv8CEcUFU8,428
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.0.9.dist-info/licenses/LICENSE,sha256=lXsPzvyEfL6vjzMMCRYi7gpsIjpSUYUsDF-MvMHyhc0,1070
36
- rapidframework_lib-1.0.9.dist-info/METADATA,sha256=tsriVBHgFt36eExvJ8rloKzHLAlB-qq44W_-B5TBtzA,1242
37
- rapidframework_lib-1.0.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
38
- rapidframework_lib-1.0.9.dist-info/entry_points.txt,sha256=UaOaGJ-BDCxtmNoPp-u_TnXXLbnXtrB13PYr5BgqmHA,72
39
- rapidframework_lib-1.0.9.dist-info/top_level.txt,sha256=7PXDkFZsYowz4aB2xVaSso4qD45jd2kHn6x3xxhMMNs,15
40
- rapidframework_lib-1.0.9.dist-info/RECORD,,
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,,