surrealdb-orm 0.1.3__py3-none-any.whl → 0.5.0__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 (51) hide show
  1. surreal_orm/__init__.py +78 -3
  2. surreal_orm/aggregations.py +164 -0
  3. surreal_orm/auth/__init__.py +15 -0
  4. surreal_orm/auth/access.py +167 -0
  5. surreal_orm/auth/mixins.py +302 -0
  6. surreal_orm/cli/__init__.py +15 -0
  7. surreal_orm/cli/commands.py +369 -0
  8. surreal_orm/connection_manager.py +58 -18
  9. surreal_orm/fields/__init__.py +36 -0
  10. surreal_orm/fields/encrypted.py +166 -0
  11. surreal_orm/fields/relation.py +465 -0
  12. surreal_orm/migrations/__init__.py +51 -0
  13. surreal_orm/migrations/executor.py +380 -0
  14. surreal_orm/migrations/generator.py +272 -0
  15. surreal_orm/migrations/introspector.py +305 -0
  16. surreal_orm/migrations/migration.py +188 -0
  17. surreal_orm/migrations/operations.py +531 -0
  18. surreal_orm/migrations/state.py +406 -0
  19. surreal_orm/model_base.py +594 -135
  20. surreal_orm/py.typed +0 -0
  21. surreal_orm/query_set.py +609 -34
  22. surreal_orm/relations.py +645 -0
  23. surreal_orm/surreal_function.py +95 -0
  24. surreal_orm/surreal_ql.py +113 -0
  25. surreal_orm/types.py +86 -0
  26. surreal_sdk/README.md +79 -0
  27. surreal_sdk/__init__.py +151 -0
  28. surreal_sdk/connection/__init__.py +17 -0
  29. surreal_sdk/connection/base.py +516 -0
  30. surreal_sdk/connection/http.py +421 -0
  31. surreal_sdk/connection/pool.py +244 -0
  32. surreal_sdk/connection/websocket.py +519 -0
  33. surreal_sdk/exceptions.py +71 -0
  34. surreal_sdk/functions.py +607 -0
  35. surreal_sdk/protocol/__init__.py +13 -0
  36. surreal_sdk/protocol/rpc.py +218 -0
  37. surreal_sdk/py.typed +0 -0
  38. surreal_sdk/pyproject.toml +49 -0
  39. surreal_sdk/streaming/__init__.py +31 -0
  40. surreal_sdk/streaming/change_feed.py +278 -0
  41. surreal_sdk/streaming/live_query.py +265 -0
  42. surreal_sdk/streaming/live_select.py +369 -0
  43. surreal_sdk/transaction.py +386 -0
  44. surreal_sdk/types.py +346 -0
  45. surrealdb_orm-0.5.0.dist-info/METADATA +465 -0
  46. surrealdb_orm-0.5.0.dist-info/RECORD +52 -0
  47. {surrealdb_orm-0.1.3.dist-info → surrealdb_orm-0.5.0.dist-info}/WHEEL +1 -1
  48. surrealdb_orm-0.5.0.dist-info/entry_points.txt +2 -0
  49. {surrealdb_orm-0.1.3.dist-info → surrealdb_orm-0.5.0.dist-info}/licenses/LICENSE +1 -1
  50. surrealdb_orm-0.1.3.dist-info/METADATA +0 -184
  51. surrealdb_orm-0.1.3.dist-info/RECORD +0 -11
@@ -0,0 +1,607 @@
1
+ """
2
+ Function call API for SurrealDB SDK.
3
+
4
+ Provides a fluent interface for calling SurrealDB built-in and custom functions.
5
+ """
6
+
7
+ from typing import TYPE_CHECKING, Any, Generator
8
+
9
+ if TYPE_CHECKING:
10
+ from .connection.base import BaseSurrealConnection
11
+
12
+
13
+ # Built-in SurrealDB function namespaces
14
+ BUILTIN_NAMESPACES = frozenset(
15
+ {
16
+ "array",
17
+ "bytes",
18
+ "count",
19
+ "crypto",
20
+ "duration",
21
+ "encoding",
22
+ "geo",
23
+ "http",
24
+ "math",
25
+ "meta",
26
+ "object",
27
+ "parse",
28
+ "rand",
29
+ "record",
30
+ "search",
31
+ "session",
32
+ "sleep",
33
+ "string",
34
+ "time",
35
+ "type",
36
+ "value",
37
+ "vector",
38
+ }
39
+ )
40
+
41
+
42
+ class FunctionCall:
43
+ """
44
+ Represents a SurrealDB function call ready for execution.
45
+
46
+ Can be awaited directly to execute the function.
47
+
48
+ Usage:
49
+ result = await conn.fn.math.sqrt(16)
50
+ # Equivalent to: SELECT * FROM math::sqrt(16)
51
+ """
52
+
53
+ def __init__(
54
+ self,
55
+ connection: "BaseSurrealConnection",
56
+ function_path: str,
57
+ args: tuple[Any, ...],
58
+ ):
59
+ """
60
+ Initialize a function call.
61
+
62
+ Args:
63
+ connection: The database connection
64
+ function_path: Full function path (e.g., "math::sqrt" or "fn::my_func")
65
+ args: Function arguments
66
+ """
67
+ self._connection = connection
68
+ self._function_path = function_path
69
+ self._args = args
70
+
71
+ @property
72
+ def function_path(self) -> str:
73
+ """Get the function path."""
74
+ return self._function_path
75
+
76
+ @property
77
+ def args(self) -> tuple[Any, ...]:
78
+ """Get the function arguments."""
79
+ return self._args
80
+
81
+ def to_sql(self) -> tuple[str, dict[str, Any]]:
82
+ """
83
+ Convert to SurrealQL with parameterized variables.
84
+
85
+ Returns:
86
+ Tuple of (sql_string, variables_dict)
87
+ """
88
+ params: dict[str, Any] = {}
89
+ placeholders: list[str] = []
90
+
91
+ for i, arg in enumerate(self._args):
92
+ param_name = f"fn_arg_{i}"
93
+ params[param_name] = arg
94
+ placeholders.append(f"${param_name}")
95
+
96
+ args_str = ", ".join(placeholders)
97
+ sql = f"RETURN {self._function_path}({args_str});"
98
+
99
+ return sql, params
100
+
101
+ async def execute(self) -> Any:
102
+ """
103
+ Execute the function call and return result.
104
+
105
+ Returns:
106
+ The function result
107
+ """
108
+ sql, params = self.to_sql()
109
+ result = await self._connection.query(sql, params)
110
+
111
+ # Extract scalar result from QueryResponse
112
+ if result.first_result and result.first_result.result is not None:
113
+ return result.first_result.result
114
+ return None
115
+
116
+ def __await__(self) -> Generator[Any, None, Any]:
117
+ """Allow direct await: result = await conn.fn.math.sqrt(16)"""
118
+ return self.execute().__await__()
119
+
120
+ def __repr__(self) -> str:
121
+ args_repr = ", ".join(repr(a) for a in self._args)
122
+ return f"FunctionCall({self._function_path}({args_repr}))"
123
+
124
+
125
+ class FunctionNamespace:
126
+ """
127
+ Namespace for building function calls.
128
+
129
+ Supports dot notation for nested namespaces:
130
+ conn.fn.math.sqrt(16) -> math::sqrt($fn_arg_0)
131
+ conn.fn.time.now() -> time::now()
132
+ conn.fn.cast_vote(...) -> fn::cast_vote(...)
133
+
134
+ Built-in namespaces (math, time, array, etc.) use namespace::function format.
135
+ Unknown namespaces are treated as custom functions with fn:: prefix.
136
+ """
137
+
138
+ def __init__(
139
+ self,
140
+ connection: "BaseSurrealConnection",
141
+ path: list[str] | None = None,
142
+ ):
143
+ """
144
+ Initialize a function namespace.
145
+
146
+ Args:
147
+ connection: The database connection
148
+ path: Current namespace path (e.g., ["math", "sqrt"])
149
+ """
150
+ self._connection = connection
151
+ self._path = path or []
152
+
153
+ def __getattr__(self, name: str) -> "FunctionNamespace":
154
+ """
155
+ Access a sub-namespace or prepare a function call.
156
+
157
+ Args:
158
+ name: Namespace or function name
159
+
160
+ Returns:
161
+ New FunctionNamespace with extended path
162
+
163
+ Examples:
164
+ conn.fn.math -> FunctionNamespace(path=["math"])
165
+ conn.fn.math.sqrt -> FunctionNamespace(path=["math", "sqrt"])
166
+ """
167
+ # Prevent recursion on special attributes
168
+ if name.startswith("_"):
169
+ raise AttributeError(f"'{type(self).__name__}' has no attribute '{name}'")
170
+ return FunctionNamespace(self._connection, self._path + [name])
171
+
172
+ def __call__(self, *args: Any) -> FunctionCall:
173
+ """
174
+ Call the function with arguments.
175
+
176
+ Args:
177
+ *args: Function arguments
178
+
179
+ Returns:
180
+ FunctionCall ready to execute
181
+
182
+ Raises:
183
+ ValueError: If called on root namespace
184
+
185
+ Examples:
186
+ conn.fn.math.sqrt(16) -> FunctionCall for "math::sqrt"
187
+ conn.fn.cast_vote(a, b, c) -> FunctionCall for "fn::cast_vote"
188
+ """
189
+ if not self._path:
190
+ raise ValueError("Cannot call root function namespace directly")
191
+
192
+ # Build function path based on namespace type
193
+ if self._path[0] in BUILTIN_NAMESPACES:
194
+ # Built-in function: math::sqrt, time::now, etc.
195
+ function_path = "::".join(self._path)
196
+ else:
197
+ # Custom function: fn::my_function, fn::nested::func
198
+ function_path = "fn::" + "::".join(self._path)
199
+
200
+ return FunctionCall(self._connection, function_path, args)
201
+
202
+ def __repr__(self) -> str:
203
+ path_str = "::".join(self._path) if self._path else "<root>"
204
+ return f"FunctionNamespace({path_str})"
205
+
206
+ # Typed helper properties for common namespaces
207
+
208
+ @property
209
+ def math(self) -> "MathFunctions":
210
+ """Access math functions with type hints."""
211
+ return MathFunctions(self._connection)
212
+
213
+ @property
214
+ def time(self) -> "TimeFunctions":
215
+ """Access time functions with type hints."""
216
+ return TimeFunctions(self._connection)
217
+
218
+ @property
219
+ def array(self) -> "ArrayFunctions":
220
+ """Access array functions with type hints."""
221
+ return ArrayFunctions(self._connection)
222
+
223
+ @property
224
+ def string(self) -> "StringFunctions":
225
+ """Access string functions with type hints."""
226
+ return StringFunctions(self._connection)
227
+
228
+ @property
229
+ def crypto(self) -> "CryptoFunctions":
230
+ """Access crypto functions with type hints."""
231
+ return CryptoFunctions(self._connection)
232
+
233
+
234
+ class MathFunctions:
235
+ """
236
+ Typed math function namespace with IDE hints.
237
+
238
+ All SurrealDB math:: functions with type annotations.
239
+ """
240
+
241
+ def __init__(self, connection: "BaseSurrealConnection"):
242
+ self._connection = connection
243
+ self._ns = FunctionNamespace(connection, ["math"])
244
+
245
+ def abs(self, value: float | int) -> FunctionCall:
246
+ """Return absolute value. math::abs(number)"""
247
+ return self._ns.abs(value)
248
+
249
+ def ceil(self, value: float | int) -> FunctionCall:
250
+ """Return ceiling value. math::ceil(number)"""
251
+ return self._ns.ceil(value)
252
+
253
+ def floor(self, value: float | int) -> FunctionCall:
254
+ """Return floor value. math::floor(number)"""
255
+ return self._ns.floor(value)
256
+
257
+ def round(self, value: float | int) -> FunctionCall:
258
+ """Return rounded value. math::round(number)"""
259
+ return self._ns.round(value)
260
+
261
+ def sqrt(self, value: float | int) -> FunctionCall:
262
+ """Return square root. math::sqrt(number)"""
263
+ return self._ns.sqrt(value)
264
+
265
+ def pow(self, base: float | int, exponent: float | int) -> FunctionCall:
266
+ """Return power. math::pow(base, exponent)"""
267
+ return self._ns.pow(base, exponent)
268
+
269
+ def log(self, value: float | int) -> FunctionCall:
270
+ """Return natural logarithm. math::log(number)"""
271
+ return self._ns.log(value)
272
+
273
+ def log2(self, value: float | int) -> FunctionCall:
274
+ """Return base-2 logarithm. math::log2(number)"""
275
+ return self._ns.log2(value)
276
+
277
+ def log10(self, value: float | int) -> FunctionCall:
278
+ """Return base-10 logarithm. math::log10(number)"""
279
+ return self._ns.log10(value)
280
+
281
+ def sin(self, value: float | int) -> FunctionCall:
282
+ """Return sine. math::sin(number)"""
283
+ return self._ns.sin(value)
284
+
285
+ def cos(self, value: float | int) -> FunctionCall:
286
+ """Return cosine. math::cos(number)"""
287
+ return self._ns.cos(value)
288
+
289
+ def tan(self, value: float | int) -> FunctionCall:
290
+ """Return tangent. math::tan(number)"""
291
+ return self._ns.tan(value)
292
+
293
+ def max(self, *values: float | int) -> FunctionCall:
294
+ """Return maximum value. math::max(numbers...)"""
295
+ return self._ns.max(*values)
296
+
297
+ def min(self, *values: float | int) -> FunctionCall:
298
+ """Return minimum value. math::min(numbers...)"""
299
+ return self._ns.min(*values)
300
+
301
+ def sum(self, values: list[float | int]) -> FunctionCall:
302
+ """Return sum of values. math::sum(array)"""
303
+ return self._ns.sum(values)
304
+
305
+ def mean(self, values: list[float | int]) -> FunctionCall:
306
+ """Return mean of values. math::mean(array)"""
307
+ return self._ns.mean(values)
308
+
309
+ def median(self, values: list[float | int]) -> FunctionCall:
310
+ """Return median of values. math::median(array)"""
311
+ return self._ns.median(values)
312
+
313
+ def __getattr__(self, name: str) -> "FunctionNamespace":
314
+ """Fall back to dynamic namespace for unlisted functions."""
315
+ result: FunctionNamespace = getattr(self._ns, name)
316
+ return result
317
+
318
+
319
+ class TimeFunctions:
320
+ """
321
+ Typed time function namespace with IDE hints.
322
+
323
+ All SurrealDB time:: functions with type annotations.
324
+ """
325
+
326
+ def __init__(self, connection: "BaseSurrealConnection"):
327
+ self._connection = connection
328
+ self._ns = FunctionNamespace(connection, ["time"])
329
+
330
+ def now(self) -> FunctionCall:
331
+ """Return current datetime. time::now()"""
332
+ return self._ns.now()
333
+
334
+ def day(self, datetime: Any) -> FunctionCall:
335
+ """Return day of month. time::day(datetime)"""
336
+ return self._ns.day(datetime)
337
+
338
+ def month(self, datetime: Any) -> FunctionCall:
339
+ """Return month. time::month(datetime)"""
340
+ return self._ns.month(datetime)
341
+
342
+ def year(self, datetime: Any) -> FunctionCall:
343
+ """Return year. time::year(datetime)"""
344
+ return self._ns.year(datetime)
345
+
346
+ def hour(self, datetime: Any) -> FunctionCall:
347
+ """Return hour. time::hour(datetime)"""
348
+ return self._ns.hour(datetime)
349
+
350
+ def minute(self, datetime: Any) -> FunctionCall:
351
+ """Return minute. time::minute(datetime)"""
352
+ return self._ns.minute(datetime)
353
+
354
+ def second(self, datetime: Any) -> FunctionCall:
355
+ """Return second. time::second(datetime)"""
356
+ return self._ns.second(datetime)
357
+
358
+ def floor(self, datetime: Any, duration: str) -> FunctionCall:
359
+ """Floor datetime to duration. time::floor(datetime, duration)"""
360
+ return self._ns.floor(datetime, duration)
361
+
362
+ def ceil(self, datetime: Any, duration: str) -> FunctionCall:
363
+ """Ceil datetime to duration. time::ceil(datetime, duration)"""
364
+ return self._ns.ceil(datetime, duration)
365
+
366
+ def round(self, datetime: Any, duration: str) -> FunctionCall:
367
+ """Round datetime to duration. time::round(datetime, duration)"""
368
+ return self._ns.round(datetime, duration)
369
+
370
+ def unix(self, datetime: Any) -> FunctionCall:
371
+ """Return Unix timestamp. time::unix(datetime)"""
372
+ return self._ns.unix(datetime)
373
+
374
+ def format(self, datetime: Any, format_str: str) -> FunctionCall:
375
+ """Format datetime. time::format(datetime, format)"""
376
+ return self._ns.format(datetime, format_str)
377
+
378
+ def __getattr__(self, name: str) -> "FunctionNamespace":
379
+ """Fall back to dynamic namespace for unlisted functions."""
380
+ result: FunctionNamespace = getattr(self._ns, name)
381
+ return result
382
+
383
+
384
+ class ArrayFunctions:
385
+ """
386
+ Typed array function namespace with IDE hints.
387
+
388
+ All SurrealDB array:: functions with type annotations.
389
+ """
390
+
391
+ def __init__(self, connection: "BaseSurrealConnection"):
392
+ self._connection = connection
393
+ self._ns = FunctionNamespace(connection, ["array"])
394
+
395
+ def len(self, array: list[Any]) -> FunctionCall:
396
+ """Return array length. array::len(array)"""
397
+ return self._ns.len(array)
398
+
399
+ def append(self, array: list[Any], value: Any) -> FunctionCall:
400
+ """Append value to array. array::append(array, value)"""
401
+ return self._ns.append(array, value)
402
+
403
+ def prepend(self, array: list[Any], value: Any) -> FunctionCall:
404
+ """Prepend value to array. array::prepend(array, value)"""
405
+ return self._ns.prepend(array, value)
406
+
407
+ def concat(self, *arrays: list[Any]) -> FunctionCall:
408
+ """Concatenate arrays. array::concat(arrays...)"""
409
+ return self._ns.concat(*arrays)
410
+
411
+ def distinct(self, array: list[Any]) -> FunctionCall:
412
+ """Return distinct values. array::distinct(array)"""
413
+ return self._ns.distinct(array)
414
+
415
+ def flatten(self, array: list[Any]) -> FunctionCall:
416
+ """Flatten nested arrays. array::flatten(array)"""
417
+ return self._ns.flatten(array)
418
+
419
+ def reverse(self, array: list[Any]) -> FunctionCall:
420
+ """Reverse array. array::reverse(array)"""
421
+ return self._ns.reverse(array)
422
+
423
+ def sort(self, array: list[Any]) -> FunctionCall:
424
+ """Sort array. array::sort(array)"""
425
+ return self._ns.sort(array)
426
+
427
+ def slice(self, array: list[Any], start: int, end: int | None = None) -> FunctionCall:
428
+ """Slice array. array::slice(array, start, end)"""
429
+ if end is not None:
430
+ return self._ns.slice(array, start, end)
431
+ return self._ns.slice(array, start)
432
+
433
+ def first(self, array: list[Any]) -> FunctionCall:
434
+ """Return first element. array::first(array)"""
435
+ return self._ns.first(array)
436
+
437
+ def last(self, array: list[Any]) -> FunctionCall:
438
+ """Return last element. array::last(array)"""
439
+ return self._ns.last(array)
440
+
441
+ def __getattr__(self, name: str) -> "FunctionNamespace":
442
+ """Fall back to dynamic namespace for unlisted functions."""
443
+ result: FunctionNamespace = getattr(self._ns, name)
444
+ return result
445
+
446
+
447
+ class StringFunctions:
448
+ """
449
+ Typed string function namespace with IDE hints.
450
+
451
+ All SurrealDB string:: functions with type annotations.
452
+ """
453
+
454
+ def __init__(self, connection: "BaseSurrealConnection"):
455
+ self._connection = connection
456
+ self._ns = FunctionNamespace(connection, ["string"])
457
+
458
+ def len(self, string: str) -> FunctionCall:
459
+ """Return string length. string::len(string)"""
460
+ return self._ns.len(string)
461
+
462
+ def lowercase(self, string: str) -> FunctionCall:
463
+ """Convert to lowercase. string::lowercase(string)"""
464
+ return self._ns.lowercase(string)
465
+
466
+ def uppercase(self, string: str) -> FunctionCall:
467
+ """Convert to uppercase. string::uppercase(string)"""
468
+ return self._ns.uppercase(string)
469
+
470
+ def trim(self, string: str) -> FunctionCall:
471
+ """Trim whitespace. string::trim(string)"""
472
+ return self._ns.trim(string)
473
+
474
+ def concat(self, *strings: str) -> FunctionCall:
475
+ """Concatenate strings. string::concat(strings...)"""
476
+ return self._ns.concat(*strings)
477
+
478
+ def split(self, string: str, delimiter: str) -> FunctionCall:
479
+ """Split string. string::split(string, delimiter)"""
480
+ return self._ns.split(string, delimiter)
481
+
482
+ def join(self, array: list[str], delimiter: str) -> FunctionCall:
483
+ """Join array. string::join(array, delimiter)"""
484
+ return self._ns.join(array, delimiter)
485
+
486
+ def replace(self, string: str, search: str, replace: str) -> FunctionCall:
487
+ """Replace in string. string::replace(string, search, replace)"""
488
+ return self._ns.replace(string, search, replace)
489
+
490
+ def slice(self, string: str, start: int, end: int | None = None) -> FunctionCall:
491
+ """Slice string. string::slice(string, start, end)"""
492
+ if end is not None:
493
+ return self._ns.slice(string, start, end)
494
+ return self._ns.slice(string, start)
495
+
496
+ def contains(self, string: str, search: str) -> FunctionCall:
497
+ """Check if string contains substring. string::contains(string, search)"""
498
+ return self._ns.contains(string, search)
499
+
500
+ def starts_with(self, string: str, prefix: str) -> FunctionCall:
501
+ """Check if string starts with prefix. string::startsWith(string, prefix)"""
502
+ return self._ns.startsWith(string, prefix)
503
+
504
+ def ends_with(self, string: str, suffix: str) -> FunctionCall:
505
+ """Check if string ends with suffix. string::endsWith(string, suffix)"""
506
+ return self._ns.endsWith(string, suffix)
507
+
508
+ def __getattr__(self, name: str) -> "FunctionNamespace":
509
+ """Fall back to dynamic namespace for unlisted functions."""
510
+ result: FunctionNamespace = getattr(self._ns, name)
511
+ return result
512
+
513
+
514
+ class CryptoFunctions:
515
+ """
516
+ Typed crypto function namespace with IDE hints.
517
+
518
+ All SurrealDB crypto:: functions with type annotations.
519
+ """
520
+
521
+ def __init__(self, connection: "BaseSurrealConnection"):
522
+ self._connection = connection
523
+ self._ns = FunctionNamespace(connection, ["crypto"])
524
+
525
+ def md5(self, value: str) -> FunctionCall:
526
+ """Return MD5 hash. crypto::md5(string)"""
527
+ return self._ns.md5(value)
528
+
529
+ def sha1(self, value: str) -> FunctionCall:
530
+ """Return SHA-1 hash. crypto::sha1(string)"""
531
+ return self._ns.sha1(value)
532
+
533
+ def sha256(self, value: str) -> FunctionCall:
534
+ """Return SHA-256 hash. crypto::sha256(string)"""
535
+ return self._ns.sha256(value)
536
+
537
+ def sha512(self, value: str) -> FunctionCall:
538
+ """Return SHA-512 hash. crypto::sha512(string)"""
539
+ return self._ns.sha512(value)
540
+
541
+ def __getattr__(self, name: str) -> "FunctionNamespace":
542
+ """Fall back to dynamic namespace for unlisted functions."""
543
+ result: FunctionNamespace = getattr(self._ns, name)
544
+ return result
545
+
546
+ @property
547
+ def argon2(self) -> "Argon2Functions":
548
+ """Access crypto::argon2 functions."""
549
+ return Argon2Functions(self._connection)
550
+
551
+ @property
552
+ def bcrypt(self) -> "BcryptFunctions":
553
+ """Access crypto::bcrypt functions."""
554
+ return BcryptFunctions(self._connection)
555
+
556
+ @property
557
+ def scrypt(self) -> "ScryptFunctions":
558
+ """Access crypto::scrypt functions."""
559
+ return ScryptFunctions(self._connection)
560
+
561
+
562
+ class Argon2Functions:
563
+ """Crypto argon2 sub-namespace."""
564
+
565
+ def __init__(self, connection: "BaseSurrealConnection"):
566
+ self._connection = connection
567
+ self._ns = FunctionNamespace(connection, ["crypto", "argon2"])
568
+
569
+ def compare(self, hash: str, password: str) -> FunctionCall:
570
+ """Compare password with argon2 hash. crypto::argon2::compare(hash, password)"""
571
+ return self._ns.compare(hash, password)
572
+
573
+ def generate(self, password: str) -> FunctionCall:
574
+ """Generate argon2 hash. crypto::argon2::generate(password)"""
575
+ return self._ns.generate(password)
576
+
577
+
578
+ class BcryptFunctions:
579
+ """Crypto bcrypt sub-namespace."""
580
+
581
+ def __init__(self, connection: "BaseSurrealConnection"):
582
+ self._connection = connection
583
+ self._ns = FunctionNamespace(connection, ["crypto", "bcrypt"])
584
+
585
+ def compare(self, hash: str, password: str) -> FunctionCall:
586
+ """Compare password with bcrypt hash. crypto::bcrypt::compare(hash, password)"""
587
+ return self._ns.compare(hash, password)
588
+
589
+ def generate(self, password: str) -> FunctionCall:
590
+ """Generate bcrypt hash. crypto::bcrypt::generate(password)"""
591
+ return self._ns.generate(password)
592
+
593
+
594
+ class ScryptFunctions:
595
+ """Crypto scrypt sub-namespace."""
596
+
597
+ def __init__(self, connection: "BaseSurrealConnection"):
598
+ self._connection = connection
599
+ self._ns = FunctionNamespace(connection, ["crypto", "scrypt"])
600
+
601
+ def compare(self, hash: str, password: str) -> FunctionCall:
602
+ """Compare password with scrypt hash. crypto::scrypt::compare(hash, password)"""
603
+ return self._ns.compare(hash, password)
604
+
605
+ def generate(self, password: str) -> FunctionCall:
606
+ """Generate scrypt hash. crypto::scrypt::generate(password)"""
607
+ return self._ns.generate(password)
@@ -0,0 +1,13 @@
1
+ """
2
+ SurrealDB SDK Protocol Module.
3
+
4
+ Implements the RPC protocol for SurrealDB communication.
5
+ """
6
+
7
+ from .rpc import RPCRequest, RPCResponse, RPCError
8
+
9
+ __all__ = [
10
+ "RPCRequest",
11
+ "RPCResponse",
12
+ "RPCError",
13
+ ]