pyinternet 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.
cache/__init__.py ADDED
@@ -0,0 +1,173 @@
1
+ """Python port of github.com/celsiainternet/elvis/cache.
2
+
3
+ Function names and parameter lists mirror the Go package one-to-one so
4
+ that code translated from Go reads the same in Python:
5
+
6
+ import cache
7
+
8
+ cache.Load()
9
+ cache.Set("greeting", "hello", 60)
10
+ cache.Get("greeting", "")
11
+
12
+ See the package README for the full Go -> Python mapping and the
13
+ handful of deliberate deviations (error handling via exceptions instead
14
+ of (value, error) tuples; HTTP handlers take a plain query dict instead
15
+ of http.ResponseWriter/*http.Request).
16
+ """
17
+
18
+ from . import cache as _cache_mod
19
+ from ._et import Item, Items, Json, List
20
+ from .cache import Close, Conn, HealthCheck, IsLoad, Load
21
+ from .connect import ConnectTo
22
+ from .ctx import (
23
+ DecrCtx,
24
+ DecrKeepTTLScript,
25
+ DeleteCtx,
26
+ ExistsCtx,
27
+ ExpireCtx,
28
+ GetCtx,
29
+ HDeleteCtx,
30
+ HGetCtx,
31
+ HSetCtx,
32
+ IncrCtx,
33
+ IncrSetTTLScript,
34
+ LPushCtx,
35
+ LRangeCtx,
36
+ LRemCtx,
37
+ LTrimCtx,
38
+ SetCtx,
39
+ )
40
+ from .handler import (
41
+ AllCache,
42
+ Decr,
43
+ Delete,
44
+ DeleteVerify,
45
+ Empty,
46
+ Exists,
47
+ Expire,
48
+ GenId,
49
+ GenKey,
50
+ Get,
51
+ GetBool,
52
+ GetFloat,
53
+ GetInt,
54
+ GetInt64,
55
+ GetItem,
56
+ GetItems,
57
+ GetJson,
58
+ GetVerify,
59
+ HandlerAll,
60
+ HandlerDelete,
61
+ HandlerGet,
62
+ HDelete,
63
+ HGet,
64
+ HGetAtrib,
65
+ HSet,
66
+ HSetAtrib,
67
+ Incr,
68
+ IsNil,
69
+ LPush,
70
+ LRange,
71
+ LRem,
72
+ LTrim,
73
+ More,
74
+ Set,
75
+ SetD,
76
+ SetH,
77
+ SetM,
78
+ SetVerify,
79
+ SetW,
80
+ SetY,
81
+ )
82
+ from .pubsub import Message
83
+
84
+
85
+ def __getattr__(name: str):
86
+ # `FromId` mirrors a package-level Go var that is reassigned inside
87
+ # Load(). A plain `from .cache import FromId` would freeze it at its
88
+ # import-time value (""), since Python import bindings are snapshots,
89
+ # not live references like Go's package-qualified access. Module-level
90
+ # __getattr__ (PEP 562) resolves it against the live value on every
91
+ # access instead, so `cache.FromId` stays a plain attribute (no
92
+ # parens) just like in Go.
93
+ if name == "FromId":
94
+ return _cache_mod.FromId
95
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
96
+
97
+
98
+ __all__ = [
99
+ # cache.py
100
+ "Load",
101
+ "Close",
102
+ "IsLoad",
103
+ "HealthCheck",
104
+ "Conn",
105
+ "FromId",
106
+ # connect.py
107
+ "ConnectTo",
108
+ # ctx.py
109
+ "SetCtx",
110
+ "ExpireCtx",
111
+ "GetCtx",
112
+ "ExistsCtx",
113
+ "DeleteCtx",
114
+ "IncrCtx",
115
+ "DecrCtx",
116
+ "LPushCtx",
117
+ "LRemCtx",
118
+ "LRangeCtx",
119
+ "LTrimCtx",
120
+ "HSetCtx",
121
+ "HGetCtx",
122
+ "HDeleteCtx",
123
+ "IncrSetTTLScript",
124
+ "DecrKeepTTLScript",
125
+ # handler.py
126
+ "IsNil",
127
+ "GenId",
128
+ "GenKey",
129
+ "Set",
130
+ "Get",
131
+ "Exists",
132
+ "Delete",
133
+ "Expire",
134
+ "Incr",
135
+ "Decr",
136
+ "LPush",
137
+ "LRem",
138
+ "LRange",
139
+ "LTrim",
140
+ "SetH",
141
+ "SetD",
142
+ "SetW",
143
+ "SetM",
144
+ "SetY",
145
+ "Empty",
146
+ "More",
147
+ "HSet",
148
+ "HGet",
149
+ "HSetAtrib",
150
+ "HGetAtrib",
151
+ "HDelete",
152
+ "SetVerify",
153
+ "GetVerify",
154
+ "DeleteVerify",
155
+ "AllCache",
156
+ "GetInt",
157
+ "GetInt64",
158
+ "GetFloat",
159
+ "GetBool",
160
+ "GetJson",
161
+ "GetItem",
162
+ "GetItems",
163
+ "HandlerAll",
164
+ "HandlerGet",
165
+ "HandlerDelete",
166
+ # pubsub.py
167
+ "Message",
168
+ # _et.py
169
+ "Json",
170
+ "Item",
171
+ "Items",
172
+ "List",
173
+ ]
cache/_et.py ADDED
@@ -0,0 +1,143 @@
1
+ """Minimal port of github.com/celsiainternet/elvis/et types.
2
+
3
+ Only the pieces consumed by the `cache` package are ported: Json, Item,
4
+ Items and List.
5
+ """
6
+
7
+ import json as _json
8
+ from typing import Any, Dict, List as _List
9
+
10
+
11
+ class Json(dict):
12
+ """Mirrors et.Json (a map[string]interface{} with helpers)."""
13
+
14
+ def ToString(self) -> str:
15
+ """
16
+ * ToString
17
+ * @return str
18
+ """
19
+ return _json.dumps(self, default=str, ensure_ascii=False)
20
+
21
+ def Scan(self, src: str) -> None:
22
+ """
23
+ * Scan
24
+ * @params src str
25
+ * @return None
26
+ """
27
+ self.clear()
28
+ self.update(_json.loads(src) if src else {})
29
+
30
+
31
+ class Item:
32
+ """Mirrors et.Item — a single result with Ok bool and Result Json."""
33
+
34
+ def __init__(self, Ok: bool = False, Result: Json = None):
35
+ self.Ok = Ok
36
+ self.Result: Json = Result if Result is not None else Json()
37
+
38
+ def ToJson(self) -> Json:
39
+ return Json({"ok": self.Ok, "result": dict(self.Result)})
40
+
41
+ def ToString(self) -> str:
42
+ """
43
+ * ToString
44
+ * @return str
45
+ """
46
+ return self.ToJson().ToString()
47
+
48
+ @staticmethod
49
+ def FromString(src: str) -> "Item":
50
+ data = _json.loads(src) if src else {}
51
+ return Item(Ok=bool(data.get("ok", False)), Result=Json(data.get("result") or {}))
52
+
53
+
54
+ class Items:
55
+ """Mirrors et.Items — a paginated result set."""
56
+
57
+ def __init__(self, Ok: bool = False, Count: int = 0, Result: _List[Json] = None):
58
+ self.Ok = Ok
59
+ self.Count = Count
60
+ self.Result: _List[Json] = Result if Result is not None else []
61
+
62
+ def ToJson(self) -> Json:
63
+ return Json({"ok": self.Ok, "count": self.Count, "result": [dict(r) for r in self.Result]})
64
+
65
+ def ToString(self) -> str:
66
+ """
67
+ * ToString
68
+ * @return str
69
+ """
70
+ return self.ToJson().ToString()
71
+
72
+ @staticmethod
73
+ def FromString(src: str) -> "Items":
74
+ data = _json.loads(src) if src else {}
75
+ result = [Json(r) for r in data.get("result") or []]
76
+ return Items(Ok=bool(data.get("ok", False)), Count=int(data.get("count", 0)), Result=result)
77
+
78
+ def ToList(self, all: int, page: int, rows: int) -> "List":
79
+ """
80
+ * ToList
81
+ * @params all int, page int, rows int
82
+ * @return List
83
+ """
84
+ count = self.Count
85
+ if count <= 0:
86
+ start = 0
87
+ end = 0
88
+ else:
89
+ offset = (page - 1) * rows
90
+ if offset > 0:
91
+ start = offset + 1
92
+ end = offset + count
93
+ else:
94
+ start = 1
95
+ end = count
96
+
97
+ return List(Rows=rows, All=all, Count=count, Page=page, Start=start, End=end, Result=self.Result)
98
+
99
+
100
+ class List:
101
+ """Mirrors et.List — a list with pagination metadata."""
102
+
103
+ def __init__(
104
+ self,
105
+ Rows: int = 0,
106
+ All: int = 0,
107
+ Count: int = 0,
108
+ Page: int = 0,
109
+ Start: int = 0,
110
+ End: int = 0,
111
+ Result: _List[Json] = None,
112
+ ):
113
+ self.Rows = Rows
114
+ self.All = All
115
+ self.Count = Count
116
+ self.Page = Page
117
+ self.Start = Start
118
+ self.End = End
119
+ self.Result: _List[Json] = Result if Result is not None else []
120
+
121
+ def ToJson(self) -> Json:
122
+ """
123
+ * ToJson
124
+ * @return Json
125
+ """
126
+ return Json(
127
+ {
128
+ "rows": self.Rows,
129
+ "all": self.All,
130
+ "count": self.Count,
131
+ "page": self.Page,
132
+ "start": self.Start,
133
+ "end": self.End,
134
+ "result": [dict(r) for r in self.Result],
135
+ }
136
+ )
137
+
138
+ def ToString(self) -> str:
139
+ """
140
+ * ToString
141
+ * @return str
142
+ """
143
+ return self.ToJson().ToString()
cache/_logs.py ADDED
@@ -0,0 +1,63 @@
1
+ """Minimal structured logging.
2
+
3
+ Mirrors the subset of github.com/celsiainternet/elvis/logs consumed by
4
+ the Go `cache` package: Log, Logf, Alert, Alertm, Alertf.
5
+ """
6
+
7
+ import sys
8
+ from typing import Optional
9
+
10
+
11
+ def _print_ln(kind: str, *args: object) -> None:
12
+ message = " ".join(str(a) for a in args)
13
+ print(f"[{kind}] {message}", file=sys.stderr)
14
+
15
+
16
+ def Log(kind: str, *args: object) -> None:
17
+ """
18
+ * Log
19
+ * @params kind str, *args
20
+ * @return None
21
+ """
22
+ _print_ln(kind, *args)
23
+
24
+
25
+ def Logf(kind: str, format: str, *args: object) -> None:
26
+ """
27
+ * Logf
28
+ * @params kind str, format str, *args
29
+ * @return None
30
+ """
31
+ _print_ln(kind, format % args if args else format)
32
+
33
+
34
+ def Alert(err: Optional[BaseException]) -> Optional[BaseException]:
35
+ """
36
+ * Alert
37
+ * @params err Exception | None
38
+ * @return Exception | None
39
+ """
40
+ if err is not None:
41
+ _print_ln("Alert", str(err))
42
+ return err
43
+
44
+
45
+ def Alertm(message: str) -> Exception:
46
+ """
47
+ * Alertm
48
+ * @params message str
49
+ * @return Exception
50
+ """
51
+ err = Exception(message)
52
+ _print_ln("Alert", str(err))
53
+ return err
54
+
55
+
56
+ def Alertf(format: str, *args: object) -> Exception:
57
+ """
58
+ * Alertf
59
+ * @params format str, *args
60
+ * @return Exception
61
+ """
62
+ message = format % args if args else format
63
+ return Alertm(message)
cache/_msg.py ADDED
@@ -0,0 +1,9 @@
1
+ """Message constants used by the cache package.
2
+
3
+ Mirrors the subset of github.com/celsiainternet/elvis/msg consumed by
4
+ the Go `cache` package.
5
+ """
6
+
7
+ MSG_ATRIB_REQUIRED = "atributo requerido (%s)"
8
+ ERR_ENV_REQUIRED = "variables de entorno requerida (%s)"
9
+ ERR_NOT_CACHE_SERVICE = "no hay servicio de caching"
cache/cache.py ADDED
@@ -0,0 +1,101 @@
1
+ """Core connection handling.
2
+
3
+ Mirrors github.com/celsiainternet/elvis/cache/cache.go: the package
4
+ level `conn` singleton, `FromId`, `Load`, `Close`, `IsLoad` and
5
+ `HealthCheck`.
6
+ """
7
+
8
+ import threading
9
+ import uuid
10
+ from typing import Dict, Optional
11
+
12
+ import redis
13
+
14
+ from . import _logs as logs
15
+ from .pubsub import PubSubMixin
16
+
17
+ conn: Optional["Conn"] = None
18
+ FromId: str = ""
19
+
20
+
21
+ class Conn(PubSubMixin):
22
+ """Mirrors cache.Conn (embeds *redis.Client)."""
23
+
24
+ def __init__(self, client: "redis.Redis", _id: str, host: str, dbname: int):
25
+ self.client = client
26
+ self._id = _id
27
+ # Unused: kept only so callers can mirror Go's `conn.ctx` access
28
+ # pattern when invoking the *Ctx functions in ctx.py.
29
+ self.ctx = None
30
+ self.host = host
31
+ self.dbname = dbname
32
+ self.channels: Dict[str, bool] = {}
33
+ self.mutex = threading.RLock()
34
+
35
+ def __getattr__(self, name: str):
36
+ # Mirrors Go embedding: promote *redis.Client methods onto Conn.
37
+ return getattr(self.client, name)
38
+
39
+ def Close(self) -> None:
40
+ self.client.close()
41
+
42
+
43
+ def Load() -> "Conn":
44
+ """
45
+ * Load
46
+ * @return Conn
47
+ """
48
+ global conn, FromId
49
+
50
+ if conn is not None:
51
+ return conn
52
+
53
+ from .connect import connect
54
+
55
+ conn = connect()
56
+ FromId = conn._id
57
+
58
+ return conn
59
+
60
+
61
+ def Close() -> None:
62
+ """
63
+ * Close
64
+ * @return None
65
+ """
66
+ global conn
67
+
68
+ if conn is None:
69
+ return
70
+
71
+ conn.Close()
72
+
73
+ logs.Log("Cache", "Disconnect...")
74
+
75
+
76
+ def IsLoad() -> bool:
77
+ """
78
+ * IsLoad
79
+ * @return bool
80
+ """
81
+ return conn is not None
82
+
83
+
84
+ def HealthCheck() -> bool:
85
+ """
86
+ * HealthCheck
87
+ * @return bool
88
+ """
89
+ if conn is None:
90
+ return False
91
+
92
+ try:
93
+ conn.client.ping()
94
+ except Exception:
95
+ return False
96
+
97
+ return True
98
+
99
+
100
+ def _new_id() -> str:
101
+ return str(uuid.uuid4())
cache/connect.py ADDED
@@ -0,0 +1,62 @@
1
+ """Connection helpers.
2
+
3
+ Mirrors github.com/celsiainternet/elvis/cache/connect.go: `ConnectTo`
4
+ and the internal `connect`.
5
+ """
6
+
7
+ import redis
8
+
9
+ import envar
10
+
11
+ from . import _logs as logs
12
+ from ._msg import ERR_ENV_REQUIRED, MSG_ATRIB_REQUIRED
13
+
14
+
15
+ def ConnectTo(host: str, password: str, dbname: int) -> "Conn":
16
+ """
17
+ * ConnectTo
18
+ * @param host str, password str, dbname int
19
+ * @return Conn
20
+ """
21
+ from .cache import Conn, _new_id
22
+
23
+ if not host:
24
+ raise ValueError(MSG_ATRIB_REQUIRED % "redist_host")
25
+
26
+ pool_size = envar.GetInt(10, "REDIS_POOL_SIZE")
27
+ # REDIS_MIN_IDLE_CONNS is read for env-var parity with Go, but redis-py's
28
+ # connection pool has no equivalent min-idle-connections setting.
29
+ envar.GetInt(2, "REDIS_MIN_IDLE_CONNS")
30
+
31
+ client = redis.Redis(
32
+ host=host.split(":")[0],
33
+ port=int(host.split(":")[1]) if ":" in host else 6379,
34
+ password=password or None,
35
+ db=dbname,
36
+ max_connections=pool_size,
37
+ decode_responses=True,
38
+ )
39
+
40
+ client.ping()
41
+
42
+ logs.Logf("Redis", "Connected host:%s", host)
43
+
44
+ return Conn(client=client, _id=_new_id(), host=host, dbname=dbname)
45
+
46
+
47
+ def connect() -> "Conn":
48
+ """
49
+ * connect
50
+ * @return Conn
51
+ """
52
+ host = envar.GetStr("", "REDIS_HOST")
53
+ password = envar.GetStr("", "REDIS_PASSWORD")
54
+ dbname = envar.GetInt(0, "REDIS_DB")
55
+
56
+ if not host:
57
+ raise logs.Alertf(ERR_ENV_REQUIRED, "REDIS_HOST")
58
+
59
+ if not password:
60
+ raise logs.Alertf(ERR_ENV_REQUIRED, "REDIS_PASSWORD")
61
+
62
+ return ConnectTo(host, password, dbname)