km-keybind 1.0.0__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.
@@ -0,0 +1,170 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or
41
+ Object form, that is based on (or derived from) the Work and for
42
+ which the editorial revisions, annotations, elaborations, or other
43
+ modifications represent, as a whole, an original work of authorship.
44
+ For the purposes of this License, Derivative Works shall not include
45
+ works that remain separable from, or merely link (or bind by name)
46
+ to the interfaces of, the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publish, distribute, sublicense, and/or sell copies of the Work, and
71
+ to permit persons to whom the Work is furnished to do so.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
124
+ any Contribution intentionally submitted for inclusion in the Work
125
+ by You to the Licensor shall be under the terms and conditions of
126
+ this License, without any additional terms or conditions.
127
+ Notwithstanding the above, nothing herein shall supersede or modify
128
+ the terms of any separate license agreement you may have executed
129
+ with Licensor regarding such Contributions.
130
+
131
+ 6. Trademarks. This License does not grant permission to use the trade
132
+ names, trademarks, service marks, or product names of the Licensor,
133
+ except as required for reasonable and customary use in describing the
134
+ origin of the Work and reproducing the content of the NOTICE file.
135
+
136
+ 7. Disclaimer of Warranty. Unless required by applicable law or
137
+ agreed to in writing, Licensor provides the Work (and each
138
+ Contributor provides its Contributions) on an "AS IS" BASIS,
139
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
140
+ implied, including, without limitation, any warranties or conditions
141
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
142
+ PARTICULAR PURPOSE. You are solely responsible for determining the
143
+ appropriateness of using or redistributing the Work and assume any
144
+ risks associated with the exercise of permissions under this License.
145
+
146
+ 8. Limitation of Liability. In no event and under no legal theory,
147
+ whether in tort (including negligence), contract, or otherwise,
148
+ unless required by applicable law (such as deliberate and grossly
149
+ negligent acts) or agreed to in writing, shall any Contributor be
150
+ liable to You for damages, including any direct, indirect, special,
151
+ incidental, or consequential damages of any character including
152
+ without limitation damages for loss of goodwill, work stoppage,
153
+ computer failure or malfunction, or any and all other commercial
154
+ damages or losses, arising out of or related to the Work or the use or
155
+ other dealings in the Work, neither in tort nor contract, or otherwise,
156
+ except as agreed by the Contributor in writing.
157
+
158
+ 9. Accepting Warranty or Additional Liability. While redistributing
159
+ the Work or Derivative Works thereof, You may choose to offer,
160
+ and charge a fee for, acceptance of support, warranty, indemnity,
161
+ or other liability obligations and/or rights consistent with this
162
+ License. However, in accepting such obligations, You may act only
163
+ on Your own behalf and on Your sole responsibility, not on behalf
164
+ of any other Contributor, and only if You agree to indemnify,
165
+ defend, and hold each Contributor harmless for any liability
166
+ incurred by, or claims asserted against, such Contributor by reason
167
+ of, or arising out of, your accepting any such warranty or
168
+ additional liability.
169
+
170
+ END OF TERMS AND CONDITIONS
@@ -0,0 +1,241 @@
1
+ Metadata-Version: 2.4
2
+ Name: km-keybind
3
+ Version: 1.0.0
4
+ Summary: Stateless encrypted identity-bound token library
5
+ Author: Pravanjan Roy
6
+ Project-URL: Homepage, https://github.com/kingmon6996/keybind
7
+ Project-URL: Repository, https://github.com/kingmon6996/keybind
8
+ Project-URL: Issues, https://github.com/kingmon6996/keybind/issues
9
+ Keywords: km-keybind,keybind,encrypted-token,identity-bound,stateless-token,cryptography
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: License :: OSI Approved :: Apache Software License
12
+ Classifier: Operating System :: OS Independent
13
+ Requires-Python: >=3.9
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE
16
+ Requires-Dist: cryptography
17
+ Requires-Dist: PyNaCl
18
+ Requires-Dist: zstandard
19
+ Requires-Dist: blake3
20
+ Requires-Dist: orjson
21
+ Requires-Dist: typing-extensions
22
+ Dynamic: license-file
23
+
24
+ # Keybind
25
+
26
+ Keybind is a Python library for turning JSON-compatible data and files into compact, encrypted, identity-bound tokens. It is useful when you want to send or store structured data or file payloads in a self-contained form without keeping server-side state.
27
+
28
+ ## What Keybind is for
29
+
30
+ You can use Keybind when you need to:
31
+
32
+ - create a compact token from a dictionary or other JSON-compatible object
33
+ - bind that token to a specific user or application context
34
+ - keep the payload encrypted and self-contained
35
+ - safely pass the token across systems or store it for later use
36
+
37
+ Typical use cases include:
38
+
39
+ - temporary session payloads
40
+ - encrypted user profile fragments
41
+ - backend-to-backend message transport
42
+ - short-lived access tokens with embedded data
43
+ - compact state handoff between services
44
+
45
+ ## The master key
46
+
47
+ The master key is the secret value that unlocks and protects the token. It is supplied when you create a Keybind instance:
48
+
49
+ ```python
50
+ from keybind import Keybind
51
+
52
+ chain = Keybind(b"master-key")
53
+ ```
54
+
55
+ In real projects, use a strong secret instead of a sample string. A good master key should be:
56
+
57
+ - long enough to be unpredictable
58
+ - stored securely
59
+ - kept private
60
+ - reused consistently for the same application context
61
+
62
+ ### How to generate a master key
63
+
64
+ A simple and safe approach is to generate a random 32-byte key:
65
+
66
+ ```python
67
+ import os
68
+
69
+ master_key = os.urandom(32)
70
+ chain = Keybind(master_key)
71
+ ```
72
+
73
+ You can also store it in an environment variable:
74
+
75
+ ```python
76
+ import os
77
+
78
+ master_key = os.environ["KEYBIND_MASTER_KEY"].encode("utf-8")
79
+ chain = Keybind(master_key)
80
+ ```
81
+
82
+ ### Why the master key matters
83
+
84
+ - It is the root secret used to derive the encryption key.
85
+ - The same key must be used later when decoding the token.
86
+ - If the master key changes, the token cannot be decrypted correctly.
87
+
88
+ ## Identities
89
+
90
+ Keybind also takes two identity values during encoding and decoding:
91
+
92
+ ```python
93
+ from keybind.keybind import DICT
94
+
95
+ token = chain.encode("user123", "app", DICT, {"hello": "world"})
96
+ chain.decode("user123", "app", token)
97
+ ```
98
+
99
+ These identities bind the token to a specific context. In practice:
100
+
101
+ - the first identity is often a user, account, or subject
102
+ - the second identity is often an app, service, or environment
103
+
104
+ This means the token is not only encrypted, but also tied to the identities used when it was created.
105
+
106
+ ## Full example
107
+
108
+ Here is a complete example from start to finish:
109
+
110
+ ```python
111
+ from keybind import Keybind
112
+ from keybind.keybind import DICT
113
+
114
+ master_key = b"example-master-key"
115
+ chain = Keybind(master_key)
116
+
117
+ payload = {
118
+ "user": "alice",
119
+ "role": "admin",
120
+ "permissions": ["read", "write"],
121
+ "active": True,
122
+ }
123
+
124
+ token = chain.encode("alice", "dashboard", DICT, payload)
125
+ print("Token:", token)
126
+
127
+ decoded, decoded_type = chain.decode("alice", "dashboard", token)
128
+ print("Decoded:", decoded)
129
+ print("Decoded type:", decoded_type)
130
+ ```
131
+
132
+ ### What happens in this example
133
+
134
+ 1. A Keybind instance is created with a master key.
135
+ 2. A JSON-compatible payload is prepared.
136
+ 3. The payload is turned into an encrypted token.
137
+ 4. The token is later decoded back into the original object.
138
+
139
+ ## How the library works internally
140
+
141
+ Keybind now supports file payloads via the `FILE` payload type. When you encode a file path, the raw file contents are encrypted and later decoded to a saved file path under `decoded_files/`, preserving the original filename.
142
+
143
+ ```python
144
+ from keybind import Keybind
145
+ from keybind.keybind import FILE
146
+
147
+ chain = Keybind(b"example-master-key")
148
+
149
+ token = chain.encode("alice", "dashboard", FILE, "summary.txt")
150
+ file_path, decoded_type = chain.decode("alice", "dashboard", token)
151
+ print("Decoded file saved to:", file_path)
152
+ print("Decoded type:", decoded_type)
153
+ ```
154
+
155
+ When you call encode, Keybind performs these steps:
156
+
157
+ 1. Normalizes the two identities.
158
+ 2. Serializes the payload into bytes.
159
+ 3. Applies optional compression.
160
+ 4. Derives an encryption key from the master key and identities.
161
+ 5. Encrypts the payload.
162
+ 6. Produces a compact token string.
163
+
164
+ When you call decode, it reverses this process:
165
+
166
+ 1. Validates the token format.
167
+ 2. Re-derives the key using the same master key and identities.
168
+ 3. Decrypts the payload.
169
+ 4. Reconstructs the original JSON-compatible object.
170
+
171
+ ## Example use cases
172
+
173
+ ### 1. Temporary user session payload
174
+
175
+ ```python
176
+ import os
177
+ from keybind import Keybind
178
+ from keybind.keybind import DICT
179
+
180
+ chain = Keybind(os.urandom(32))
181
+
182
+ session_data = {"user_id": 42, "plan": "pro", "expires_in": 3600}
183
+ token = chain.encode("42", "web-app", DICT, session_data)
184
+ ```
185
+
186
+ ### 2. Cross-service message transport
187
+
188
+ ```python
189
+ from keybind import Keybind
190
+ from keybind.keybind import DICT
191
+
192
+ chain = Keybind(b"shared-secret")
193
+
194
+ message = {"event": "user.created", "id": 101}
195
+ token = chain.encode("service-a", "service-b", DICT, message)
196
+ ```
197
+
198
+ ### 3. Compact state handoff
199
+
200
+ ```python
201
+ from keybind import Keybind
202
+ from keybind.keybind import DICT
203
+
204
+ chain = Keybind(b"state-secret")
205
+
206
+ state = {"step": 3, "status": "pending", "retry": False}
207
+ token = chain.encode("job-17", "worker", DICT, state)
208
+ ```
209
+
210
+ ## Important security notes
211
+
212
+ - Keep the master key secret.
213
+ - Do not hard-code production secrets in source files.
214
+ - Use a secure secret store or environment variable in production.
215
+ - Reuse the same master key consistently for the same application context.
216
+ - Keep the identities meaningful and consistent with your system design.
217
+
218
+ ## Installation
219
+
220
+ Install the package from PyPI with:
221
+
222
+ ```bash
223
+ pip install km-keybind
224
+ ```
225
+
226
+ Install it directly from GitHub as a package with:
227
+
228
+ ```bash
229
+ pip install git+https://github.com/kingmon6996/keybind.git
230
+ ```
231
+
232
+ ## Summary
233
+
234
+ Keybind gives you a simple way to turn JSON-compatible data into a compact, encrypted, identity-bound token. The core idea is straightforward:
235
+
236
+ - provide a master key
237
+ - provide two identities
238
+ - encode data into a token
239
+ - decode later with the same key and identities
240
+
241
+ Thank you for using Keybind.
@@ -0,0 +1,218 @@
1
+ # Keybind
2
+
3
+ Keybind is a Python library for turning JSON-compatible data and files into compact, encrypted, identity-bound tokens. It is useful when you want to send or store structured data or file payloads in a self-contained form without keeping server-side state.
4
+
5
+ ## What Keybind is for
6
+
7
+ You can use Keybind when you need to:
8
+
9
+ - create a compact token from a dictionary or other JSON-compatible object
10
+ - bind that token to a specific user or application context
11
+ - keep the payload encrypted and self-contained
12
+ - safely pass the token across systems or store it for later use
13
+
14
+ Typical use cases include:
15
+
16
+ - temporary session payloads
17
+ - encrypted user profile fragments
18
+ - backend-to-backend message transport
19
+ - short-lived access tokens with embedded data
20
+ - compact state handoff between services
21
+
22
+ ## The master key
23
+
24
+ The master key is the secret value that unlocks and protects the token. It is supplied when you create a Keybind instance:
25
+
26
+ ```python
27
+ from keybind import Keybind
28
+
29
+ chain = Keybind(b"master-key")
30
+ ```
31
+
32
+ In real projects, use a strong secret instead of a sample string. A good master key should be:
33
+
34
+ - long enough to be unpredictable
35
+ - stored securely
36
+ - kept private
37
+ - reused consistently for the same application context
38
+
39
+ ### How to generate a master key
40
+
41
+ A simple and safe approach is to generate a random 32-byte key:
42
+
43
+ ```python
44
+ import os
45
+
46
+ master_key = os.urandom(32)
47
+ chain = Keybind(master_key)
48
+ ```
49
+
50
+ You can also store it in an environment variable:
51
+
52
+ ```python
53
+ import os
54
+
55
+ master_key = os.environ["KEYBIND_MASTER_KEY"].encode("utf-8")
56
+ chain = Keybind(master_key)
57
+ ```
58
+
59
+ ### Why the master key matters
60
+
61
+ - It is the root secret used to derive the encryption key.
62
+ - The same key must be used later when decoding the token.
63
+ - If the master key changes, the token cannot be decrypted correctly.
64
+
65
+ ## Identities
66
+
67
+ Keybind also takes two identity values during encoding and decoding:
68
+
69
+ ```python
70
+ from keybind.keybind import DICT
71
+
72
+ token = chain.encode("user123", "app", DICT, {"hello": "world"})
73
+ chain.decode("user123", "app", token)
74
+ ```
75
+
76
+ These identities bind the token to a specific context. In practice:
77
+
78
+ - the first identity is often a user, account, or subject
79
+ - the second identity is often an app, service, or environment
80
+
81
+ This means the token is not only encrypted, but also tied to the identities used when it was created.
82
+
83
+ ## Full example
84
+
85
+ Here is a complete example from start to finish:
86
+
87
+ ```python
88
+ from keybind import Keybind
89
+ from keybind.keybind import DICT
90
+
91
+ master_key = b"example-master-key"
92
+ chain = Keybind(master_key)
93
+
94
+ payload = {
95
+ "user": "alice",
96
+ "role": "admin",
97
+ "permissions": ["read", "write"],
98
+ "active": True,
99
+ }
100
+
101
+ token = chain.encode("alice", "dashboard", DICT, payload)
102
+ print("Token:", token)
103
+
104
+ decoded, decoded_type = chain.decode("alice", "dashboard", token)
105
+ print("Decoded:", decoded)
106
+ print("Decoded type:", decoded_type)
107
+ ```
108
+
109
+ ### What happens in this example
110
+
111
+ 1. A Keybind instance is created with a master key.
112
+ 2. A JSON-compatible payload is prepared.
113
+ 3. The payload is turned into an encrypted token.
114
+ 4. The token is later decoded back into the original object.
115
+
116
+ ## How the library works internally
117
+
118
+ Keybind now supports file payloads via the `FILE` payload type. When you encode a file path, the raw file contents are encrypted and later decoded to a saved file path under `decoded_files/`, preserving the original filename.
119
+
120
+ ```python
121
+ from keybind import Keybind
122
+ from keybind.keybind import FILE
123
+
124
+ chain = Keybind(b"example-master-key")
125
+
126
+ token = chain.encode("alice", "dashboard", FILE, "summary.txt")
127
+ file_path, decoded_type = chain.decode("alice", "dashboard", token)
128
+ print("Decoded file saved to:", file_path)
129
+ print("Decoded type:", decoded_type)
130
+ ```
131
+
132
+ When you call encode, Keybind performs these steps:
133
+
134
+ 1. Normalizes the two identities.
135
+ 2. Serializes the payload into bytes.
136
+ 3. Applies optional compression.
137
+ 4. Derives an encryption key from the master key and identities.
138
+ 5. Encrypts the payload.
139
+ 6. Produces a compact token string.
140
+
141
+ When you call decode, it reverses this process:
142
+
143
+ 1. Validates the token format.
144
+ 2. Re-derives the key using the same master key and identities.
145
+ 3. Decrypts the payload.
146
+ 4. Reconstructs the original JSON-compatible object.
147
+
148
+ ## Example use cases
149
+
150
+ ### 1. Temporary user session payload
151
+
152
+ ```python
153
+ import os
154
+ from keybind import Keybind
155
+ from keybind.keybind import DICT
156
+
157
+ chain = Keybind(os.urandom(32))
158
+
159
+ session_data = {"user_id": 42, "plan": "pro", "expires_in": 3600}
160
+ token = chain.encode("42", "web-app", DICT, session_data)
161
+ ```
162
+
163
+ ### 2. Cross-service message transport
164
+
165
+ ```python
166
+ from keybind import Keybind
167
+ from keybind.keybind import DICT
168
+
169
+ chain = Keybind(b"shared-secret")
170
+
171
+ message = {"event": "user.created", "id": 101}
172
+ token = chain.encode("service-a", "service-b", DICT, message)
173
+ ```
174
+
175
+ ### 3. Compact state handoff
176
+
177
+ ```python
178
+ from keybind import Keybind
179
+ from keybind.keybind import DICT
180
+
181
+ chain = Keybind(b"state-secret")
182
+
183
+ state = {"step": 3, "status": "pending", "retry": False}
184
+ token = chain.encode("job-17", "worker", DICT, state)
185
+ ```
186
+
187
+ ## Important security notes
188
+
189
+ - Keep the master key secret.
190
+ - Do not hard-code production secrets in source files.
191
+ - Use a secure secret store or environment variable in production.
192
+ - Reuse the same master key consistently for the same application context.
193
+ - Keep the identities meaningful and consistent with your system design.
194
+
195
+ ## Installation
196
+
197
+ Install the package from PyPI with:
198
+
199
+ ```bash
200
+ pip install km-keybind
201
+ ```
202
+
203
+ Install it directly from GitHub as a package with:
204
+
205
+ ```bash
206
+ pip install git+https://github.com/kingmon6996/keybind.git
207
+ ```
208
+
209
+ ## Summary
210
+
211
+ Keybind gives you a simple way to turn JSON-compatible data into a compact, encrypted, identity-bound token. The core idea is straightforward:
212
+
213
+ - provide a master key
214
+ - provide two identities
215
+ - encode data into a token
216
+ - decode later with the same key and identities
217
+
218
+ Thank you for using Keybind.
@@ -0,0 +1,19 @@
1
+ # Copyright 2026 Pravanjan Roy
2
+
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from .keybind import Keybind
16
+
17
+ __all__ = ["Keybind"]
18
+
19
+
@@ -0,0 +1,30 @@
1
+ # Copyright 2026 Pravanjan Roy
2
+
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from __future__ import annotations
16
+
17
+
18
+ class ChunkManager:
19
+
20
+ def __init__(self, chunk_size: int = 1024 * 1024) -> None:
21
+ self.chunk_size = chunk_size
22
+
23
+ def split(self, payload: bytes) -> list[bytes]:
24
+ if payload is None:
25
+ return []
26
+ if len(payload) == 0:
27
+ return [b""]
28
+ return [payload[i : i + self.chunk_size] for i in range(0, len(payload), self.chunk_size)]
29
+
30
+