createsonline 0.1.26__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.
- createsonline/__init__.py +46 -0
- createsonline/admin/__init__.py +7 -0
- createsonline/admin/content.py +526 -0
- createsonline/admin/crud.py +805 -0
- createsonline/admin/field_builder.py +559 -0
- createsonline/admin/integration.py +482 -0
- createsonline/admin/interface.py +2562 -0
- createsonline/admin/model_creator.py +513 -0
- createsonline/admin/model_manager.py +388 -0
- createsonline/admin/modern_dashboard.py +498 -0
- createsonline/admin/permissions.py +264 -0
- createsonline/admin/user_forms.py +594 -0
- createsonline/ai/__init__.py +202 -0
- createsonline/ai/fields.py +1226 -0
- createsonline/ai/orm.py +325 -0
- createsonline/ai/services.py +1244 -0
- createsonline/app.py +506 -0
- createsonline/auth/__init__.py +8 -0
- createsonline/auth/management.py +228 -0
- createsonline/auth/models.py +552 -0
- createsonline/cli/__init__.py +5 -0
- createsonline/cli/commands/__init__.py +122 -0
- createsonline/cli/commands/database.py +416 -0
- createsonline/cli/commands/info.py +173 -0
- createsonline/cli/commands/initdb.py +218 -0
- createsonline/cli/commands/project.py +545 -0
- createsonline/cli/commands/serve.py +173 -0
- createsonline/cli/commands/shell.py +93 -0
- createsonline/cli/commands/users.py +148 -0
- createsonline/cli/main.py +2041 -0
- createsonline/cli/manage.py +274 -0
- createsonline/config/__init__.py +9 -0
- createsonline/config/app.py +2577 -0
- createsonline/config/database.py +179 -0
- createsonline/config/docs.py +384 -0
- createsonline/config/errors.py +160 -0
- createsonline/config/orm.py +43 -0
- createsonline/config/request.py +93 -0
- createsonline/config/settings.py +176 -0
- createsonline/data/__init__.py +23 -0
- createsonline/data/dataframe.py +925 -0
- createsonline/data/io.py +453 -0
- createsonline/data/series.py +557 -0
- createsonline/database/__init__.py +60 -0
- createsonline/database/abstraction.py +440 -0
- createsonline/database/assistant.py +585 -0
- createsonline/database/fields.py +442 -0
- createsonline/database/migrations.py +132 -0
- createsonline/database/models.py +604 -0
- createsonline/database.py +438 -0
- createsonline/http/__init__.py +28 -0
- createsonline/http/client.py +535 -0
- createsonline/ml/__init__.py +55 -0
- createsonline/ml/classification.py +552 -0
- createsonline/ml/clustering.py +680 -0
- createsonline/ml/metrics.py +542 -0
- createsonline/ml/neural.py +560 -0
- createsonline/ml/preprocessing.py +784 -0
- createsonline/ml/regression.py +501 -0
- createsonline/performance/__init__.py +19 -0
- createsonline/performance/cache.py +444 -0
- createsonline/performance/compression.py +335 -0
- createsonline/performance/core.py +419 -0
- createsonline/project_init.py +789 -0
- createsonline/routing.py +528 -0
- createsonline/security/__init__.py +34 -0
- createsonline/security/core.py +811 -0
- createsonline/security/encryption.py +349 -0
- createsonline/server.py +295 -0
- createsonline/static/css/admin.css +263 -0
- createsonline/static/css/common.css +358 -0
- createsonline/static/css/dashboard.css +89 -0
- createsonline/static/favicon.ico +0 -0
- createsonline/static/icons/icon-128x128.png +0 -0
- createsonline/static/icons/icon-128x128.webp +0 -0
- createsonline/static/icons/icon-16x16.png +0 -0
- createsonline/static/icons/icon-16x16.webp +0 -0
- createsonline/static/icons/icon-180x180.png +0 -0
- createsonline/static/icons/icon-180x180.webp +0 -0
- createsonline/static/icons/icon-192x192.png +0 -0
- createsonline/static/icons/icon-192x192.webp +0 -0
- createsonline/static/icons/icon-256x256.png +0 -0
- createsonline/static/icons/icon-256x256.webp +0 -0
- createsonline/static/icons/icon-32x32.png +0 -0
- createsonline/static/icons/icon-32x32.webp +0 -0
- createsonline/static/icons/icon-384x384.png +0 -0
- createsonline/static/icons/icon-384x384.webp +0 -0
- createsonline/static/icons/icon-48x48.png +0 -0
- createsonline/static/icons/icon-48x48.webp +0 -0
- createsonline/static/icons/icon-512x512.png +0 -0
- createsonline/static/icons/icon-512x512.webp +0 -0
- createsonline/static/icons/icon-64x64.png +0 -0
- createsonline/static/icons/icon-64x64.webp +0 -0
- createsonline/static/image/android-chrome-192x192.png +0 -0
- createsonline/static/image/android-chrome-512x512.png +0 -0
- createsonline/static/image/apple-touch-icon.png +0 -0
- createsonline/static/image/favicon-16x16.png +0 -0
- createsonline/static/image/favicon-32x32.png +0 -0
- createsonline/static/image/favicon.ico +0 -0
- createsonline/static/image/favicon.svg +17 -0
- createsonline/static/image/icon-128x128.png +0 -0
- createsonline/static/image/icon-128x128.webp +0 -0
- createsonline/static/image/icon-16x16.png +0 -0
- createsonline/static/image/icon-16x16.webp +0 -0
- createsonline/static/image/icon-180x180.png +0 -0
- createsonline/static/image/icon-180x180.webp +0 -0
- createsonline/static/image/icon-192x192.png +0 -0
- createsonline/static/image/icon-192x192.webp +0 -0
- createsonline/static/image/icon-256x256.png +0 -0
- createsonline/static/image/icon-256x256.webp +0 -0
- createsonline/static/image/icon-32x32.png +0 -0
- createsonline/static/image/icon-32x32.webp +0 -0
- createsonline/static/image/icon-384x384.png +0 -0
- createsonline/static/image/icon-384x384.webp +0 -0
- createsonline/static/image/icon-48x48.png +0 -0
- createsonline/static/image/icon-48x48.webp +0 -0
- createsonline/static/image/icon-512x512.png +0 -0
- createsonline/static/image/icon-512x512.webp +0 -0
- createsonline/static/image/icon-64x64.png +0 -0
- createsonline/static/image/icon-64x64.webp +0 -0
- createsonline/static/image/logo-header-h100.png +0 -0
- createsonline/static/image/logo-header-h100.webp +0 -0
- createsonline/static/image/logo-header-h200@2x.png +0 -0
- createsonline/static/image/logo-header-h200@2x.webp +0 -0
- createsonline/static/image/logo.png +0 -0
- createsonline/static/js/admin.js +274 -0
- createsonline/static/site.webmanifest +35 -0
- createsonline/static/templates/admin/base.html +87 -0
- createsonline/static/templates/admin/dashboard.html +217 -0
- createsonline/static/templates/admin/model_form.html +270 -0
- createsonline/static/templates/admin/model_list.html +202 -0
- createsonline/static/test_script.js +15 -0
- createsonline/static/test_styles.css +59 -0
- createsonline/static_files.py +365 -0
- createsonline/templates/404.html +100 -0
- createsonline/templates/admin_login.html +169 -0
- createsonline/templates/base.html +102 -0
- createsonline/templates/index.html +151 -0
- createsonline/templates.py +205 -0
- createsonline/testing.py +322 -0
- createsonline/utils.py +448 -0
- createsonline/validation/__init__.py +49 -0
- createsonline/validation/fields.py +598 -0
- createsonline/validation/models.py +504 -0
- createsonline/validation/validators.py +561 -0
- createsonline/views.py +184 -0
- createsonline-0.1.26.dist-info/METADATA +46 -0
- createsonline-0.1.26.dist-info/RECORD +152 -0
- createsonline-0.1.26.dist-info/WHEEL +5 -0
- createsonline-0.1.26.dist-info/entry_points.txt +2 -0
- createsonline-0.1.26.dist-info/licenses/LICENSE +21 -0
- createsonline-0.1.26.dist-info/top_level.txt +1 -0
createsonline/ai/orm.py
ADDED
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
# createsonline/ai/orm.py
|
|
2
|
+
"""
|
|
3
|
+
CREATESONLINE AI-Enhanced ORM
|
|
4
|
+
|
|
5
|
+
AI-powered database operations with smart queries and intelligent fields.
|
|
6
|
+
"""
|
|
7
|
+
from typing import Any, Dict, List, Optional, Type
|
|
8
|
+
import sqlalchemy as sa
|
|
9
|
+
from sqlalchemy.ext.declarative import declarative_base
|
|
10
|
+
from sqlalchemy.orm import sessionmaker, Session
|
|
11
|
+
from datetime import datetime
|
|
12
|
+
|
|
13
|
+
# Create base model class for CREATESONLINE
|
|
14
|
+
Base = declarative_base()
|
|
15
|
+
|
|
16
|
+
class AIBaseModel(Base):
|
|
17
|
+
"""
|
|
18
|
+
Base model class with AI enhancements for CREATESONLINE applications
|
|
19
|
+
|
|
20
|
+
Provides automatic AI field processing and intelligent database operations.
|
|
21
|
+
"""
|
|
22
|
+
__abstract__ = True
|
|
23
|
+
|
|
24
|
+
# Standard fields for all models
|
|
25
|
+
id = sa.Column(sa.Integer, primary_key=True, index=True)
|
|
26
|
+
created_at = sa.Column(sa.DateTime, default=datetime.utcnow, nullable=False)
|
|
27
|
+
updated_at = sa.Column(
|
|
28
|
+
sa.DateTime,
|
|
29
|
+
default=datetime.utcnow,
|
|
30
|
+
onupdate=datetime.utcnow,
|
|
31
|
+
nullable=False
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
def __init__(self, **kwargs):
|
|
35
|
+
"""Initialize model with AI field processing"""
|
|
36
|
+
super().__init__(**kwargs)
|
|
37
|
+
self._ai_fields = {}
|
|
38
|
+
self._discover_ai_fields()
|
|
39
|
+
|
|
40
|
+
def _discover_ai_fields(self):
|
|
41
|
+
"""Discover AI fields in this model"""
|
|
42
|
+
from createsonline.ai.fields import AIFieldMixin
|
|
43
|
+
|
|
44
|
+
for attr_name in dir(self.__class__):
|
|
45
|
+
attr = getattr(self.__class__, attr_name)
|
|
46
|
+
if isinstance(attr, type) and issubclass(attr, AIFieldMixin):
|
|
47
|
+
self._ai_fields[attr_name] = attr
|
|
48
|
+
|
|
49
|
+
async def compute_ai_fields(self):
|
|
50
|
+
"""Compute all AI fields for this instance"""
|
|
51
|
+
from createsonline.ai.fields import AIComputedField, LLMField, VectorField
|
|
52
|
+
|
|
53
|
+
for field_name, field in self._ai_fields.items():
|
|
54
|
+
try:
|
|
55
|
+
if isinstance(field, AIComputedField):
|
|
56
|
+
# Compute AI-predicted value
|
|
57
|
+
features = self._extract_features_for_field(field)
|
|
58
|
+
value = await field.compute_value(self, features)
|
|
59
|
+
setattr(self, field_name, value)
|
|
60
|
+
|
|
61
|
+
elif isinstance(field, LLMField):
|
|
62
|
+
# Generate content with LLM
|
|
63
|
+
template_data = self._extract_template_data_for_field(field)
|
|
64
|
+
content = await field.generate_content(self, template_data)
|
|
65
|
+
setattr(self, field_name, content)
|
|
66
|
+
|
|
67
|
+
elif isinstance(field, VectorField):
|
|
68
|
+
# Generate vector embedding
|
|
69
|
+
source_data = self._extract_source_data_for_field(field)
|
|
70
|
+
embedding = await field.generate_embedding(self, source_data)
|
|
71
|
+
setattr(self, field_name, embedding)
|
|
72
|
+
|
|
73
|
+
except Exception as e:
|
|
74
|
+
pass
|
|
75
|
+
|
|
76
|
+
def _extract_features_for_field(self, field) -> Dict[str, Any]:
|
|
77
|
+
"""Extract features for AI computation"""
|
|
78
|
+
features = {}
|
|
79
|
+
|
|
80
|
+
# Get features from field configuration
|
|
81
|
+
feature_fields = field.ai_config.get('features', [])
|
|
82
|
+
source_field = field.ai_config.get('source_field')
|
|
83
|
+
|
|
84
|
+
if feature_fields:
|
|
85
|
+
for feature_field in feature_fields:
|
|
86
|
+
if hasattr(self, feature_field):
|
|
87
|
+
features[feature_field] = getattr(self, feature_field)
|
|
88
|
+
elif source_field:
|
|
89
|
+
if hasattr(self, source_field):
|
|
90
|
+
features[source_field] = getattr(self, source_field)
|
|
91
|
+
|
|
92
|
+
return features
|
|
93
|
+
|
|
94
|
+
def _extract_template_data_for_field(self, field) -> Dict[str, Any]:
|
|
95
|
+
"""Extract template data for LLM generation"""
|
|
96
|
+
template_data = {}
|
|
97
|
+
|
|
98
|
+
# Extract all non-AI fields as template variables
|
|
99
|
+
for attr_name in dir(self):
|
|
100
|
+
if not attr_name.startswith('_') and hasattr(self, attr_name):
|
|
101
|
+
value = getattr(self, attr_name)
|
|
102
|
+
if isinstance(value, (str, int, float, bool)) and value is not None:
|
|
103
|
+
template_data[attr_name] = value
|
|
104
|
+
|
|
105
|
+
return template_data
|
|
106
|
+
|
|
107
|
+
def _extract_source_data_for_field(self, field) -> Any:
|
|
108
|
+
"""Extract source data for vector embedding"""
|
|
109
|
+
source_field = field.ai_config.get('source_field')
|
|
110
|
+
|
|
111
|
+
if source_field and hasattr(self, source_field):
|
|
112
|
+
return getattr(self, source_field)
|
|
113
|
+
|
|
114
|
+
# Fallback to description or name field
|
|
115
|
+
for fallback_field in ['description', 'content', 'text', 'name']:
|
|
116
|
+
if hasattr(self, fallback_field):
|
|
117
|
+
return getattr(self, fallback_field)
|
|
118
|
+
|
|
119
|
+
return str(self)
|
|
120
|
+
|
|
121
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
122
|
+
"""Convert model to dictionary"""
|
|
123
|
+
result = {}
|
|
124
|
+
for column in self.__table__.columns:
|
|
125
|
+
value = getattr(self, column.name)
|
|
126
|
+
if isinstance(value, datetime):
|
|
127
|
+
result[column.name] = value.isoformat()
|
|
128
|
+
elif isinstance(value, (list, dict)):
|
|
129
|
+
result[column.name] = value
|
|
130
|
+
else:
|
|
131
|
+
result[column.name] = value
|
|
132
|
+
return result
|
|
133
|
+
|
|
134
|
+
def __repr__(self) -> str:
|
|
135
|
+
return f"<{self.__class__.__name__}(id={getattr(self, 'id', None)})>"
|
|
136
|
+
|
|
137
|
+
class AIEnhancedORM:
|
|
138
|
+
"""
|
|
139
|
+
AI-Enhanced ORM for CREATESONLINE framework
|
|
140
|
+
|
|
141
|
+
Provides intelligent database operations with AI capabilities.
|
|
142
|
+
"""
|
|
143
|
+
|
|
144
|
+
def __init__(self, database_url: str, echo: bool = False):
|
|
145
|
+
"""
|
|
146
|
+
Initialize AI-Enhanced ORM
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
database_url: Database connection string
|
|
150
|
+
echo: Enable SQL logging
|
|
151
|
+
"""
|
|
152
|
+
self.database_url = database_url
|
|
153
|
+
self.engine = sa.create_engine(database_url, echo=echo)
|
|
154
|
+
self.SessionLocal = sessionmaker(
|
|
155
|
+
autocommit=False,
|
|
156
|
+
autoflush=False,
|
|
157
|
+
bind=self.engine
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
# AI services integration
|
|
161
|
+
self._ai_enabled = True
|
|
162
|
+
self._ai_cache = {}
|
|
163
|
+
|
|
164
|
+
def create_tables(self):
|
|
165
|
+
"""Create all tables in the database"""
|
|
166
|
+
Base.metadata.create_all(bind=self.engine)
|
|
167
|
+
|
|
168
|
+
def drop_tables(self):
|
|
169
|
+
"""Drop all tables in the database"""
|
|
170
|
+
Base.metadata.drop_all(bind=self.engine)
|
|
171
|
+
|
|
172
|
+
def get_session(self) -> Session:
|
|
173
|
+
"""Get a database session"""
|
|
174
|
+
return self.SessionLocal()
|
|
175
|
+
|
|
176
|
+
@staticmethod
|
|
177
|
+
def _to_snake_case(name: str) -> str:
|
|
178
|
+
"""Convert ``CamelCase`` identifiers into ``snake_case`` table names."""
|
|
179
|
+
|
|
180
|
+
import re
|
|
181
|
+
|
|
182
|
+
if not name:
|
|
183
|
+
return name
|
|
184
|
+
|
|
185
|
+
snake = re.sub(r"(.)([A-Z][a-z]+)", r"\1_\2", name)
|
|
186
|
+
snake = re.sub(r"([a-z0-9])([A-Z])", r"\1_\2", snake)
|
|
187
|
+
return snake.replace("__", "_").strip("_").lower()
|
|
188
|
+
|
|
189
|
+
async def smart_query(
|
|
190
|
+
self,
|
|
191
|
+
model: Type[AIBaseModel],
|
|
192
|
+
natural_language_query: str
|
|
193
|
+
) -> List[AIBaseModel]:
|
|
194
|
+
"""
|
|
195
|
+
Execute a query using natural language
|
|
196
|
+
|
|
197
|
+
Args:
|
|
198
|
+
model: Model class to query
|
|
199
|
+
natural_language_query: Natural language query string
|
|
200
|
+
|
|
201
|
+
Returns:
|
|
202
|
+
List of query results
|
|
203
|
+
"""
|
|
204
|
+
# TODO: Implement natural language to SQL transformation
|
|
205
|
+
# For now, return basic query
|
|
206
|
+
session = self.get_session()
|
|
207
|
+
try:
|
|
208
|
+
# Simple implementation - would be enhanced with AI
|
|
209
|
+
query = session.query(model)
|
|
210
|
+
|
|
211
|
+
# Basic keyword matching
|
|
212
|
+
if 'recent' in natural_language_query.lower():
|
|
213
|
+
query = query.order_by(model.created_at.desc())
|
|
214
|
+
|
|
215
|
+
if 'limit' in natural_language_query.lower():
|
|
216
|
+
# Extract number after 'limit'
|
|
217
|
+
import re
|
|
218
|
+
match = re.search(r'limit\s+(\d+)', natural_language_query.lower())
|
|
219
|
+
if match:
|
|
220
|
+
limit = int(match.group(1))
|
|
221
|
+
query = query.limit(limit)
|
|
222
|
+
|
|
223
|
+
return query.all()
|
|
224
|
+
|
|
225
|
+
finally:
|
|
226
|
+
session.close()
|
|
227
|
+
|
|
228
|
+
def create_model_from_description(
|
|
229
|
+
self,
|
|
230
|
+
description: str,
|
|
231
|
+
model_name: str = "GeneratedModel"
|
|
232
|
+
) -> Type[AIBaseModel]:
|
|
233
|
+
"""
|
|
234
|
+
Generate a model class from natural language description
|
|
235
|
+
|
|
236
|
+
Args:
|
|
237
|
+
description: Natural language description of the model
|
|
238
|
+
model_name: Name for the generated model
|
|
239
|
+
|
|
240
|
+
Returns:
|
|
241
|
+
Generated model class
|
|
242
|
+
"""
|
|
243
|
+
# TODO: Implement AI-driven schema generation
|
|
244
|
+
# For now, create a basic model
|
|
245
|
+
|
|
246
|
+
attributes = {
|
|
247
|
+
'__tablename__': self._to_snake_case(model_name),
|
|
248
|
+
'name': sa.Column(sa.String(255), nullable=False),
|
|
249
|
+
'description': sa.Column(sa.Text),
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
# Create dynamic model class
|
|
253
|
+
GeneratedModel = type(model_name, (AIBaseModel,), attributes)
|
|
254
|
+
|
|
255
|
+
return GeneratedModel
|
|
256
|
+
|
|
257
|
+
def generate_schema_from_description(
|
|
258
|
+
self,
|
|
259
|
+
description: str,
|
|
260
|
+
model_name: str = "GeneratedModel"
|
|
261
|
+
) -> Type[AIBaseModel]:
|
|
262
|
+
"""Backward compatible wrapper for deprecated API usage.
|
|
263
|
+
|
|
264
|
+
Earlier revisions of the project exposed ``generate_schema_from_description``
|
|
265
|
+
which delegated to the dynamic model creation helper. The method was
|
|
266
|
+
renamed during refactoring, but parts of the codebase – including the
|
|
267
|
+
published tests – still rely on the original name. Provide the thin
|
|
268
|
+
alias so existing integrations continue to function while new code can
|
|
269
|
+
adopt :meth:`create_model_from_description`.
|
|
270
|
+
"""
|
|
271
|
+
|
|
272
|
+
return self.create_model_from_description(description, model_name)
|
|
273
|
+
|
|
274
|
+
async def predict_related_entities(
|
|
275
|
+
self,
|
|
276
|
+
instance: AIBaseModel
|
|
277
|
+
) -> Dict[str, List[Any]]:
|
|
278
|
+
"""
|
|
279
|
+
Predict related entities using AI
|
|
280
|
+
|
|
281
|
+
Args:
|
|
282
|
+
instance: Model instance
|
|
283
|
+
|
|
284
|
+
Returns:
|
|
285
|
+
Dictionary of predicted related entities
|
|
286
|
+
"""
|
|
287
|
+
# TODO: Implement AI-based relationship prediction
|
|
288
|
+
return {}
|
|
289
|
+
|
|
290
|
+
def get_model_statistics(self, model: Type[AIBaseModel]) -> Dict[str, Any]:
|
|
291
|
+
"""Get statistics for a model"""
|
|
292
|
+
session = self.get_session()
|
|
293
|
+
try:
|
|
294
|
+
total_count = session.query(model).count()
|
|
295
|
+
|
|
296
|
+
# Recent activity (last 30 days)
|
|
297
|
+
thirty_days_ago = datetime.utcnow().replace(day=1) # Simplified
|
|
298
|
+
recent_count = session.query(model).filter(
|
|
299
|
+
model.created_at >= thirty_days_ago
|
|
300
|
+
).count()
|
|
301
|
+
|
|
302
|
+
return {
|
|
303
|
+
'total_records': total_count,
|
|
304
|
+
'recent_records': recent_count,
|
|
305
|
+
'model_name': model.__name__,
|
|
306
|
+
'table_name': model.__tablename__
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
finally:
|
|
310
|
+
session.close()
|
|
311
|
+
|
|
312
|
+
# Global ORM instance (initialized by application)
|
|
313
|
+
ai_orm: Optional[AIEnhancedORM] = None
|
|
314
|
+
|
|
315
|
+
def get_ai_orm() -> AIEnhancedORM:
|
|
316
|
+
"""Get the global AI ORM instance"""
|
|
317
|
+
if ai_orm is None:
|
|
318
|
+
raise RuntimeError("AI ORM not initialized. Call initialize_ai_orm() first.")
|
|
319
|
+
return ai_orm
|
|
320
|
+
|
|
321
|
+
def initialize_ai_orm(database_url: str, echo: bool = False) -> AIEnhancedORM:
|
|
322
|
+
"""Initialize the global AI ORM instance"""
|
|
323
|
+
global ai_orm
|
|
324
|
+
ai_orm = AIEnhancedORM(database_url, echo)
|
|
325
|
+
return ai_orm
|