python-plugins 0.1.2__tar.gz → 0.1.4__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.
Files changed (60) hide show
  1. {python_plugins-0.1.2 → python_plugins-0.1.4}/CHANGES.rst +15 -0
  2. {python_plugins-0.1.2 → python_plugins-0.1.4}/PKG-INFO +3 -1
  3. {python_plugins-0.1.2 → python_plugins-0.1.4}/docs/usage.rst +9 -0
  4. {python_plugins-0.1.2 → python_plugins-0.1.4}/pyproject.toml +1 -0
  5. python_plugins-0.1.4/requirements/test.in +5 -0
  6. python_plugins-0.1.4/src/python_plugins/__about__.py +1 -0
  7. python_plugins-0.1.4/src/python_plugins/convert/__init__.py +2 -0
  8. python_plugins-0.1.4/src/python_plugins/convert/datetime_str.py +15 -0
  9. python_plugins-0.1.4/src/python_plugins/convert/xml.py +7 -0
  10. python_plugins-0.1.4/src/python_plugins/crypto/__init__.py +1 -0
  11. python_plugins-0.1.4/src/python_plugins/crypto/fernet.py +41 -0
  12. python_plugins-0.1.4/src/python_plugins/crypto/str_to_list.py +91 -0
  13. python_plugins-0.1.4/src/python_plugins/dumps/__init__.py +2 -0
  14. python_plugins-0.1.4/src/python_plugins/dumps/postgresql_dump.py +31 -0
  15. python_plugins-0.1.4/src/python_plugins/hashes/__init__.py +1 -0
  16. python_plugins-0.1.4/src/python_plugins/hashes/hash.py +26 -0
  17. python_plugins-0.1.4/src/python_plugins/jwt/__init__.py +1 -0
  18. python_plugins-0.1.4/src/python_plugins/jwt/jwt.py +37 -0
  19. python_plugins-0.1.4/src/python_plugins/models/update.py +33 -0
  20. python_plugins-0.1.4/src/python_plugins/process/__init__.py +2 -0
  21. python_plugins-0.1.4/src/python_plugins/process/python_venv_process.py +18 -0
  22. python_plugins-0.1.4/src/python_plugins/process/sub_process.py +12 -0
  23. python_plugins-0.1.4/src/python_plugins/random/__init__.py +4 -0
  24. python_plugins-0.1.4/src/python_plugins/random/random_str.py +46 -0
  25. python_plugins-0.1.4/src/python_plugins/utils/remove_pycache.py +13 -0
  26. python_plugins-0.1.4/tests/test_crypto.py +82 -0
  27. python_plugins-0.1.4/tests/test_jwt.py +25 -0
  28. python_plugins-0.1.4/tests/test_process.py +9 -0
  29. python_plugins-0.1.4/tests/test_random.py +8 -0
  30. python_plugins-0.1.4/tests/test_sqlalchemy.py +29 -0
  31. python_plugins-0.1.4/tests/test_utils.py +8 -0
  32. python_plugins-0.1.2/requirements/test.in +0 -2
  33. python_plugins-0.1.2/src/python_plugins/__about__.py +0 -1
  34. {python_plugins-0.1.2 → python_plugins-0.1.4}/.github/workflows/release.yml +0 -0
  35. {python_plugins-0.1.2 → python_plugins-0.1.4}/.gitignore +0 -0
  36. {python_plugins-0.1.2 → python_plugins-0.1.4}/.readthedocs.yaml +0 -0
  37. {python_plugins-0.1.2 → python_plugins-0.1.4}/LICENSE.rst +0 -0
  38. {python_plugins-0.1.2 → python_plugins-0.1.4}/README.rst +0 -0
  39. {python_plugins-0.1.2 → python_plugins-0.1.4}/docs/Makefile +0 -0
  40. {python_plugins-0.1.2 → python_plugins-0.1.4}/docs/api.rst +0 -0
  41. {python_plugins-0.1.2 → python_plugins-0.1.4}/docs/changes.rst +0 -0
  42. {python_plugins-0.1.2 → python_plugins-0.1.4}/docs/conf.py +0 -0
  43. {python_plugins-0.1.2 → python_plugins-0.1.4}/docs/examples.rst +0 -0
  44. {python_plugins-0.1.2 → python_plugins-0.1.4}/docs/index.rst +0 -0
  45. {python_plugins-0.1.2 → python_plugins-0.1.4}/docs/make.bat +0 -0
  46. {python_plugins-0.1.2 → python_plugins-0.1.4}/docs/requirements.txt +0 -0
  47. {python_plugins-0.1.2 → python_plugins-0.1.4}/examples/README.rst +0 -0
  48. {python_plugins-0.1.2 → python_plugins-0.1.4}/requirements/build.in +0 -0
  49. {python_plugins-0.1.2 → python_plugins-0.1.4}/src/python_plugins/__init__.py +0 -0
  50. {python_plugins-0.1.2 → python_plugins-0.1.4}/src/python_plugins/email/__init__.py +0 -0
  51. {python_plugins-0.1.2 → python_plugins-0.1.4}/src/python_plugins/email/smtp.py +0 -0
  52. {python_plugins-0.1.2 → python_plugins-0.1.4}/src/python_plugins/models/__init__.py +0 -0
  53. {python_plugins-0.1.2 → python_plugins-0.1.4}/src/python_plugins/models/mixins/__init__.py +0 -0
  54. {python_plugins-0.1.2 → python_plugins-0.1.4}/src/python_plugins/models/mixins/data_mixin.py +0 -0
  55. {python_plugins-0.1.2 → python_plugins-0.1.4}/src/python_plugins/models/mixins/primary_key_mixin.py +0 -0
  56. {python_plugins-0.1.2 → python_plugins-0.1.4}/src/python_plugins/models/mixins/timestamp_mixin.py +0 -0
  57. {python_plugins-0.1.2 → python_plugins-0.1.4}/src/python_plugins/models/mixins/user_minxin.py +0 -0
  58. {python_plugins-0.1.2 → python_plugins-0.1.4}/tests/__init__.py +0 -0
  59. {python_plugins-0.1.2 → python_plugins-0.1.4}/tests/conftest.py +0 -0
  60. {python_plugins-0.1.2 → python_plugins-0.1.4}/tests/test_email.py +0 -0
@@ -1,3 +1,18 @@
1
+ v0.1.4
2
+ ------
3
+
4
+ Released 2024-09-26
5
+
6
+ - remove_pycache
7
+ - models.update
8
+
9
+ v0.1.3
10
+ ------
11
+
12
+ Released 2024-09-19
13
+
14
+ - support random_str,jwt,hash_file,fernet
15
+
1
16
  v0.1.2
2
17
  ------
3
18
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: python-plugins
3
- Version: 0.1.2
3
+ Version: 0.1.4
4
4
  Summary: A collection of Python functions and classes.
5
5
  Project-URL: Documentation, https://python-plugins.readthedocs.io
6
6
  Project-URL: Source, https://github.com/ojso/python-plugins
@@ -40,6 +40,8 @@ Classifier: Topic :: Software Development :: Build Tools
40
40
  Requires-Python: >=3.10
41
41
  Provides-Extra: cryptography
42
42
  Requires-Dist: cryptography; extra == 'cryptography'
43
+ Provides-Extra: jwt
44
+ Requires-Dist: pyjwt; extra == 'jwt'
43
45
  Provides-Extra: pillow
44
46
  Requires-Dist: pillow; extra == 'pillow'
45
47
  Provides-Extra: qrcode
@@ -50,3 +50,12 @@ mixins
50
50
 
51
51
  class User(PrimaryKeyMixin,UserMixin, TimestampMixin,db.models):
52
52
  pass
53
+
54
+ remove_pycache
55
+ =======================
56
+
57
+ .. code-block :: python
58
+
59
+ from python_plugins.utils.remove_pycache import remove_pycache
60
+
61
+ remove_pycache(".")
@@ -31,6 +31,7 @@ sqlalchemy = ["SQLAlchemy"]
31
31
  cryptography = ["cryptography"]
32
32
  pillow = ["pillow"]
33
33
  qrcode = ["qrcode"]
34
+ jwt = ["PyJWT"]
34
35
 
35
36
  [project.urls]
36
37
  Documentation = "https://python-plugins.readthedocs.io"
@@ -0,0 +1,5 @@
1
+ pytest
2
+ Faker
3
+ cryptography
4
+ SQLAlchemy
5
+ PyJWT
@@ -0,0 +1 @@
1
+ __version__ = "0.1.4"
@@ -0,0 +1,2 @@
1
+ from .datetime_str import datetime2str, str2datetime
2
+ from .xml import xml2dict
@@ -0,0 +1,15 @@
1
+ from datetime import datetime
2
+
3
+ date_fmt = "%Y-%m-%d"
4
+ datetime_fmt = "%Y-%m-%d %H:%M:%S"
5
+
6
+ # datetime.isoformat()
7
+ # datetime.fromisoformat(str)
8
+
9
+
10
+ def datetime2str(dt):
11
+ return datetime.strftime(dt, datetime_fmt)
12
+
13
+
14
+ def str2datetime(s):
15
+ return datetime.strptime(s, datetime_fmt)
@@ -0,0 +1,7 @@
1
+ import xml.etree.cElementTree as ET
2
+
3
+
4
+ def xml2dict(xmlstr):
5
+ xml_tree = ET.fromstring(xmlstr)
6
+ xmldict = {k.tag: k.text for k in xml_tree}
7
+ return xmldict
@@ -0,0 +1 @@
1
+ from .fernet import generate_fernet_key,fernet_encrypt,fernet_decrypt
@@ -0,0 +1,41 @@
1
+ import base64
2
+ from cryptography.hazmat.primitives import padding
3
+ from cryptography.fernet import Fernet
4
+
5
+ # Fernet文档 : https://github.com/fernet/spec/blob/master/Spec.md
6
+
7
+
8
+ def generate_fernet_key(key) -> bytes:
9
+ """see cryptography.fernet.Fernet.generate_key()
10
+
11
+ :param key: _description_
12
+ :raises ValueError: _description_
13
+ :return: _description_
14
+ """
15
+ if isinstance(key, str):
16
+ key = key.encode("utf-8")
17
+ if not isinstance(key, bytes):
18
+ raise ValueError
19
+ if len(key) < 32:
20
+ padder = padding.PKCS7(32 * 8).padder()
21
+ key = padder.update(key) + padder.finalize()
22
+ fernet_key = key[0:16] + key[16:32]
23
+ return base64.urlsafe_b64encode(fernet_key)
24
+
25
+
26
+ def fernet_encrypt(key, txt) -> str:
27
+ if isinstance(txt, str):
28
+ txt = txt.encode("utf-8")
29
+ fernet_key = generate_fernet_key(key)
30
+ f = Fernet(fernet_key)
31
+ token = f.encrypt(txt)
32
+ return token.decode("utf-8")
33
+
34
+
35
+ def fernet_decrypt(key, token) -> str:
36
+ if isinstance(token, str):
37
+ token = token.encode("utf-8")
38
+ fernet_key = generate_fernet_key(key)
39
+ f = Fernet(fernet_key)
40
+ decrypt_data = f.decrypt(token)
41
+ return decrypt_data.decode("utf-8")
@@ -0,0 +1,91 @@
1
+ import base64
2
+ import os
3
+ import random
4
+ from cryptography.fernet import Fernet
5
+ from cryptography.hazmat.primitives import hashes
6
+ from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
7
+ from ..random import rand_letter
8
+
9
+
10
+ def bytes_to_url64str(bstr: bytes):
11
+ s = base64.urlsafe_b64encode(bstr).rstrip(b"=").decode()
12
+ return s
13
+
14
+
15
+ def url64str_to_bytes(s):
16
+ _, r = divmod(len(s), 4)
17
+ bstr = base64.urlsafe_b64decode((s + "=" * r).encode())
18
+ return bstr
19
+
20
+
21
+ def get_key(password, safe_salt=None, times=None):
22
+ if isinstance(password, str):
23
+ password = password.encode()
24
+ if safe_salt is None:
25
+ salt = os.urandom(16)
26
+ safe_salt = bytes_to_url64str(salt)
27
+ else:
28
+ salt = url64str_to_bytes(safe_salt)
29
+ if times is None:
30
+ times = random.randint(100, 100000)
31
+
32
+ kdf = PBKDF2HMAC(
33
+ algorithm=hashes.SHA256(),
34
+ length=32,
35
+ salt=salt,
36
+ iterations=times,
37
+ )
38
+ key = base64.urlsafe_b64encode(kdf.derive(password))
39
+ return (key, safe_salt, times)
40
+
41
+
42
+ def str_randsplit_to_list(s, n1=10, n2=30):
43
+ r = []
44
+ while s:
45
+ if len(s) < 40:
46
+ r.append(s)
47
+ break
48
+ k = random.randint(n1, n2)
49
+ r.append(s[:k])
50
+ if k < len(s):
51
+ s = s[k:]
52
+ else:
53
+ s = ""
54
+ return r
55
+
56
+
57
+ def encrypt_str_to_list(s: str, password=None, prefix=None):
58
+ if password is None:
59
+ password = rand_letter(random.randint(6, 16))
60
+ out_password = password
61
+ else:
62
+ out_password = "-"
63
+ if prefix is not None:
64
+ password = str(prefix) + password
65
+
66
+ key, safe_salt, times = get_key(password)
67
+
68
+ cipher_suite = Fernet(key)
69
+ encrypted_data = cipher_suite.encrypt(s.encode())
70
+ safe_data = bytes_to_url64str(encrypted_data)
71
+
72
+ list_out = [out_password, safe_salt, str(times)] + str_randsplit_to_list(safe_data)
73
+
74
+ return list_out
75
+
76
+
77
+ def decrypt_list_to_str(list_in, password=None, prefix=None):
78
+ _password, safe_salt, _times, *_data = list_in
79
+ if password is None:
80
+ password = _password
81
+ else:
82
+ password = password
83
+ if prefix is not None:
84
+ password = str(prefix) + password
85
+
86
+ times = int(_times)
87
+ s = "".join(_data)
88
+ key, _, _ = get_key(password, safe_salt, times)
89
+ cipher_suite = Fernet(key)
90
+ decrypted_bytes = cipher_suite.decrypt(url64str_to_bytes(s))
91
+ return decrypted_bytes.decode()
@@ -0,0 +1,2 @@
1
+ from .postgresql_dump import pg_dump
2
+ from .postgresql_dump import remove_ndays_ago
@@ -0,0 +1,31 @@
1
+ import subprocess
2
+ import sys
3
+
4
+
5
+ def pg_dump(dump_dir, username, dbname, tbname):
6
+ """pg_dump
7
+
8
+ :param dir: dump dir
9
+ :param username: db user
10
+ :param dbname: db name
11
+ :param tbname: table name
12
+ """
13
+ pgdump_cmd = (
14
+ f"dump_user={username};dump_db={dbname};dump_tb={tbname};dump_dir={dump_dir};"
15
+ "pg_dump -U ${dump_user} --no-password -d ${dump_db} -t ${dump_tb} | gzip > ${dump_dir}/${dump_db}.${dump_tb}-`date +'%Y%m%d'`.gz;"
16
+ "cp ${dump_dir}/${dump_db}.${dump_tb}-`date +'%Y%m%d'`.gz ${dump_dir}/${dump_db}.${dump_tb}.gz;"
17
+ )
18
+ if sys.platform == "linux":
19
+ r = subprocess.run(pgdump_cmd, shell=True)
20
+ else:
21
+ r = f"not pg_dump because sys.platform is {sys.platform}"
22
+ return r
23
+
24
+
25
+ def remove_ndays_ago(dir, days=30):
26
+ remove_cmd = f"rm -f {dir}/*`date +'%Y%m%d' -d'-{days} days'`.gz"
27
+ if sys.platform == "linux":
28
+ r = subprocess.run(remove_cmd, shell=True)
29
+ else:
30
+ r = f"not remove files because sys.platform is {sys.platform}"
31
+ return r
@@ -0,0 +1 @@
1
+ from .hash import hash_file, hash_text
@@ -0,0 +1,26 @@
1
+ import hashlib
2
+ import os.path
3
+
4
+
5
+ def hash_file(filename, algorithm="sha1"):
6
+ if os.path.isfile(filename) is False:
7
+ raise Exception("File not found for hash operation")
8
+
9
+ sha_func = getattr(hashlib, algorithm)
10
+ sha_obj = sha_func()
11
+
12
+ with open(filename, "rb") as f:
13
+ chunk = 0
14
+ while chunk != b"":
15
+ chunk = f.read(1024)
16
+ sha_obj.update(chunk)
17
+
18
+ return sha_obj.hexdigest()
19
+
20
+
21
+ def hash_text(text, algorithm="sha1"):
22
+ # hashlib.md5(text).hexdigest() # simple
23
+ sha_func = getattr(hashlib, algorithm)
24
+ sha_obj = sha_func()
25
+ sha_obj.update(text)
26
+ return sha_obj.hexdigest()
@@ -0,0 +1 @@
1
+ from .jwt import jwt_encode, jwt_decode
@@ -0,0 +1,37 @@
1
+ import jwt
2
+ import datetime
3
+
4
+
5
+ def jwt_encode(payload: dict, key: str, delta: int = None, algorithm="HS256"):
6
+ """encode payload.
7
+
8
+ :param payload: _description_
9
+ :param key: _description_
10
+ :param delta: _description_, defaults to None
11
+ :param algorithm: _description_, defaults to "HS256"
12
+ :return: An encoded access token
13
+ """
14
+ if delta and delta > 0:
15
+ exp = datetime.datetime.now(tz=datetime.timezone.utc) + datetime.timedelta(
16
+ seconds=delta
17
+ )
18
+ payload |= {"exp": exp}
19
+
20
+ token = jwt.encode(payload, key, algorithm)
21
+ return token
22
+
23
+
24
+ def jwt_decode(encoded, key: str, algorithm="HS256"):
25
+ """decode jwt."""
26
+
27
+ payload = jwt.decode(encoded, key, algorithm)
28
+ return payload
29
+
30
+
31
+ # try:
32
+ # ...
33
+ # except Exception as e:
34
+ # # import sys
35
+ # # print(sys.exc_info())
36
+ # # return None,str(e)
37
+ # return None
@@ -0,0 +1,33 @@
1
+ def update_obj(db, old_obj, new_data: dict, NewClass, force=None):
2
+ """insert or update object
3
+
4
+ :param db: sqlalchemy db
5
+ :param old_obj: old object
6
+ :param new_data: new dict
7
+ :param NewClass: object class
8
+ :param force: update= update old object with new attribute
9
+ """
10
+ # 1. old is not exist
11
+ if old_obj is None:
12
+ new_obj = NewClass()
13
+ for k in new_data:
14
+ if hasattr(new_obj, k):
15
+ setattr(new_obj, k, new_data.get(k))
16
+ db.session.add(new_obj)
17
+ db.session.commit()
18
+ print(f"{new_obj} inserted")
19
+ return
20
+
21
+ # 2. old is exist
22
+ match force:
23
+ case None:
24
+ print(f"{old_obj} exists")
25
+ case "update":
26
+ # update old
27
+ for k in new_data:
28
+ if hasattr(old_obj, k):
29
+ setattr(old_obj, k, new_data.get(k))
30
+ db.session.commit()
31
+ print(f"{old_obj} updated")
32
+ case _:
33
+ raise Exception
@@ -0,0 +1,2 @@
1
+ from .sub_process import run_process
2
+ from .python_venv_process import run_process_in_venv
@@ -0,0 +1,18 @@
1
+ import subprocess
2
+ import os.path
3
+ import json
4
+
5
+
6
+ def run_process_in_venv(dir: str, cmd: str, params):
7
+ if not (os.path.exists(dir) and os.path.isdir(dir)):
8
+ return f"dir {dir} not exists"
9
+
10
+ cmd = [
11
+ os.path.join(dir, "venv/bin/python"),
12
+ os.path.join(dir, cmd),
13
+ json.dumps(params) if isinstance(params, dict) else str(params),
14
+ ]
15
+ # print(cmd)
16
+ completedProcess = subprocess.run(cmd, capture_output=True)
17
+ r = str(completedProcess)
18
+ return r
@@ -0,0 +1,12 @@
1
+ import subprocess
2
+ import json
3
+
4
+
5
+ def run_process(cmd: str, params=None,shell=False):
6
+ cmd_args = [
7
+ cmd,
8
+ json.dumps(params) if isinstance(params, dict) else str(params),
9
+ ]
10
+ completedProcess = subprocess.run(cmd_args, capture_output=True,shell=shell)
11
+ r = str(completedProcess)
12
+ return r
@@ -0,0 +1,4 @@
1
+ from .random_str import rand_digit
2
+ from .random_str import rand_letter
3
+ from .random_str import rand_sentence
4
+ from .random_str import secret_token, secret_token_16
@@ -0,0 +1,46 @@
1
+ import random
2
+ import string
3
+ import os
4
+ import base64
5
+ import uuid
6
+ import secrets
7
+
8
+ # random.sample # unique
9
+ # random.choices # not unique
10
+
11
+
12
+ def rand_digit(n):
13
+ """随机数字"""
14
+ return "".join(random.choices(string.digits, k=n))
15
+
16
+
17
+ def rand_letter(n: int):
18
+ return "".join(random.choices(string.ascii_letters + string.digits, k=n))
19
+
20
+
21
+ def rand_sentence(n):
22
+ return "".join(
23
+ random.choices(string.ascii_letters + string.digits + " " * 10, k=n)
24
+ ).strip()
25
+
26
+
27
+ def rand_uuid4():
28
+ return str(uuid.uuid4())
29
+
30
+
31
+ def rand_token():
32
+ return uuid.uuid4().hex
33
+
34
+
35
+ def secret_token():
36
+ return secrets.token_hex(32)
37
+
38
+
39
+ def secret_token_16():
40
+ return secrets.token_hex(16)
41
+
42
+
43
+ def rand_token_2(n):
44
+ # replace '+/' with '1a'
45
+ token = base64.b64encode(os.urandom(n), b"1a").decode()[0:n]
46
+ return token
@@ -0,0 +1,13 @@
1
+ import os
2
+ import shutil
3
+
4
+ def remove_pycache(dir_path):
5
+ for root, dirs, files in os.walk(dir_path):
6
+ if "venv" in root or "git" in root:
7
+ continue
8
+ for dir in dirs:
9
+ if dir == "__pycache__":
10
+ pycache_path = os.path.join(root, dir)
11
+ print(f"Removing {pycache_path}")
12
+ shutil.rmtree(pycache_path)
13
+
@@ -0,0 +1,82 @@
1
+ import pytest
2
+ import random
3
+ import base64
4
+ from python_plugins.random import rand_letter, rand_sentence
5
+ from python_plugins.random import secret_token, secret_token_16
6
+ from python_plugins.crypto.str_to_list import get_key
7
+ from python_plugins.crypto.str_to_list import encrypt_str_to_list, decrypt_list_to_str
8
+ from python_plugins.crypto import generate_fernet_key, fernet_encrypt, fernet_decrypt
9
+
10
+
11
+ class TestFetnet:
12
+ def test_random_secret_token(self):
13
+ token_1 = secret_token()
14
+ # print(token_1)
15
+ assert len(token_1) == 64
16
+ token_2 = secret_token_16()
17
+ # print(token_2)
18
+ assert len(token_2) == 32
19
+
20
+ def test_generate_fernet_key(self, fake):
21
+ skey = fake.sentence()
22
+ key = generate_fernet_key(skey)
23
+ # print(key)
24
+ decode_key = base64.urlsafe_b64decode(key)
25
+ # print(decode_key)
26
+ assert len(decode_key) == 32
27
+
28
+ def test_fernet_encrypt_decrypt(self, fake):
29
+ key = generate_fernet_key(fake.sentence())
30
+ txt = fake.sentence()
31
+ # print(key,txt)
32
+ token = fernet_encrypt(key, txt)
33
+ # print(token)
34
+ assert isinstance(token, str)
35
+ decrypt_txt = fernet_decrypt(key, token)
36
+ # print(decrypt_txt)
37
+ assert isinstance(decrypt_txt, str)
38
+ assert txt == decrypt_txt
39
+
40
+
41
+ class TestStr2List:
42
+ def test_get_key(self):
43
+ password = rand_letter(random.randint(1, 50))
44
+ key, safe_salt, times = get_key(password)
45
+ decode_key = base64.urlsafe_b64decode(key)
46
+ assert len(decode_key) == 32
47
+
48
+ def test_encrypt_decrypt(self):
49
+ s = rand_sentence(random.randint(10, 100))
50
+ encrypted_list = encrypt_str_to_list(s)
51
+ s2 = decrypt_list_to_str(encrypted_list)
52
+ assert s == s2
53
+
54
+ def test_encrypt_decrypt_with_password(self):
55
+ s = rand_sentence(random.randint(10, 100))
56
+ password = rand_letter(16)
57
+ encrypted_list = encrypt_str_to_list(s, password)
58
+ with pytest.raises(Exception):
59
+ s1 = decrypt_list_to_str(encrypted_list)
60
+ s2 = decrypt_list_to_str(encrypted_list, password)
61
+ assert s == s2
62
+ s3 = decrypt_list_to_str([None] + encrypted_list[1:], password)
63
+ assert s == s3
64
+
65
+ def test_encrypt_decrypt_with_prefix(self):
66
+ s = rand_sentence(random.randint(10, 100))
67
+ prefix = rand_letter(16)
68
+ encrypted_list = encrypt_str_to_list(s, prefix=prefix)
69
+ with pytest.raises(Exception):
70
+ s1 = decrypt_list_to_str(encrypted_list)
71
+ s2 = decrypt_list_to_str(encrypted_list, prefix=prefix)
72
+ assert s == s2
73
+
74
+ def test_encrypt_decrypt_with_password_prefix(self):
75
+ s = rand_sentence(random.randint(10, 100))
76
+ password = rand_letter(16)
77
+ prefix = rand_letter(16)
78
+ encrypted_list = encrypt_str_to_list(s, password, prefix)
79
+ with pytest.raises(Exception):
80
+ s1 = decrypt_list_to_str(encrypted_list, prefix=prefix)
81
+ s2 = decrypt_list_to_str(encrypted_list, password, prefix)
82
+ assert s == s2
@@ -0,0 +1,25 @@
1
+ import time
2
+ import datetime
3
+ from python_plugins.jwt import jwt_encode, jwt_decode
4
+
5
+
6
+ def test_jwt(fake):
7
+ payload = {"some": fake.sentence()}
8
+ key = fake.vin()
9
+ # print(payload, key)
10
+ token = jwt_encode(payload, key)
11
+ # print(token)
12
+ decoded = jwt_decode(token, key)
13
+ # print(decoded)
14
+ assert decoded["some"] == payload["some"]
15
+ delta = 100
16
+ token = jwt_encode(payload, key, delta)
17
+ # print(token)
18
+ decoded = jwt_decode(token, key)
19
+ # print(decoded)
20
+ assert decoded["some"] == payload["some"]
21
+ # print(decoded["exp"],time.mktime(datetime.datetime.now().timetuple()))
22
+ assert "exp" in decoded
23
+ exp_time = time.mktime(datetime.datetime.now().timetuple()) + delta - 10
24
+ assert decoded["exp"] > exp_time
25
+ # print(datetime.datetime.fromtimestamp(decoded["exp"]))
@@ -0,0 +1,9 @@
1
+ import pytest
2
+ from python_plugins.process import run_process
3
+
4
+ @pytest.mark.skip(reason="[test_shell_process] only for debug.")
5
+ def test_run_process():
6
+ cmd = 'ls '
7
+ params='-l'
8
+ r = run_process(cmd,params,True)
9
+ # print(r)
@@ -0,0 +1,8 @@
1
+ from python_plugins.random.random_str import secret_token, secret_token_16
2
+
3
+
4
+ def test_random_secret_token():
5
+ token_1 = secret_token()
6
+ assert len(token_1) == 64
7
+ token_2 = secret_token_16()
8
+ assert len(token_2) == 32
@@ -0,0 +1,29 @@
1
+ from sqlalchemy.orm import Mapped
2
+ from sqlalchemy.orm import mapped_column
3
+ from python_plugins.models.mixins import PrimaryKeyMixin
4
+ from python_plugins.models.mixins import DataMixin
5
+ from python_plugins.models.mixins import TimestampMixin
6
+ from sqlalchemy.orm import DeclarativeBase
7
+ from sqlalchemy.schema import CreateTable
8
+
9
+ from sqlalchemy import create_mock_engine
10
+
11
+
12
+ class Base(DeclarativeBase):
13
+ pass
14
+
15
+
16
+ class Demo(PrimaryKeyMixin, DataMixin, TimestampMixin,Base):
17
+ __tablename__ = "demo"
18
+
19
+
20
+ def test_createtable():
21
+
22
+ assert Demo.__table__.name == "demo"
23
+ stmt = CreateTable(Demo.__table__)
24
+ # print(stmt)
25
+ assert "id INTEGER" in str(stmt)
26
+ assert "PRIMARY KEY" in str(stmt)
27
+ assert "data JSON" in str(stmt)
28
+ assert "created_at DATETIME" in str(stmt)
29
+ assert "updated_at DATETIME" in str(stmt)
@@ -0,0 +1,8 @@
1
+ import pytest
2
+
3
+ from python_plugins.utils.remove_pycache import remove_pycache
4
+
5
+ @pytest.mark.skip
6
+ def test_remove_pycache():
7
+ remove_pycache("./tests")
8
+
@@ -1,2 +0,0 @@
1
- pytest
2
- Faker
@@ -1 +0,0 @@
1
- __version__ = "0.1.2"