cfwtools 0.1.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.
cfwtools/__init__.py ADDED
File without changes
@@ -0,0 +1,24 @@
1
+ from functools import cached_property
2
+
3
+ from workers import DurableObject as _DurableObject
4
+ from cfwtools.sql import Sql
5
+
6
+ if TYPE_CHECKING:
7
+ from js import DurableObjectState, Env
8
+
9
+
10
+ class DurableObject(_DurableObject):
11
+ def __init__(self, ctx: "DurableObjectState", env: "Env") -> None:
12
+ super().__init__(ctx, env)
13
+ self.__post_init__()
14
+
15
+ @cached_property
16
+ def name(self) -> str:
17
+ return self.ctx.id.name
18
+
19
+ @cached_property
20
+ def sql(self) -> Sql:
21
+ return Sql(self.ctx.storage.sql)
22
+
23
+ def __post_init__(self) -> None:
24
+ pass
cfwtools/py.typed ADDED
File without changes
cfwtools/sql.py ADDED
@@ -0,0 +1,35 @@
1
+ from typing import Any, Protocol, Iterator, Self
2
+ from jinja2 import Template
3
+
4
+
5
+ class _CursorRow(Protocol):
6
+ def to_py(self) -> dict[str, str]: ...
7
+
8
+
9
+ class _CursorIterable(Protocol):
10
+ def __iter__(self) -> Iterator[_CursorRow]: ...
11
+
12
+
13
+ class _SqlStorage(Protocol):
14
+ def exec(self, query: str, /, *bindings: Any) -> _CursorIterable: ...
15
+
16
+
17
+ class Cursor:
18
+ def __init__(self, cursor: _CursorIterable) -> None:
19
+ self._iter = iter(cursor)
20
+
21
+ def __iter__(self) -> Self:
22
+ return self
23
+
24
+ def __next__(self) -> dict[str, str]:
25
+ return next(self._iter).to_py()
26
+
27
+
28
+ class Sql:
29
+ def __init__(self, sql: _SqlStorage) -> None:
30
+ self._sql = sql
31
+
32
+ def __call__(self, query: str | Template, /, **values: Any) -> Cursor:
33
+ if isinstance(query, Template):
34
+ query = query.render(**values)
35
+ return Cursor(self._sql.exec(query))
cfwtools/template.py ADDED
@@ -0,0 +1,17 @@
1
+ from jinja2 import Template, Environment, StrictUndefined, Undefined
2
+ from typing import Any
3
+
4
+ JINJA_ENV = Environment(undefined=StrictUndefined)
5
+
6
+
7
+ def _safe_repr(value: Any) -> str | Undefined:
8
+ """Safely represent a value, preserving Undefined objects without conversion."""
9
+ return value if isinstance(value, Undefined) else repr(value)
10
+
11
+
12
+ JINJA_ENV.filters["r"] = _safe_repr
13
+
14
+
15
+ def template(source: str) -> Template:
16
+ """Create a Jinja2 template from a source string with strict undefined handling."""
17
+ return JINJA_ENV.from_string(source)
@@ -0,0 +1,11 @@
1
+ Metadata-Version: 2.3
2
+ Name: cfwtools
3
+ Version: 0.1.0
4
+ Summary: Cloudflare's Python Worker Development Tools
5
+ Requires-Dist: workers-py>=1.12.0
6
+ Requires-Dist: jinja2
7
+ Requires-Python: >=3.12
8
+ Description-Content-Type: text/markdown
9
+
10
+ # cfwtools
11
+ Cloudflare's Python Worker Development Tools
@@ -0,0 +1,8 @@
1
+ cfwtools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ cfwtools/durable_object.py,sha256=JKQUskn5iDoQRuxx3flT-h1ztvZkA8_fT4jf70Hin4Q,577
3
+ cfwtools/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ cfwtools/sql.py,sha256=L-FtnOk-ULpVgit8iWDcC0jH9kTPl8X7mBhauOfr1UM,876
5
+ cfwtools/template.py,sha256=LGJ9PUAt8mB-5-6L9Y2XVS05FvngqlD7yEUcy4cwSRE,552
6
+ cfwtools-0.1.0.dist-info/WHEEL,sha256=GuAqCqoyQuys5_R4zkHUJFlKXw4RpRLNzo31-ui90WQ,81
7
+ cfwtools-0.1.0.dist-info/METADATA,sha256=CjA6JQgfWXVaDvD_Z7HA1pLyGrmZMjK2tJz8tFR8gHs,283
8
+ cfwtools-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: uv 0.10.12
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any