zexus 1.6.2

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 (227) hide show
  1. package/LICENSE +0 -0
  2. package/README.md +2513 -0
  3. package/bin/zexus +2 -0
  4. package/bin/zpics +2 -0
  5. package/bin/zpm +2 -0
  6. package/bin/zx +2 -0
  7. package/bin/zx-deploy +2 -0
  8. package/bin/zx-dev +2 -0
  9. package/bin/zx-run +2 -0
  10. package/package.json +66 -0
  11. package/scripts/README.md +24 -0
  12. package/scripts/postinstall.js +44 -0
  13. package/shared_config.json +24 -0
  14. package/src/README.md +1525 -0
  15. package/src/tests/run_zexus_tests.py +117 -0
  16. package/src/tests/test_all_phases.zx +346 -0
  17. package/src/tests/test_blockchain_features.zx +306 -0
  18. package/src/tests/test_complexity_features.zx +321 -0
  19. package/src/tests/test_core_integration.py +185 -0
  20. package/src/tests/test_phase10_ecosystem.zx +177 -0
  21. package/src/tests/test_phase1_modifiers.zx +87 -0
  22. package/src/tests/test_phase2_plugins.zx +80 -0
  23. package/src/tests/test_phase3_security.zx +97 -0
  24. package/src/tests/test_phase4_vfs.zx +116 -0
  25. package/src/tests/test_phase5_types.zx +117 -0
  26. package/src/tests/test_phase6_metaprogramming.zx +125 -0
  27. package/src/tests/test_phase7_optimization.zx +132 -0
  28. package/src/tests/test_phase9_advanced_types.zx +157 -0
  29. package/src/tests/test_security_features.py +419 -0
  30. package/src/tests/test_security_features.zx +276 -0
  31. package/src/tests/test_simple_zx.zx +1 -0
  32. package/src/tests/test_verification_simple.zx +69 -0
  33. package/src/zexus/__init__.py +28 -0
  34. package/src/zexus/__main__.py +5 -0
  35. package/src/zexus/__pycache__/__init__.cpython-312.pyc +0 -0
  36. package/src/zexus/__pycache__/advanced_types.cpython-312.pyc +0 -0
  37. package/src/zexus/__pycache__/builtin_modules.cpython-312.pyc +0 -0
  38. package/src/zexus/__pycache__/capability_system.cpython-312.pyc +0 -0
  39. package/src/zexus/__pycache__/complexity_system.cpython-312.pyc +0 -0
  40. package/src/zexus/__pycache__/concurrency_system.cpython-312.pyc +0 -0
  41. package/src/zexus/__pycache__/config.cpython-312.pyc +0 -0
  42. package/src/zexus/__pycache__/dependency_injection.cpython-312.pyc +0 -0
  43. package/src/zexus/__pycache__/ecosystem.cpython-312.pyc +0 -0
  44. package/src/zexus/__pycache__/environment.cpython-312.pyc +0 -0
  45. package/src/zexus/__pycache__/error_reporter.cpython-312.pyc +0 -0
  46. package/src/zexus/__pycache__/hybrid_orchestrator.cpython-312.pyc +0 -0
  47. package/src/zexus/__pycache__/lexer.cpython-312.pyc +0 -0
  48. package/src/zexus/__pycache__/metaprogramming.cpython-312.pyc +0 -0
  49. package/src/zexus/__pycache__/module_cache.cpython-312.pyc +0 -0
  50. package/src/zexus/__pycache__/object.cpython-312.pyc +0 -0
  51. package/src/zexus/__pycache__/optimization.cpython-312.pyc +0 -0
  52. package/src/zexus/__pycache__/plugin_system.cpython-312.pyc +0 -0
  53. package/src/zexus/__pycache__/policy_engine.cpython-312.pyc +0 -0
  54. package/src/zexus/__pycache__/security.cpython-312.pyc +0 -0
  55. package/src/zexus/__pycache__/stdlib_integration.cpython-312.pyc +0 -0
  56. package/src/zexus/__pycache__/strategy_recovery.cpython-312.pyc +0 -0
  57. package/src/zexus/__pycache__/syntax_validator.cpython-312.pyc +0 -0
  58. package/src/zexus/__pycache__/type_system.cpython-312.pyc +0 -0
  59. package/src/zexus/__pycache__/virtual_filesystem.cpython-312.pyc +0 -0
  60. package/src/zexus/__pycache__/zexus_ast.cpython-312.pyc +0 -0
  61. package/src/zexus/__pycache__/zexus_token.cpython-312.pyc +0 -0
  62. package/src/zexus/advanced_types.py +401 -0
  63. package/src/zexus/blockchain/__init__.py +40 -0
  64. package/src/zexus/blockchain/__pycache__/__init__.cpython-312.pyc +0 -0
  65. package/src/zexus/blockchain/__pycache__/crypto.cpython-312.pyc +0 -0
  66. package/src/zexus/blockchain/__pycache__/ledger.cpython-312.pyc +0 -0
  67. package/src/zexus/blockchain/__pycache__/transaction.cpython-312.pyc +0 -0
  68. package/src/zexus/blockchain/crypto.py +463 -0
  69. package/src/zexus/blockchain/ledger.py +255 -0
  70. package/src/zexus/blockchain/transaction.py +267 -0
  71. package/src/zexus/builtin_modules.py +284 -0
  72. package/src/zexus/builtin_plugins.py +317 -0
  73. package/src/zexus/capability_system.py +372 -0
  74. package/src/zexus/cli/__init__.py +2 -0
  75. package/src/zexus/cli/__pycache__/__init__.cpython-312.pyc +0 -0
  76. package/src/zexus/cli/__pycache__/main.cpython-312.pyc +0 -0
  77. package/src/zexus/cli/main.py +707 -0
  78. package/src/zexus/cli/zpm.py +203 -0
  79. package/src/zexus/compare_interpreter_compiler.py +146 -0
  80. package/src/zexus/compiler/__init__.py +169 -0
  81. package/src/zexus/compiler/__pycache__/__init__.cpython-312.pyc +0 -0
  82. package/src/zexus/compiler/__pycache__/lexer.cpython-312.pyc +0 -0
  83. package/src/zexus/compiler/__pycache__/parser.cpython-312.pyc +0 -0
  84. package/src/zexus/compiler/__pycache__/zexus_ast.cpython-312.pyc +0 -0
  85. package/src/zexus/compiler/bytecode.py +266 -0
  86. package/src/zexus/compiler/compat_runtime.py +277 -0
  87. package/src/zexus/compiler/lexer.py +257 -0
  88. package/src/zexus/compiler/parser.py +779 -0
  89. package/src/zexus/compiler/semantic.py +118 -0
  90. package/src/zexus/compiler/zexus_ast.py +454 -0
  91. package/src/zexus/complexity_system.py +575 -0
  92. package/src/zexus/concurrency_system.py +493 -0
  93. package/src/zexus/config.py +201 -0
  94. package/src/zexus/crypto_bridge.py +19 -0
  95. package/src/zexus/dependency_injection.py +423 -0
  96. package/src/zexus/ecosystem.py +434 -0
  97. package/src/zexus/environment.py +101 -0
  98. package/src/zexus/environment_manager.py +119 -0
  99. package/src/zexus/error_reporter.py +314 -0
  100. package/src/zexus/evaluator/__init__.py +12 -0
  101. package/src/zexus/evaluator/__pycache__/__init__.cpython-312.pyc +0 -0
  102. package/src/zexus/evaluator/__pycache__/bytecode_compiler.cpython-312.pyc +0 -0
  103. package/src/zexus/evaluator/__pycache__/core.cpython-312.pyc +0 -0
  104. package/src/zexus/evaluator/__pycache__/expressions.cpython-312.pyc +0 -0
  105. package/src/zexus/evaluator/__pycache__/functions.cpython-312.pyc +0 -0
  106. package/src/zexus/evaluator/__pycache__/integration.cpython-312.pyc +0 -0
  107. package/src/zexus/evaluator/__pycache__/statements.cpython-312.pyc +0 -0
  108. package/src/zexus/evaluator/__pycache__/utils.cpython-312.pyc +0 -0
  109. package/src/zexus/evaluator/bytecode_compiler.py +700 -0
  110. package/src/zexus/evaluator/core.py +891 -0
  111. package/src/zexus/evaluator/expressions.py +827 -0
  112. package/src/zexus/evaluator/functions.py +3989 -0
  113. package/src/zexus/evaluator/integration.py +396 -0
  114. package/src/zexus/evaluator/statements.py +4303 -0
  115. package/src/zexus/evaluator/utils.py +126 -0
  116. package/src/zexus/evaluator_original.py +2041 -0
  117. package/src/zexus/external_bridge.py +16 -0
  118. package/src/zexus/find_affected_imports.sh +155 -0
  119. package/src/zexus/hybrid_orchestrator.py +152 -0
  120. package/src/zexus/input_validation.py +259 -0
  121. package/src/zexus/lexer.py +571 -0
  122. package/src/zexus/logging.py +89 -0
  123. package/src/zexus/lsp/__init__.py +9 -0
  124. package/src/zexus/lsp/completion_provider.py +207 -0
  125. package/src/zexus/lsp/definition_provider.py +22 -0
  126. package/src/zexus/lsp/hover_provider.py +71 -0
  127. package/src/zexus/lsp/server.py +269 -0
  128. package/src/zexus/lsp/symbol_provider.py +31 -0
  129. package/src/zexus/metaprogramming.py +321 -0
  130. package/src/zexus/module_cache.py +89 -0
  131. package/src/zexus/module_manager.py +107 -0
  132. package/src/zexus/object.py +973 -0
  133. package/src/zexus/optimization.py +424 -0
  134. package/src/zexus/parser/__init__.py +31 -0
  135. package/src/zexus/parser/__pycache__/__init__.cpython-312.pyc +0 -0
  136. package/src/zexus/parser/__pycache__/parser.cpython-312.pyc +0 -0
  137. package/src/zexus/parser/__pycache__/strategy_context.cpython-312.pyc +0 -0
  138. package/src/zexus/parser/__pycache__/strategy_structural.cpython-312.pyc +0 -0
  139. package/src/zexus/parser/integration.py +86 -0
  140. package/src/zexus/parser/parser.py +3977 -0
  141. package/src/zexus/parser/strategy_context.py +7254 -0
  142. package/src/zexus/parser/strategy_structural.py +1033 -0
  143. package/src/zexus/persistence.py +391 -0
  144. package/src/zexus/plugin_system.py +290 -0
  145. package/src/zexus/policy_engine.py +365 -0
  146. package/src/zexus/profiler/__init__.py +5 -0
  147. package/src/zexus/profiler/profiler.py +233 -0
  148. package/src/zexus/purity_system.py +398 -0
  149. package/src/zexus/runtime/__init__.py +20 -0
  150. package/src/zexus/runtime/async_runtime.py +324 -0
  151. package/src/zexus/search_old_imports.sh +65 -0
  152. package/src/zexus/security.py +1407 -0
  153. package/src/zexus/stack_trace.py +233 -0
  154. package/src/zexus/stdlib/__init__.py +27 -0
  155. package/src/zexus/stdlib/blockchain.py +341 -0
  156. package/src/zexus/stdlib/compression.py +167 -0
  157. package/src/zexus/stdlib/crypto.py +124 -0
  158. package/src/zexus/stdlib/datetime.py +163 -0
  159. package/src/zexus/stdlib/db_mongo.py +199 -0
  160. package/src/zexus/stdlib/db_mysql.py +162 -0
  161. package/src/zexus/stdlib/db_postgres.py +163 -0
  162. package/src/zexus/stdlib/db_sqlite.py +133 -0
  163. package/src/zexus/stdlib/encoding.py +230 -0
  164. package/src/zexus/stdlib/fs.py +195 -0
  165. package/src/zexus/stdlib/http.py +219 -0
  166. package/src/zexus/stdlib/http_server.py +248 -0
  167. package/src/zexus/stdlib/json_module.py +61 -0
  168. package/src/zexus/stdlib/math.py +360 -0
  169. package/src/zexus/stdlib/os_module.py +265 -0
  170. package/src/zexus/stdlib/regex.py +148 -0
  171. package/src/zexus/stdlib/sockets.py +253 -0
  172. package/src/zexus/stdlib/test_framework.zx +208 -0
  173. package/src/zexus/stdlib/test_runner.zx +119 -0
  174. package/src/zexus/stdlib_integration.py +341 -0
  175. package/src/zexus/strategy_recovery.py +256 -0
  176. package/src/zexus/syntax_validator.py +356 -0
  177. package/src/zexus/testing/zpics.py +407 -0
  178. package/src/zexus/testing/zpics_runtime.py +369 -0
  179. package/src/zexus/type_system.py +374 -0
  180. package/src/zexus/validation_system.py +569 -0
  181. package/src/zexus/virtual_filesystem.py +355 -0
  182. package/src/zexus/vm/__init__.py +8 -0
  183. package/src/zexus/vm/__pycache__/__init__.cpython-312.pyc +0 -0
  184. package/src/zexus/vm/__pycache__/async_optimizer.cpython-312.pyc +0 -0
  185. package/src/zexus/vm/__pycache__/bytecode.cpython-312.pyc +0 -0
  186. package/src/zexus/vm/__pycache__/cache.cpython-312.pyc +0 -0
  187. package/src/zexus/vm/__pycache__/jit.cpython-312.pyc +0 -0
  188. package/src/zexus/vm/__pycache__/memory_manager.cpython-312.pyc +0 -0
  189. package/src/zexus/vm/__pycache__/memory_pool.cpython-312.pyc +0 -0
  190. package/src/zexus/vm/__pycache__/optimizer.cpython-312.pyc +0 -0
  191. package/src/zexus/vm/__pycache__/parallel_vm.cpython-312.pyc +0 -0
  192. package/src/zexus/vm/__pycache__/peephole_optimizer.cpython-312.pyc +0 -0
  193. package/src/zexus/vm/__pycache__/profiler.cpython-312.pyc +0 -0
  194. package/src/zexus/vm/__pycache__/register_allocator.cpython-312.pyc +0 -0
  195. package/src/zexus/vm/__pycache__/register_vm.cpython-312.pyc +0 -0
  196. package/src/zexus/vm/__pycache__/ssa_converter.cpython-312.pyc +0 -0
  197. package/src/zexus/vm/__pycache__/vm.cpython-312.pyc +0 -0
  198. package/src/zexus/vm/async_optimizer.py +420 -0
  199. package/src/zexus/vm/bytecode.py +428 -0
  200. package/src/zexus/vm/bytecode_converter.py +297 -0
  201. package/src/zexus/vm/cache.py +532 -0
  202. package/src/zexus/vm/jit.py +720 -0
  203. package/src/zexus/vm/memory_manager.py +520 -0
  204. package/src/zexus/vm/memory_pool.py +511 -0
  205. package/src/zexus/vm/optimizer.py +478 -0
  206. package/src/zexus/vm/parallel_vm.py +899 -0
  207. package/src/zexus/vm/peephole_optimizer.py +452 -0
  208. package/src/zexus/vm/profiler.py +527 -0
  209. package/src/zexus/vm/register_allocator.py +462 -0
  210. package/src/zexus/vm/register_vm.py +520 -0
  211. package/src/zexus/vm/ssa_converter.py +757 -0
  212. package/src/zexus/vm/vm.py +1392 -0
  213. package/src/zexus/zexus_ast.py +1782 -0
  214. package/src/zexus/zexus_token.py +253 -0
  215. package/src/zexus/zpm/__init__.py +15 -0
  216. package/src/zexus/zpm/installer.py +116 -0
  217. package/src/zexus/zpm/package_manager.py +208 -0
  218. package/src/zexus/zpm/publisher.py +98 -0
  219. package/src/zexus/zpm/registry.py +110 -0
  220. package/src/zexus.egg-info/PKG-INFO +2235 -0
  221. package/src/zexus.egg-info/SOURCES.txt +876 -0
  222. package/src/zexus.egg-info/dependency_links.txt +1 -0
  223. package/src/zexus.egg-info/entry_points.txt +3 -0
  224. package/src/zexus.egg-info/not-zip-safe +1 -0
  225. package/src/zexus.egg-info/requires.txt +14 -0
  226. package/src/zexus.egg-info/top_level.txt +2 -0
  227. package/zexus.json +14 -0
@@ -0,0 +1,195 @@
1
+ """File System module for Zexus standard library."""
2
+
3
+ import os
4
+ import shutil
5
+ import glob as glob_module
6
+ from pathlib import Path
7
+ from typing import List, Dict, Any
8
+
9
+
10
+ class FileSystemModule:
11
+ """Provides file system operations."""
12
+
13
+ @staticmethod
14
+ def read_file(path: str, encoding: str = 'utf-8') -> str:
15
+ """Read entire file as text."""
16
+ with open(path, 'r', encoding=encoding) as f:
17
+ return f.read()
18
+
19
+ @staticmethod
20
+ def write_file(path: str, content: str, encoding: str = 'utf-8') -> None:
21
+ """Write text to file."""
22
+ # Create parent directory if it doesn't exist
23
+ Path(path).parent.mkdir(parents=True, exist_ok=True)
24
+ with open(path, 'w', encoding=encoding) as f:
25
+ f.write(content)
26
+
27
+ @staticmethod
28
+ def append_file(path: str, content: str, encoding: str = 'utf-8') -> None:
29
+ """Append text to file."""
30
+ # Create parent directory if it doesn't exist (for consistency with write_file)
31
+ Path(path).parent.mkdir(parents=True, exist_ok=True)
32
+ with open(path, 'a', encoding=encoding) as f:
33
+ f.write(content)
34
+
35
+ @staticmethod
36
+ def read_binary(path: str) -> bytes:
37
+ """Read file as binary."""
38
+ with open(path, 'rb') as f:
39
+ return f.read()
40
+
41
+ @staticmethod
42
+ def write_binary(path: str, data: bytes) -> None:
43
+ """Write binary data to file."""
44
+ Path(path).parent.mkdir(parents=True, exist_ok=True)
45
+ with open(path, 'wb') as f:
46
+ f.write(data)
47
+
48
+ @staticmethod
49
+ def exists(path: str) -> bool:
50
+ """Check if file or directory exists."""
51
+ return os.path.exists(path)
52
+
53
+ @staticmethod
54
+ def is_file(path: str) -> bool:
55
+ """Check if path is a file."""
56
+ return os.path.isfile(path)
57
+
58
+ @staticmethod
59
+ def is_dir(path: str) -> bool:
60
+ """Check if path is a directory."""
61
+ return os.path.isdir(path)
62
+
63
+ @staticmethod
64
+ def mkdir(path: str, parents: bool = True) -> None:
65
+ """Create directory."""
66
+ Path(path).mkdir(parents=parents, exist_ok=True)
67
+
68
+ @staticmethod
69
+ def rmdir(path: str, recursive: bool = False) -> None:
70
+ """Remove directory."""
71
+ if recursive:
72
+ shutil.rmtree(path)
73
+ else:
74
+ os.rmdir(path)
75
+
76
+ @staticmethod
77
+ def remove(path: str) -> None:
78
+ """Remove file."""
79
+ os.remove(path)
80
+
81
+ @staticmethod
82
+ def rename(old_path: str, new_path: str) -> None:
83
+ """Rename/move file or directory."""
84
+ os.rename(old_path, new_path)
85
+
86
+ @staticmethod
87
+ def copy_file(src: str, dst: str) -> None:
88
+ """Copy file."""
89
+ shutil.copy2(src, dst)
90
+
91
+ @staticmethod
92
+ def copy_dir(src: str, dst: str) -> None:
93
+ """Copy directory recursively."""
94
+ shutil.copytree(src, dst)
95
+
96
+ @staticmethod
97
+ def list_dir(path: str = '.') -> List[str]:
98
+ """List directory contents."""
99
+ return os.listdir(path)
100
+
101
+ @staticmethod
102
+ def walk(path: str) -> List[Dict[str, Any]]:
103
+ """Walk directory tree."""
104
+ result = []
105
+ for root, dirs, files in os.walk(path):
106
+ result.append({
107
+ 'root': root,
108
+ 'dirs': dirs,
109
+ 'files': files
110
+ })
111
+ return result
112
+
113
+ @staticmethod
114
+ def glob(pattern: str, recursive: bool = False) -> List[str]:
115
+ """Find files matching pattern."""
116
+ return glob_module.glob(pattern, recursive=recursive)
117
+
118
+ @staticmethod
119
+ def get_size(path: str) -> int:
120
+ """Get file size in bytes."""
121
+ return os.path.getsize(path)
122
+
123
+ @staticmethod
124
+ def get_cwd() -> str:
125
+ """Get current working directory."""
126
+ return os.getcwd()
127
+
128
+ @staticmethod
129
+ def chdir(path: str) -> None:
130
+ """Change current working directory."""
131
+ os.chdir(path)
132
+
133
+ @staticmethod
134
+ def abs_path(path: str) -> str:
135
+ """Get absolute path."""
136
+ return os.path.abspath(path)
137
+
138
+ @staticmethod
139
+ def join(*paths: str) -> str:
140
+ """Join path components."""
141
+ return os.path.join(*paths)
142
+
143
+ @staticmethod
144
+ def basename(path: str) -> str:
145
+ """Get file name from path."""
146
+ return os.path.basename(path)
147
+
148
+ @staticmethod
149
+ def dirname(path: str) -> str:
150
+ """Get directory name from path."""
151
+ return os.path.dirname(path)
152
+
153
+ @staticmethod
154
+ def splitext(path: str) -> tuple:
155
+ """Split file extension."""
156
+ return os.path.splitext(path)
157
+
158
+ @staticmethod
159
+ def get_stat(path: str) -> Dict[str, Any]:
160
+ """Get file statistics."""
161
+ stat = os.stat(path)
162
+ return {
163
+ 'size': stat.st_size,
164
+ 'atime': stat.st_atime,
165
+ 'mtime': stat.st_mtime,
166
+ 'ctime': stat.st_ctime,
167
+ 'mode': stat.st_mode,
168
+ }
169
+
170
+
171
+ # Export functions for easy access
172
+ read_file = FileSystemModule.read_file
173
+ write_file = FileSystemModule.write_file
174
+ append_file = FileSystemModule.append_file
175
+ exists = FileSystemModule.exists
176
+ is_file = FileSystemModule.is_file
177
+ is_dir = FileSystemModule.is_dir
178
+ mkdir = FileSystemModule.mkdir
179
+ rmdir = FileSystemModule.rmdir
180
+ remove = FileSystemModule.remove
181
+ rename = FileSystemModule.rename
182
+ copy_file = FileSystemModule.copy_file
183
+ copy_dir = FileSystemModule.copy_dir
184
+ list_dir = FileSystemModule.list_dir
185
+ walk = FileSystemModule.walk
186
+ glob = FileSystemModule.glob
187
+ get_size = FileSystemModule.get_size
188
+ get_cwd = FileSystemModule.get_cwd
189
+ chdir = FileSystemModule.chdir
190
+ abs_path = FileSystemModule.abs_path
191
+ join = FileSystemModule.join
192
+ basename = FileSystemModule.basename
193
+ dirname = FileSystemModule.dirname
194
+ splitext = FileSystemModule.splitext
195
+ get_stat = FileSystemModule.get_stat
@@ -0,0 +1,219 @@
1
+ """HTTP module for Zexus standard library."""
2
+
3
+ import urllib.request
4
+ import urllib.parse
5
+ import urllib.error
6
+ import json as json_lib
7
+ from typing import Dict, Any, Optional
8
+
9
+
10
+ class HttpModule:
11
+ """Provides HTTP client operations."""
12
+
13
+ @staticmethod
14
+ def get(url: str, headers: Optional[Dict[str, str]] = None, timeout: int = 30) -> Dict[str, Any]:
15
+ """Make HTTP GET request."""
16
+ if headers is None:
17
+ headers = {}
18
+
19
+ req = urllib.request.Request(url, headers=headers, method='GET')
20
+
21
+ try:
22
+ with urllib.request.urlopen(req, timeout=timeout) as response:
23
+ body = response.read().decode('utf-8')
24
+ return {
25
+ 'status': response.status,
26
+ 'headers': dict(response.headers),
27
+ 'body': body
28
+ }
29
+ except urllib.error.HTTPError as e:
30
+ try:
31
+ error_body = e.read().decode('utf-8')
32
+ except UnicodeDecodeError:
33
+ error_body = e.read().decode('utf-8', errors='replace')
34
+ return {
35
+ 'status': e.code,
36
+ 'headers': dict(e.headers),
37
+ 'body': error_body,
38
+ 'error': str(e)
39
+ }
40
+ except Exception as e:
41
+ return {
42
+ 'status': 0,
43
+ 'headers': {},
44
+ 'body': '',
45
+ 'error': str(e)
46
+ }
47
+
48
+ @staticmethod
49
+ def post(url: str, data: Any = None, headers: Optional[Dict[str, str]] = None,
50
+ json: bool = False, timeout: int = 30) -> Dict[str, Any]:
51
+ """Make HTTP POST request."""
52
+ if headers is None:
53
+ headers = {}
54
+
55
+ if json and data is not None:
56
+ data = json_lib.dumps(data).encode('utf-8')
57
+ headers['Content-Type'] = 'application/json'
58
+ elif isinstance(data, str):
59
+ data = data.encode('utf-8')
60
+ elif isinstance(data, dict):
61
+ data = urllib.parse.urlencode(data).encode('utf-8')
62
+
63
+ req = urllib.request.Request(url, data=data, headers=headers, method='POST')
64
+
65
+ try:
66
+ with urllib.request.urlopen(req, timeout=timeout) as response:
67
+ body = response.read().decode('utf-8')
68
+ return {
69
+ 'status': response.status,
70
+ 'headers': dict(response.headers),
71
+ 'body': body
72
+ }
73
+ except urllib.error.HTTPError as e:
74
+ try:
75
+ error_body = e.read().decode('utf-8')
76
+ except UnicodeDecodeError:
77
+ error_body = e.read().decode('utf-8', errors='replace')
78
+ return {
79
+ 'status': e.code,
80
+ 'headers': dict(e.headers),
81
+ 'body': error_body,
82
+ 'error': str(e)
83
+ }
84
+ except Exception as e:
85
+ return {
86
+ 'status': 0,
87
+ 'headers': {},
88
+ 'body': '',
89
+ 'error': str(e)
90
+ }
91
+
92
+ @staticmethod
93
+ def put(url: str, data: Any = None, headers: Optional[Dict[str, str]] = None,
94
+ json: bool = False, timeout: int = 30) -> Dict[str, Any]:
95
+ """Make HTTP PUT request."""
96
+ if headers is None:
97
+ headers = {}
98
+
99
+ if json and data is not None:
100
+ data = json_lib.dumps(data).encode('utf-8')
101
+ headers['Content-Type'] = 'application/json'
102
+ elif isinstance(data, str):
103
+ data = data.encode('utf-8')
104
+ elif isinstance(data, dict):
105
+ data = urllib.parse.urlencode(data).encode('utf-8')
106
+
107
+ req = urllib.request.Request(url, data=data, headers=headers, method='PUT')
108
+
109
+ try:
110
+ with urllib.request.urlopen(req, timeout=timeout) as response:
111
+ body = response.read().decode('utf-8')
112
+ return {
113
+ 'status': response.status,
114
+ 'headers': dict(response.headers),
115
+ 'body': body
116
+ }
117
+ except urllib.error.HTTPError as e:
118
+ try:
119
+ error_body = e.read().decode('utf-8')
120
+ except UnicodeDecodeError:
121
+ error_body = e.read().decode('utf-8', errors='replace')
122
+ return {
123
+ 'status': e.code,
124
+ 'headers': dict(e.headers),
125
+ 'body': error_body,
126
+ 'error': str(e)
127
+ }
128
+ except Exception as e:
129
+ return {
130
+ 'status': 0,
131
+ 'headers': {},
132
+ 'body': '',
133
+ 'error': str(e)
134
+ }
135
+
136
+ @staticmethod
137
+ def delete(url: str, headers: Optional[Dict[str, str]] = None, timeout: int = 30) -> Dict[str, Any]:
138
+ """Make HTTP DELETE request."""
139
+ if headers is None:
140
+ headers = {}
141
+
142
+ req = urllib.request.Request(url, headers=headers, method='DELETE')
143
+
144
+ try:
145
+ with urllib.request.urlopen(req, timeout=timeout) as response:
146
+ body = response.read().decode('utf-8')
147
+ return {
148
+ 'status': response.status,
149
+ 'headers': dict(response.headers),
150
+ 'body': body
151
+ }
152
+ except urllib.error.HTTPError as e:
153
+ try:
154
+ error_body = e.read().decode('utf-8')
155
+ except UnicodeDecodeError:
156
+ error_body = e.read().decode('utf-8', errors='replace')
157
+ return {
158
+ 'status': e.code,
159
+ 'headers': dict(e.headers),
160
+ 'body': error_body,
161
+ 'error': str(e)
162
+ }
163
+ except Exception as e:
164
+ return {
165
+ 'status': 0,
166
+ 'headers': {},
167
+ 'body': '',
168
+ 'error': str(e)
169
+ }
170
+
171
+ @staticmethod
172
+ def request(method: str, url: str, data: Any = None, headers: Optional[Dict[str, str]] = None,
173
+ timeout: int = 30) -> Dict[str, Any]:
174
+ """Make HTTP request with custom method."""
175
+ if headers is None:
176
+ headers = {}
177
+
178
+ if data is not None:
179
+ if isinstance(data, str):
180
+ data = data.encode('utf-8')
181
+ elif isinstance(data, dict):
182
+ data = urllib.parse.urlencode(data).encode('utf-8')
183
+
184
+ req = urllib.request.Request(url, data=data, headers=headers, method=method.upper())
185
+
186
+ try:
187
+ with urllib.request.urlopen(req, timeout=timeout) as response:
188
+ body = response.read().decode('utf-8')
189
+ return {
190
+ 'status': response.status,
191
+ 'headers': dict(response.headers),
192
+ 'body': body
193
+ }
194
+ except urllib.error.HTTPError as e:
195
+ try:
196
+ error_body = e.read().decode('utf-8')
197
+ except UnicodeDecodeError:
198
+ error_body = e.read().decode('utf-8', errors='replace')
199
+ return {
200
+ 'status': e.code,
201
+ 'headers': dict(e.headers),
202
+ 'body': error_body,
203
+ 'error': str(e)
204
+ }
205
+ except Exception as e:
206
+ return {
207
+ 'status': 0,
208
+ 'headers': {},
209
+ 'body': '',
210
+ 'error': str(e)
211
+ }
212
+
213
+
214
+ # Export functions for easy access
215
+ get = HttpModule.get
216
+ post = HttpModule.post
217
+ put = HttpModule.put
218
+ delete = HttpModule.delete
219
+ request = HttpModule.request
@@ -0,0 +1,248 @@
1
+ """HTTP Server module for Zexus standard library.
2
+ Built on top of the socket primitives."""
3
+
4
+ import socket
5
+ import threading
6
+ import re
7
+ from typing import Dict, List, Callable, Optional, Any, Tuple
8
+ from urllib.parse import parse_qs, urlparse
9
+
10
+
11
+ class HTTPRequest:
12
+ """Represents an HTTP request."""
13
+
14
+ def __init__(self, method: str, path: str, headers: Dict[str, str],
15
+ body: str, query: Dict[str, List[str]]):
16
+ self.method = method
17
+ self.path = path
18
+ self.headers = headers
19
+ self.body = body
20
+ self.query = query
21
+
22
+ def to_dict(self) -> Dict[str, Any]:
23
+ """Convert to dictionary for Zexus."""
24
+ return {
25
+ 'method': self.method,
26
+ 'path': self.path,
27
+ 'headers': self.headers,
28
+ 'body': self.body,
29
+ 'query': self.query
30
+ }
31
+
32
+
33
+ class HTTPResponse:
34
+ """Represents an HTTP response."""
35
+
36
+ def __init__(self):
37
+ self.status = 200
38
+ self.headers: Dict[str, str] = {'Content-Type': 'text/plain'}
39
+ self.body = ''
40
+
41
+ def set_status(self, code: int) -> 'HTTPResponse':
42
+ """Set response status code."""
43
+ self.status = code
44
+ return self
45
+
46
+ def set_header(self, name: str, value: str) -> 'HTTPResponse':
47
+ """Set response header."""
48
+ self.headers[name] = value
49
+ return self
50
+
51
+ def send(self, body: str) -> 'HTTPResponse':
52
+ """Set response body."""
53
+ self.body = body
54
+ return self
55
+
56
+ def json(self, data: Any) -> 'HTTPResponse':
57
+ """Send JSON response."""
58
+ import json
59
+ self.headers['Content-Type'] = 'application/json'
60
+ self.body = json.dumps(data)
61
+ return self
62
+
63
+ def build(self) -> str:
64
+ """Build HTTP response string."""
65
+ status_messages = {
66
+ 200: 'OK',
67
+ 201: 'Created',
68
+ 400: 'Bad Request',
69
+ 404: 'Not Found',
70
+ 500: 'Internal Server Error'
71
+ }
72
+
73
+ status_msg = status_messages.get(self.status, 'OK')
74
+ response = f"HTTP/1.1 {self.status} {status_msg}\r\n"
75
+
76
+ # Add Content-Length
77
+ self.headers['Content-Length'] = str(len(self.body.encode('utf-8')))
78
+
79
+ # Add headers
80
+ for name, value in self.headers.items():
81
+ response += f"{name}: {value}\r\n"
82
+
83
+ response += "\r\n"
84
+ response += self.body
85
+
86
+ return response
87
+
88
+
89
+ class HTTPServer:
90
+ """Simple HTTP server with routing."""
91
+
92
+ def __init__(self, host: str = '0.0.0.0', port: int = 8080):
93
+ self.host = host
94
+ self.port = port
95
+ self.routes: Dict[Tuple[str, str], Callable] = {} # (method, path) -> handler
96
+ self.socket: Optional[socket.socket] = None
97
+ self.running = False
98
+ self.thread: Optional[threading.Thread] = None
99
+
100
+ def route(self, method: str, path: str, handler: Callable):
101
+ """Register a route handler."""
102
+ self.routes[(method.upper(), path)] = handler
103
+
104
+ def get(self, path: str, handler: Callable):
105
+ """Register GET route."""
106
+ self.route('GET', path, handler)
107
+
108
+ def post(self, path: str, handler: Callable):
109
+ """Register POST route."""
110
+ self.route('POST', path, handler)
111
+
112
+ def put(self, path: str, handler: Callable):
113
+ """Register PUT route."""
114
+ self.route('PUT', path, handler)
115
+
116
+ def delete(self, path: str, handler: Callable):
117
+ """Register DELETE route."""
118
+ self.route('DELETE', path, handler)
119
+
120
+ def _parse_request(self, raw_request: str) -> Optional[HTTPRequest]:
121
+ """Parse raw HTTP request."""
122
+ try:
123
+ lines = raw_request.split('\r\n')
124
+ if not lines:
125
+ return None
126
+
127
+ # Parse request line
128
+ request_line = lines[0]
129
+ parts = request_line.split(' ')
130
+ if len(parts) < 3:
131
+ return None
132
+
133
+ method, full_path, _ = parts
134
+
135
+ # Parse path and query string
136
+ parsed = urlparse(full_path)
137
+ path = parsed.path
138
+ query = parse_qs(parsed.query)
139
+
140
+ # Parse headers
141
+ headers = {}
142
+ body_start = 0
143
+ for i, line in enumerate(lines[1:], 1):
144
+ if line == '':
145
+ body_start = i + 1
146
+ break
147
+ if ': ' in line:
148
+ name, value = line.split(': ', 1)
149
+ headers[name] = value
150
+
151
+ # Parse body
152
+ body = '\r\n'.join(lines[body_start:]) if body_start > 0 else ''
153
+
154
+ return HTTPRequest(method, path, headers, body, query)
155
+
156
+ except Exception as e:
157
+ print(f"Request parse error: {e}")
158
+ return None
159
+
160
+ def _handle_connection(self, client_socket: socket.socket, address: tuple):
161
+ """Handle a client connection."""
162
+ try:
163
+ # Receive request
164
+ raw_request = client_socket.recv(8192).decode('utf-8')
165
+
166
+ if not raw_request:
167
+ return
168
+
169
+ # Parse request
170
+ request = self._parse_request(raw_request)
171
+ if not request:
172
+ response = HTTPResponse().set_status(400).send("Bad Request")
173
+ client_socket.sendall(response.build().encode('utf-8'))
174
+ return
175
+
176
+ # Find matching route
177
+ route_key = (request.method, request.path)
178
+ handler = self.routes.get(route_key)
179
+
180
+ if not handler:
181
+ response = HTTPResponse().set_status(404).send("Not Found")
182
+ client_socket.sendall(response.build().encode('utf-8'))
183
+ return
184
+
185
+ # Create response object
186
+ response = HTTPResponse()
187
+
188
+ # Call handler
189
+ try:
190
+ handler(request, response)
191
+ except Exception as e:
192
+ print(f"Handler error: {e}")
193
+ response = HTTPResponse().set_status(500).send(f"Internal Server Error: {str(e)}")
194
+
195
+ # Send response
196
+ client_socket.sendall(response.build().encode('utf-8'))
197
+
198
+ except Exception as e:
199
+ print(f"Connection handler error: {e}")
200
+
201
+ finally:
202
+ try:
203
+ client_socket.close()
204
+ except:
205
+ pass
206
+
207
+ def listen(self):
208
+ """Start the HTTP server."""
209
+ if self.running:
210
+ raise RuntimeError("Server is already running")
211
+
212
+ self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
213
+ self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
214
+ self.socket.bind((self.host, self.port))
215
+ self.socket.listen(10)
216
+ self.running = True
217
+
218
+ print(f"HTTP Server listening on {self.host}:{self.port}")
219
+
220
+ # Accept connections
221
+ while self.running:
222
+ try:
223
+ self.socket.settimeout(1.0)
224
+ client_socket, address = self.socket.accept()
225
+
226
+ # Handle in new thread
227
+ handler_thread = threading.Thread(
228
+ target=self._handle_connection,
229
+ args=(client_socket, address),
230
+ daemon=True
231
+ )
232
+ handler_thread.start()
233
+
234
+ except socket.timeout:
235
+ continue
236
+ except Exception as e:
237
+ if self.running:
238
+ print(f"Accept error: {e}")
239
+ break
240
+
241
+ def stop(self):
242
+ """Stop the server."""
243
+ self.running = False
244
+ if self.socket:
245
+ try:
246
+ self.socket.close()
247
+ except:
248
+ pass