httpstate 0.0.13__tar.gz → 0.0.14__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: httpstate
3
- Version: 0.0.13
3
+ Version: 0.0.14
4
4
  Summary: HTTP State, httpstate.com
5
5
  Author-email: "Alex Morales, HTTP State" <alex@httpstate.com>
6
6
  License-Expression: AGPL-3.0
@@ -28,7 +28,7 @@ Import
28
28
  import httpstate
29
29
  ```
30
30
 
31
- Pick any valid UUID v4. You can [generate one here](https://www.uuidgenerator.net/version4).
31
+ Pick any valid UUID v4. You can [generate one here](https://uuid.httpstate.com).
32
32
 
33
33
  We'll use `45fb3654-0e92-44da-aa21-ca409c6bdab3` or `45fb36540e9244daaa21ca409c6bdab3` (without dashes).
34
34
 
@@ -44,7 +44,7 @@ and retrieve it with
44
44
  data = httpstate.get('45fb36540e9244daaa21ca409c6bdab3')
45
45
  ```
46
46
 
47
- You can also get real-time updates
47
+ You can also get realtime updates
48
48
 
49
49
  ```python
50
50
  hs = httpstate.HttpState('45fb36540e9244daaa21ca409c6bdab3')
@@ -58,40 +58,53 @@ That's it! 🐙
58
58
 
59
59
  ### Functions
60
60
 
61
- - `get(uuid)`
61
+ - `get(uuid)`
62
62
  Get state of UUIDv4.
63
63
 
64
- - `read(uuid)`
64
+ - `post(uuid, data)`
65
+ Alias for `set`.
66
+
67
+ - `read(uuid)`
65
68
  Alias for `get`.
66
69
 
67
- - `set(uuid, data)`
70
+ - `set(uuid, data)`
68
71
  Set state of UUIDv4.
69
72
 
70
- - `write(uuid, data)`
73
+ - `write(uuid, data)`
71
74
  Alias for `set`.
72
75
 
73
76
  ### HttpState Class
74
77
 
75
- - `HttpState(uuid)`
78
+ - `HttpState(uuid)`
76
79
  Create a reactive state instance of UUIDv4.
80
+ - `<HttpState>.data`
81
+ Property with the most up-to-date state value.
77
82
 
78
83
  <br>
79
84
 
80
- - `<HttpState>.get()`
85
+ - `<HttpState>.get()`
81
86
  Get state.
82
- - `<HttpState>.read()`
87
+ - `<HttpState>.post(data)`
88
+ Alias for `set`.
89
+ - `<HttpState>.read()`
83
90
  Alias for `get`.
84
- - `<HttpState>.set(data)`
91
+ - `<HttpState>.set(data)`
85
92
  Set state.
86
- - `<HttpState>.write(data)`
93
+ - `<HttpState>.write(data)`
87
94
  Alias for `set`.
88
95
 
89
96
  <br>
90
97
 
91
- - `<HttpState>.off(type, callback)`
92
- Unsubscribe from real-time updates.
93
- - `<HttpState>.on(type, callback)`
94
- Subscribe to real-time updates (type = `change`).
98
+ - `<HttpState>.off(type, callback)`
99
+ Unsubscribe from realtime updates.
100
+ - `<HttpState>.on(type, callback)`
101
+ Subscribe to realtime updates.
102
+ - `change`: fired when state data changes. Callback receives current data as argument.
103
+
104
+ <br>
105
+
106
+ - `<HttpState>.delete()`
107
+ Cleanup and delete the instance.
95
108
 
96
109
  ---
97
110
 
@@ -14,7 +14,7 @@ Import
14
14
  import httpstate
15
15
  ```
16
16
 
17
- Pick any valid UUID v4. You can [generate one here](https://www.uuidgenerator.net/version4).
17
+ Pick any valid UUID v4. You can [generate one here](https://uuid.httpstate.com).
18
18
 
19
19
  We'll use `45fb3654-0e92-44da-aa21-ca409c6bdab3` or `45fb36540e9244daaa21ca409c6bdab3` (without dashes).
20
20
 
@@ -30,7 +30,7 @@ and retrieve it with
30
30
  data = httpstate.get('45fb36540e9244daaa21ca409c6bdab3')
31
31
  ```
32
32
 
33
- You can also get real-time updates
33
+ You can also get realtime updates
34
34
 
35
35
  ```python
36
36
  hs = httpstate.HttpState('45fb36540e9244daaa21ca409c6bdab3')
@@ -44,40 +44,53 @@ That's it! 🐙
44
44
 
45
45
  ### Functions
46
46
 
47
- - `get(uuid)`
47
+ - `get(uuid)`
48
48
  Get state of UUIDv4.
49
49
 
50
- - `read(uuid)`
50
+ - `post(uuid, data)`
51
+ Alias for `set`.
52
+
53
+ - `read(uuid)`
51
54
  Alias for `get`.
52
55
 
53
- - `set(uuid, data)`
56
+ - `set(uuid, data)`
54
57
  Set state of UUIDv4.
55
58
 
56
- - `write(uuid, data)`
59
+ - `write(uuid, data)`
57
60
  Alias for `set`.
58
61
 
59
62
  ### HttpState Class
60
63
 
61
- - `HttpState(uuid)`
64
+ - `HttpState(uuid)`
62
65
  Create a reactive state instance of UUIDv4.
66
+ - `<HttpState>.data`
67
+ Property with the most up-to-date state value.
63
68
 
64
69
  <br>
65
70
 
66
- - `<HttpState>.get()`
71
+ - `<HttpState>.get()`
67
72
  Get state.
68
- - `<HttpState>.read()`
73
+ - `<HttpState>.post(data)`
74
+ Alias for `set`.
75
+ - `<HttpState>.read()`
69
76
  Alias for `get`.
70
- - `<HttpState>.set(data)`
77
+ - `<HttpState>.set(data)`
71
78
  Set state.
72
- - `<HttpState>.write(data)`
79
+ - `<HttpState>.write(data)`
73
80
  Alias for `set`.
74
81
 
75
82
  <br>
76
83
 
77
- - `<HttpState>.off(type, callback)`
78
- Unsubscribe from real-time updates.
79
- - `<HttpState>.on(type, callback)`
80
- Subscribe to real-time updates (type = `change`).
84
+ - `<HttpState>.off(type, callback)`
85
+ Unsubscribe from realtime updates.
86
+ - `<HttpState>.on(type, callback)`
87
+ Subscribe to realtime updates.
88
+ - `change`: fired when state data changes. Callback receives current data as argument.
89
+
90
+ <br>
91
+
92
+ - `<HttpState>.delete()`
93
+ Cleanup and delete the instance.
81
94
 
82
95
  ---
83
96
 
@@ -16,7 +16,7 @@ license-files = ["LICEN[CS]E*"]
16
16
  name = "httpstate"
17
17
  readme = "README.md"
18
18
  requires-python = ">=3.10"
19
- version = "0.0.13"
19
+ version = "0.0.14"
20
20
 
21
21
  [project.url]
22
22
  Homepage = "https://httpstate.com"
@@ -8,6 +8,9 @@
8
8
 
9
9
  from .httpstate import(
10
10
  get,
11
+ message,
12
+ post,
13
+ put,
11
14
  read,
12
15
  set,
13
16
  write,
@@ -16,6 +19,9 @@ from .httpstate import(
16
19
 
17
20
  __all__ = [
18
21
  'get',
22
+ 'message',
23
+ 'post',
24
+ 'put',
19
25
  'read',
20
26
  'set',
21
27
  'write',
@@ -7,7 +7,9 @@
7
7
  # version 3 of the License, or (at your option) any later version.
8
8
 
9
9
  import asyncio
10
+ import struct
10
11
  import threading
12
+ import types
11
13
  import urllib.error
12
14
  import urllib.request
13
15
  import websockets
@@ -26,11 +28,38 @@ def get(uuid:str) -> None|str:
26
28
  except Exception:
27
29
  return None
28
30
 
31
+ class MessageType:
32
+ def __init__(self, uuid:str, timestamp:int, type:int, value:bytes) -> None:
33
+ self.uuid:str = uuid
34
+ self.timestamp:int = timestamp
35
+ self.type:int = type
36
+ self.value:bytes = value
37
+
38
+ class Message:
39
+ @staticmethod
40
+ def unpack(b:bytes) -> MessageType:
41
+ length:int = b[0]
42
+
43
+ return MessageType(
44
+ uuid=b[1:1+length].decode('utf-8'),
45
+ timestamp=struct.unpack_from('>Q', b, 1+length)[0],
46
+ type=b[1+length+8],
47
+ value=b[1+length+9:],
48
+ )
49
+
50
+ message:type = Message
51
+
52
+ def post(uuid:str, data:str) -> None|int:
53
+ return set(uuid, data)
54
+
55
+ def put(uuid:str, data:str) -> None|int:
56
+ return set(uuid, data)
57
+
29
58
  def read(uuid:str) -> None|str:
30
59
  return get(uuid)
31
60
 
32
61
  def set(uuid:str, data:str) -> None|int:
33
- req = urllib.request.Request(
62
+ req:urllib.request.Request = urllib.request.Request(
34
63
  f'https://httpstate.com/{uuid}',
35
64
  data=data.encode('utf-8'),
36
65
  headers={ 'Content-Type':'text/plain;charset=UTF-8' },
@@ -50,7 +79,7 @@ def write(uuid:str, data:str) -> None|int:
50
79
 
51
80
  # HTTP State
52
81
  class HttpState:
53
- def __init__(self, uuid:str):
82
+ def __init__(self, uuid:str) -> None:
54
83
  self.data:None|str = None
55
84
  self.el:None|asyncio.AbstractEventLoop = None
56
85
  self.et:Dict[str, List[Callable[[None|str], None]]] = {}
@@ -67,8 +96,8 @@ class HttpState:
67
96
  target=lambda : asyncio.run(self._ws())
68
97
  ).start()
69
98
 
70
- def _el(self):
71
- self.el = asyncio.new_event_loop()
99
+ def _el(self) -> None:
100
+ self.el:asyncio.AbstractEventLoop = asyncio.new_event_loop()
72
101
 
73
102
  asyncio.set_event_loop(self.el)
74
103
 
@@ -76,29 +105,28 @@ class HttpState:
76
105
 
77
106
  self.el.run_forever()
78
107
 
79
- async def _ws(self):
80
- self.ws = await websockets.connect(f"wss://httpstate.com/{self.uuid}")
108
+ async def _ws(self) -> None:
109
+ self.ws:websockets.WebSocketClientProtocol = await websockets.connect(f"wss://httpstate.com/{self.uuid}")
81
110
 
82
111
  await self.ws.send(f'{{"open":"{self.uuid}"}}')
83
112
  self.emit('open')
84
113
 
85
- async def data():
114
+ async def data() -> None:
86
115
  async for data in self.ws:
87
- data = data.decode()
116
+ data:MessageType = message.unpack(data)
88
117
 
89
118
  if(
90
119
  data
91
- and len(data) > 32
92
- and data[:32] == self.uuid
93
- and data[45] == '1'
120
+ and data.uuid == self.uuid
121
+ and data.type == 1
94
122
  ):
95
- self.data = data[46:]
123
+ self.data:None|str = data.value.decode()
96
124
 
97
125
  self.emit('change', self.data)
98
126
 
99
127
  asyncio.create_task(data())
100
128
 
101
- async def interval():
129
+ async def interval() -> None:
102
130
  while True:
103
131
  try:
104
132
  await self.ws.ping()
@@ -111,10 +139,10 @@ class HttpState:
111
139
 
112
140
  await asyncio.Event().wait()
113
141
 
114
- def destroy(self):
142
+ def delete(self) -> None:
115
143
  pass
116
144
 
117
- def emit(self, type:str, data:None|str = None):
145
+ def emit(self, type:str, data:None|str = None) -> "HttpState":
118
146
  for callback in self.et.get(type, []):
119
147
  if(data is None):
120
148
  callback()
@@ -124,7 +152,7 @@ class HttpState:
124
152
  return self
125
153
 
126
154
  def get(self) -> None|str:
127
- data = get(self.uuid)
155
+ data:None|str = get(self.uuid)
128
156
 
129
157
  if(data != self.data):
130
158
  self.el.call_soon_threadsafe(lambda : self.emit('change', self.data))
@@ -133,7 +161,7 @@ class HttpState:
133
161
 
134
162
  return self.data
135
163
 
136
- def off(self, type:str, callback:Callable[[None|str], None]):
164
+ def off(self, type:str, callback:Callable[[None|str], None]) -> "HttpState":
137
165
  if type in self.et:
138
166
  try:
139
167
  self.et[type].remove(callback)
@@ -145,13 +173,19 @@ class HttpState:
145
173
 
146
174
  return self
147
175
 
148
- def on(self, type:str, callback:Callable[[None|str], None]):
176
+ def on(self, type:str, callback:Callable[[None|str], None]) -> "HttpState":
149
177
  if type not in self.et:
150
178
  self.et[type] = []
151
179
 
152
180
  self.et[type].append(callback)
153
181
 
154
182
  return self
183
+
184
+ def post(self, data:str) -> None|int:
185
+ return self.set(data)
186
+
187
+ def put(self, data:str) -> None|int:
188
+ return self.set(data)
155
189
 
156
190
  def read(self) -> None|str:
157
191
  return self.get()
File without changes
File without changes