rapidframework-lib 1.0.8.2__tar.gz → 1.1.1__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.
Files changed (49) hide show
  1. {rapidframework_lib-1.0.8.2 → rapidframework_lib-1.1.1}/PKG-INFO +2 -2
  2. {rapidframework_lib-1.0.8.2 → rapidframework_lib-1.1.1}/README.md +1 -1
  3. rapidframework_lib-1.1.1/rapidframework/config.py +107 -0
  4. {rapidframework_lib-1.0.8.2 → rapidframework_lib-1.1.1}/rapidframework/configs/managers.json +12 -13
  5. rapidframework_lib-1.1.1/rapidframework/frameworks/django.py +18 -0
  6. rapidframework_lib-1.1.1/rapidframework/frameworks/examples/django_1/manage.py-tpl +25 -0
  7. rapidframework_lib-1.1.1/rapidframework/frameworks/examples/django_1/project_name/__init__.py-tpl +0 -0
  8. rapidframework_lib-1.1.1/rapidframework/frameworks/examples/django_1/project_name/asgi.py-tpl +21 -0
  9. rapidframework_lib-1.1.1/rapidframework/frameworks/examples/django_1/project_name/settings.py-tpl +162 -0
  10. rapidframework_lib-1.1.1/rapidframework/frameworks/examples/django_1/project_name/urls.py-tpl +13 -0
  11. rapidframework_lib-1.1.1/rapidframework/frameworks/examples/django_1/project_name/users/__init__.py-tpl +0 -0
  12. rapidframework_lib-1.1.1/rapidframework/frameworks/examples/django_1/project_name/users/admin.py-tpl +5 -0
  13. rapidframework_lib-1.1.1/rapidframework/frameworks/examples/django_1/project_name/users/migrations/0001_initial.py-tpl +46 -0
  14. rapidframework_lib-1.1.1/rapidframework/frameworks/examples/django_1/project_name/users/migrations/__init__.py-tpl +0 -0
  15. rapidframework_lib-1.1.1/rapidframework/frameworks/examples/django_1/project_name/users/models.py-tpl +5 -0
  16. rapidframework_lib-1.1.1/rapidframework/frameworks/examples/django_1/project_name/wsgi.py-tpl +18 -0
  17. {rapidframework_lib-1.0.8.2 → rapidframework_lib-1.1.1}/rapidframework/frameworks/fastapi.py +1 -0
  18. {rapidframework_lib-1.0.8.2 → rapidframework_lib-1.1.1}/rapidframework/main.py +14 -21
  19. rapidframework_lib-1.1.1/rapidframework/template.py +80 -0
  20. {rapidframework_lib-1.0.8.2 → rapidframework_lib-1.1.1}/rapidframework_lib.egg-info/PKG-INFO +2 -2
  21. {rapidframework_lib-1.0.8.2 → rapidframework_lib-1.1.1}/rapidframework_lib.egg-info/SOURCES.txt +11 -0
  22. {rapidframework_lib-1.0.8.2 → rapidframework_lib-1.1.1}/setup.py +1 -1
  23. rapidframework_lib-1.0.8.2/rapidframework/config.py +0 -83
  24. rapidframework_lib-1.0.8.2/rapidframework/frameworks/django.py +0 -33
  25. rapidframework_lib-1.0.8.2/rapidframework/template.py +0 -79
  26. {rapidframework_lib-1.0.8.2 → rapidframework_lib-1.1.1}/LICENSE +0 -0
  27. {rapidframework_lib-1.0.8.2 → rapidframework_lib-1.1.1}/pyproject.toml +0 -0
  28. {rapidframework_lib-1.0.8.2 → rapidframework_lib-1.1.1}/rapidframework/__init__.py +0 -0
  29. {rapidframework_lib-1.0.8.2 → rapidframework_lib-1.1.1}/rapidframework/__pycache__/main.cpython-313.pyc +0 -0
  30. {rapidframework_lib-1.0.8.2 → rapidframework_lib-1.1.1}/rapidframework/frameworks/__init__.py +0 -0
  31. {rapidframework_lib-1.0.8.2 → rapidframework_lib-1.1.1}/rapidframework/frameworks/examples/__init__.py +0 -0
  32. {rapidframework_lib-1.0.8.2 → rapidframework_lib-1.1.1}/rapidframework/frameworks/examples/bottle_1.py +0 -0
  33. {rapidframework_lib-1.0.8.2 → rapidframework_lib-1.1.1}/rapidframework/frameworks/examples/cherrypy_1.py +0 -0
  34. {rapidframework_lib-1.0.8.2 → rapidframework_lib-1.1.1}/rapidframework/frameworks/examples/fastapi_1.py +0 -0
  35. {rapidframework_lib-1.0.8.2 → rapidframework_lib-1.1.1}/rapidframework/frameworks/examples/flask_1.py +0 -0
  36. {rapidframework_lib-1.0.8.2 → rapidframework_lib-1.1.1}/rapidframework/frameworks/examples/grok_1.py +0 -0
  37. {rapidframework_lib-1.0.8.2 → rapidframework_lib-1.1.1}/rapidframework/frameworks/examples/litestar_1.py +0 -0
  38. {rapidframework_lib-1.0.8.2 → rapidframework_lib-1.1.1}/rapidframework/frameworks/examples/pyramid_1.py +0 -0
  39. {rapidframework_lib-1.0.8.2 → rapidframework_lib-1.1.1}/rapidframework/frameworks/examples/socketify_1.py +0 -0
  40. {rapidframework_lib-1.0.8.2 → rapidframework_lib-1.1.1}/rapidframework/frameworks/examples/starlette_1.py +0 -0
  41. {rapidframework_lib-1.0.8.2 → rapidframework_lib-1.1.1}/rapidframework/frameworks/examples/tornado_1.py +0 -0
  42. {rapidframework_lib-1.0.8.2 → rapidframework_lib-1.1.1}/rapidframework/frameworks/examples/turbogears2_1.py +0 -0
  43. {rapidframework_lib-1.0.8.2 → rapidframework_lib-1.1.1}/rapidframework/frameworks/examples/web2py_1.py +0 -0
  44. {rapidframework_lib-1.0.8.2 → rapidframework_lib-1.1.1}/rapidframework/frameworks/simple_frameworks.py +0 -0
  45. {rapidframework_lib-1.0.8.2 → rapidframework_lib-1.1.1}/rapidframework_lib.egg-info/dependency_links.txt +0 -0
  46. {rapidframework_lib-1.0.8.2 → rapidframework_lib-1.1.1}/rapidframework_lib.egg-info/entry_points.txt +0 -0
  47. {rapidframework_lib-1.0.8.2 → rapidframework_lib-1.1.1}/rapidframework_lib.egg-info/requires.txt +0 -0
  48. {rapidframework_lib-1.0.8.2 → rapidframework_lib-1.1.1}/rapidframework_lib.egg-info/top_level.txt +0 -0
  49. {rapidframework_lib-1.0.8.2 → rapidframework_lib-1.1.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rapidframework-lib
3
- Version: 1.0.8.2
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.8.2/
16
+ ## https://pypi.org/project/rapidframework-lib/1.1.1/
17
17
 
18
18
  ## Installation
19
19
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  > **RapidFramework** is a Python library for quickly creating and setting up projects from templates.
4
4
 
5
- ## https://pypi.org/project/rapidframework-lib/1.0.8.2/
5
+ ## https://pypi.org/project/rapidframework-lib/1.1.1/
6
6
 
7
7
  ## Installation
8
8
 
@@ -0,0 +1,107 @@
1
+ from pathlib import Path
2
+ from typing import Optional, Self, Dict, List
3
+ import pkgutil
4
+ from msgspec import json, Struct, DecodeError
5
+ from subprocess import run, CalledProcessError
6
+ from importlib.metadata import distribution
7
+ from re import sub
8
+
9
+
10
+ class Config:
11
+ _instance = None
12
+
13
+ def __new__(cls) -> Self:
14
+ if cls._instance is None:
15
+ cls._instance = super().__new__(cls)
16
+ return cls._instance
17
+
18
+ def __init__(self) -> None:
19
+ if not hasattr(self, "_initialized"):
20
+ self.source_dir = Path.cwd()
21
+ self.source_files = self.source_dir.iterdir()
22
+ self.project_name = Path(self.source_dir).name
23
+ self.dirs_to_create = [
24
+ "tests",
25
+ "templates",
26
+ "static",
27
+ "static/css",
28
+ "static/js",
29
+ "static/images",
30
+ ]
31
+ manager = AutoManager()
32
+ self.install = manager.get_config_managers()
33
+ self.pkg_manager = manager.get_pkg_manager()
34
+ self._initialized = True
35
+
36
+
37
+ def create_dirs(self, _dirs_to_create: Optional[List[str]] = None) -> None:
38
+ dirs_to_create: list = self.dirs_to_create.copy()
39
+ if _dirs_to_create:
40
+ dirs_to_create.extend(_dirs_to_create)
41
+ #
42
+ for _dir in dirs_to_create:
43
+ (self.source_dir / _dir).mkdir(exist_ok=True)
44
+
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"): ...
48
+
49
+
50
+ class _ConfigCommands(Struct):
51
+ install: str
52
+ uninstall: str
53
+
54
+ class _ConfigFormat(Struct):
55
+ managers: Dict[str, _ConfigCommands]
56
+
57
+ class AutoManager:
58
+ _instance = None
59
+ _decoder = json.Decoder(type=_ConfigFormat, strict=True)
60
+
61
+ def __new__(cls) -> Self:
62
+ if cls._instance is None:
63
+ cls._instance = super().__new__(cls)
64
+ return cls._instance
65
+
66
+ def __init__(self, config_name: str = "managers.json") -> None:
67
+ if not hasattr(self, "_initialized"):
68
+ self.config_name = config_name
69
+ self._ConfigFormat = _ConfigFormat
70
+ self._initialized = True
71
+
72
+ def get_config_managers(self) -> _ConfigFormat:
73
+ config = pkgutil.get_data("rapidframework", f"configs/{self.config_name}")
74
+ #
75
+ if config is None:
76
+ raise FileNotFoundError(f"Configuration file '{self.config_name}' not found.")
77
+ #
78
+ return self._decoder.decode(config.decode("utf-8"))
79
+
80
+ def get_pkg_manager(self) -> str:
81
+ try:
82
+ return sub(r'\s+', '', distribution("rapidframework-lib").read_text("INSTALLER")) # type: ignore
83
+ except (DecodeError, FileNotFoundError, ValueError):
84
+ return "pip"
85
+
86
+ def install_libs(self, libs: list) -> None:
87
+ managers = self.get_config_managers().managers
88
+ pkg = self.get_pkg_manager()
89
+ if pkg not in managers:
90
+ raise ValueError(f"Package manager '{pkg}' not found in configuration.")
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
+
96
+
97
+ if __name__ == "__main__":
98
+ # Example usage of AutoManager singleton
99
+ a = AutoManager()
100
+ b = AutoManager()
101
+ print(f"{a is b=}") # Should print True, confirming singleton behavior
102
+ assert a is b
103
+ # # Example usage of Config singleton
104
+ c = Config()
105
+ d = Config()
106
+ print(f"{c is d=}") # Should print True, confirming singleton behavior
107
+ assert c is d
@@ -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
  }
@@ -0,0 +1,18 @@
1
+ from ..template import Template
2
+ from os import path
3
+ from pathlib import Path
4
+ from subprocess import run
5
+
6
+
7
+ class DjangoManager(Template):
8
+ extra_libs = ["Pillow", "djangorestframework", "django-cors-headers", \
9
+ "celery", "django-redis", "redis", "django-allauth", "django-crispy-forms", "django-environ", \
10
+ "django-extensions", "gunicorn", "whitenoise", "django-configurations", "django-debug-toolbar"]
11
+ example = True
12
+
13
+ def create_example(self, example_id) -> None:
14
+ package_dir = Path(__file__).resolve().parent
15
+ example_folder_path = package_dir / "examples" / f"{self.framework_name}_{example_id}"
16
+
17
+ if path.isdir(example_folder_path):
18
+ run(["django-admin", "startproject", f"--template={example_folder_path}", self.name])
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env python
2
+ """Django's command-line utility for administrative tasks."""
3
+ import os
4
+ import sys
5
+
6
+
7
+ def main():
8
+ """Run administrative tasks."""
9
+ configuration = os.getenv('ENVIRONMENT', 'development').title()
10
+ os.environ.setdefault('DJANGO_SETTINGS_MODULE', '{{ project_name }}.settings')
11
+ os.environ.setdefault('DJANGO_CONFIGURATION', configuration)
12
+
13
+ try:
14
+ from configurations.management import execute_from_command_line
15
+ except ImportError as exc:
16
+ raise ImportError(
17
+ "Couldn't import Django. Are you sure it's installed and "
18
+ "available on your PYTHONPATH environment variable? Did you "
19
+ "forget to activate a virtual environment?"
20
+ ) from exc
21
+ execute_from_command_line(sys.argv)
22
+
23
+
24
+ if __name__ == '__main__':
25
+ main()
@@ -0,0 +1,21 @@
1
+ """
2
+ ASGI config for {{ project_name }} project.
3
+
4
+ It exposes the ASGI callable as a module-level variable named ``application``.
5
+
6
+ For more information on this file, see
7
+ https://docs.djangoproject.com/en/{{ docs_version }}/howto/deployment/asgi/
8
+ """
9
+
10
+ import os
11
+
12
+
13
+ configuration = os.getenv('ENVIRONMENT', 'development').title()
14
+ os.environ.setdefault('DJANGO_SETTINGS_MODULE', '{{ project_name }}.settings')
15
+ os.environ.setdefault('DJANGO_CONFIGURATION', configuration)
16
+
17
+ from configurations import importer # noqa
18
+ importer.install()
19
+
20
+ from django.core.asgi import get_asgi_application # noqa
21
+ application = get_asgi_application()
@@ -0,0 +1,162 @@
1
+ """
2
+ Django settings for {{ project_name }} project.
3
+
4
+ For more information on this file, see
5
+ https://docs.djangoproject.com/en/{{ docs_version }}/topics/settings/
6
+
7
+ For the full list of settings and their values, see
8
+ https://docs.djangoproject.com/en/{{ docs_version }}/ref/settings/
9
+ """
10
+ import os
11
+ from pathlib import Path
12
+
13
+ from configurations import Configuration, values
14
+
15
+
16
+ class Common(Configuration):
17
+ # Build paths inside the project like this: BASE_DIR / 'subdir'.
18
+ BASE_DIR = Path(__file__).resolve().parent.parent
19
+
20
+ # SECURITY WARNING: keep the secret key used in production secret!
21
+ SECRET_KEY = values.SecretValue()
22
+
23
+ # SECURITY WARNING: don't run with debug turned on in production!
24
+ DEBUG = values.BooleanValue(False)
25
+
26
+ ALLOWED_HOSTS = values.ListValue([])
27
+
28
+ # Application definition
29
+ INSTALLED_APPS = [
30
+ 'django.contrib.admin',
31
+ 'django.contrib.auth',
32
+ 'django.contrib.contenttypes',
33
+ 'django.contrib.sessions',
34
+ 'django.contrib.messages',
35
+ 'whitenoise.runserver_nostatic',
36
+ 'django.contrib.staticfiles',
37
+
38
+ 'django_extensions',
39
+ 'debug_toolbar',
40
+
41
+ '{{ project_name }}.users',
42
+ ]
43
+
44
+ MIDDLEWARE = [
45
+ 'django.middleware.security.SecurityMiddleware',
46
+ 'whitenoise.middleware.WhiteNoiseMiddleware',
47
+ 'django.contrib.sessions.middleware.SessionMiddleware',
48
+ 'django.middleware.common.CommonMiddleware',
49
+ 'django.middleware.csrf.CsrfViewMiddleware',
50
+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
51
+ 'django.contrib.messages.middleware.MessageMiddleware',
52
+ 'django.middleware.clickjacking.XFrameOptionsMiddleware',
53
+ ]
54
+
55
+ ROOT_URLCONF = '{{ project_name }}.urls'
56
+
57
+ TEMPLATES = [
58
+ {
59
+ 'BACKEND': 'django.template.backends.django.DjangoTemplates',
60
+ 'DIRS': [],
61
+ 'APP_DIRS': True,
62
+ 'OPTIONS': {
63
+ 'context_processors': [
64
+ 'django.template.context_processors.debug',
65
+ 'django.template.context_processors.request',
66
+ 'django.contrib.auth.context_processors.auth',
67
+ 'django.contrib.messages.context_processors.messages',
68
+ ],
69
+ },
70
+ },
71
+ ]
72
+
73
+ WSGI_APPLICATION = '{{ project_name }}.wsgi.application'
74
+
75
+ # Database
76
+ # https://docs.djangoproject.com/en/{{ docs_version }}/ref/settings/#databases
77
+ DATABASES = values.DatabaseURLValue(
78
+ 'sqlite:///{}'.format(os.path.join(BASE_DIR, 'db.sqlite3'))
79
+ )
80
+
81
+ # Password validation
82
+ # https://docs.djangoproject.com/en/{{ docs_version }}/ref/settings/#auth-password-validators
83
+ AUTH_PASSWORD_VALIDATORS = [
84
+ {
85
+ 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
86
+ },
87
+ {
88
+ 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
89
+ },
90
+ {
91
+ 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
92
+ },
93
+ {
94
+ 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
95
+ },
96
+ ]
97
+
98
+ # Internationalization
99
+ # https://docs.djangoproject.com/en/{{ docs_version }}/topics/i18n/
100
+ LANGUAGE_CODE = 'en-us'
101
+
102
+ TIME_ZONE = 'UTC'
103
+
104
+ USE_I18N = True
105
+
106
+ USE_L10N = True
107
+
108
+ USE_TZ = True
109
+
110
+ # Static files (CSS, JavaScript, Images)
111
+ # https://docs.djangoproject.com/en/{{ docs_version }}/howto/static-files/
112
+ STATIC_URL = '/static/'
113
+ STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
114
+ STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
115
+
116
+ # Default primary key field type
117
+ # https://docs.djangoproject.com/en/{{ docs_version }}/ref/settings/#default-auto-field
118
+ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
119
+
120
+ AUTH_USER_MODEL = 'users.User'
121
+
122
+
123
+ class Development(Common):
124
+ """
125
+ The in-development settings and the default configuration.
126
+ """
127
+ DEBUG = True
128
+
129
+ ALLOWED_HOSTS = []
130
+
131
+ INTERNAL_IPS = [
132
+ '127.0.0.1'
133
+ ]
134
+
135
+ MIDDLEWARE = Common.MIDDLEWARE + [
136
+ 'debug_toolbar.middleware.DebugToolbarMiddleware'
137
+ ]
138
+
139
+
140
+ class Staging(Common):
141
+ """
142
+ The in-staging settings.
143
+ """
144
+ # Security
145
+ SESSION_COOKIE_SECURE = values.BooleanValue(True)
146
+ SECURE_BROWSER_XSS_FILTER = values.BooleanValue(True)
147
+ SECURE_CONTENT_TYPE_NOSNIFF = values.BooleanValue(True)
148
+ SECURE_HSTS_INCLUDE_SUBDOMAINS = values.BooleanValue(True)
149
+ SECURE_HSTS_SECONDS = values.IntegerValue(31536000)
150
+ SECURE_REDIRECT_EXEMPT = values.ListValue([])
151
+ SECURE_SSL_HOST = values.Value(None)
152
+ SECURE_SSL_REDIRECT = values.BooleanValue(True)
153
+ SECURE_PROXY_SSL_HEADER = values.TupleValue(
154
+ ('HTTP_X_FORWARDED_PROTO', 'https')
155
+ )
156
+
157
+
158
+ class Production(Staging):
159
+ """
160
+ The in-production settings.
161
+ """
162
+ pass
@@ -0,0 +1,13 @@
1
+ from django.conf import settings
2
+ from django.contrib import admin
3
+ from django.urls import include, path
4
+
5
+ urlpatterns = [
6
+ path('admin/', admin.site.urls),
7
+ ]
8
+
9
+ if settings.DEBUG:
10
+ import debug_toolbar
11
+ urlpatterns = [
12
+ path('__debug__/', include(debug_toolbar.urls)),
13
+ ] + urlpatterns
@@ -0,0 +1,5 @@
1
+ from django.contrib import admin
2
+ from django.contrib.auth.admin import UserAdmin
3
+ from .models import User
4
+
5
+ admin.site.register(User, UserAdmin)
@@ -0,0 +1,46 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by Django 1.11.2 on 2017-06-20 13:29
3
+ from __future__ import unicode_literals
4
+
5
+ import django.contrib.auth.models
6
+ import django.contrib.auth.validators
7
+ from django.db import migrations, models
8
+ import django.utils.timezone
9
+
10
+
11
+ class Migration(migrations.Migration):
12
+
13
+ initial = True
14
+
15
+ dependencies = [
16
+ ('auth', '0008_alter_user_username_max_length'),
17
+ ]
18
+
19
+ operations = [
20
+ migrations.CreateModel(
21
+ name='User',
22
+ fields=[
23
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
24
+ ('password', models.CharField(max_length=128, verbose_name='password')),
25
+ ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
26
+ ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
27
+ ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')),
28
+ ('first_name', models.CharField(blank=True, max_length=30, verbose_name='first name')),
29
+ ('last_name', models.CharField(blank=True, max_length=30, verbose_name='last name')),
30
+ ('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')),
31
+ ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
32
+ ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
33
+ ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
34
+ ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')),
35
+ ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')),
36
+ ],
37
+ options={
38
+ 'verbose_name_plural': 'users',
39
+ 'verbose_name': 'user',
40
+ 'abstract': False,
41
+ },
42
+ managers=[
43
+ ('objects', django.contrib.auth.models.UserManager()),
44
+ ],
45
+ ),
46
+ ]
@@ -0,0 +1,5 @@
1
+ from django.contrib.auth.models import AbstractUser
2
+
3
+
4
+ class User(AbstractUser):
5
+ pass
@@ -0,0 +1,18 @@
1
+ """
2
+ WSGI config for {{ project_name }} project.
3
+
4
+ It exposes the WSGI callable as a module-level variable named ``application``.
5
+
6
+ For more information on this file, see
7
+ https://docs.djangoproject.com/en/{{ docs_version }}/howto/deployment/wsgi/
8
+ """
9
+
10
+ import os
11
+
12
+ configuration = os.getenv('ENVIRONMENT', 'development').title()
13
+ os.environ.setdefault('DJANGO_SETTINGS_MODULE', '{{ project_name }}.settings')
14
+ os.environ.setdefault('DJANGO_CONFIGURATION', configuration)
15
+
16
+ from configurations.wsgi import get_wsgi_application
17
+
18
+ application = get_wsgi_application()
@@ -3,6 +3,7 @@ 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 = True
6
7
 
7
8
  class StarletteManager(FastapiManager):
8
9
  extra_libs = ["aiomysql"]
@@ -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"
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
16
+ raise Exception(f"Manager class for '{base_name}' not found. Ensure it is defined and imported correctly.")
16
17
 
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
22
- return None
23
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
  #
@@ -43,22 +38,20 @@ class Main:
43
38
  #
44
39
  self.args = self.parser.parse_args()
45
40
  #
46
- self.framework_manager = find_manager_class(self.args.framework)
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):
52
- example_id = 1 if self.args.example is None else self.args.example
53
- #
46
+ def run(self) -> None:
54
47
  framework = self.framework_manager(self.args.name)
55
48
  #
56
49
  if hasattr(self.framework_manager, "install_framework"):
57
- framework.install_framework(version=self.args.version)
50
+ framework.install_framework(_version=self.args.version)
58
51
  if hasattr(self.framework_manager, "create_example"):
59
- framework.create_example(example_id)
52
+ framework.create_example(self.args.example or 1)
60
53
 
61
- def main_entry_point():
54
+ def main_entry_point() -> None:
62
55
  Main().run()
63
56
 
64
57
 
@@ -0,0 +1,80 @@
1
+ from pathlib import Path
2
+ from .config import AutoManager
3
+ from .config import Config
4
+ from typing import Optional, List
5
+ from copy import deepcopy
6
+
7
+
8
+ cfg = Config()
9
+
10
+ class Template:
11
+ extra_libs: List[str]
12
+ extra_dirs: List[str]
13
+ extra_files: List[str]
14
+ example: bool = True
15
+
16
+ def __init_subclass__(cls, **kwargs) -> None:
17
+ super().__init_subclass__(**kwargs)
18
+ cls.framework_name = cls.__name__.lower().removesuffix("manager")
19
+
20
+ bases = [base for base in cls.__mro__[1:] if issubclass(base, Template)]
21
+
22
+ fields = ["extra_libs", "extra_dirs", "extra_files"]
23
+
24
+ seen = set()
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
+ ]
32
+ values += getattr(cls, attr, [])
33
+ setattr(cls, attr, values)
34
+
35
+ cls.example = getattr(cls, "example", True)
36
+
37
+
38
+ def __init__(
39
+ self,
40
+ name: str,
41
+ framework_name: Optional[str] = None,
42
+ source_dir: Optional[str] = None,
43
+ project_name: Optional[str] = None
44
+ ):
45
+ self.name = name
46
+ self.source_dir = source_dir or cfg.source_dir
47
+ self.project_name = project_name or cfg.project_name
48
+ self.framework_name = framework_name or self.__class__.framework_name
49
+ self.AutoManager = AutoManager()
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)
54
+ self.example = self.__class__.example
55
+
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()
61
+
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)
67
+
68
+ def create_example(self, example_id) -> None:
69
+ if self.example:
70
+ from pkgutil import get_data
71
+
72
+ example_code = get_data("rapidframework", f"frameworks/examples/{self.framework_name}_{example_id}.py")
73
+
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"))
79
+ else:
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.8.2
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.8.2/
16
+ ## https://pypi.org/project/rapidframework-lib/1.1.1/
17
17
 
18
18
  ## Installation
19
19
 
@@ -25,6 +25,17 @@ rapidframework/frameworks/examples/starlette_1.py
25
25
  rapidframework/frameworks/examples/tornado_1.py
26
26
  rapidframework/frameworks/examples/turbogears2_1.py
27
27
  rapidframework/frameworks/examples/web2py_1.py
28
+ rapidframework/frameworks/examples/django_1/manage.py-tpl
29
+ rapidframework/frameworks/examples/django_1/project_name/__init__.py-tpl
30
+ rapidframework/frameworks/examples/django_1/project_name/asgi.py-tpl
31
+ rapidframework/frameworks/examples/django_1/project_name/settings.py-tpl
32
+ rapidframework/frameworks/examples/django_1/project_name/urls.py-tpl
33
+ rapidframework/frameworks/examples/django_1/project_name/wsgi.py-tpl
34
+ rapidframework/frameworks/examples/django_1/project_name/users/__init__.py-tpl
35
+ rapidframework/frameworks/examples/django_1/project_name/users/admin.py-tpl
36
+ rapidframework/frameworks/examples/django_1/project_name/users/models.py-tpl
37
+ rapidframework/frameworks/examples/django_1/project_name/users/migrations/0001_initial.py-tpl
38
+ rapidframework/frameworks/examples/django_1/project_name/users/migrations/__init__.py-tpl
28
39
  rapidframework_lib.egg-info/PKG-INFO
29
40
  rapidframework_lib.egg-info/SOURCES.txt
30
41
  rapidframework_lib.egg-info/dependency_links.txt
@@ -3,7 +3,7 @@ from setuptools import setup, find_packages
3
3
 
4
4
  setup(
5
5
  name="rapidframework-lib",
6
- version="1.0.8.2",
6
+ version="1.1.1",
7
7
  packages=find_packages(),
8
8
  install_requires=[
9
9
  "msgspec"
@@ -1,83 +0,0 @@
1
- from os import getcwd, listdir, path, makedirs
2
- from typing import Self, Dict
3
- import pkgutil
4
- from msgspec import json, Struct, field
5
- from subprocess import run
6
- from importlib.metadata import distribution
7
- from re import sub
8
-
9
-
10
- class Config:
11
- _instance = None
12
-
13
- def __new__(cls) -> Self:
14
- if cls._instance is None:
15
- cls._instance = super(Config, cls).__new__(cls)
16
- cls._instance.source_dir = getcwd()
17
- cls._instance.source_files = listdir()
18
- cls._instance.dirs_to_create = [
19
- "tests",
20
- "templates",
21
- "static",
22
- "static/css",
23
- "static/js",
24
- "static/images",
25
- ]
26
-
27
- # cls._instance.pyproject_deps: list
28
- cls._instance.project_name = path.basename(cls._instance.source_dir)
29
- cls.install = AutoManager().get_config_managers()
30
- cls.pkg_manager = AutoManager().get_pkg_manager()
31
-
32
- return cls._instance
33
-
34
- def create_dirs(cls, app_path, extra_dirs=[]) -> None:
35
- dirs_to_create: list = cls._instance.dirs_to_create.copy()
36
- dirs_to_create.extend(extra_dirs)
37
- #
38
- for _dir in dirs_to_create:
39
- makedirs(path.join(app_path, _dir), exist_ok=True)
40
-
41
- def create_files(cls, file_paths) -> None:
42
- for file_path in file_paths:
43
- with open(path.join(cls._instance.source_dir, file_path), "w"): ...
44
-
45
-
46
- class AutoManager:
47
- _instance = None
48
-
49
-
50
- def __new__(cls, config_name: str = "managers.json") -> Self:
51
- if cls._instance is None:
52
- cls._instance = super(AutoManager, cls).__new__(cls)
53
-
54
- class _ConfigCommands(Struct):
55
- install: str
56
- uninstall: str
57
- list_: str = field(name="list")
58
-
59
- class _ConfigFormat(Struct):
60
- managers: Dict[str, _ConfigCommands]
61
-
62
- cls._instance.config_name = config_name
63
- cls._instance._ConfigFormat = _ConfigFormat
64
- cls._instance.decoder = json.Decoder()
65
-
66
- return cls._instance
67
-
68
-
69
- def get_config_managers(cls) -> dict:
70
- config = pkgutil.get_data("rapidframework", f"configs/{cls._instance.config_name}")
71
- return json.decode(config.decode("utf-8"), type=cls._instance._ConfigFormat)
72
-
73
-
74
- def get_pkg_manager(cls) -> str:
75
- try:
76
- return sub(r'\s+', '', distribution("rapidframework-lib").read_text("INSTALLER"))
77
- except:
78
- return "pip"
79
-
80
-
81
- def install_libs(cls, libs: list) -> None:
82
- print(libs)
83
- run([cls.get_pkg_manager(), cls.get_config_managers().managers.get(cls.get_pkg_manager()).install] + libs)
@@ -1,33 +0,0 @@
1
- # from ..template import Template
2
- # from subprocess import run
3
- # from os import chdir
4
-
5
-
6
- # class DjangoManager(Template):
7
- # extra_libs = ["Pillow"]
8
- # example = False
9
-
10
- # def run_manage(self, commands: list):
11
- # manage_py = f"{self.source_dir}/{self.project_name}/manage.py"
12
- # for command in commands:
13
- # full_command = ["python", manage_py] + command.strip().split(" ")
14
- # run(full_command, check=True)
15
-
16
- # def setup_framework(self):
17
- # run([
18
- # "python", "-m", "django", "startproject",
19
- # self.project_name, self.source_dir
20
- # ], check=True)
21
-
22
- # chdir(f"{self.source_dir}/{self.project_name}")
23
- # self.run_manage([f"startapp {self.name}", "makemigrations", "migrate"])
24
-
25
- # self.extra_files.append(f"{self.project_name}/{self.name}/urls.py")
26
-
27
- # return super().setup_framework(
28
- # source_dir=f"{self.source_dir}/{self.project_name}/{self.name}",
29
- # extra_files=self.extra_files
30
- # )
31
- """
32
- The class is being redeveloped for better performance and capabilities
33
- """
@@ -1,79 +0,0 @@
1
- from os import path
2
- from .config import AutoManager
3
- from .config import Config
4
- from typing import Optional, List
5
-
6
- cfg = Config()
7
-
8
- class Template:
9
- extra_libs: List[str] = []
10
- extra_dirs: List[str] = []
11
- extra_files: List[str] = []
12
- example: bool = True
13
-
14
- def __init_subclass__(cls, **kwargs):
15
- super().__init_subclass__(**kwargs)
16
- cls.framework_name = cls.__name__.lower().replace("manager", "")
17
-
18
- bases = [base for base in cls.__mro__[1:] if issubclass(base, Template)]
19
-
20
- cls.extra_libs = sum([getattr(base, "extra_libs", []) for base in reversed(bases)], []) + cls.extra_libs
21
- cls.extra_dirs = sum([getattr(base, "extra_dirs", []) for base in reversed(bases)], []) + cls.extra_dirs
22
- cls.extra_files = sum([getattr(base, "extra_files", []) for base in reversed(bases)], []) + cls.extra_files
23
-
24
- cls.example = getattr(cls, "example", True)
25
-
26
- def __init__(
27
- self,
28
- name: str,
29
- framework_name: Optional[str] = None,
30
- source_dir = cfg.source_dir,
31
- project_name = cfg.project_name
32
- ):
33
- self.name = name
34
- self.framework_name = framework_name or self.__class__.framework_name
35
- self.source_dir = source_dir
36
- self.project_name = project_name
37
- self.AutoManager = AutoManager()
38
- self.extra_libs = self.__class__.extra_libs
39
- self.extra_dirs = self.__class__.extra_dirs
40
- self.extra_files = self.__class__.extra_files
41
- self.example = self.__class__.example
42
-
43
- def install_framework(self, **kwargs):
44
- version = f"=={kwargs.get('version')}" if kwargs.get('version') else ""
45
- libs_to_install: list = kwargs.get("libs") or []
46
- #
47
- libs_to_install.extend([f"{self.framework_name}{version}"])
48
- libs_to_install.extend(self.extra_libs)
49
- #
50
- self.AutoManager.install_libs(libs_to_install)
51
- #
52
- self.setup_framework()
53
-
54
- def setup_framework(self, source_dir: list = None, extra_dirs: list = None, extra_files: list = None):
55
- source_dir = source_dir or self.source_dir
56
- #
57
- dirs = (extra_dirs or []) + self.extra_dirs
58
- files = (extra_files or []) + self.extra_files
59
- #
60
- if dirs:
61
- cfg.create_dirs(source_dir, dirs)
62
- if files:
63
- cfg.create_files(files)
64
-
65
- def create_example(self, example_id):
66
- if self.__class__.example:
67
- from pkgutil import get_data
68
-
69
- example_code = get_data(
70
- "rapidframework",
71
- f"frameworks/examples/{self.framework_name}_{example_id}.py",
72
- ).decode("utf-8")
73
-
74
- with open(
75
- path.join(self.source_dir, self.name + ".py"), "w", encoding="utf-8"
76
- ) as example_file:
77
- example_file.write(example_code)
78
- else:
79
- raise Exception("Example method is'n allowed for this framework !")