generateApiKey 0.4.5__tar.gz → 0.4.8__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,27 +1,42 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: generateApiKey
3
- Version: 0.4.5
3
+ Version: 0.4.8
4
4
  Summary: This package provides a convenient way to generate API keys using a secret, seed, and an optional include keyword. The generated keys are unique and secure, making them suitable for use in a variety of applications
5
5
  Home-page: https://github.com/nuhmanpk/generate-api-key
6
6
  Author: Nuhman Pk
7
7
  Author-email: nuhmanpk7@gmail.com
8
8
  License: MIT
9
- Platform: UNKNOWN
9
+ Project-URL: Documentation, https://github.com/nuhmanpk/generate-api-key/blob/main/README.md
10
+ Project-URL: Funding, https://github.com/sponsors/nuhmanpk
11
+ Project-URL: Source, https://github.com/nuhmanpk/generate-api-key/
12
+ Project-URL: Tracker, https://github.com/nuhmanpk/generate-api-key/issues
10
13
  Classifier: Programming Language :: Python :: 3.9
11
14
  Classifier: License :: OSI Approved :: MIT License
12
15
  Classifier: Operating System :: OS Independent
13
16
  Requires-Python: >=3.9
14
17
  Description-Content-Type: text/markdown
15
18
  License-File: LICENSE
19
+ Requires-Dist: cryptography
20
+ Dynamic: author
21
+ Dynamic: author-email
22
+ Dynamic: classifier
23
+ Dynamic: description
24
+ Dynamic: description-content-type
25
+ Dynamic: home-page
26
+ Dynamic: license
27
+ Dynamic: license-file
28
+ Dynamic: project-url
29
+ Dynamic: requires-dist
30
+ Dynamic: requires-python
31
+ Dynamic: summary
16
32
 
17
33
  [![Downloads](https://static.pepy.tech/personalized-badge/generateApiKey?period=total&units=abbreviation&left_color=grey&right_color=yellow&left_text=Total-Downloads)](https://pepy.tech/project/generateApiKey)
18
34
  [![Supported Versions](https://img.shields.io/pypi/pyversions/generateApiKey.svg)](https://pypi.org/project/YoutubeTags)
19
35
  ![GitHub](https://img.shields.io/github/license/nuhmanpk/generate-api-key)
20
36
  ![PyPI](https://img.shields.io/pypi/v/generateApiKey)
21
- [![Documentation Status](https://readthedocs.org/projects/generateApiKey/badge/?version=latest)](https://generateApiKey.readthedocs.io/en/latest/?badge=latest)
22
37
  ![PyPI - Downloads](https://img.shields.io/pypi/dm/generateApiKey)
23
38
  [![Downloads](https://static.pepy.tech/personalized-badge/generateApiKey?period=week&units=international_system&left_color=grey&right_color=brightgreen&left_text=Downloads/Week)](https://pepy.tech/project/generateApiKey)
24
- [![Upload to PIP](https://github.com/nuhmanpk/generate-api-key/actions/workflows/pypi-upload.yml/badge.svg?branch=main&event=workflow_dispatch)](https://github.com/nuhmanpk/generate-api-key/actions/workflows/Pypi-uploads.yml)
39
+ [![Upload to PIP](https://github.com/nuhmanpk/generate-api-key/actions/workflows/pypi-upload.yml/badge.svg)](https://github.com/nuhmanpk/generate-api-key/actions/workflows/pypi-upload.yml)
25
40
  ![PyPI - Format](https://img.shields.io/pypi/format/generateApiKey)
26
41
  # API Key Generation Package
27
42
 
@@ -56,77 +71,107 @@ To install your package, you can use the pip package manager by running the foll
56
71
  pip install generateApiKey
57
72
  ```
58
73
 
59
- # Importing the package
60
- Once the package is installed, you can import the package in your code by using the import statement:
74
+ # Quick start
75
+
76
+ The simplest way to get a secure key — no arguments, no `await`:
77
+
61
78
  ```python
62
- from generateApiKey import generateApiKey
79
+ from generateApiKey import generate_api_key
80
+
81
+ api_key = generate_api_key() # 'uYTvAuzrTHAeU202ScbN6jV8kxIMogDf'
63
82
  ```
64
- # Generating an API key
65
- To generate an API key, you can use the generateApiKey() function and pass in the secret, seed, and an optional include keyword. For example:
66
83
 
67
- ```python
68
- from generateApiKey import generateApiKey
84
+ That's it. Everything below is optional.
85
+
86
+ ## Common recipes
69
87
 
70
- seed='12'
71
- secret='Topsecrect'
72
- api_key=generateApiKey(secret,seed)
73
- print(api_key)
88
+ ```python
89
+ generate_api_key(length=48) # longer key
90
+ generate_api_key(prefix="sk") # 'sk-gRsNbb2lQ1cZxoT3...'
91
+ generate_api_key(dashes=True) # 'GdBA-6DhM-M3Fv-g99C...'
92
+ generate_api_key(charset="hex", length=32) # hex only
93
+ generate_api_key(charset="base58") # no ambiguous 0/O/I/l
94
+ generate_api_key(charset="ABC123", length=10) # your own alphabet
95
+ generate_api_key(case="upper", charset="alphabetic")
74
96
  ```
75
97
 
98
+ ## Charsets
99
+
100
+ Pass a preset name or a literal string of characters to `charset`:
101
+
102
+ | Preset | Characters |
103
+ |--------|-----------|
104
+ | `alphanumeric` (default) | `A-Z a-z 0-9` |
105
+ | `base62` | `A-Z a-z 0-9` |
106
+ | `base58` | base62 minus `0 O I l` |
107
+ | `base64url` | `A-Z a-z 0-9 - _` |
108
+ | `alphabetic` | `A-Z a-z` |
109
+ | `numeric` | `0-9` |
110
+ | `hex` | `0-9 a-f` |
111
+ | `base16` | `0-9 A-F` |
112
+
113
+ ## Expiring keys
114
+
115
+ Set `expiry` (minutes). The returned key **is a string** but also carries expiry metadata:
76
116
 
77
117
  ```python
78
- from generateApiKey import generateApiKey
79
- api_key = generateApiKey(secret='Topsecret', seed='12',include='user1')
80
- print(api_key)
118
+ key = generate_api_key(expiry=60)
119
+
120
+ headers = {"Authorization": key} # works — it's a str
121
+ key.expires_at # unix timestamp
122
+ key.is_expired # False (until 60 min pass)
81
123
  ```
82
124
 
125
+ ## Derived keys (secret + seed)
126
+
127
+ Provide both `secret` and `seed` to derive the key deterministically from them
128
+ (HMAC-SHA256). A random salt still makes each generated key unique:
129
+
83
130
  ```python
84
- from generateApiKey import generateApiKey
85
- api_key = generateApiKey(secret='Topsecret', seed='12',include='user1',add_dashes=True)
86
- print(api_key)
131
+ generate_api_key("mysecret", "user-42", length=20, include="prod")
87
132
  ```
88
133
 
134
+ ## Async is optional
135
+
136
+ The library is synchronous by default. When you need an awaitable:
89
137
 
90
138
  ```python
91
- secret = 'mysecret'
92
- seed = 'randomseed'
93
- include = "TopSecretWord"
94
- api_key = generateApiKey(secret, seed, include)
95
- print(api_key)
139
+ from generateApiKey import generate_api_key_async
140
+
141
+ api_key = await generate_api_key_async(length=48, prefix="sk")
96
142
  ```
97
- This will generate an API key based on the provided secret, seed, and include keyword.
143
+
144
+ > The original `await generateApiKey(secret, seed, ...)` still works unchanged
145
+ > for backwards compatibility, but `generate_api_key` is recommended.
98
146
 
99
147
  ## Error handling
100
- It is a good practice to handle errors, you can use the try and except block to handle any exception that may occur during the key generation process.
101
148
 
102
149
  ```python
103
150
  try:
104
- secret = 'mysecret'
105
- seed = 'randomseed'
106
- include = "Production"
107
- api_key = generateApiKey(secret, seed, include)
108
- print(api_key)
109
- except Exception as e:
110
- print(e)
151
+ api_key = generate_api_key(length=32)
152
+ except ValueError as e:
153
+ print(e) # e.g. bad length, or only one of secret/seed given
111
154
  ```
112
155
 
113
- You can use the None return in the package function, to check if the key generation was successful.
156
+ # Parameters
114
157
 
115
- ```python
116
- api_key = generateApiKey(secret, seed, include)
117
- if api_key is None:
118
- print("Failed to generate api key")
119
- else:
120
- print(api_key)
121
- ```
122
- # Parameters
158
+ All parameters are optional. Call `generate_api_key()` with nothing for a secure default.
159
+
160
+ | **Parameter** | **Type** | **Default** | **Description** |
161
+ |---------------|----------|-------------|-----------------|
162
+ | `secret` | `str` | `None` | Optional secret. Given with `seed`, the key is HMAC-derived instead of random. |
163
+ | `seed` | `str` | `None` | Optional per-key value, used together with `secret`. |
164
+ | `length` | `int` | `32` | Number of characters in the key body. |
165
+ | `charset` | `str` | `"alphanumeric"` | Preset name (see table) or a literal string of allowed characters. |
166
+ | `case` | `str` | `"mixed"` | `"mixed"`, `"lower"` or `"upper"`. Affects letters only. |
167
+ | `prefix` | `str` | `None` | Prefix joined with `separator`, e.g. `sk-...`. |
168
+ | `separator` | `str` | `"-"` | String between prefix and key. |
169
+ | `dashes` | `bool` | `False` | Group the key with dashes for readability. |
170
+ | `dash_group` | `int` | `4` | Group size when `dashes=True`. |
171
+ | `include` | `str` | `None` | Extra value mixed into a derived key (needs `secret` + `seed`). |
172
+ | `expiry` | `int` | `None` | Expiry in minutes; sets `.expires_at` / `.is_expired`. |
123
173
 
124
- | **Variable** | **Type** | **Required** | **Example Value** | Description |
125
- |----------|---------|-----------|--------------------|-------------|
126
- | secret | `String` | Yes | "Topsecret" | The secret key used to generate the API key. It should be kept private and not shared with unauthorized parties. |
127
- | seed | `String` | Yes | "12" | A value used to seed the generation of the API key. It can be any value, but it should be unique for each key. |
128
- | include | `String` | Optional | "user1" | An optional value that can be included in the generated API key. It can be used to identify the user or application associated with the key. |
129
- | add_dashes | `boolean` | Optional | True | A value used to determine wheather to add dashes or not in a key |
174
+ Returns an `ApiKey` a `str` subclass, so it works anywhere a string does.
130
175
 
131
176
 
132
177
  By using this package, you are solely liable for any legal issues that may arise from its unauthorized use or misuse, as well as any security risks that may result from not properly securing the secret key used to generate the API keys.
@@ -137,6 +182,6 @@ This package is provided as is, without any warranties or guarantees of any kind
137
182
 
138
183
  We encourage you to use the package responsibly, and to report any security issues or bugs you may encounter.
139
184
 
140
- [Nuhman Pk](https://github.com/nuhmanpk)
141
185
 
142
186
 
187
+ Made with ❤️ , **Happy coding! 🚀**
@@ -1,27 +1,10 @@
1
- Metadata-Version: 2.1
2
- Name: generateApiKey
3
- Version: 0.4.5
4
- Summary: This package provides a convenient way to generate API keys using a secret, seed, and an optional include keyword. The generated keys are unique and secure, making them suitable for use in a variety of applications
5
- Home-page: https://github.com/nuhmanpk/generate-api-key
6
- Author: Nuhman Pk
7
- Author-email: nuhmanpk7@gmail.com
8
- License: MIT
9
- Platform: UNKNOWN
10
- Classifier: Programming Language :: Python :: 3.9
11
- Classifier: License :: OSI Approved :: MIT License
12
- Classifier: Operating System :: OS Independent
13
- Requires-Python: >=3.9
14
- Description-Content-Type: text/markdown
15
- License-File: LICENSE
16
-
17
1
  [![Downloads](https://static.pepy.tech/personalized-badge/generateApiKey?period=total&units=abbreviation&left_color=grey&right_color=yellow&left_text=Total-Downloads)](https://pepy.tech/project/generateApiKey)
18
2
  [![Supported Versions](https://img.shields.io/pypi/pyversions/generateApiKey.svg)](https://pypi.org/project/YoutubeTags)
19
3
  ![GitHub](https://img.shields.io/github/license/nuhmanpk/generate-api-key)
20
4
  ![PyPI](https://img.shields.io/pypi/v/generateApiKey)
21
- [![Documentation Status](https://readthedocs.org/projects/generateApiKey/badge/?version=latest)](https://generateApiKey.readthedocs.io/en/latest/?badge=latest)
22
5
  ![PyPI - Downloads](https://img.shields.io/pypi/dm/generateApiKey)
23
6
  [![Downloads](https://static.pepy.tech/personalized-badge/generateApiKey?period=week&units=international_system&left_color=grey&right_color=brightgreen&left_text=Downloads/Week)](https://pepy.tech/project/generateApiKey)
24
- [![Upload to PIP](https://github.com/nuhmanpk/generate-api-key/actions/workflows/pypi-upload.yml/badge.svg?branch=main&event=workflow_dispatch)](https://github.com/nuhmanpk/generate-api-key/actions/workflows/Pypi-uploads.yml)
7
+ [![Upload to PIP](https://github.com/nuhmanpk/generate-api-key/actions/workflows/pypi-upload.yml/badge.svg)](https://github.com/nuhmanpk/generate-api-key/actions/workflows/pypi-upload.yml)
25
8
  ![PyPI - Format](https://img.shields.io/pypi/format/generateApiKey)
26
9
  # API Key Generation Package
27
10
 
@@ -56,77 +39,107 @@ To install your package, you can use the pip package manager by running the foll
56
39
  pip install generateApiKey
57
40
  ```
58
41
 
59
- # Importing the package
60
- Once the package is installed, you can import the package in your code by using the import statement:
42
+ # Quick start
43
+
44
+ The simplest way to get a secure key — no arguments, no `await`:
45
+
61
46
  ```python
62
- from generateApiKey import generateApiKey
47
+ from generateApiKey import generate_api_key
48
+
49
+ api_key = generate_api_key() # 'uYTvAuzrTHAeU202ScbN6jV8kxIMogDf'
63
50
  ```
64
- # Generating an API key
65
- To generate an API key, you can use the generateApiKey() function and pass in the secret, seed, and an optional include keyword. For example:
66
51
 
67
- ```python
68
- from generateApiKey import generateApiKey
52
+ That's it. Everything below is optional.
69
53
 
70
- seed='12'
71
- secret='Topsecrect'
72
- api_key=generateApiKey(secret,seed)
73
- print(api_key)
54
+ ## Common recipes
55
+
56
+ ```python
57
+ generate_api_key(length=48) # longer key
58
+ generate_api_key(prefix="sk") # 'sk-gRsNbb2lQ1cZxoT3...'
59
+ generate_api_key(dashes=True) # 'GdBA-6DhM-M3Fv-g99C...'
60
+ generate_api_key(charset="hex", length=32) # hex only
61
+ generate_api_key(charset="base58") # no ambiguous 0/O/I/l
62
+ generate_api_key(charset="ABC123", length=10) # your own alphabet
63
+ generate_api_key(case="upper", charset="alphabetic")
74
64
  ```
75
65
 
66
+ ## Charsets
67
+
68
+ Pass a preset name or a literal string of characters to `charset`:
69
+
70
+ | Preset | Characters |
71
+ |--------|-----------|
72
+ | `alphanumeric` (default) | `A-Z a-z 0-9` |
73
+ | `base62` | `A-Z a-z 0-9` |
74
+ | `base58` | base62 minus `0 O I l` |
75
+ | `base64url` | `A-Z a-z 0-9 - _` |
76
+ | `alphabetic` | `A-Z a-z` |
77
+ | `numeric` | `0-9` |
78
+ | `hex` | `0-9 a-f` |
79
+ | `base16` | `0-9 A-F` |
80
+
81
+ ## Expiring keys
82
+
83
+ Set `expiry` (minutes). The returned key **is a string** but also carries expiry metadata:
76
84
 
77
85
  ```python
78
- from generateApiKey import generateApiKey
79
- api_key = generateApiKey(secret='Topsecret', seed='12',include='user1')
80
- print(api_key)
86
+ key = generate_api_key(expiry=60)
87
+
88
+ headers = {"Authorization": key} # works — it's a str
89
+ key.expires_at # unix timestamp
90
+ key.is_expired # False (until 60 min pass)
81
91
  ```
82
92
 
93
+ ## Derived keys (secret + seed)
94
+
95
+ Provide both `secret` and `seed` to derive the key deterministically from them
96
+ (HMAC-SHA256). A random salt still makes each generated key unique:
97
+
83
98
  ```python
84
- from generateApiKey import generateApiKey
85
- api_key = generateApiKey(secret='Topsecret', seed='12',include='user1',add_dashes=True)
86
- print(api_key)
99
+ generate_api_key("mysecret", "user-42", length=20, include="prod")
87
100
  ```
88
101
 
102
+ ## Async is optional
103
+
104
+ The library is synchronous by default. When you need an awaitable:
89
105
 
90
106
  ```python
91
- secret = 'mysecret'
92
- seed = 'randomseed'
93
- include = "TopSecretWord"
94
- api_key = generateApiKey(secret, seed, include)
95
- print(api_key)
107
+ from generateApiKey import generate_api_key_async
108
+
109
+ api_key = await generate_api_key_async(length=48, prefix="sk")
96
110
  ```
97
- This will generate an API key based on the provided secret, seed, and include keyword.
111
+
112
+ > The original `await generateApiKey(secret, seed, ...)` still works unchanged
113
+ > for backwards compatibility, but `generate_api_key` is recommended.
98
114
 
99
115
  ## Error handling
100
- It is a good practice to handle errors, you can use the try and except block to handle any exception that may occur during the key generation process.
101
116
 
102
117
  ```python
103
118
  try:
104
- secret = 'mysecret'
105
- seed = 'randomseed'
106
- include = "Production"
107
- api_key = generateApiKey(secret, seed, include)
108
- print(api_key)
109
- except Exception as e:
110
- print(e)
119
+ api_key = generate_api_key(length=32)
120
+ except ValueError as e:
121
+ print(e) # e.g. bad length, or only one of secret/seed given
111
122
  ```
112
123
 
113
- You can use the None return in the package function, to check if the key generation was successful.
124
+ # Parameters
114
125
 
115
- ```python
116
- api_key = generateApiKey(secret, seed, include)
117
- if api_key is None:
118
- print("Failed to generate api key")
119
- else:
120
- print(api_key)
121
- ```
122
- # Parameters
126
+ All parameters are optional. Call `generate_api_key()` with nothing for a secure default.
127
+
128
+ | **Parameter** | **Type** | **Default** | **Description** |
129
+ |---------------|----------|-------------|-----------------|
130
+ | `secret` | `str` | `None` | Optional secret. Given with `seed`, the key is HMAC-derived instead of random. |
131
+ | `seed` | `str` | `None` | Optional per-key value, used together with `secret`. |
132
+ | `length` | `int` | `32` | Number of characters in the key body. |
133
+ | `charset` | `str` | `"alphanumeric"` | Preset name (see table) or a literal string of allowed characters. |
134
+ | `case` | `str` | `"mixed"` | `"mixed"`, `"lower"` or `"upper"`. Affects letters only. |
135
+ | `prefix` | `str` | `None` | Prefix joined with `separator`, e.g. `sk-...`. |
136
+ | `separator` | `str` | `"-"` | String between prefix and key. |
137
+ | `dashes` | `bool` | `False` | Group the key with dashes for readability. |
138
+ | `dash_group` | `int` | `4` | Group size when `dashes=True`. |
139
+ | `include` | `str` | `None` | Extra value mixed into a derived key (needs `secret` + `seed`). |
140
+ | `expiry` | `int` | `None` | Expiry in minutes; sets `.expires_at` / `.is_expired`. |
123
141
 
124
- | **Variable** | **Type** | **Required** | **Example Value** | Description |
125
- |----------|---------|-----------|--------------------|-------------|
126
- | secret | `String` | Yes | "Topsecret" | The secret key used to generate the API key. It should be kept private and not shared with unauthorized parties. |
127
- | seed | `String` | Yes | "12" | A value used to seed the generation of the API key. It can be any value, but it should be unique for each key. |
128
- | include | `String` | Optional | "user1" | An optional value that can be included in the generated API key. It can be used to identify the user or application associated with the key. |
129
- | add_dashes | `boolean` | Optional | True | A value used to determine wheather to add dashes or not in a key |
142
+ Returns an `ApiKey` a `str` subclass, so it works anywhere a string does.
130
143
 
131
144
 
132
145
  By using this package, you are solely liable for any legal issues that may arise from its unauthorized use or misuse, as well as any security risks that may result from not properly securing the secret key used to generate the API keys.
@@ -137,6 +150,6 @@ This package is provided as is, without any warranties or guarantees of any kind
137
150
 
138
151
  We encourage you to use the package responsibly, and to report any security issues or bugs you may encounter.
139
152
 
140
- [Nuhman Pk](https://github.com/nuhmanpk)
141
153
 
142
154
 
155
+ Made with ❤️ , **Happy coding! 🚀**
@@ -0,0 +1,173 @@
1
+ """generateApiKey — simple, secure API key generation.
2
+
3
+ Quick start::
4
+
5
+ from generateApiKey import generate_api_key
6
+
7
+ key = generate_api_key() # secure random, 32 chars
8
+ key = generate_api_key(length=48, prefix="sk") # sk-xxxxxxxx...
9
+ key = generate_api_key(expiry=60) # expires in 60 minutes
10
+
11
+ Everything is synchronous by default. Use :func:`generate_api_key_async`
12
+ when you need an awaitable, or the legacy :func:`generateApiKey`.
13
+ """
14
+
15
+ import time
16
+
17
+ from .utils import (
18
+ CHARSETS,
19
+ build_charset,
20
+ random_key,
21
+ derived_key,
22
+ add_dashes,
23
+ )
24
+
25
+ __all__ = [
26
+ "generate_api_key",
27
+ "generate_api_key_async",
28
+ "generateApiKey",
29
+ "ApiKey",
30
+ "is_expired",
31
+ "is_token_valid",
32
+ "CHARSETS",
33
+ ]
34
+
35
+
36
+ class ApiKey(str):
37
+ """An API key.
38
+
39
+ Behaves exactly like a ``str`` (usable in headers, f-strings, comparisons)
40
+ while carrying optional expiry metadata::
41
+
42
+ key = generate_api_key(expiry=60)
43
+ headers = {"Authorization": key} # works, it's a str
44
+ key.expires_at # unix timestamp or None
45
+ key.is_expired # bool
46
+ """
47
+
48
+ expires_at = None
49
+
50
+ def __new__(cls, value: str, expires_at: int = None) -> "ApiKey":
51
+ obj = super().__new__(cls, value)
52
+ obj.expires_at = expires_at
53
+ return obj
54
+
55
+ @property
56
+ def is_expired(self) -> bool:
57
+ """True if an expiry was set and it is now in the past."""
58
+ return self.expires_at is not None and time.time() >= self.expires_at
59
+
60
+
61
+ def generate_api_key(
62
+ secret: str = None,
63
+ seed: str = None,
64
+ *,
65
+ length: int = 32,
66
+ charset: str = "alphanumeric",
67
+ case: str = "mixed",
68
+ prefix: str = None,
69
+ separator: str = "-",
70
+ dashes: bool = False,
71
+ dash_group: int = 4,
72
+ include: str = None,
73
+ expiry: int = None,
74
+ ) -> ApiKey:
75
+ """Generate a secure API key.
76
+
77
+ With no arguments it returns a cryptographically random key. Pass both
78
+ ``secret`` and ``seed`` to derive the key from them via HMAC-SHA256 instead.
79
+
80
+ Args:
81
+ secret: Optional secret. If given with ``seed``, the key is HMAC-derived.
82
+ seed: Optional per-key value used together with ``secret``.
83
+ length: Number of characters in the key body (before prefix/dashes). Default 32.
84
+ charset: A preset name (see ``CHARSETS``) or a literal string of allowed
85
+ characters. Presets: alphanumeric, base62, base58, base64url,
86
+ alphabetic, numeric, hex, base16.
87
+ case: ``"mixed"`` (default), ``"lower"`` or ``"upper"``.
88
+ prefix: Optional prefix, joined with ``separator`` (e.g. ``sk-...``).
89
+ separator: String used between prefix and key. Default ``"-"``.
90
+ dashes: If True, group the key body with dashes for readability.
91
+ dash_group: Group size when ``dashes`` is True. Default 4.
92
+ include: Extra value mixed into a derived key (requires secret + seed).
93
+ expiry: Optional expiry in minutes. Sets ``ApiKey.expires_at``.
94
+
95
+ Returns:
96
+ An :class:`ApiKey` (a ``str`` subclass).
97
+
98
+ Raises:
99
+ ValueError: If ``length`` < 1, or a bad ``charset``/``case`` is given, or
100
+ only one of ``secret``/``seed`` is supplied.
101
+ """
102
+ if length < 1:
103
+ raise ValueError("length must be a positive integer.")
104
+ if (secret is None) != (seed is None):
105
+ raise ValueError("Provide both 'secret' and 'seed', or neither.")
106
+
107
+ chars = build_charset(charset, case)
108
+
109
+ if secret and seed:
110
+ body = derived_key(secret, seed, include, length, chars)
111
+ else:
112
+ body = random_key(length, chars)
113
+
114
+ if dashes:
115
+ body = add_dashes(body, dash_group)
116
+
117
+ key = f"{prefix}{separator}{body}" if prefix else body
118
+
119
+ expires_at = int(time.time()) + expiry * 60 if expiry else None
120
+ return ApiKey(key, expires_at)
121
+
122
+
123
+ async def generate_api_key_async(*args, **kwargs) -> ApiKey:
124
+ """Async wrapper around :func:`generate_api_key` with the same signature."""
125
+ return generate_api_key(*args, **kwargs)
126
+
127
+
128
+ def is_expired(key: "ApiKey") -> bool:
129
+ """Return True if ``key`` is an expired :class:`ApiKey`."""
130
+ return getattr(key, "is_expired", False)
131
+
132
+
133
+ # ---------------------------------------------------------------------------
134
+ # Backwards-compatible legacy API (async). Prefer generate_api_key above.
135
+ # ---------------------------------------------------------------------------
136
+
137
+ async def generateApiKey(
138
+ secret: str,
139
+ seed: str,
140
+ include: str = None,
141
+ add_dashes: bool = False,
142
+ prefix: str = None,
143
+ length: int = None,
144
+ expiry: int = None,
145
+ ) -> ApiKey:
146
+ """Legacy async entry point. Kept for backwards compatibility.
147
+
148
+ New code should use :func:`generate_api_key` (synchronous, more options).
149
+ """
150
+ if not secret or not seed:
151
+ raise ValueError("Secret and seed cannot be empty strings.")
152
+
153
+ return generate_api_key(
154
+ secret,
155
+ seed,
156
+ length=length or 32,
157
+ include=include,
158
+ prefix=prefix,
159
+ dashes=add_dashes,
160
+ dash_group=4,
161
+ expiry=expiry,
162
+ )
163
+
164
+
165
+ async def is_token_valid(token: str) -> bool:
166
+ """Legacy check for the ``_<timestamp>`` expiry token format."""
167
+ if "_" not in token:
168
+ return False
169
+ try:
170
+ expiration_time = int(token.split("_")[1])
171
+ return int(time.time()) < expiration_time
172
+ except (IndexError, ValueError):
173
+ return False
@@ -0,0 +1,82 @@
1
+ import hmac
2
+ import time
3
+ import hashlib
4
+ import string
5
+ from secrets import choice, token_bytes
6
+
7
+ # Named character sets available via the ``charset`` option.
8
+ CHARSETS = {
9
+ "alphanumeric": string.ascii_letters + string.digits,
10
+ "base62": string.ascii_letters + string.digits,
11
+ "alphabetic": string.ascii_letters,
12
+ "numeric": string.digits,
13
+ "hex": string.digits + "abcdef",
14
+ "base16": string.digits + "ABCDEF",
15
+ "base64url": string.ascii_letters + string.digits + "-_",
16
+ # base58 = base62 minus the ambiguous chars 0, O, I and l
17
+ "base58": "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz",
18
+ }
19
+
20
+
21
+ def build_charset(charset: str, case: str) -> str:
22
+ """Resolve a charset name (or a custom literal string) and apply a case rule.
23
+
24
+ Args:
25
+ charset: A named preset in ``CHARSETS`` or a literal string of characters.
26
+ case: One of ``"mixed"``, ``"lower"`` or ``"upper"``. Only affects letters.
27
+
28
+ Returns:
29
+ The final string of characters to draw from.
30
+ """
31
+ chars = CHARSETS.get(charset, charset)
32
+ if not chars:
33
+ raise ValueError(f"Unknown or empty charset: {charset!r}")
34
+
35
+ if case == "lower":
36
+ chars = "".join(dict.fromkeys(chars.lower()))
37
+ elif case == "upper":
38
+ chars = "".join(dict.fromkeys(chars.upper()))
39
+ elif case != "mixed":
40
+ raise ValueError("case must be one of 'mixed', 'lower', 'upper'.")
41
+ return chars
42
+
43
+
44
+ def random_key(length: int, chars: str) -> str:
45
+ """Return a cryptographically secure random string of ``length`` from ``chars``."""
46
+ return "".join(choice(chars) for _ in range(length))
47
+
48
+
49
+ def derived_key(secret: str, seed: str, include: str, length: int, chars: str) -> str:
50
+ """Derive a key from ``secret``/``seed`` using HMAC-SHA256 as a byte stream.
51
+
52
+ A fresh random salt keeps every generated key unique even for identical
53
+ inputs. The HMAC output is mapped onto ``chars`` to honour the charset.
54
+ """
55
+ salt = token_bytes(16)
56
+ message = f"{seed}{include or ''}{int(time.time())}".encode()
57
+ material = bytearray()
58
+ counter = 0
59
+ while len(material) < length:
60
+ block = hmac.new(
61
+ secret.encode(),
62
+ message + salt + counter.to_bytes(4, "big"),
63
+ hashlib.sha256,
64
+ ).digest()
65
+ material.extend(block)
66
+ counter += 1
67
+ return "".join(chars[b % len(chars)] for b in material[:length])
68
+
69
+
70
+ def add_dashes(key: str, group: int, sep: str = "-") -> str:
71
+ """Insert ``sep`` every ``group`` characters, e.g. ``ABCD-EFGH-IJKL``."""
72
+ if group < 1:
73
+ return key
74
+ return sep.join(key[i : i + group] for i in range(0, len(key), group))
75
+
76
+
77
+ def generate_expiration_token(minutes: int) -> str:
78
+ """Return a stateless expiry token of the form ``_<unix_timestamp>``.
79
+
80
+ Kept for backwards compatibility with :func:`generateApiKey`.
81
+ """
82
+ return f"_{int(time.time()) + minutes * 60}"
@@ -0,0 +1,187 @@
1
+ Metadata-Version: 2.4
2
+ Name: generateApiKey
3
+ Version: 0.4.8
4
+ Summary: This package provides a convenient way to generate API keys using a secret, seed, and an optional include keyword. The generated keys are unique and secure, making them suitable for use in a variety of applications
5
+ Home-page: https://github.com/nuhmanpk/generate-api-key
6
+ Author: Nuhman Pk
7
+ Author-email: nuhmanpk7@gmail.com
8
+ License: MIT
9
+ Project-URL: Documentation, https://github.com/nuhmanpk/generate-api-key/blob/main/README.md
10
+ Project-URL: Funding, https://github.com/sponsors/nuhmanpk
11
+ Project-URL: Source, https://github.com/nuhmanpk/generate-api-key/
12
+ Project-URL: Tracker, https://github.com/nuhmanpk/generate-api-key/issues
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Requires-Python: >=3.9
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Requires-Dist: cryptography
20
+ Dynamic: author
21
+ Dynamic: author-email
22
+ Dynamic: classifier
23
+ Dynamic: description
24
+ Dynamic: description-content-type
25
+ Dynamic: home-page
26
+ Dynamic: license
27
+ Dynamic: license-file
28
+ Dynamic: project-url
29
+ Dynamic: requires-dist
30
+ Dynamic: requires-python
31
+ Dynamic: summary
32
+
33
+ [![Downloads](https://static.pepy.tech/personalized-badge/generateApiKey?period=total&units=abbreviation&left_color=grey&right_color=yellow&left_text=Total-Downloads)](https://pepy.tech/project/generateApiKey)
34
+ [![Supported Versions](https://img.shields.io/pypi/pyversions/generateApiKey.svg)](https://pypi.org/project/YoutubeTags)
35
+ ![GitHub](https://img.shields.io/github/license/nuhmanpk/generate-api-key)
36
+ ![PyPI](https://img.shields.io/pypi/v/generateApiKey)
37
+ ![PyPI - Downloads](https://img.shields.io/pypi/dm/generateApiKey)
38
+ [![Downloads](https://static.pepy.tech/personalized-badge/generateApiKey?period=week&units=international_system&left_color=grey&right_color=brightgreen&left_text=Downloads/Week)](https://pepy.tech/project/generateApiKey)
39
+ [![Upload to PIP](https://github.com/nuhmanpk/generate-api-key/actions/workflows/pypi-upload.yml/badge.svg)](https://github.com/nuhmanpk/generate-api-key/actions/workflows/pypi-upload.yml)
40
+ ![PyPI - Format](https://img.shields.io/pypi/format/generateApiKey)
41
+ # API Key Generation Package
42
+
43
+ Timestamp and Numeric Representation: Now, the package incorporates a time-based and date-based hashing mechanism, adding an extra layer of security to your API keys. It captures the current timestamp and numeric representation of the key generation process, creating a unique identifier that's closely tied to the moment it was generated. This feature adds an element of time-based uniqueness to your keys, making them even more secure and less predictable.
44
+
45
+ This package provides a convenient way to generate API keys using a secret, seed, and an optional include keyword. The generated keys are unique and secure, making them suitable for use in a variety of applications.
46
+
47
+ The package supports generating API keys using a variety of methods such as UUID v5 and SHA-256 algorithm. The keys are generated using a combination of seed, secret, and include keyword. Additionally, the package allows you to insert the include keyword at a random position in the seed which will make it more difficult to guess.
48
+
49
+ It is important to keep the secret used to generate the keys secure and not share it with unauthorized parties. Additionally, the package can only be used for legitimate and legal purposes.
50
+
51
+ Please keep in mind that, even though this package provides a secure way to generate API keys, it is still important to use other security measures such as rate limiting, IP whitelisting, and encryption to protect your API and the data it accesses.
52
+
53
+ By using this package, you agree to take all necessary precautions to protect the data and resources accessed with the keys from unauthorized access or misuse. It is recommended to consult with a security expert before using this package or handling sensitive data.
54
+
55
+ # Privacy Policy
56
+
57
+ This package generates API keys that can be used to access sensitive data or resources. By using this package, you agree to keep the secret used to generate the keys secure and not share it with unauthorized parties. Additionally, the package can only be used for legitimate and legal purposes.
58
+
59
+ Please be aware that the package may cause a security risk if not used properly. The authors of this package cannot be held responsible for any unauthorized access or misuse of the keys generated by this package.
60
+
61
+ It is the user's responsibility to ensure the security of the keys and the protection of the data. It is recommended to consult with a security expert before using this package or handling sensitive data.
62
+
63
+ By using this package, you agree to take all necessary precautions to protect the data and resources accessed with the keys from unauthorized access or misuse.
64
+
65
+
66
+
67
+ # Installation
68
+ To install your package, you can use the pip package manager by running the following command in your command line:
69
+
70
+ ```python
71
+ pip install generateApiKey
72
+ ```
73
+
74
+ # Quick start
75
+
76
+ The simplest way to get a secure key — no arguments, no `await`:
77
+
78
+ ```python
79
+ from generateApiKey import generate_api_key
80
+
81
+ api_key = generate_api_key() # 'uYTvAuzrTHAeU202ScbN6jV8kxIMogDf'
82
+ ```
83
+
84
+ That's it. Everything below is optional.
85
+
86
+ ## Common recipes
87
+
88
+ ```python
89
+ generate_api_key(length=48) # longer key
90
+ generate_api_key(prefix="sk") # 'sk-gRsNbb2lQ1cZxoT3...'
91
+ generate_api_key(dashes=True) # 'GdBA-6DhM-M3Fv-g99C...'
92
+ generate_api_key(charset="hex", length=32) # hex only
93
+ generate_api_key(charset="base58") # no ambiguous 0/O/I/l
94
+ generate_api_key(charset="ABC123", length=10) # your own alphabet
95
+ generate_api_key(case="upper", charset="alphabetic")
96
+ ```
97
+
98
+ ## Charsets
99
+
100
+ Pass a preset name or a literal string of characters to `charset`:
101
+
102
+ | Preset | Characters |
103
+ |--------|-----------|
104
+ | `alphanumeric` (default) | `A-Z a-z 0-9` |
105
+ | `base62` | `A-Z a-z 0-9` |
106
+ | `base58` | base62 minus `0 O I l` |
107
+ | `base64url` | `A-Z a-z 0-9 - _` |
108
+ | `alphabetic` | `A-Z a-z` |
109
+ | `numeric` | `0-9` |
110
+ | `hex` | `0-9 a-f` |
111
+ | `base16` | `0-9 A-F` |
112
+
113
+ ## Expiring keys
114
+
115
+ Set `expiry` (minutes). The returned key **is a string** but also carries expiry metadata:
116
+
117
+ ```python
118
+ key = generate_api_key(expiry=60)
119
+
120
+ headers = {"Authorization": key} # works — it's a str
121
+ key.expires_at # unix timestamp
122
+ key.is_expired # False (until 60 min pass)
123
+ ```
124
+
125
+ ## Derived keys (secret + seed)
126
+
127
+ Provide both `secret` and `seed` to derive the key deterministically from them
128
+ (HMAC-SHA256). A random salt still makes each generated key unique:
129
+
130
+ ```python
131
+ generate_api_key("mysecret", "user-42", length=20, include="prod")
132
+ ```
133
+
134
+ ## Async is optional
135
+
136
+ The library is synchronous by default. When you need an awaitable:
137
+
138
+ ```python
139
+ from generateApiKey import generate_api_key_async
140
+
141
+ api_key = await generate_api_key_async(length=48, prefix="sk")
142
+ ```
143
+
144
+ > The original `await generateApiKey(secret, seed, ...)` still works unchanged
145
+ > for backwards compatibility, but `generate_api_key` is recommended.
146
+
147
+ ## Error handling
148
+
149
+ ```python
150
+ try:
151
+ api_key = generate_api_key(length=32)
152
+ except ValueError as e:
153
+ print(e) # e.g. bad length, or only one of secret/seed given
154
+ ```
155
+
156
+ # Parameters
157
+
158
+ All parameters are optional. Call `generate_api_key()` with nothing for a secure default.
159
+
160
+ | **Parameter** | **Type** | **Default** | **Description** |
161
+ |---------------|----------|-------------|-----------------|
162
+ | `secret` | `str` | `None` | Optional secret. Given with `seed`, the key is HMAC-derived instead of random. |
163
+ | `seed` | `str` | `None` | Optional per-key value, used together with `secret`. |
164
+ | `length` | `int` | `32` | Number of characters in the key body. |
165
+ | `charset` | `str` | `"alphanumeric"` | Preset name (see table) or a literal string of allowed characters. |
166
+ | `case` | `str` | `"mixed"` | `"mixed"`, `"lower"` or `"upper"`. Affects letters only. |
167
+ | `prefix` | `str` | `None` | Prefix joined with `separator`, e.g. `sk-...`. |
168
+ | `separator` | `str` | `"-"` | String between prefix and key. |
169
+ | `dashes` | `bool` | `False` | Group the key with dashes for readability. |
170
+ | `dash_group` | `int` | `4` | Group size when `dashes=True`. |
171
+ | `include` | `str` | `None` | Extra value mixed into a derived key (needs `secret` + `seed`). |
172
+ | `expiry` | `int` | `None` | Expiry in minutes; sets `.expires_at` / `.is_expired`. |
173
+
174
+ Returns an `ApiKey` — a `str` subclass, so it works anywhere a string does.
175
+
176
+
177
+ By using this package, you are solely liable for any legal issues that may arise from its unauthorized use or misuse, as well as any security risks that may result from not properly securing the secret key used to generate the API keys.
178
+
179
+ # Fair Use Policy:
180
+
181
+ This package is provided as is, without any warranties or guarantees of any kind. We are not liable for any damages or losses that may result from its use. We reserve the right to change or discontinue the package at any time without notice.
182
+
183
+ We encourage you to use the package responsibly, and to report any security issues or bugs you may encounter.
184
+
185
+
186
+
187
+ Made with ❤️ , **Happy coding! 🚀**
@@ -3,8 +3,10 @@ MANIFEST.in
3
3
  README.md
4
4
  setup.py
5
5
  generateApiKey/__init__.py
6
+ generateApiKey/utils.py
6
7
  generateApiKey.egg-info/PKG-INFO
7
8
  generateApiKey.egg-info/SOURCES.txt
8
9
  generateApiKey.egg-info/dependency_links.txt
9
10
  generateApiKey.egg-info/requires.txt
10
- generateApiKey.egg-info/top_level.txt
11
+ generateApiKey.egg-info/top_level.txt
12
+ tests/test_generate.py
@@ -7,7 +7,7 @@ README = (file / "README.md").read_text()
7
7
 
8
8
  setuptools.setup(
9
9
  name="generateApiKey",
10
- version="0.4.5",
10
+ version="0.4.8",
11
11
  author="Nuhman Pk",
12
12
  author_email="nuhmanpk7@gmail.com",
13
13
  long_description = README,
@@ -25,5 +25,11 @@ setuptools.setup(
25
25
  ],
26
26
  packages=setuptools.find_packages(include=['generateApiKey']),
27
27
  python_requires=">=3.9",
28
+ project_urls={
29
+ 'Documentation': 'https://github.com/nuhmanpk/generate-api-key/blob/main/README.md',
30
+ 'Funding': 'https://github.com/sponsors/nuhmanpk',
31
+ 'Source': 'https://github.com/nuhmanpk/generate-api-key/',
32
+ 'Tracker': 'https://github.com/nuhmanpk/generate-api-key/issues',
33
+ },
28
34
 
29
35
  )
@@ -0,0 +1,97 @@
1
+ import time
2
+ import asyncio
3
+
4
+ from generateApiKey import (
5
+ generate_api_key,
6
+ generate_api_key_async,
7
+ generateApiKey,
8
+ ApiKey,
9
+ is_expired,
10
+ CHARSETS,
11
+ )
12
+
13
+
14
+ def test_default_length_and_charset():
15
+ key = generate_api_key()
16
+ assert isinstance(key, ApiKey) and isinstance(key, str)
17
+ assert len(key) == 32
18
+ assert all(c in CHARSETS["alphanumeric"] for c in key)
19
+
20
+
21
+ def test_length():
22
+ assert len(generate_api_key(length=48)) == 48
23
+
24
+
25
+ def test_charset_hex():
26
+ key = generate_api_key(charset="hex", length=40)
27
+ assert all(c in CHARSETS["hex"] for c in key)
28
+
29
+
30
+ def test_case_upper():
31
+ key = generate_api_key(charset="alphabetic", case="upper", length=20)
32
+ assert key.isupper()
33
+
34
+
35
+ def test_custom_charset():
36
+ key = generate_api_key(charset="AB12", length=16)
37
+ assert set(key) <= set("AB12")
38
+
39
+
40
+ def test_prefix():
41
+ assert generate_api_key(prefix="sk", length=8).startswith("sk-")
42
+
43
+
44
+ def test_dashes():
45
+ key = generate_api_key(dashes=True, dash_group=4, length=16)
46
+ assert key.count("-") == 3
47
+
48
+
49
+ def test_expiry_metadata():
50
+ key = generate_api_key(expiry=60)
51
+ assert key.expires_at is not None
52
+ assert not key.is_expired
53
+ assert not is_expired(key)
54
+
55
+
56
+ def test_expired():
57
+ past = ApiKey("x", int(time.time()) - 1)
58
+ assert past.is_expired
59
+
60
+
61
+ def test_uniqueness():
62
+ assert len({generate_api_key() for _ in range(1000)}) == 1000
63
+
64
+
65
+ def test_secret_seed_pair_required():
66
+ for kwargs in ({"secret": "x"}, {"seed": "y"}):
67
+ try:
68
+ generate_api_key(**kwargs)
69
+ assert False, "expected ValueError"
70
+ except ValueError:
71
+ pass
72
+
73
+
74
+ def test_bad_length():
75
+ try:
76
+ generate_api_key(length=0)
77
+ assert False
78
+ except ValueError:
79
+ pass
80
+
81
+
82
+ def test_async_wrapper():
83
+ key = asyncio.run(generate_api_key_async(length=8))
84
+ assert len(key) == 8
85
+
86
+
87
+ def test_legacy_async():
88
+ key = asyncio.run(generateApiKey("s", "seed", prefix="hf", add_dashes=True))
89
+ assert key.startswith("hf-")
90
+
91
+
92
+ if __name__ == "__main__":
93
+ for name, fn in sorted(globals().items()):
94
+ if name.startswith("test_"):
95
+ fn()
96
+ print("ok", name)
97
+ print("all passed")
@@ -1,124 +0,0 @@
1
- [![Downloads](https://static.pepy.tech/personalized-badge/generateApiKey?period=total&units=abbreviation&left_color=grey&right_color=yellow&left_text=Total-Downloads)](https://pepy.tech/project/generateApiKey)
2
- [![Supported Versions](https://img.shields.io/pypi/pyversions/generateApiKey.svg)](https://pypi.org/project/YoutubeTags)
3
- ![GitHub](https://img.shields.io/github/license/nuhmanpk/generate-api-key)
4
- ![PyPI](https://img.shields.io/pypi/v/generateApiKey)
5
- [![Documentation Status](https://readthedocs.org/projects/generateApiKey/badge/?version=latest)](https://generateApiKey.readthedocs.io/en/latest/?badge=latest)
6
- ![PyPI - Downloads](https://img.shields.io/pypi/dm/generateApiKey)
7
- [![Downloads](https://static.pepy.tech/personalized-badge/generateApiKey?period=week&units=international_system&left_color=grey&right_color=brightgreen&left_text=Downloads/Week)](https://pepy.tech/project/generateApiKey)
8
- [![Upload to PIP](https://github.com/nuhmanpk/generate-api-key/actions/workflows/pypi-upload.yml/badge.svg?branch=main&event=workflow_dispatch)](https://github.com/nuhmanpk/generate-api-key/actions/workflows/Pypi-uploads.yml)
9
- ![PyPI - Format](https://img.shields.io/pypi/format/generateApiKey)
10
- # API Key Generation Package
11
-
12
- Timestamp and Numeric Representation: Now, the package incorporates a time-based and date-based hashing mechanism, adding an extra layer of security to your API keys. It captures the current timestamp and numeric representation of the key generation process, creating a unique identifier that's closely tied to the moment it was generated. This feature adds an element of time-based uniqueness to your keys, making them even more secure and less predictable.
13
-
14
- This package provides a convenient way to generate API keys using a secret, seed, and an optional include keyword. The generated keys are unique and secure, making them suitable for use in a variety of applications.
15
-
16
- The package supports generating API keys using a variety of methods such as UUID v5 and SHA-256 algorithm. The keys are generated using a combination of seed, secret, and include keyword. Additionally, the package allows you to insert the include keyword at a random position in the seed which will make it more difficult to guess.
17
-
18
- It is important to keep the secret used to generate the keys secure and not share it with unauthorized parties. Additionally, the package can only be used for legitimate and legal purposes.
19
-
20
- Please keep in mind that, even though this package provides a secure way to generate API keys, it is still important to use other security measures such as rate limiting, IP whitelisting, and encryption to protect your API and the data it accesses.
21
-
22
- By using this package, you agree to take all necessary precautions to protect the data and resources accessed with the keys from unauthorized access or misuse. It is recommended to consult with a security expert before using this package or handling sensitive data.
23
-
24
- # Privacy Policy
25
-
26
- This package generates API keys that can be used to access sensitive data or resources. By using this package, you agree to keep the secret used to generate the keys secure and not share it with unauthorized parties. Additionally, the package can only be used for legitimate and legal purposes.
27
-
28
- Please be aware that the package may cause a security risk if not used properly. The authors of this package cannot be held responsible for any unauthorized access or misuse of the keys generated by this package.
29
-
30
- It is the user's responsibility to ensure the security of the keys and the protection of the data. It is recommended to consult with a security expert before using this package or handling sensitive data.
31
-
32
- By using this package, you agree to take all necessary precautions to protect the data and resources accessed with the keys from unauthorized access or misuse.
33
-
34
-
35
-
36
- # Installation
37
- To install your package, you can use the pip package manager by running the following command in your command line:
38
-
39
- ```python
40
- pip install generateApiKey
41
- ```
42
-
43
- # Importing the package
44
- Once the package is installed, you can import the package in your code by using the import statement:
45
- ```python
46
- from generateApiKey import generateApiKey
47
- ```
48
- # Generating an API key
49
- To generate an API key, you can use the generateApiKey() function and pass in the secret, seed, and an optional include keyword. For example:
50
-
51
- ```python
52
- from generateApiKey import generateApiKey
53
-
54
- seed='12'
55
- secret='Topsecrect'
56
- api_key=generateApiKey(secret,seed)
57
- print(api_key)
58
- ```
59
-
60
-
61
- ```python
62
- from generateApiKey import generateApiKey
63
- api_key = generateApiKey(secret='Topsecret', seed='12',include='user1')
64
- print(api_key)
65
- ```
66
-
67
- ```python
68
- from generateApiKey import generateApiKey
69
- api_key = generateApiKey(secret='Topsecret', seed='12',include='user1',add_dashes=True)
70
- print(api_key)
71
- ```
72
-
73
-
74
- ```python
75
- secret = 'mysecret'
76
- seed = 'randomseed'
77
- include = "TopSecretWord"
78
- api_key = generateApiKey(secret, seed, include)
79
- print(api_key)
80
- ```
81
- This will generate an API key based on the provided secret, seed, and include keyword.
82
-
83
- ## Error handling
84
- It is a good practice to handle errors, you can use the try and except block to handle any exception that may occur during the key generation process.
85
-
86
- ```python
87
- try:
88
- secret = 'mysecret'
89
- seed = 'randomseed'
90
- include = "Production"
91
- api_key = generateApiKey(secret, seed, include)
92
- print(api_key)
93
- except Exception as e:
94
- print(e)
95
- ```
96
-
97
- You can use the None return in the package function, to check if the key generation was successful.
98
-
99
- ```python
100
- api_key = generateApiKey(secret, seed, include)
101
- if api_key is None:
102
- print("Failed to generate api key")
103
- else:
104
- print(api_key)
105
- ```
106
- # Parameters
107
-
108
- | **Variable** | **Type** | **Required** | **Example Value** | Description |
109
- |----------|---------|-----------|--------------------|-------------|
110
- | secret | `String` | Yes | "Topsecret" | The secret key used to generate the API key. It should be kept private and not shared with unauthorized parties. |
111
- | seed | `String` | Yes | "12" | A value used to seed the generation of the API key. It can be any value, but it should be unique for each key. |
112
- | include | `String` | Optional | "user1" | An optional value that can be included in the generated API key. It can be used to identify the user or application associated with the key. |
113
- | add_dashes | `boolean` | Optional | True | A value used to determine wheather to add dashes or not in a key |
114
-
115
-
116
- By using this package, you are solely liable for any legal issues that may arise from its unauthorized use or misuse, as well as any security risks that may result from not properly securing the secret key used to generate the API keys.
117
-
118
- # Fair Use Policy:
119
-
120
- This package is provided as is, without any warranties or guarantees of any kind. We are not liable for any damages or losses that may result from its use. We reserve the right to change or discontinue the package at any time without notice.
121
-
122
- We encourage you to use the package responsibly, and to report any security issues or bugs you may encounter.
123
-
124
- [Nuhman Pk](https://github.com/nuhmanpk)
@@ -1,58 +0,0 @@
1
- import hashlib
2
- import hmac
3
- import uuid
4
- import random
5
- import os
6
- import base64
7
- import re
8
- import time
9
- import datetime
10
- from cryptography.hazmat.primitives import hashes
11
- from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
12
-
13
-
14
- def generateApiKey(secret, seed, include=None, add_dashes=False):
15
- try:
16
- current_timestamp = int(time.time())
17
- now = datetime.datetime.now()
18
- pbkdf2_iterations = random.randint(1000,10000)
19
- numeric_representation = int(
20
- f"{now.year}{now.month:02d}{now.day:02d}{now.hour:02d}{now.minute:02d}{now.second:02d}"
21
- )
22
- timestamp_hash = hashlib.sha256(
23
- str(current_timestamp).encode()).hexdigest()
24
- numeric_hash = hashlib.sha256(
25
- str(numeric_representation).encode()).hexdigest()
26
-
27
- if add_dashes:
28
- message = str(seed).encode()
29
- if include:
30
- pos = random.randint(0, 32)
31
- message = message[:pos] + include.encode() + message[pos:]
32
-
33
- combined_hash = f"{timestamp_hash}{numeric_hash}{message}"
34
-
35
- combined_hash = ''.join(random.sample(
36
- combined_hash, len(combined_hash)))
37
- api_key = hmac.new(
38
- secret.encode(), combined_hash.encode(), hashlib.sha256).hexdigest()
39
- return str(uuid.uuid5(uuid.NAMESPACE_DNS, api_key))
40
- else:
41
- salt = os.urandom(16)
42
- kdf = PBKDF2HMAC(
43
- algorithm=hashes.SHA256(),
44
- salt=salt,
45
- iterations=pbkdf2_iterations,
46
- length=32
47
- )
48
- seed = f'{seed}{current_timestamp}{numeric_hash}'.encode()
49
- if include:
50
- pos = random.randint(0, len(seed))
51
- seed = seed[:pos] + include.encode() + seed[pos:]
52
- key_bytes = kdf.derive(seed)
53
- key_base64 = base64.urlsafe_b64encode(key_bytes).decode()
54
- api_key = re.sub(r'[^a-zA-Z0-9]', '', key_base64)
55
- return api_key
56
- except Exception as e:
57
- print(e)
58
- return None
File without changes
File without changes