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.
Files changed (152) hide show
  1. createsonline/__init__.py +46 -0
  2. createsonline/admin/__init__.py +7 -0
  3. createsonline/admin/content.py +526 -0
  4. createsonline/admin/crud.py +805 -0
  5. createsonline/admin/field_builder.py +559 -0
  6. createsonline/admin/integration.py +482 -0
  7. createsonline/admin/interface.py +2562 -0
  8. createsonline/admin/model_creator.py +513 -0
  9. createsonline/admin/model_manager.py +388 -0
  10. createsonline/admin/modern_dashboard.py +498 -0
  11. createsonline/admin/permissions.py +264 -0
  12. createsonline/admin/user_forms.py +594 -0
  13. createsonline/ai/__init__.py +202 -0
  14. createsonline/ai/fields.py +1226 -0
  15. createsonline/ai/orm.py +325 -0
  16. createsonline/ai/services.py +1244 -0
  17. createsonline/app.py +506 -0
  18. createsonline/auth/__init__.py +8 -0
  19. createsonline/auth/management.py +228 -0
  20. createsonline/auth/models.py +552 -0
  21. createsonline/cli/__init__.py +5 -0
  22. createsonline/cli/commands/__init__.py +122 -0
  23. createsonline/cli/commands/database.py +416 -0
  24. createsonline/cli/commands/info.py +173 -0
  25. createsonline/cli/commands/initdb.py +218 -0
  26. createsonline/cli/commands/project.py +545 -0
  27. createsonline/cli/commands/serve.py +173 -0
  28. createsonline/cli/commands/shell.py +93 -0
  29. createsonline/cli/commands/users.py +148 -0
  30. createsonline/cli/main.py +2041 -0
  31. createsonline/cli/manage.py +274 -0
  32. createsonline/config/__init__.py +9 -0
  33. createsonline/config/app.py +2577 -0
  34. createsonline/config/database.py +179 -0
  35. createsonline/config/docs.py +384 -0
  36. createsonline/config/errors.py +160 -0
  37. createsonline/config/orm.py +43 -0
  38. createsonline/config/request.py +93 -0
  39. createsonline/config/settings.py +176 -0
  40. createsonline/data/__init__.py +23 -0
  41. createsonline/data/dataframe.py +925 -0
  42. createsonline/data/io.py +453 -0
  43. createsonline/data/series.py +557 -0
  44. createsonline/database/__init__.py +60 -0
  45. createsonline/database/abstraction.py +440 -0
  46. createsonline/database/assistant.py +585 -0
  47. createsonline/database/fields.py +442 -0
  48. createsonline/database/migrations.py +132 -0
  49. createsonline/database/models.py +604 -0
  50. createsonline/database.py +438 -0
  51. createsonline/http/__init__.py +28 -0
  52. createsonline/http/client.py +535 -0
  53. createsonline/ml/__init__.py +55 -0
  54. createsonline/ml/classification.py +552 -0
  55. createsonline/ml/clustering.py +680 -0
  56. createsonline/ml/metrics.py +542 -0
  57. createsonline/ml/neural.py +560 -0
  58. createsonline/ml/preprocessing.py +784 -0
  59. createsonline/ml/regression.py +501 -0
  60. createsonline/performance/__init__.py +19 -0
  61. createsonline/performance/cache.py +444 -0
  62. createsonline/performance/compression.py +335 -0
  63. createsonline/performance/core.py +419 -0
  64. createsonline/project_init.py +789 -0
  65. createsonline/routing.py +528 -0
  66. createsonline/security/__init__.py +34 -0
  67. createsonline/security/core.py +811 -0
  68. createsonline/security/encryption.py +349 -0
  69. createsonline/server.py +295 -0
  70. createsonline/static/css/admin.css +263 -0
  71. createsonline/static/css/common.css +358 -0
  72. createsonline/static/css/dashboard.css +89 -0
  73. createsonline/static/favicon.ico +0 -0
  74. createsonline/static/icons/icon-128x128.png +0 -0
  75. createsonline/static/icons/icon-128x128.webp +0 -0
  76. createsonline/static/icons/icon-16x16.png +0 -0
  77. createsonline/static/icons/icon-16x16.webp +0 -0
  78. createsonline/static/icons/icon-180x180.png +0 -0
  79. createsonline/static/icons/icon-180x180.webp +0 -0
  80. createsonline/static/icons/icon-192x192.png +0 -0
  81. createsonline/static/icons/icon-192x192.webp +0 -0
  82. createsonline/static/icons/icon-256x256.png +0 -0
  83. createsonline/static/icons/icon-256x256.webp +0 -0
  84. createsonline/static/icons/icon-32x32.png +0 -0
  85. createsonline/static/icons/icon-32x32.webp +0 -0
  86. createsonline/static/icons/icon-384x384.png +0 -0
  87. createsonline/static/icons/icon-384x384.webp +0 -0
  88. createsonline/static/icons/icon-48x48.png +0 -0
  89. createsonline/static/icons/icon-48x48.webp +0 -0
  90. createsonline/static/icons/icon-512x512.png +0 -0
  91. createsonline/static/icons/icon-512x512.webp +0 -0
  92. createsonline/static/icons/icon-64x64.png +0 -0
  93. createsonline/static/icons/icon-64x64.webp +0 -0
  94. createsonline/static/image/android-chrome-192x192.png +0 -0
  95. createsonline/static/image/android-chrome-512x512.png +0 -0
  96. createsonline/static/image/apple-touch-icon.png +0 -0
  97. createsonline/static/image/favicon-16x16.png +0 -0
  98. createsonline/static/image/favicon-32x32.png +0 -0
  99. createsonline/static/image/favicon.ico +0 -0
  100. createsonline/static/image/favicon.svg +17 -0
  101. createsonline/static/image/icon-128x128.png +0 -0
  102. createsonline/static/image/icon-128x128.webp +0 -0
  103. createsonline/static/image/icon-16x16.png +0 -0
  104. createsonline/static/image/icon-16x16.webp +0 -0
  105. createsonline/static/image/icon-180x180.png +0 -0
  106. createsonline/static/image/icon-180x180.webp +0 -0
  107. createsonline/static/image/icon-192x192.png +0 -0
  108. createsonline/static/image/icon-192x192.webp +0 -0
  109. createsonline/static/image/icon-256x256.png +0 -0
  110. createsonline/static/image/icon-256x256.webp +0 -0
  111. createsonline/static/image/icon-32x32.png +0 -0
  112. createsonline/static/image/icon-32x32.webp +0 -0
  113. createsonline/static/image/icon-384x384.png +0 -0
  114. createsonline/static/image/icon-384x384.webp +0 -0
  115. createsonline/static/image/icon-48x48.png +0 -0
  116. createsonline/static/image/icon-48x48.webp +0 -0
  117. createsonline/static/image/icon-512x512.png +0 -0
  118. createsonline/static/image/icon-512x512.webp +0 -0
  119. createsonline/static/image/icon-64x64.png +0 -0
  120. createsonline/static/image/icon-64x64.webp +0 -0
  121. createsonline/static/image/logo-header-h100.png +0 -0
  122. createsonline/static/image/logo-header-h100.webp +0 -0
  123. createsonline/static/image/logo-header-h200@2x.png +0 -0
  124. createsonline/static/image/logo-header-h200@2x.webp +0 -0
  125. createsonline/static/image/logo.png +0 -0
  126. createsonline/static/js/admin.js +274 -0
  127. createsonline/static/site.webmanifest +35 -0
  128. createsonline/static/templates/admin/base.html +87 -0
  129. createsonline/static/templates/admin/dashboard.html +217 -0
  130. createsonline/static/templates/admin/model_form.html +270 -0
  131. createsonline/static/templates/admin/model_list.html +202 -0
  132. createsonline/static/test_script.js +15 -0
  133. createsonline/static/test_styles.css +59 -0
  134. createsonline/static_files.py +365 -0
  135. createsonline/templates/404.html +100 -0
  136. createsonline/templates/admin_login.html +169 -0
  137. createsonline/templates/base.html +102 -0
  138. createsonline/templates/index.html +151 -0
  139. createsonline/templates.py +205 -0
  140. createsonline/testing.py +322 -0
  141. createsonline/utils.py +448 -0
  142. createsonline/validation/__init__.py +49 -0
  143. createsonline/validation/fields.py +598 -0
  144. createsonline/validation/models.py +504 -0
  145. createsonline/validation/validators.py +561 -0
  146. createsonline/views.py +184 -0
  147. createsonline-0.1.26.dist-info/METADATA +46 -0
  148. createsonline-0.1.26.dist-info/RECORD +152 -0
  149. createsonline-0.1.26.dist-info/WHEEL +5 -0
  150. createsonline-0.1.26.dist-info/entry_points.txt +2 -0
  151. createsonline-0.1.26.dist-info/licenses/LICENSE +21 -0
  152. createsonline-0.1.26.dist-info/top_level.txt +1 -0
@@ -0,0 +1,535 @@
1
+ """
2
+ CREATESONLINE Internal HTTP Client Implementation
3
+
4
+ Pure Python HTTP client with zero external dependencies.
5
+ Supports sync/async operations, authentication, file uploads, and more.
6
+ """
7
+
8
+ import asyncio
9
+ import json
10
+ import ssl
11
+ import socket
12
+ import urllib.parse
13
+ import urllib.request
14
+ import urllib.error
15
+ from typing import Dict, Any, Optional, Union
16
+ import time
17
+
18
+
19
+ # Custom exception classes
20
+ class HTTPError(Exception):
21
+ """Base HTTP error"""
22
+ def __init__(self, message: str, status_code: Optional[int] = None, response: Optional['HTTPResponse'] = None):
23
+ super().__init__(message)
24
+ self.status_code = status_code
25
+ self.response = response
26
+
27
+
28
+ class ConnectionError(HTTPError):
29
+ """Connection failed"""
30
+ pass
31
+
32
+
33
+ class TimeoutError(HTTPError):
34
+ """Request timeout"""
35
+ pass
36
+
37
+
38
+ class RequestError(HTTPError):
39
+ """Invalid request"""
40
+ pass
41
+
42
+
43
+ class HTTPResponse:
44
+ """HTTP Response object"""
45
+
46
+ def __init__(
47
+ self,
48
+ status_code: int,
49
+ headers: Dict[str, str],
50
+ content: bytes,
51
+ url: str,
52
+ encoding: str = 'utf-8'
53
+ ):
54
+ self.status_code = status_code
55
+ self.headers = headers
56
+ self.content = content
57
+ self.url = url
58
+ self.encoding = encoding
59
+ self._json_cache = None
60
+
61
+ @property
62
+ def text(self) -> str:
63
+ """Get response as text"""
64
+ return self.content.decode(self.encoding, errors='replace')
65
+
66
+ def json(self) -> Dict[str, Any]:
67
+ """Parse response as JSON"""
68
+ if self._json_cache is None:
69
+ try:
70
+ self._json_cache = json.loads(self.text)
71
+ except json.JSONDecodeError as e:
72
+ raise HTTPError(f"Failed to parse JSON: {e}")
73
+ return self._json_cache
74
+
75
+ @property
76
+ def ok(self) -> bool:
77
+ """Check if response is successful (2xx status code)"""
78
+ return 200 <= self.status_code < 300
79
+
80
+ def raise_for_status(self):
81
+ """Raise HTTPError for bad responses"""
82
+ if not self.ok:
83
+ raise HTTPError(
84
+ f"HTTP {self.status_code} Error",
85
+ status_code=self.status_code,
86
+ response=self
87
+ )
88
+
89
+
90
+ class HTTPRequest:
91
+ """HTTP Request object"""
92
+
93
+ def __init__(
94
+ self,
95
+ method: str,
96
+ url: str,
97
+ headers: Optional[Dict[str, str]] = None,
98
+ data: Optional[Union[str, bytes, Dict[str, Any]]] = None,
99
+ json_data: Optional[Dict[str, Any]] = None,
100
+ files: Optional[Dict[str, Any]] = None,
101
+ params: Optional[Dict[str, Any]] = None,
102
+ auth: Optional[tuple] = None,
103
+ timeout: Optional[float] = None
104
+ ):
105
+ self.method = method.upper()
106
+ self.url = url
107
+ self.headers = headers or {}
108
+ self.data = data
109
+ self.json_data = json_data
110
+ self.files = files or {}
111
+ self.params = params or {}
112
+ self.auth = auth
113
+ self.timeout = timeout or 30.0
114
+
115
+ # Process URL with parameters
116
+ if self.params:
117
+ parsed = urllib.parse.urlparse(self.url)
118
+ query_params = urllib.parse.parse_qs(parsed.query)
119
+ query_params.update(self.params)
120
+ query_string = urllib.parse.urlencode(query_params, doseq=True)
121
+ self.url = urllib.parse.urlunparse((
122
+ parsed.scheme, parsed.netloc, parsed.path,
123
+ parsed.params, query_string, parsed.fragment
124
+ ))
125
+
126
+ # Set Content-Type for JSON
127
+ if self.json_data:
128
+ self.headers['Content-Type'] = 'application/json'
129
+ self.data = json.dumps(self.json_data).encode('utf-8')
130
+
131
+ # Handle authentication
132
+ if self.auth:
133
+ import base64
134
+ username, password = self.auth
135
+ credentials = base64.b64encode(f"{username}:{password}".encode()).decode()
136
+ self.headers['Authorization'] = f'Basic {credentials}'
137
+
138
+
139
+ class HTTPClient:
140
+ """Synchronous HTTP Client"""
141
+
142
+ def __init__(
143
+ self,
144
+ base_url: Optional[str] = None,
145
+ headers: Optional[Dict[str, str]] = None,
146
+ timeout: Optional[float] = 30.0,
147
+ verify_ssl: bool = True,
148
+ max_retries: int = 3,
149
+ retry_delay: float = 1.0
150
+ ):
151
+ self.base_url = base_url
152
+ self.default_headers = headers or {}
153
+ self.timeout = timeout
154
+ self.verify_ssl = verify_ssl
155
+ self.max_retries = max_retries
156
+ self.retry_delay = retry_delay
157
+
158
+ # Add User-Agent
159
+ self.default_headers.setdefault(
160
+ 'User-Agent',
161
+ 'CREATESONLINE-HTTP-Client/1.0'
162
+ )
163
+
164
+ def _build_url(self, url: str) -> str:
165
+ """Build full URL with base URL"""
166
+ if self.base_url and not url.startswith(('http://', 'https://')):
167
+ return urllib.parse.urljoin(self.base_url, url)
168
+ return url
169
+
170
+ def _prepare_headers(self, headers: Optional[Dict[str, str]]) -> Dict[str, str]:
171
+ """Merge default and request headers"""
172
+ final_headers = self.default_headers.copy()
173
+ if headers:
174
+ final_headers.update(headers)
175
+ return final_headers
176
+
177
+ def _make_request(self, request: HTTPRequest) -> HTTPResponse:
178
+ """Make the actual HTTP request"""
179
+ url = self._build_url(request.url)
180
+ headers = self._prepare_headers(request.headers)
181
+
182
+ # Create urllib request
183
+ req = urllib.request.Request(
184
+ url=url,
185
+ data=request.data if isinstance(request.data, bytes) else
186
+ request.data.encode('utf-8') if request.data else None,
187
+ headers=headers,
188
+ method=request.method
189
+ )
190
+
191
+ # Create SSL context if needed
192
+ ssl_context = None
193
+ if not self.verify_ssl:
194
+ ssl_context = ssl.create_default_context()
195
+ ssl_context.check_hostname = False
196
+ ssl_context.verify_mode = ssl.CERT_NONE
197
+
198
+ # Make request with retry logic
199
+ last_error = None
200
+ for attempt in range(self.max_retries + 1):
201
+ try:
202
+ with urllib.request.urlopen(
203
+ req,
204
+ timeout=request.timeout,
205
+ context=ssl_context
206
+ ) as response:
207
+ content = response.read()
208
+ status_code = response.getcode()
209
+ headers_dict = dict(response.headers)
210
+
211
+ return HTTPResponse(
212
+ status_code=status_code,
213
+ headers=headers_dict,
214
+ content=content,
215
+ url=url
216
+ )
217
+
218
+ except urllib.error.HTTPError as e:
219
+ # HTTP errors (4xx, 5xx) are not retried
220
+ content = e.read() if hasattr(e, 'read') else b''
221
+ return HTTPResponse(
222
+ status_code=e.code,
223
+ headers=dict(e.headers) if hasattr(e, 'headers') else {},
224
+ content=content,
225
+ url=url
226
+ )
227
+
228
+ except (urllib.error.URLError, socket.timeout, OSError) as e:
229
+ last_error = e
230
+ if attempt < self.max_retries:
231
+ time.sleep(self.retry_delay * (2 ** attempt)) # Exponential backoff
232
+ continue
233
+
234
+ # Convert to our exception types
235
+ if isinstance(e, socket.timeout):
236
+ raise TimeoutError(f"Request timeout after {request.timeout}s")
237
+ else:
238
+ raise ConnectionError(f"Connection failed: {e}")
239
+
240
+ # If we get here, all retries failed
241
+ raise ConnectionError(f"Max retries exceeded: {last_error}")
242
+
243
+ def request(
244
+ self,
245
+ method: str,
246
+ url: str,
247
+ **kwargs
248
+ ) -> HTTPResponse:
249
+ """Make HTTP request"""
250
+ request = HTTPRequest(method, url, **kwargs)
251
+ return self._make_request(request)
252
+
253
+ def get(self, url: str, **kwargs) -> HTTPResponse:
254
+ """HTTP GET request"""
255
+ return self.request('GET', url, **kwargs)
256
+
257
+ def post(self, url: str, **kwargs) -> HTTPResponse:
258
+ """HTTP POST request"""
259
+ return self.request('POST', url, **kwargs)
260
+
261
+ def put(self, url: str, **kwargs) -> HTTPResponse:
262
+ """HTTP PUT request"""
263
+ return self.request('PUT', url, **kwargs)
264
+
265
+ def delete(self, url: str, **kwargs) -> HTTPResponse:
266
+ """HTTP DELETE request"""
267
+ return self.request('DELETE', url, **kwargs)
268
+
269
+ def patch(self, url: str, **kwargs) -> HTTPResponse:
270
+ """HTTP PATCH request"""
271
+ return self.request('PATCH', url, **kwargs)
272
+
273
+ def head(self, url: str, **kwargs) -> HTTPResponse:
274
+ """HTTP HEAD request"""
275
+ return self.request('HEAD', url, **kwargs)
276
+
277
+ def options(self, url: str, **kwargs) -> HTTPResponse:
278
+ """HTTP OPTIONS request"""
279
+ return self.request('OPTIONS', url, **kwargs)
280
+
281
+
282
+ class AsyncHTTPClient:
283
+ """Asynchronous HTTP Client"""
284
+
285
+ def __init__(
286
+ self,
287
+ base_url: Optional[str] = None,
288
+ headers: Optional[Dict[str, str]] = None,
289
+ timeout: Optional[float] = 30.0,
290
+ verify_ssl: bool = True,
291
+ max_retries: int = 3,
292
+ retry_delay: float = 1.0,
293
+ max_connections: int = 100
294
+ ):
295
+ self.base_url = base_url
296
+ self.default_headers = headers or {}
297
+ self.timeout = timeout
298
+ self.verify_ssl = verify_ssl
299
+ self.max_retries = max_retries
300
+ self.retry_delay = retry_delay
301
+ self.max_connections = max_connections
302
+
303
+ # Add User-Agent
304
+ self.default_headers.setdefault(
305
+ 'User-Agent',
306
+ 'CREATESONLINE-Async-HTTP-Client/1.0'
307
+ )
308
+
309
+ # Connection semaphore for limiting concurrent connections
310
+ self._connection_semaphore = asyncio.Semaphore(max_connections)
311
+
312
+ def _build_url(self, url: str) -> str:
313
+ """Build full URL with base URL"""
314
+ if self.base_url and not url.startswith(('http://', 'https://')):
315
+ return urllib.parse.urljoin(self.base_url, url)
316
+ return url
317
+
318
+ def _prepare_headers(self, headers: Optional[Dict[str, str]]) -> Dict[str, str]:
319
+ """Merge default and request headers"""
320
+ final_headers = self.default_headers.copy()
321
+ if headers:
322
+ final_headers.update(headers)
323
+ return final_headers
324
+
325
+ async def _make_request(self, request: HTTPRequest) -> HTTPResponse:
326
+ """Make the actual async HTTP request"""
327
+ async with self._connection_semaphore:
328
+ url = self._build_url(request.url)
329
+ headers = self._prepare_headers(request.headers)
330
+
331
+ # Parse URL components
332
+ parsed = urllib.parse.urlparse(url)
333
+ host = parsed.hostname
334
+ port = parsed.port or (443 if parsed.scheme == 'https' else 80)
335
+ path = parsed.path or '/'
336
+ if parsed.query:
337
+ path += f'?{parsed.query}'
338
+
339
+ # Create SSL context if needed
340
+ ssl_context = None
341
+ if parsed.scheme == 'https':
342
+ ssl_context = ssl.create_default_context()
343
+ if not self.verify_ssl:
344
+ ssl_context.check_hostname = False
345
+ ssl_context.verify_mode = ssl.CERT_NONE
346
+
347
+ # Retry logic
348
+ last_error = None
349
+ for attempt in range(self.max_retries + 1):
350
+ try:
351
+ # Open connection
352
+ if parsed.scheme == 'https':
353
+ reader, writer = await asyncio.wait_for(
354
+ asyncio.open_connection(host, port, ssl=ssl_context),
355
+ timeout=request.timeout
356
+ )
357
+ else:
358
+ reader, writer = await asyncio.wait_for(
359
+ asyncio.open_connection(host, port),
360
+ timeout=request.timeout
361
+ )
362
+
363
+ try:
364
+ # Build HTTP request
365
+ http_request = f"{request.method} {path} HTTP/1.1\r\n"
366
+ http_request += f"Host: {host}\r\n"
367
+
368
+ for key, value in headers.items():
369
+ http_request += f"{key}: {value}\r\n"
370
+
371
+ if request.data:
372
+ content_length = len(request.data)
373
+ http_request += f"Content-Length: {content_length}\r\n"
374
+
375
+ http_request += "Connection: close\r\n"
376
+ http_request += "\r\n"
377
+
378
+ # Send request
379
+ writer.write(http_request.encode('utf-8'))
380
+ if request.data:
381
+ writer.write(request.data)
382
+ await writer.drain()
383
+
384
+ # Read response
385
+ response_data = await asyncio.wait_for(
386
+ reader.read(),
387
+ timeout=request.timeout
388
+ )
389
+
390
+ # Parse HTTP response
391
+ response_lines = response_data.decode('utf-8', errors='replace').split('\r\n')
392
+ status_line = response_lines[0]
393
+ status_code = int(status_line.split()[1])
394
+
395
+ # Parse headers
396
+ response_headers = {}
397
+ body_start = 0
398
+ for i, line in enumerate(response_lines[1:], 1):
399
+ if line == '':
400
+ body_start = i + 1
401
+ break
402
+ if ':' in line:
403
+ key, value = line.split(':', 1)
404
+ response_headers[key.strip()] = value.strip()
405
+
406
+ # Get body
407
+ body_text = '\r\n'.join(response_lines[body_start:])
408
+ content = body_text.encode('utf-8')
409
+
410
+ return HTTPResponse(
411
+ status_code=status_code,
412
+ headers=response_headers,
413
+ content=content,
414
+ url=url
415
+ )
416
+
417
+ finally:
418
+ writer.close()
419
+ await writer.wait_closed()
420
+
421
+ except (asyncio.TimeoutError, OSError, ConnectionResetError) as e:
422
+ last_error = e
423
+ if attempt < self.max_retries:
424
+ await asyncio.sleep(self.retry_delay * (2 ** attempt))
425
+ continue
426
+
427
+ # Convert to our exception types
428
+ if isinstance(e, asyncio.TimeoutError):
429
+ raise TimeoutError(f"Request timeout after {request.timeout}s")
430
+ else:
431
+ raise ConnectionError(f"Connection failed: {e}")
432
+
433
+ # If we get here, all retries failed
434
+ raise ConnectionError(f"Max retries exceeded: {last_error}")
435
+
436
+ async def request(
437
+ self,
438
+ method: str,
439
+ url: str,
440
+ **kwargs
441
+ ) -> HTTPResponse:
442
+ """Make async HTTP request"""
443
+ request = HTTPRequest(method, url, **kwargs)
444
+ return await self._make_request(request)
445
+
446
+ async def get(self, url: str, **kwargs) -> HTTPResponse:
447
+ """Async HTTP GET request"""
448
+ return await self.request('GET', url, **kwargs)
449
+
450
+ async def post(self, url: str, **kwargs) -> HTTPResponse:
451
+ """Async HTTP POST request"""
452
+ return await self.request('POST', url, **kwargs)
453
+
454
+ async def put(self, url: str, **kwargs) -> HTTPResponse:
455
+ """Async HTTP PUT request"""
456
+ return await self.request('PUT', url, **kwargs)
457
+
458
+ async def delete(self, url: str, **kwargs) -> HTTPResponse:
459
+ """Async HTTP DELETE request"""
460
+ return await self.request('DELETE', url, **kwargs)
461
+
462
+ async def patch(self, url: str, **kwargs) -> HTTPResponse:
463
+ """Async HTTP PATCH request"""
464
+ return await self.request('PATCH', url, **kwargs)
465
+
466
+ async def head(self, url: str, **kwargs) -> HTTPResponse:
467
+ """Async HTTP HEAD request"""
468
+ return await self.request('HEAD', url, **kwargs)
469
+
470
+ async def options(self, url: str, **kwargs) -> HTTPResponse:
471
+ """Async HTTP OPTIONS request"""
472
+ return await self.request('OPTIONS', url, **kwargs)
473
+
474
+ async def close(self):
475
+ """Close the client and cleanup resources"""
476
+ # In a more sophisticated implementation, we'd track open connections
477
+ # and close them here. For now, connections are closed after each request.
478
+ pass
479
+
480
+ async def __aenter__(self):
481
+ """Async context manager entry"""
482
+ return self
483
+
484
+ async def __aexit__(self, exc_type, exc_val, exc_tb):
485
+ """Async context manager exit"""
486
+ await self.close()
487
+
488
+
489
+ # Convenience functions for quick HTTP requests
490
+ def get(url: str, **kwargs) -> HTTPResponse:
491
+ """Quick HTTP GET request"""
492
+ client = HTTPClient()
493
+ return client.get(url, **kwargs)
494
+
495
+
496
+ def post(url: str, **kwargs) -> HTTPResponse:
497
+ """Quick HTTP POST request"""
498
+ client = HTTPClient()
499
+ return client.post(url, **kwargs)
500
+
501
+
502
+ def put(url: str, **kwargs) -> HTTPResponse:
503
+ """Quick HTTP PUT request"""
504
+ client = HTTPClient()
505
+ return client.put(url, **kwargs)
506
+
507
+
508
+ def delete(url: str, **kwargs) -> HTTPResponse:
509
+ """Quick HTTP DELETE request"""
510
+ client = HTTPClient()
511
+ return client.delete(url, **kwargs)
512
+
513
+
514
+ async def async_get(url: str, **kwargs) -> HTTPResponse:
515
+ """Quick async HTTP GET request"""
516
+ async with AsyncHTTPClient() as client:
517
+ return await client.get(url, **kwargs)
518
+
519
+
520
+ async def async_post(url: str, **kwargs) -> HTTPResponse:
521
+ """Quick async HTTP POST request"""
522
+ async with AsyncHTTPClient() as client:
523
+ return await client.post(url, **kwargs)
524
+
525
+
526
+ async def async_put(url: str, **kwargs) -> HTTPResponse:
527
+ """Quick async HTTP PUT request"""
528
+ async with AsyncHTTPClient() as client:
529
+ return await client.put(url, **kwargs)
530
+
531
+
532
+ async def async_delete(url: str, **kwargs) -> HTTPResponse:
533
+ """Quick async HTTP DELETE request"""
534
+ async with AsyncHTTPClient() as client:
535
+ return await client.delete(url, **kwargs)
@@ -0,0 +1,55 @@
1
+ """
2
+ CREATESONLINE Internal Machine Learning Module
3
+
4
+ Pure Python ML algorithms with zero external dependencies (except numpy).
5
+ Lightweight replacement for scikit-learn with AI-native features.
6
+ """
7
+
8
+ from .regression import LinearRegression, LogisticRegression
9
+ from .classification import DecisionTreeClassifier, KNearestNeighbors
10
+ from .clustering import KMeans, DBScan
11
+ from .metrics import (
12
+ accuracy_score, precision_score, recall_score, f1_score,
13
+ mean_squared_error, mean_absolute_error, r2_score,
14
+ confusion_matrix, classification_report
15
+ )
16
+ from .preprocessing import (
17
+ StandardScaler, MinMaxScaler, LabelEncoder,
18
+ train_test_split, cross_validate
19
+ )
20
+ from .neural import NeuralNetwork
21
+
22
+ __all__ = [
23
+ # Regression
24
+ 'LinearRegression',
25
+ 'LogisticRegression',
26
+
27
+ # Classification
28
+ 'DecisionTreeClassifier',
29
+ 'KNearestNeighbors',
30
+
31
+ # Clustering
32
+ 'KMeans',
33
+ 'DBScan',
34
+
35
+ # Metrics
36
+ 'accuracy_score',
37
+ 'precision_score',
38
+ 'recall_score',
39
+ 'f1_score',
40
+ 'mean_squared_error',
41
+ 'mean_absolute_error',
42
+ 'r2_score',
43
+ 'confusion_matrix',
44
+ 'classification_report',
45
+
46
+ # Preprocessing
47
+ 'StandardScaler',
48
+ 'MinMaxScaler',
49
+ 'LabelEncoder',
50
+ 'train_test_split',
51
+ 'cross_validate',
52
+
53
+ # Neural Networks
54
+ 'NeuralNetwork'
55
+ ]