smart-dynamic-path 1.0.1__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.
@@ -0,0 +1,9 @@
1
+ # Copyright (©) 2026, Alexander Suvorov. All rights reserved.
2
+ __version__ = '1.0.1'
3
+ __all__ = [
4
+ 'generate_secret_key',
5
+ 'generate_path',
6
+ 'secret_to_path',
7
+ ]
8
+
9
+ from smart_dynamic_path.core import generate_secret_key, generate_path, secret_to_path
@@ -0,0 +1,50 @@
1
+ # Copyright (©) 2026, Alexander Suvorov. All rights reserved.
2
+ """
3
+ Smart Dynamic Path CLI — Local key and path generation from a secret phrase
4
+
5
+ Installation: pip install smart-dynamic-path
6
+ Usage:
7
+ smart-dynamic-path --secret "my secret phrase"
8
+ smart-dynamic-path --secret "my secret phrase" --period month --full
9
+ """
10
+
11
+ import argparse
12
+ from smart_dynamic_path.core import secret_to_path, get_full_path
13
+
14
+
15
+ def main():
16
+ parser = argparse.ArgumentParser(
17
+ prog='smart-dynamic-path',
18
+ description='Generate deterministic time-based paths from a secret phrase'
19
+ )
20
+ parser.add_argument('--secret', '-s', required=True, help='Secret phrase')
21
+ parser.add_argument('--period', '-P', default='day',
22
+ choices=['day', 'month', 'hour', 'static'],
23
+ help='Path change period (default: day)')
24
+ parser.add_argument('--prefix', '-p', default='',
25
+ help='Optional path prefix')
26
+ parser.add_argument('--full', '-f', action='store_true',
27
+ help='Show full URL path')
28
+ parser.add_argument('--key-only', '-k', action='store_true',
29
+ help='Show only SECRET_KEY')
30
+ parser.add_argument('--path-only', '-a', action='store_true',
31
+ help='Show only path')
32
+
33
+ args = parser.parse_args()
34
+
35
+ secret_key, path = secret_to_path(args.secret, args.period, args.prefix)
36
+
37
+ if args.key_only:
38
+ print(secret_key)
39
+ elif args.path_only:
40
+ print(path)
41
+ elif args.full:
42
+ print(get_full_path(secret_key, args.period, args.prefix))
43
+ else:
44
+ print(f"SECRET_KEY: {secret_key}")
45
+ print(f"Path: {path}")
46
+ print(f"Full URL: {get_full_path(secret_key, args.period, args.prefix)}")
47
+
48
+
49
+ if __name__ == '__main__':
50
+ main()
@@ -0,0 +1,75 @@
1
+ # Copyright (©) 2026, Alexander Suvorov. All rights reserved.
2
+ import hashlib
3
+ from datetime import datetime
4
+
5
+
6
+ def generate_secret_key(secret: str) -> str:
7
+ """
8
+ Generate SECRET_KEY from secret phrase.
9
+
10
+ Args:
11
+ secret: Secret phrase
12
+
13
+ Returns:
14
+ 64 hex chars (256 bits)
15
+ """
16
+ return hashlib.sha256(secret.encode()).hexdigest()
17
+
18
+
19
+ def generate_path(secret_key: str, period: str = 'day', prefix: str = '') -> str:
20
+ """
21
+ Generate deterministic time-based path.
22
+
23
+ Args:
24
+ secret_key: 64 hex chars (256 bits) from generate_secret_key()
25
+ period: 'day', 'month', 'hour', 'static'
26
+ prefix: Optional path prefix (e.g., 'admin')
27
+
28
+ Returns:
29
+ 32 hex chars path or "prefix/path"
30
+ """
31
+ now = datetime.now()
32
+
33
+ if period == 'day':
34
+ key = now.strftime("%Y-%m-%d")
35
+ elif period == 'month':
36
+ key = now.strftime("%Y-%m")
37
+ elif period == 'hour':
38
+ key = now.strftime("%Y-%m-%d-%H")
39
+ else:
40
+ key = 'static'
41
+
42
+ h = hashlib.sha256(f"{secret_key}_{key}".encode()).digest()
43
+ path_hash = h[:16].hex()
44
+
45
+ if prefix:
46
+ return f"{prefix}/{path_hash}"
47
+ return path_hash
48
+
49
+
50
+ def secret_to_path(secret: str, period: str = 'day', prefix: str = '') -> tuple:
51
+ """
52
+ Convert secret phrase to (secret_key, path).
53
+
54
+ Args:
55
+ secret: Secret phrase
56
+ period: 'day', 'month', 'hour', 'static'
57
+ prefix: Optional path prefix
58
+
59
+ Returns:
60
+ (secret_key, path) tuple
61
+ """
62
+ key = generate_secret_key(secret)
63
+ path = generate_path(key, period, prefix)
64
+ return key, path
65
+
66
+
67
+ def get_full_path(secret_key: str, period: str = 'day', prefix: str = '') -> str:
68
+ """
69
+ Get full path with leading slash.
70
+
71
+ Returns:
72
+ Full path like "/admin/a1b2c3d4e5f6g7h8/"
73
+ """
74
+ path = generate_path(secret_key, period, prefix)
75
+ return f"/{path}/"
@@ -0,0 +1,168 @@
1
+ Metadata-Version: 2.4
2
+ Name: smart-dynamic-path
3
+ Version: 1.0.1
4
+ Summary: Dynamic, deterministic, time-dependent path generation. No storage. No database. No dependencies. One secret phrase → one deterministic path per time period. Same phrase + same day = same path. No storage. No database. Just pure math.
5
+ Author-email: Alexander Suvorov <smartlegionlab@gmail.com>
6
+ License: BSD-3-Clause
7
+ Project-URL: Homepage, https://github.com/smartlegionlab/smart-dynamic-path
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.7
10
+ Classifier: Programming Language :: Python :: 3.8
11
+ Classifier: Programming Language :: Python :: 3.9
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Topic :: Security
17
+ Requires-Python: >=3.7
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Dynamic: license-file
21
+
22
+ # Smart Dynamic Path <sup>v1.0.1</sup>
23
+
24
+ **Dynamic, deterministic, time-dependent path generation. No storage. No database. No dependencies.**
25
+
26
+ Generate cryptographically secure paths that change automatically based on time (day, month, hour) from a secret phrase.
27
+ Perfect for hiding admin panels, creating temporary access links, or building time-based API keys.
28
+
29
+ ---
30
+
31
+ [![GitHub release (latest by date)](https://img.shields.io/github/v/release/smartlegionlab/smart-dynamic-path)](https://github.com/smartlegionlab/smart-dynamic-path/)
32
+ ![GitHub top language](https://img.shields.io/github/languages/top/smartlegionlab/smart-dynamic-path)
33
+ [![GitHub](https://img.shields.io/github/license/smartlegionlab/smart-dynamic-path)](https://github.com/smartlegionlab/smart-dynamic-path/blob/master/LICENSE)
34
+ [![GitHub stars](https://img.shields.io/github/stars/smartlegionlab/smart-dynamic-path?style=social)](https://github.com/smartlegionlab/smart-dynamic-path/stargazers)
35
+ [![GitHub forks](https://img.shields.io/github/forks/smartlegionlab/smart-dynamic-path?style=social)](https://github.com/smartlegionlab/smart-dynamic-path/network/members)
36
+
37
+ [![PyPI - Downloads](https://img.shields.io/pypi/dm/smart-dynamic-path?label=pypi%20downloads)](https://pypi.org/project/smart-dynamic-path/)
38
+ [![PyPI](https://img.shields.io/pypi/v/smart-dynamic-path)](https://pypi.org/project/smart-dynamic-path)
39
+ [![PyPI - Format](https://img.shields.io/pypi/format/smart-dynamic-path)](https://pypi.org/project/smart-dynamic-path)
40
+ [![PyPI Downloads](https://static.pepy.tech/badge/smart-dynamic-path)](https://pepy.tech/projects/smart-dynamic-path)
41
+ [![PyPI Downloads](https://static.pepy.tech/badge/smart-dynamic-path/month)](https://pepy.tech/projects/smart-dynamic-path)
42
+ [![PyPI Downloads](https://static.pepy.tech/badge/smart-dynamic-path/week)](https://pepy.tech/projects/smart-dynamic-path)
43
+
44
+ ---
45
+
46
+ ## Core idea
47
+
48
+ One secret phrase → one deterministic path per time period. Same phrase + same day = same path. No storage. No database. Just pure math.
49
+
50
+ ---
51
+
52
+ ## Disclaimer
53
+
54
+ **By using this software, you agree to the full disclaimer terms.**
55
+
56
+ **Summary:** Software provided "AS IS" without warranty. You assume all risks.
57
+
58
+ **Full legal disclaimer:** See [DISCLAIMER.md](https://github.com/smartlegionlab/smart-dynamic-path/blob/master/DISCLAIMER.md)
59
+
60
+ ---
61
+
62
+ ## Use cases
63
+
64
+ - Hide Django admin: `/admin/a1b2c3d4e5f6g7h8/`
65
+ - Temporary download links that expire after a day
66
+ - Time-rotating API endpoints
67
+ - "Secret room" pattern for any web framework
68
+
69
+ and others...
70
+
71
+ ## Local usage without installation
72
+
73
+ ```bash
74
+ git clone https://github.com/smartlegionlab/smart-dynamic-path
75
+ cd smart-dynamic-path
76
+
77
+ python -m smart_dynamic_path.cli --secret "my secret phrase"
78
+ python -m smart_dynamic_path.cli --secret "my secret phrase" --period month --full
79
+ python -m smart_dynamic_path.cli --secret "my secret phrase" --key-only
80
+ ```
81
+
82
+ ## Installation
83
+
84
+ ```bash
85
+ pip install smart-dynamic-path
86
+ ```
87
+
88
+ ## Quick start
89
+
90
+ ```python
91
+ from smart_dynamic_path import generate_path, secret_to_path
92
+
93
+ # Generate path from secret key
94
+ path = generate_path(secret_key='your_64_hex_secret_key', period='day')
95
+ # Output: "4e30939634dfc6617f10a2f8fe259f44"
96
+
97
+ # With prefix
98
+ path = generate_path(secret_key='...', period='day', prefix='admin')
99
+ # Output: "admin/4ab3b83e39bbb1d7e31e0978ea8cea05"
100
+
101
+ # From secret phrase (local use only)
102
+ key, path = secret_to_path('my secret phrase', period='day')
103
+ ```
104
+
105
+ ## CLI commands
106
+
107
+ | Command | Output |
108
+ |--------------------------------------------------------------|------------------------------|
109
+ | `smart-dynamic-path --secret "secret"` | Full info (key + path + URL) |
110
+ | `smart-dynamic-path --secret "secret" --key-only` | Only SECRET_KEY (64 hex) |
111
+ | `smart-dynamic-path --secret "secret" --path-only` | Only path (32 hex) |
112
+ | `smart-dynamic-path --secret "secret" --full` | Only full URL `/xxxx/` |
113
+ | `smart-dynamic-path --secret "secret" --period month --full` | Monthly rotation |
114
+ | `smart-dynamic-path --secret "secret" --prefix admin --full` | With prefix |
115
+
116
+ ## Python API
117
+
118
+ ```python
119
+ from smart_dynamic_path import generate_secret_key, generate_path, secret_to_path
120
+
121
+ # From secret phrase
122
+ key = generate_secret_key("my secret phrase")
123
+ path = generate_path(key, period='day')
124
+ key, path = secret_to_path("my secret phrase", period='day')
125
+ ```
126
+
127
+ ## How it works
128
+
129
+ ```
130
+ SECRET_KEY = SHA256(secret_phrase) # 64 hex chars (256 bits)
131
+ PATH = SHA256(SECRET_KEY + date)[:16].hex() # 32 hex chars (128 bits)
132
+ ```
133
+
134
+ - Secret phrase → SECRET_KEY (256 bits)
135
+ - SECRET_KEY + current date/time → path (128 bits)
136
+ - Path changes automatically based on period (day/month/hour/static)
137
+
138
+ ## Implemented paradigms
139
+
140
+ ### 1. Pointer‑Based Security
141
+ The path is not stored anywhere. It is regenerated on demand from a secret phrase and current time. There is no stored "pointer" — only the ability to compute it.
142
+
143
+ **DOI:** [10.5281/zenodo.17204738](https://doi.org/10.5281/zenodo.17204738)
144
+
145
+ ### 2. Local Data Regeneration
146
+ The exact path is computed locally on the developer's machine using only the secret phrase and date, without accessing any server.
147
+
148
+ **DOI:** [10.5281/zenodo.17264327](https://doi.org/10.5281/zenodo.17264327)
149
+
150
+ ### 3. Position‑Candidate‑Hypothesis (PCH)
151
+ Among all possible paths (2¹²⁸ candidates), only one specific path generated by the secret phrase is valid at any given time.
152
+
153
+ **DOI:** [10.5281/zenodo.17614888](https://doi.org/10.5281/zenodo.17614888)
154
+
155
+ ## Security
156
+
157
+ - No storage — paths are regenerated, not stored
158
+ - Deterministic — same input always produces same output
159
+ - 32 hex chars = 2¹²⁸ possible paths (no brute force)
160
+ - Time-based rotation limits exposure window
161
+
162
+ ## License
163
+
164
+ BSD-3-Clause
165
+
166
+ ## Author
167
+
168
+ Alexander Suvorov [@smartlegionlab](https://github.com/smartlegionlab)
@@ -0,0 +1,9 @@
1
+ smart_dynamic_path/__init__.py,sha256=VBc_CcUV8IVzcirOPLprLHui8O99mC8Oc-LnBylYsf0,256
2
+ smart_dynamic_path/cli.py,sha256=hJAm5CGDk6RbcvyicoIAasIpYt-3l4SygHGnnibJ-ZI,1793
3
+ smart_dynamic_path/core.py,sha256=VYNTSlNQbEnPcCT4G6udztybUaZvyFxk-o6vYiG_Mcg,1872
4
+ smart_dynamic_path-1.0.1.dist-info/licenses/LICENSE,sha256=bXnWlOMydXEp3EEgmsJuPpErliZndYEC9RReI1H-Jek,1504
5
+ smart_dynamic_path-1.0.1.dist-info/METADATA,sha256=a0G6HTf_TUAQycFX_bZxmSOPlsgnj7TWlHupo6fLsmk,6970
6
+ smart_dynamic_path-1.0.1.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
7
+ smart_dynamic_path-1.0.1.dist-info/entry_points.txt,sha256=HUOHeHXnqE_XeNskicxRZ1LIbLt48XWlvIgEHHiZ4SA,67
8
+ smart_dynamic_path-1.0.1.dist-info/top_level.txt,sha256=1SOWFhZ_ysV6m33PJwXBl5FW70gVeawRSCUYCweMfiU,19
9
+ smart_dynamic_path-1.0.1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ smart-dynamic-path = smart_dynamic_path.cli:main
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2026, Alexander Suvorov
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1 @@
1
+ smart_dynamic_path