lionagi 0.0.209__py3-none-any.whl → 0.0.211__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 (86) hide show
  1. lionagi/__init__.py +2 -4
  2. lionagi/api_service/base_endpoint.py +65 -0
  3. lionagi/api_service/base_rate_limiter.py +121 -0
  4. lionagi/api_service/base_service.py +146 -0
  5. lionagi/api_service/chat_completion.py +6 -0
  6. lionagi/api_service/embeddings.py +6 -0
  7. lionagi/api_service/payload_package.py +47 -0
  8. lionagi/api_service/status_tracker.py +29 -0
  9. lionagi/core/__init__.py +3 -3
  10. lionagi/core/branch.py +22 -3
  11. lionagi/core/session.py +14 -2
  12. lionagi/schema/__init__.py +5 -8
  13. lionagi/schema/base_schema.py +821 -0
  14. lionagi/structures/graph.py +1 -1
  15. lionagi/structures/relationship.py +1 -1
  16. lionagi/structures/structure.py +1 -1
  17. lionagi/tools/tool_manager.py +0 -163
  18. lionagi/tools/tool_util.py +2 -1
  19. lionagi/utils/__init__.py +5 -6
  20. lionagi/utils/api_util.py +6 -1
  21. lionagi/version.py +1 -1
  22. {lionagi-0.0.209.dist-info → lionagi-0.0.211.dist-info}/METADATA +3 -18
  23. lionagi-0.0.211.dist-info/RECORD +56 -0
  24. lionagi/agents/planner.py +0 -1
  25. lionagi/agents/prompter.py +0 -1
  26. lionagi/agents/scorer.py +0 -1
  27. lionagi/agents/summarizer.py +0 -1
  28. lionagi/agents/validator.py +0 -1
  29. lionagi/bridge/__init__.py +0 -22
  30. lionagi/bridge/langchain.py +0 -195
  31. lionagi/bridge/llama_index.py +0 -266
  32. lionagi/datastores/__init__.py +0 -1
  33. lionagi/datastores/chroma.py +0 -1
  34. lionagi/datastores/deeplake.py +0 -1
  35. lionagi/datastores/elasticsearch.py +0 -1
  36. lionagi/datastores/lantern.py +0 -1
  37. lionagi/datastores/pinecone.py +0 -1
  38. lionagi/datastores/postgres.py +0 -1
  39. lionagi/datastores/qdrant.py +0 -1
  40. lionagi/iservices/anthropic.py +0 -79
  41. lionagi/iservices/anyscale.py +0 -0
  42. lionagi/iservices/azure.py +0 -1
  43. lionagi/iservices/bedrock.py +0 -0
  44. lionagi/iservices/everlyai.py +0 -0
  45. lionagi/iservices/gemini.py +0 -0
  46. lionagi/iservices/gpt4all.py +0 -0
  47. lionagi/iservices/huggingface.py +0 -0
  48. lionagi/iservices/litellm.py +0 -33
  49. lionagi/iservices/localai.py +0 -0
  50. lionagi/iservices/openllm.py +0 -0
  51. lionagi/iservices/openrouter.py +0 -44
  52. lionagi/iservices/perplexity.py +0 -0
  53. lionagi/iservices/predibase.py +0 -0
  54. lionagi/iservices/rungpt.py +0 -0
  55. lionagi/iservices/vllm.py +0 -0
  56. lionagi/iservices/xinference.py +0 -0
  57. lionagi/loaders/__init__.py +0 -18
  58. lionagi/loaders/chunker.py +0 -166
  59. lionagi/loaders/load_util.py +0 -240
  60. lionagi/loaders/reader.py +0 -122
  61. lionagi/models/__init__.py +0 -0
  62. lionagi/models/base_model.py +0 -0
  63. lionagi/models/imodel.py +0 -53
  64. lionagi/parsers/__init__.py +0 -1
  65. lionagi/schema/async_queue.py +0 -158
  66. lionagi/schema/base_condition.py +0 -1
  67. lionagi/schema/base_node.py +0 -422
  68. lionagi/schema/base_tool.py +0 -44
  69. lionagi/schema/data_logger.py +0 -131
  70. lionagi/schema/data_node.py +0 -88
  71. lionagi/schema/status_tracker.py +0 -37
  72. lionagi/tests/test_utils/test_encrypt_util.py +0 -323
  73. lionagi/utils/encrypt_util.py +0 -283
  74. lionagi-0.0.209.dist-info/RECORD +0 -98
  75. /lionagi/{agents → api_service}/__init__.py +0 -0
  76. /lionagi/{iservices → services}/__init__.py +0 -0
  77. /lionagi/{iservices → services}/base_service.py +0 -0
  78. /lionagi/{iservices → services}/mistralai.py +0 -0
  79. /lionagi/{iservices → services}/mlx_service.py +0 -0
  80. /lionagi/{iservices → services}/oai.py +0 -0
  81. /lionagi/{iservices → services}/ollama.py +0 -0
  82. /lionagi/{iservices → services}/services.py +0 -0
  83. /lionagi/{iservices → services}/transformers.py +0 -0
  84. {lionagi-0.0.209.dist-info → lionagi-0.0.211.dist-info}/LICENSE +0 -0
  85. {lionagi-0.0.209.dist-info → lionagi-0.0.211.dist-info}/WHEEL +0 -0
  86. {lionagi-0.0.209.dist-info → lionagi-0.0.211.dist-info}/top_level.txt +0 -0
@@ -1,37 +0,0 @@
1
- from dataclasses import dataclass
2
-
3
-
4
- # credit to OpenAI for the following object
5
- @dataclass
6
- class StatusTracker:
7
- """
8
- Class for keeping track of various task statuses.
9
-
10
- This class serves as a simple way to monitor different types of task
11
- outcomes and errors within a system. It uses dataclasses for easy
12
- creation and management of state.
13
-
14
- Attributes:
15
- num_tasks_started:
16
- The number of tasks that have been initiated.
17
- num_tasks_in_progress:
18
- The number of tasks currently being processed.
19
- num_tasks_succeeded:
20
- The number of tasks that have completed successfully.
21
- num_tasks_failed:
22
- The number of tasks that have failed.
23
- num_rate_limit_errors:
24
- The number of tasks that failed due to rate limiting.
25
- num_api_errors:
26
- The number of tasks that failed due to API errors.
27
- num_other_errors:
28
- The number of tasks that failed due to other errors.
29
- """
30
- num_tasks_started: int = 0
31
- num_tasks_in_progress: int = 0
32
- num_tasks_succeeded: int = 0
33
- num_tasks_failed: int = 0
34
- num_rate_limit_errors: int = 0
35
- num_api_errors: int = 0
36
- num_other_errors: int = 0
37
-
@@ -1,323 +0,0 @@
1
- import unittest
2
- import os
3
- import tempfile
4
- import zipfile
5
- import hashlib
6
- from cryptography.fernet import InvalidToken
7
- from lionagi.utils.encrypt_util import EncrytionUtil
8
-
9
-
10
- class TestPasswordStrengthChecker(unittest.TestCase):
11
-
12
- def test_short_passwords(self):
13
- self.assertFalse(EncrytionUtil.password_strength_checker("Short1"))
14
- self.assertFalse(EncrytionUtil.password_strength_checker("A1"))
15
-
16
- def test_passwords_without_digits(self):
17
- self.assertFalse(EncrytionUtil.password_strength_checker("NoDigitsHere"))
18
- self.assertFalse(EncrytionUtil.password_strength_checker("Onlyletters!"))
19
-
20
- def test_passwords_without_uppercase(self):
21
- self.assertFalse(EncrytionUtil.password_strength_checker("alllowercase1"))
22
- self.assertFalse(EncrytionUtil.password_strength_checker("nouppercase1!"))
23
-
24
- def test_strong_passwords(self):
25
- self.assertTrue(EncrytionUtil.password_strength_checker("ValidPass1"))
26
- self.assertTrue(EncrytionUtil.password_strength_checker("AnotherGood1"))
27
-
28
-
29
- class TestGenerateEncryptionKey(unittest.TestCase):
30
-
31
- def setUp(self):
32
- # Strong password and predefined salt for testing
33
- self.strong_password = "StrongPass1"
34
- self.salt = b'0123456789abcdef'
35
-
36
- def test_with_strong_password_and_provided_salt(self):
37
- key = EncrytionUtil.generate_encryption_key(password=self.strong_password, salt=self.salt)
38
- self.assertIsInstance(key, str)
39
-
40
- def test_with_strong_password_and_no_salt(self):
41
- key = EncrytionUtil.generate_encryption_key(password=self.strong_password)
42
- self.assertIsInstance(key, str)
43
-
44
- def test_with_weak_password(self):
45
- with self.assertRaises(ValueError):
46
- EncrytionUtil.generate_encryption_key(password="weak")
47
-
48
- def test_with_no_password(self):
49
- key = EncrytionUtil.generate_encryption_key()
50
- self.assertIsInstance(key, str)
51
- self.assertEqual(len(key), 44) # Typical length of a Fernet key
52
-
53
-
54
- class TestEncrypt(unittest.TestCase):
55
-
56
- def setUp(self):
57
- self.valid_key = EncrytionUtil.generate_encryption_key("StrongPass1")
58
- self.invalid_key = "invalidkey"
59
- self.test_data = "This is a test string."
60
-
61
- def test_valid_encryption(self):
62
- encrypted_data = EncrytionUtil.encrypt(self.test_data, self.valid_key)
63
- self.assertIsInstance(encrypted_data, str)
64
- self.assertNotEqual(encrypted_data, self.test_data)
65
-
66
- def test_with_invalid_key(self):
67
- with self.assertRaises(Exception):
68
- EncrytionUtil.encrypt(self.test_data, self.invalid_key)
69
-
70
- def test_with_non_string_data(self):
71
- with self.assertRaises(AttributeError): # or whichever error is appropriate
72
- EncrytionUtil.encrypt(12345, self.valid_key)
73
-
74
- def test_with_empty_string(self):
75
- encrypted_data = EncrytionUtil.encrypt("", self.valid_key)
76
- self.assertIsInstance(encrypted_data, str)
77
- self.assertNotEqual(encrypted_data, "")
78
-
79
-
80
- class TestDecrypt(unittest.TestCase):
81
-
82
- def setUp(self):
83
- self.valid_key = EncrytionUtil.generate_encryption_key("StrongPass1")
84
- self.invalid_key = "invalidkey"
85
- self.test_data = "This is a test string."
86
- self.encrypted_data = EncrytionUtil.encrypt(self.test_data, self.valid_key)
87
-
88
- def test_valid_decryption(self):
89
- decrypted_data = EncrytionUtil.decrypt(self.encrypted_data, self.valid_key)
90
- self.assertIsInstance(decrypted_data, str)
91
- self.assertEqual(decrypted_data, self.test_data)
92
-
93
- def test_decryption_with_invalid_key(self):
94
- with self.assertRaises(ValueError):
95
- EncrytionUtil.decrypt(self.encrypted_data, self.invalid_key)
96
-
97
- def test_with_non_string_data(self):
98
- with self.assertRaises(AttributeError):
99
- EncrytionUtil.decrypt(12345, self.valid_key)
100
-
101
- def test_decryption_of_non_encrypted_string(self):
102
- with self.assertRaises(InvalidToken):
103
- EncrytionUtil.decrypt("plain text", self.valid_key)
104
-
105
-
106
- class TestEncryptFile(unittest.TestCase):
107
-
108
- def setUp(self):
109
- self.valid_key = EncrytionUtil.generate_encryption_key("StrongPass1")
110
- # Create a temporary file with some test data
111
- self.temp_file = tempfile.NamedTemporaryFile(delete=False)
112
- self.temp_file.write(b"This is a test file.")
113
- self.temp_file.close()
114
-
115
- def tearDown(self):
116
- # Cleanup: Remove temporary files
117
- os.remove(self.temp_file.name)
118
- if os.path.exists(self.temp_file.name + '.enc'):
119
- os.remove(self.temp_file.name + '.enc')
120
-
121
- def test_encrypting_valid_file(self):
122
- EncrytionUtil.encrypt_file(self.temp_file.name, self.valid_key)
123
- self.assertTrue(os.path.exists(self.temp_file.name + '.enc'))
124
-
125
- def test_with_non_existent_file_path(self):
126
- with self.assertRaises(FileNotFoundError):
127
- EncrytionUtil.encrypt_file("non_existent_file.txt", self.valid_key)
128
-
129
-
130
- class TestDecryptFile(unittest.TestCase):
131
-
132
- def setUp(self):
133
- self.valid_key = EncrytionUtil.generate_encryption_key("StrongPass1")
134
- # Create a temporary file and encrypt it
135
- self.temp_file = tempfile.NamedTemporaryFile(delete=False)
136
- self.temp_file.write(b"This is a test file.")
137
- self.temp_file.close()
138
- EncrytionUtil.encrypt_file(self.temp_file.name, self.valid_key)
139
-
140
- def tearDown(self):
141
- # Cleanup: Remove temporary files
142
- os.remove(self.temp_file.name)
143
- if os.path.exists(self.temp_file.name + '.enc'):
144
- os.remove(self.temp_file.name + '.enc')
145
- decrypted_file_path = self.temp_file.name.replace('.enc', '')
146
- if os.path.exists(decrypted_file_path):
147
- os.remove(decrypted_file_path)
148
-
149
- def test_decrypting_valid_encrypted_file(self):
150
- EncrytionUtil.decrypt_file(self.temp_file.name + '.enc', self.valid_key)
151
- decrypted_file_path = self.temp_file.name.replace('.enc', '')
152
- self.assertTrue(os.path.exists(decrypted_file_path))
153
-
154
- def test_with_non_existent_encrypted_file_path(self):
155
- with self.assertRaises(FileNotFoundError):
156
- EncrytionUtil.decrypt_file("non_existent_file.txt.enc", self.valid_key)
157
-
158
- def test_decrypting_with_invalid_key(self):
159
- with self.assertRaises(ValueError):
160
- EncrytionUtil.decrypt_file(self.temp_file.name + '.enc', 'invalidkey')
161
-
162
-
163
- class TestIsEncrypted(unittest.TestCase):
164
-
165
- def setUp(self):
166
- self.valid_key = EncrytionUtil.generate_encryption_key("StrongPass1")
167
- # Create a temporary file and encrypt it
168
- self.temp_file = tempfile.NamedTemporaryFile(delete=False)
169
- self.temp_file.write(b"This is a test file.")
170
- self.temp_file.close()
171
- EncrytionUtil.encrypt_file(self.temp_file.name, self.valid_key)
172
-
173
- # Create a non-encrypted temporary file
174
- self.non_encrypted_file = tempfile.NamedTemporaryFile(delete=False)
175
- self.non_encrypted_file.write(b"This is a non-encrypted test file.")
176
- self.non_encrypted_file.close()
177
-
178
- def tearDown(self):
179
- # Cleanup: Remove temporary files
180
- os.remove(self.temp_file.name)
181
- if os.path.exists(self.temp_file.name + '.enc'):
182
- os.remove(self.temp_file.name + '.enc')
183
- os.remove(self.non_encrypted_file.name)
184
-
185
- def test_with_encrypted_file(self):
186
- self.assertTrue(EncrytionUtil.is_encrypted(self.temp_file.name + '.enc', self.valid_key))
187
-
188
- def test_with_non_encrypted_file(self):
189
- self.assertFalse(EncrytionUtil.is_encrypted(self.non_encrypted_file.name, self.valid_key))
190
-
191
-
192
- class TestDecompressFile(unittest.TestCase):
193
-
194
- def setUp(self):
195
- # Create a temporary directory
196
- self.temp_dir = tempfile.mkdtemp()
197
-
198
- # Create a temporary zip file with some content
199
- self.temp_zip_file = os.path.join(self.temp_dir, 'test.zip')
200
- with zipfile.ZipFile(self.temp_zip_file, 'w') as zipf:
201
- zipf.writestr('test.txt', 'This is a test file.')
202
-
203
- def tearDown(self):
204
- # Cleanup: Remove temporary directory and its contents
205
- for root, dirs, files in os.walk(self.temp_dir, topdown=False):
206
- for name in files:
207
- os.remove(os.path.join(root, name))
208
- for name in dirs:
209
- os.rmdir(os.path.join(root, name))
210
- os.rmdir(self.temp_dir)
211
-
212
- def test_decompressing_valid_zip_file(self):
213
- EncrytionUtil.decompress_file(self.temp_zip_file, self.temp_dir)
214
- self.assertTrue(os.path.exists(os.path.join(self.temp_dir, 'test.txt')))
215
-
216
- def test_with_non_existent_zip_file_path(self):
217
- with self.assertRaises(FileNotFoundError):
218
- EncrytionUtil.decompress_file("non_existent_file.zip", self.temp_dir)
219
-
220
- def test_with_invalid_zip_file(self):
221
- invalid_zip_file = os.path.join(self.temp_dir, 'invalid.zip')
222
- with open(invalid_zip_file, 'w') as f:
223
- f.write("This is not a zip file.")
224
- with self.assertRaises(zipfile.BadZipFile):
225
- EncrytionUtil.decompress_file(invalid_zip_file, self.temp_dir)
226
-
227
-
228
- class TestCompressFile(unittest.TestCase):
229
-
230
- def setUp(self):
231
- # Create a temporary file with some test data
232
- self.temp_file = tempfile.NamedTemporaryFile(delete=False)
233
- self.temp_file.write(b"This is a test file.")
234
- self.temp_file.close()
235
-
236
- def tearDown(self):
237
- # Cleanup: Remove temporary files
238
- os.remove(self.temp_file.name)
239
- if os.path.exists(self.temp_file.name + '.zip'):
240
- os.remove(self.temp_file.name + '.zip')
241
-
242
- def test_compressing_valid_file(self):
243
- EncrytionUtil.compress_file(self.temp_file.name)
244
- self.assertTrue(os.path.exists(self.temp_file.name + '.zip'))
245
-
246
- def test_with_non_existent_file_path(self):
247
- with self.assertRaises(FileNotFoundError):
248
- EncrytionUtil.compress_file("non_existent_file.txt")
249
-
250
-
251
- class TestBinaryToHex(unittest.TestCase):
252
-
253
- def test_with_valid_binary_data(self):
254
- # Test a variety of binary data
255
- self.assertEqual(EncrytionUtil.binary_to_hex(b'\x00\x0F'), '000f')
256
- self.assertEqual(EncrytionUtil.binary_to_hex(b'hello'), '68656c6c6f')
257
- self.assertEqual(EncrytionUtil.binary_to_hex(b'\xff\xfe\xfd\xfc'), 'fffefdfc')
258
-
259
- def test_with_empty_bytes(self):
260
- self.assertEqual(EncrytionUtil.binary_to_hex(b''), '')
261
-
262
-
263
- class TestCreateHash(unittest.TestCase):
264
-
265
- def test_hashing_with_default_algorithm(self):
266
- data = "test"
267
- expected_hash = hashlib.sha256(data.encode()).hexdigest()
268
- self.assertEqual(EncrytionUtil.create_hash(data), expected_hash)
269
-
270
- def test_hashing_with_different_algorithms(self):
271
- data = "test"
272
- algorithms = ['sha1', 'sha224', 'sha384', 'sha512']
273
- for algo in algorithms:
274
- with self.subTest(algorithm=algo):
275
- expected_hash = hashlib.new(algo, data.encode()).hexdigest()
276
- self.assertEqual(EncrytionUtil.create_hash(data, algo), expected_hash)
277
-
278
- def test_with_unsupported_algorithm(self):
279
- with self.assertRaises(ValueError):
280
- EncrytionUtil.create_hash("test", "unsupported_algo")
281
-
282
-
283
- class TestDecodeBase64(unittest.TestCase):
284
-
285
- def test_with_valid_base64_encoded_strings(self):
286
- # Test a variety of valid base64 encoded strings
287
- test_cases = [
288
- ("SGVsbG8sIFdvcmxkIQ==", "Hello, World!"),
289
- ("VGhpcyBpcyBhIHRlc3Q=", "This is a test"),
290
- ("c29tZSBieXRlcw==", "some bytes")
291
- ]
292
- for encoded, original in test_cases:
293
- with self.subTest(encoded=encoded):
294
- self.assertEqual(EncrytionUtil.decode_base64(encoded), original)
295
-
296
- def test_with_invalid_base64_string(self):
297
- invalid_data = "This is not base64!"
298
- with self.assertRaises(Exception): # Replace Exception with the specific exception if known
299
- EncrytionUtil.decode_base64(invalid_data)
300
-
301
- def test_with_empty_string(self):
302
- self.assertEqual(EncrytionUtil.decode_base64(""), "")
303
-
304
-
305
- class TestEncodeBase64(unittest.TestCase):
306
-
307
- def test_with_valid_strings(self):
308
- # Test a variety of strings
309
- test_cases = [
310
- ("Hello, World!", "SGVsbG8sIFdvcmxkIQ=="),
311
- ("This is a test", "VGhpcyBpcyBhIHRlc3Q="),
312
- ("some bytes", "c29tZSBieXRlcw==")
313
- ]
314
- for original, encoded in test_cases:
315
- with self.subTest(original=original):
316
- self.assertEqual(EncrytionUtil.encode_base64(original), encoded)
317
-
318
- def test_with_empty_string(self):
319
- self.assertEqual(EncrytionUtil.encode_base64(""), "")
320
-
321
-
322
- if __name__ == '__main__':
323
- unittest.main()
@@ -1,283 +0,0 @@
1
- import base64
2
- import binascii
3
- import hashlib
4
- import os
5
- import zipfile
6
- from base64 import urlsafe_b64encode
7
- from cryptography.fernet import Fernet, InvalidToken
8
- from cryptography.hazmat.backends import default_backend
9
- from cryptography.hazmat.primitives import hashes
10
- from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
11
- from typing import Optional
12
-
13
-
14
- class EncrytionUtil:
15
- """
16
- A utility class for handling encryption, decryption, file operations, and password strength checking.
17
- """
18
-
19
- @staticmethod
20
- def password_strength_checker(password: str) -> bool:
21
- """
22
- Check the strength of a password.
23
-
24
- Args:
25
- password (str): The password to check.
26
-
27
- Returns:
28
- bool: True if the password is strong, False otherwise.
29
-
30
- Examples:
31
- >>> password_strength_checker("Weakpass")
32
- False
33
- >>> password_strength_checker("Strongpass1")
34
- True
35
- """
36
- if len(password) < 8 or not any(char.isdigit() for char in password) or not any(char.isupper() for char in password):
37
- return False
38
- return True
39
-
40
- @staticmethod
41
- def generate_encryption_key(password: Optional[str] = None, salt: Optional[bytes] = None) -> str:
42
- """
43
- Generate an encryption key from a password and salt.
44
-
45
- Args:
46
- password (Optional[str]): The password to derive the key from. If None, a random key is generated.
47
- salt (Optional[bytes]): A salt for the key derivation. If None, a random salt is used.
48
-
49
- Returns:
50
- str: The generated encryption key as a URL-safe base64-encoded string.
51
-
52
- Raises:
53
- ValueError: If the password is too weak.
54
-
55
- Examples:
56
- >>> key = generate_encryption_key("Strongpass1")
57
- >>> isinstance(key, str)
58
- True
59
- """
60
- if password:
61
- if not EncrytionUtil.password_strength_checker(password):
62
- raise ValueError("Password is too weak.")
63
- if not salt:
64
- salt = os.urandom(16)
65
- kdf = PBKDF2HMAC(
66
- algorithm=hashes.SHA256(),
67
- length=32,
68
- salt=salt,
69
- iterations=100000,
70
- backend=default_backend()
71
- )
72
- key = kdf.derive(password.encode())
73
- return urlsafe_b64encode(key).decode()
74
- else:
75
- return Fernet.generate_key().decode()
76
-
77
- @staticmethod
78
- def encrypt(data: str, key: str) -> str:
79
- """
80
- Encrypt the provided data using the provided key.
81
-
82
- Args:
83
- data (str): The data to encrypt.
84
- key (str): The encryption key.
85
-
86
- Returns:
87
- str: The encrypted data.
88
-
89
- Example:
90
- >>> encrypt("This is some test data.", "esvCExTuhddRb8kSobU_gnNRYObyTRTI2LJF4nYai5I=")
91
- 'gAAAAABloX9m_S_G1VUtbfGUDB7ooHJNt8sPiSCwnp1ehe6dExvMEqtw_ua2ELk_uUbLoB6a1XkbKLOkM4UBvwmk6sMoY-yNvE-Lv-w-VNnfzf89zH82rgI='
92
- """
93
- fernet = Fernet(key.encode())
94
- return fernet.encrypt(data.encode()).decode()
95
-
96
- @staticmethod
97
- def decrypt(data: str, key: str) -> str:
98
- """
99
- Decrypt the provided data using the provided key.
100
-
101
- Args:
102
- data (str): The data to decrypt.
103
- key (str): The encryption key.
104
-
105
- Returns:
106
- str: The decrypted data.
107
-
108
- Example:
109
- >>> decrypt('gAAAAABloX9m_S_G1VUtbfGUDB7ooHJNt8sPiSCwnp1ehe6dExvMEqtw_ua2ELk_uUbLoB6a1XkbKLOkM4UBvwmk6sMoY-yNvE-Lv-w-VNnfzf89zH82rgI=', "esvCExTuhddRb8kSobU_gnNRYObyTRTI2LJF4nYai5I=")
110
- 'This is some test data.'
111
- """
112
- fernet = Fernet(key.encode())
113
- return fernet.decrypt(data.encode()).decode()
114
-
115
- @staticmethod
116
- def encrypt_file(file_path: str, key: str, output_path: str = None):
117
- """
118
- Encrypt a file.
119
-
120
- Args:
121
- file_path (str): The path of the file to encrypt.
122
- key (str): The encryption key.
123
- output_path (str, optional): The path to save the encrypted file. If not provided, '.enc' is appended to the input file path.
124
-
125
- Example:
126
- >>> encrypt_file("test_file.txt", "esvCExTuhddRb8kSobU_gnNRYObyTRTI2LJF4nYai5I=")
127
- """
128
- if not output_path:
129
- output_path = file_path + '.enc'
130
- with open(file_path, 'rb') as file_to_encrypt:
131
- encrypted_data = EncrytionUtil.encrypt(file_to_encrypt.read().decode(), key)
132
- with open(output_path, 'wb') as encrypted_file:
133
- encrypted_file.write(encrypted_data.encode())
134
-
135
- @staticmethod
136
- def decrypt_file(encrypted_file_path: str, key: str, output_path: str = None):
137
- """
138
- Decrypt a file.
139
-
140
- Args:
141
- encrypted_file_path (str): The path of the file to decrypt.
142
- key (str): The encryption key.
143
- output_path (str, optional): The path to save the decrypted file. If not provided, '.enc' is removed from the input file path.
144
-
145
- Example:
146
- >>> decrypt_file("test_file.txt.enc", "esvCExTuhddRb8kSobU_gnNRYObyTRTI2LJF4nYai5I=")
147
- """
148
- if not output_path:
149
- output_path = encrypted_file_path.replace('.enc', '')
150
- with open(encrypted_file_path, 'rb') as encrypted_file:
151
- decrypted_data = EncrytionUtil.decrypt(encrypted_file.read().decode(), key)
152
- with open(output_path, 'wb') as decrypted_file:
153
- decrypted_file.write(decrypted_data.encode())
154
-
155
- @staticmethod
156
- def is_encrypted(file_path: str, key: str) -> bool:
157
- """
158
- Check if a file is encrypted.
159
-
160
- Args:
161
- file_path (str): The path of the file to check.
162
- key (str): The encryption key.
163
-
164
- Returns:
165
- bool: True if the file is encrypted, False otherwise.
166
-
167
- Example:
168
- >>> is_encrypted("test_file.txt.enc", "esvCExTuhddRb8kSobU_gnNRYObyTRTI2LJF4nYai5I=")
169
- True
170
- """
171
- try:
172
- EncrytionUtil.decrypt_file(file_path, key, "temp_decrypted_file")
173
- os.remove("temp_decrypted_file")
174
- return True
175
- except InvalidToken:
176
- return False
177
-
178
- @staticmethod
179
- def decompress_file(file_path: str, output_path: str = None):
180
- """
181
- Decompress a file.
182
-
183
- Args:
184
- file_path (str): The path of the file to decompress.
185
- output_path (str, optional): The path to save the decompressed file. If not provided, the file is decompressed in the same directory.
186
-
187
- Example:
188
- >>> decompress_file("test_file.txt.zip")
189
- """
190
- if not output_path:
191
- output_path = os.path.dirname(file_path)
192
- with zipfile.ZipFile(file_path, 'r') as zipf:
193
- zipf.extractall(output_path)
194
-
195
- @staticmethod
196
- def compress_file(file_path: str, output_path: str = None):
197
- """
198
- Compress a file.
199
-
200
- Args:
201
- file_path (str): The path of the file to compress.
202
- output_path (str, optional): The path to save the compressed file. If not provided, '.zip' is appended to the input file path.
203
-
204
- Example:
205
- >>> compress_file("test_file.txt")
206
- """
207
- if not output_path:
208
- output_path = file_path + '.zip'
209
- with zipfile.ZipFile(output_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
210
- zipf.write(file_path)
211
-
212
- @staticmethod
213
- def binary_to_hex(data: bytes) -> str:
214
- """
215
- Convert binary data to a hexadecimal string representation.
216
-
217
- Args:
218
- data: A bytes object containing binary data.
219
-
220
- Returns:
221
- A string containing the hexadecimal representation of the binary data.
222
-
223
- Examples:
224
- >>> binary_to_hex(b'\x00\x0F')
225
- '000f'
226
- >>> binary_to_hex(b'hello')
227
- '68656c6c6f'
228
- """
229
- return binascii.hexlify(data).decode()
230
-
231
- @staticmethod
232
- def create_hash(data: str, algorithm: str = 'sha256') -> str:
233
- """
234
- Create a hash of the given data using the specified algorithm.
235
-
236
- Args:
237
- data: The string to hash.
238
- algorithm: The hashing algorithm to use (default is 'sha256').
239
-
240
- Returns:
241
- The hexadecimal digest of the hash.
242
-
243
- Examples:
244
- >>> create_hash('hello')
245
- '2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824'
246
- """
247
- hasher = hashlib.new(algorithm)
248
- hasher.update(data.encode())
249
- return hasher.hexdigest()
250
-
251
- @staticmethod
252
- def decode_base64(data: str) -> str:
253
- """
254
- Decode a base64 encoded string.
255
-
256
- Args:
257
- data: A base64 encoded string.
258
-
259
- Returns:
260
- A decoded string.
261
-
262
- Examples:
263
- >>> decode_base64('SGVsbG8sIFdvcmxkIQ==')
264
- 'Hello, World!'
265
- """
266
- return base64.b64decode(data).decode()
267
-
268
- @staticmethod
269
- def encode_base64(data: str) -> str:
270
- """
271
- Encode a string using base64 encoding.
272
-
273
- Args:
274
- data: A string to be encoded.
275
-
276
- Returns:
277
- A base64 encoded string.
278
-
279
- Examples:
280
- >>> encode_base64("Hello, World!")
281
- 'SGVsbG8sIFdvcmxkIQ=='
282
- """
283
- return base64.b64encode(data.encode()).decode()