daniel-sources 1.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,10 @@
1
+ # Rename to .env and add your OWN credentials. Never commit real .env files.
2
+ STRIPE_SECRET_KEY=sk_test_replace_me
3
+ STRIPE_WEBHOOK_SECRET=whsec_replace_me
4
+ SMTP_HOST=
5
+ SMTP_FROM=
6
+ SMTP_USERNAME=
7
+ SMTP_PASSWORD=
8
+
9
+ # Optional: set to 0 in your OS shell before import to disable automatic .env loading
10
+ # DANIEL_SOURCES_AUTO_DOTENV=0
@@ -0,0 +1,89 @@
1
+ # Complete public API index
2
+
3
+ **60 exported names** in `daniel_sources.py`. Import with `import daniel_sources as ds`.
4
+
5
+ | Name | Signature | What it does |
6
+ |---|---|---|
7
+ | `hash` | `(hashType: str, content: str \| bytes)` | Return a hexadecimal digest, e.g. hash('SHA256', 'hello'). |
8
+ | `compare_hash` | `(hashType: str, content: str \| bytes, expected_hex: str)` | Constant-time comparison of a computed digest and expected hex digest. |
9
+ | `password_hash` | `(password: str, method: str='scrypt')` | Werkzeug-compatible password hash, as used for KleeQuiz user accounts. |
10
+ | `password_verify` | `(password: str, stored_hash: str)` | Validate a Werkzeug-style stored password hash. |
11
+ | `random_token` | `(nbytes: int=32)` | Generate a cryptographically secure URL-safe token. |
12
+ | `generate_code` | `(length: int=6)` | Generate a cryptographically secure, zero-padded numeric code. |
13
+ | `hash_code` | `(code: str, secret: str \| None=None)` | KleeQuiz-compatible SHA256(secret + '\|' + code) hash. |
14
+ | `verify_code` | `(code: str, saved_digest: str, *, secret: str \| None=None)` | Check a code against a KleeQuiz-style secret-bound digest. |
15
+ | `create_api_key` | `(prefix: str='kq_live_')` | Generate a raw API key (store its SHA256 hash, not the raw string). |
16
+ | `hash_api_key` | `(key: str)` | SHA256 hash of an API key, compatible with APIStore/hash_key. |
17
+ | `hash_key` | `(raw: str)` | (see code) |
18
+ | `safe_prefix` | `(raw: str)` | (see code) |
19
+ | `APIStore` | `(class)` | SQLite-backed API keys, credit ledger, usage, and developer portal sessions. |
20
+ | `KeyRecord` | `(class)` | (see code) |
21
+ | `utc_now` | `()` | (see code) |
22
+ | `utc_iso` | `()` | (see code) |
23
+ | `generate_encryption_key` | `()` | Generate a Fernet key suitable for encrypt/decrypt; keep it secret. |
24
+ | `derive_fernet_key` | `(secret: str)` | Derive the legacy KleeQuiz quiz-file Fernet key from its configured secret. |
25
+ | `encrypt` | `(data: str \| bytes, key: str \| bytes)` | Encrypt text or bytes into a Fernet token string (key must be stable). |
26
+ | `decrypt` | `(token: str \| bytes, key: str \| bytes, *, as_bytes: bool=False)` | Decrypt a Fernet token; fails for invalid tokens or wrong keys. |
27
+ | `jwt_create` | `(payload: dict, secret: str, *, expires_in: int=3600)` | Sign an HS256 JWT, expiring in expires_in seconds by default. |
28
+ | `jwt_read` | `(token: str, secret: str)` | Verify an HS256 JWT signature and expiration (raises on failure). |
29
+ | `getenv_bool` | `(name: str, default: bool=False)` | Parse a Boolean environment variable as in production _bool_env(). |
30
+ | `required_env` | `(name: str)` | Read a nonempty environment variable or raise a clear error. |
31
+ | `normalize_phone` | `(value: str)` | Normalize international E.164-ish phone numbers, or return None. |
32
+ | `normalize_promo_code` | `(value: str)` | Uppercase and keep only alphanumeric, hyphen, underscore (max 64). |
33
+ | `slugify` | `(name: str, max_length: int=60)` | Build a URL slug. Doesn't check a database for collisions. |
34
+ | `generate_invite_code` | `(name: str='KleeQuiz')` | Random educator-style invitation code; caller must check uniqueness in DB. |
35
+ | `browser_label` | `(user_agent: str)` | Identify the browser category using KleeQuiz's User-Agent rules. |
36
+ | `safe_filename` | `(name: str)` | Reduce a path to a safe ASCII filename; no traversal or separators. |
37
+ | `allowed_file` | `(name: str, extensions=('.pdf', '.docx'))` | Check an extension; does NOT inspect the file's contents. |
38
+ | `extract_document` | `(path: str \| Path)` | Extract text from PDF or DOCX files like KleeQuiz production does. |
39
+ | `split_chunks` | `(text_value: str, size: int=18000)` | Split long text near paragraph boundaries, extracted from KleeQuiz. |
40
+ | `image_data_url` | `(path: str \| Path)` | Convert an image on disk to an inline data: URL. |
41
+ | `load_json` | `(path: str \| Path, default=None)` | Read a JSON file or return default if it doesn't exist. |
42
+ | `save_json` | `(path: str \| Path, data, *, indent: int=2)` | Atomically write UTF-8 JSON, replacing any existing file. |
43
+ | `question_id` | `(source: str, question: str)` | KleeQuiz legacy ID: SHA1 of source + '\|' + question (not for security). |
44
+ | `question_key` | `(question: dict)` | Stable SHA256 identifier using question ID or canonical content. |
45
+ | `parse_question_types` | `(raw: str \| list[str])` | Normalize KleeQuiz question type aliases, reject unsupported types. |
46
+ | `balanced_plan` | `(count: int, selected: list[str])` | Developer API round-robin plan; respects the requested type order. |
47
+ | `build_question_type_plan` | `(count: int, selected_types: list[str])` | KleeQuiz Production's weighted mixed-question allocator. |
48
+ | `validate_question` | `(question: dict, source: str, requested_type: str)` | Validate a question in the original KleeQuiz format; return clean copy. |
49
+ | `question_type_prompt` | `(question_type: str)` | KleeQuiz AI instruction corresponding to a single question type. |
50
+ | `reference_text_from_package` | `(payload: dict)` | Render existing quiz questions as reference material for the generator. |
51
+ | `quiz_required_plan_from_questions` | `(questions: list[dict])` | Infer KleeQuiz required membership from the question features. |
52
+ | `build_quiz_package` | `(title: str, source: str, questions: list[dict], key: str, *, source_kind: str='study_material', generation_style: str='study', required_plan: str \| None=None, assets: dict[str, bytes] \| None=None)` | Export a KleeQuiz-compatible encrypted .kleequiz container in memory. |
53
+ | `read_quiz_package_bytes` | `(blob: bytes, key: str)` | Read and validate encrypted .kleequiz bytes using their original key. |
54
+ | `export_quiz_file` | `(path: str \| Path, title: str, source: str, questions: list[dict], key: str, **kwargs)` | Write an encrypted KleeQuiz quiz file. |
55
+ | `import_quiz_file` | `(path: str \| Path, key: str)` | Read an encrypted KleeQuiz quiz file. |
56
+ | `send_email` | `(to_email: str, subject: str, body: str, *, host: str \| None=None, port: int \| None=None, sender: str \| None=None, username: str \| None=None, password: str \| None=None, use_ssl: bool \| None=None, use_tls: bool \| None=None, reply_to: str \| None=None)` | Send a plain-text SMTP email, adapted from KleeQuiz production. |
57
+ | `credits_to_cents` | `(credits: int, credits_per_usd: int=100)` | Developer API conversion: default 100 credits = USD $1.00. |
58
+ | `create_stripe_checkout` | `(amount_cents: int \| None=None, *, api_key: str \| None=None, currency: str='usd', product_name: str='Purchase', success_url: str, cancel_url: str, price_id: str \| None=None, mode: str='payment', quantity: int=1, metadata: dict \| None=None, customer_email: str \| None=None, client_reference_id: str \| None=None, idempotency_key: str \| None=None)` | Create a hosted Stripe Checkout Session; returns stripe Session with .url. |
59
+ | `create_credits_checkout` | `(key_id: int, credits: int, *, api_key: str \| None=None, base_url: str, credits_per_usd: int=100, currency: str='usd')` | Create developer-API-style credit recharge Checkout Session. |
60
+ | `verify_stripe_webhook` | `(payload: str \| bytes, signature: str, webhook_secret: str \| None=None)` | Verify Stripe-Signature before processing event. Returns parsed Stripe Event. |
61
+ | `paid_credits_from_webhook` | `(event, *, credits_per_usd: int=100, currency: str='usd')` | Check an ALREADY VERIFIED Stripe event's amount/currency/metadata. |
62
+ | `api_request` | `(method: str, url: str, *, bearer_token: str \| None=None, json_body: dict \| None=None, timeout: float=30, params: dict \| None=None)` | Call a JSON API with optional Bearer token; raises for HTTP errors. |
63
+ | `generate_quiz_via_api` | `(document_path: str \| Path, question_type_plan: list[str], *, api_url: str, api_key: str, timeout_seconds: int=300, difficulty: str='normal', seed: int=2026)` | Send a document to the KleeQuiz Developer API for text-only quiz generation. |
64
+ | `KleeQuizDeveloperAPIError` | `(class)` | KleeQuiz developer API error. |
65
+ | `configure_rotating_logger` | `(name: str, file_path: str \| Path, *, level: int=logging.INFO, max_bytes: int=5 * 1024 * 1024, backups: int=5)` | Configure named rotating file logger without changing root loggers. |
66
+ | `RateLimiter` | `(class)` | Thread-safe in-process sliding 60-second request limiter. |
67
+
68
+ ## Public methods of key classes
69
+
70
+ - **`APIStore.create_key`** — See docstring/source
71
+ - **`APIStore.authenticate`** — See docstring/source
72
+ - **`APIStore.list_keys`** — See docstring/source
73
+ - **`APIStore.revoke_key`** — See docstring/source
74
+ - **`APIStore.key_info`** — See docstring/source
75
+ - **`APIStore.credit_balance`** — See docstring/source
76
+ - **`APIStore.reserve_credits`** — See docstring/source
77
+ - **`APIStore.refund_credits`** — See docstring/source
78
+ - **`APIStore.add_credits`** — See docstring/source
79
+ - **`APIStore.recent_ledger`** — See docstring/source
80
+ - **`APIStore.recent_usage`** — See docstring/source
81
+ - **`APIStore.create_portal_session`** — See docstring/source
82
+ - **`APIStore.portal_session_key`** — See docstring/source
83
+ - **`APIStore.delete_portal_session`** — See docstring/source
84
+ - **`APIStore.log_usage`** — See docstring/source
85
+ - **`RateLimiter.allow`** — Return True if allowed (and record it); False if at limit.
86
+
87
+ ### Extra helper included in pip version
88
+
89
+ - `load_env(path=".env", *, override=False)` — Load environment variables from a `.env` file using `python-dotenv` (called explicitly; never automatically on import).
@@ -0,0 +1,22 @@
1
+ INSTALL DANIEL SOURCES IN ANY WINDOWS VENV
2
+ =======================================
3
+ 1. Extract this ZIP to any folder. Open PowerShell in that folder.
4
+ 2. In an existing project, create a virtual environment if needed:
5
+ py -m venv .venv
6
+ 3. Install from the source folder (replace C:\path\to...):
7
+ .\.venv\Scripts\python.exe -m pip install "C:\path\to\Daniel_Sources_Pip_Package_v1_2"
8
+ OR install from the prebuilt wheel:
9
+ .\.venv\Scripts\python.exe -m pip install "C:\path\to\daniel_sources-1.2.0-py3-none-any.whl"
10
+ 4. Verify:
11
+ .\.venv\Scripts\python.exe -c "import daniel_sources as ds; print(ds.hash('SHA256', 'hello'))"
12
+ 5. Add this to your app:
13
+ import daniel_sources as ds
14
+
15
+ All eight dependencies are installed into the venv by pip, using package metadata.
16
+ You do not need to activate the venv to use its Python executable.
17
+
18
+ The short command `pip install daniel_sources` from the internet requires
19
+ publishing the distribution to PyPI first. No upload has been performed.
20
+
21
+ TIP: A `.env` file in your current project folder is auto-loaded on import,
22
+ without overriding environment variables. This is independent of `.venv`.
@@ -0,0 +1,12 @@
1
+ include README.md
2
+ include FUNCTION_INDEX.md
3
+ include SOURCES.md
4
+ include example_project.py
5
+ include INSTALL_WINDOWS.txt
6
+ include requirements.txt
7
+ include .env.example
8
+ include test_daniel_sources.py
9
+ recursive-include docs *.md
10
+ prune dist
11
+ prune build
12
+ prune .venv
@@ -0,0 +1,135 @@
1
+ Metadata-Version: 2.4
2
+ Name: daniel_sources
3
+ Version: 1.2.0
4
+ Summary: Reusable Python utilities for hashing, encryption, Stripe Checkout, documents, and quiz projects
5
+ Author: Daniel
6
+ Keywords: utilities,hashing,stripe,quizzes,pdf,environment
7
+ Classifier: Development Status :: 4 - Beta
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.10
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
15
+ Requires-Python: >=3.10
16
+ Description-Content-Type: text/markdown
17
+ Requires-Dist: cryptography>=42.0
18
+ Requires-Dist: Werkzeug>=3.0
19
+ Requires-Dist: PyJWT>=2.9
20
+ Requires-Dist: requests>=2.31
21
+ Requires-Dist: stripe>=12.0
22
+ Requires-Dist: pypdf>=5.0
23
+ Requires-Dist: python-docx>=1.1
24
+ Requires-Dist: python-dotenv>=1.0
25
+
26
+ # daniel_sources — pip-installable Python utility library
27
+
28
+ **Python 3.10 or newer** · **Version 1.2.0** · import as `import daniel_sources as ds`
29
+
30
+ This is a reusable standalone module adapted from your KleeQuiz production + developer source code. It includes hashing/password helpers, JWTs, encryption, random codes, email, Stripe Checkout/webhook utilities, PDFs and DOCX, quizzes, SQLite API-key/credits helpers, and the Developer API client.
31
+
32
+ ## Install from the ZIP (works now, even before PyPI publishing)
33
+
34
+ 1. Extract the ZIP. Open a terminal in the extracted folder containing `pyproject.toml`.
35
+ 2. Install it in your active Python environment:
36
+
37
+ ```powershell
38
+ python -m pip install .
39
+ ```
40
+
41
+ **Windows virtual environment (no activation required):**
42
+
43
+ ```powershell
44
+ py -m venv .venv
45
+ .\.venv\Scripts\python.exe -m pip install .
46
+ .\.venv\Scripts\python.exe -c "import daniel_sources as ds; print(ds.hash('SHA256', 'hello'))"
47
+ ```
48
+
49
+ This automatically installs all eight declared third-party dependencies, *into the selected Python environment*: `cryptography`, `Werkzeug`, `PyJWT`, `requests`, `stripe`, `pypdf`, `python-docx`, and `python-dotenv`. Dependencies may require an internet connection if pip hasn't cached them. You do **not** need to install a separate requirements file.
50
+
51
+ **If you have the wheel instead** (from the included `dist` folder):
52
+
53
+ ```powershell
54
+ python -m pip install .\dist\daniel_sources-1.2.0-py3-none-any.whl
55
+ ```
56
+
57
+ ## Code examples
58
+
59
+ ```python
60
+ import daniel_sources as ds
61
+
62
+ print(ds.hash("SHA256", "hello"))
63
+ code = ds.generate_code()
64
+ key = ds.generate_encryption_key()
65
+ print(ds.decrypt(ds.encrypt("hello", key), key))
66
+ ```
67
+
68
+ ## Virtual environments and `.env` files
69
+
70
+ Make a `.env` file beside your project (not inside the installed library):
71
+
72
+ ```dotenv
73
+ STRIPE_SECRET_KEY=sk_test_your_own_key_here
74
+ STRIPE_WEBHOOK_SECRET=whsec_your_own_signing_secret_here
75
+ ```
76
+
77
+ `import daniel_sources` automatically loads the `.env` file in your **current working directory**, without overwriting existing environment variables. It does not look inside other projects or search parent folders. This is separate from the Python virtual environment `.venv` folder.
78
+
79
+ ```python
80
+ import os
81
+ import daniel_sources as ds # loads .env in your project folder, if present
82
+
83
+ print("Stripe configured?", bool(os.getenv("STRIPE_SECRET_KEY")))
84
+ print(ds.hash("SHA256", "hello"))
85
+ ```
86
+
87
+ If you keep configuration in a nonstandard file or need to reload it after import, use `ds.load_env("config/dev.env")`. Use `ds.load_env(".env", override=True)` only when you intentionally want the file to replace process variables.
88
+
89
+ To turn import-time loading **off**, set `DANIEL_SOURCES_AUTO_DOTENV=0` *before importing* the library (e.g. in your Windows terminal: `$env:DANIEL_SOURCES_AUTO_DOTENV="0"`). No network access or payment occurs on import. **Never commit real secrets to GitHub.**
90
+
91
+ ## Use `pip install daniel_sources` from anywhere
92
+
93
+ The exact command `pip install daniel_sources` works **only after** the package name has been claimed and this distribution has been uploaded to the public Python Package Index (PyPI), or an equivalent configured private index. This ZIP is **not yet published**. The included wheel and source distribution are ready to publish.
94
+
95
+ To publish on PyPI yourself:
96
+
97
+ 1. Create a PyPI account at https://pypi.org/ and configure authentication (use a protected PyPI token or trusted publishing).
98
+ 2. Review the module, license/ownership and documentation: publishing makes the **source public**.
99
+ 3. From this folder, install packaging tools and build (the prebuilt archives in `dist/` can be used instead):
100
+
101
+ ```powershell
102
+ python -m pip install --upgrade build twine
103
+ python -m build
104
+ python -m twine check dist/*
105
+ python -m twine upload dist/*
106
+ ```
107
+
108
+ 4. Once your package is live on PyPI, in any new project / virtualenv:
109
+
110
+ ```powershell
111
+ python -m pip install daniel_sources
112
+ ```
113
+
114
+ After every source update, increment the version in `pyproject.toml` and `__version__` before publishing again, then users can upgrade with `python -m pip install --upgrade daniel_sources`.
115
+
116
+ If the name is already reserved when you publish, choose a distinct PyPI distribution name (e.g., `daniel-sources-kleequiz`); the *import* can still be `import daniel_sources as ds`.
117
+
118
+ ## Install/edit your local package while developing
119
+
120
+ ```powershell
121
+ python -m pip install -e .
122
+ python test_daniel_sources.py
123
+ ```
124
+
125
+ Editable installs let you change `daniel_sources.py` and immediately use its changes in the same virtualenv. Publishing is not needed to develop locally.
126
+
127
+ ## Security and limits
128
+
129
+ - Hashing with SHA256 is **not** password storage; use `ds.password_hash` and `ds.password_verify` for passwords.
130
+ - Stripe helpers require real Stripe credentials and a server-side integration; webhook signatures must be verified before crediting purchases.
131
+ - These helpers do not automatically handle web routes, model weights, Google OAuth, or live production deployment.
132
+ - This distribution contains no real API tokens, private `.env` files, production database or user records.
133
+ - Publishing the package publicly is your decision: inspect all code for any information you don't want publicly available and decide on your license before upload.
134
+
135
+ Also see `FUNCTION_INDEX.md`, `SOURCES.md`, and `docs/ORIGINAL_LIBRARY_GUIDE.md`.
@@ -0,0 +1,110 @@
1
+ # daniel_sources — pip-installable Python utility library
2
+
3
+ **Python 3.10 or newer** · **Version 1.2.0** · import as `import daniel_sources as ds`
4
+
5
+ This is a reusable standalone module adapted from your KleeQuiz production + developer source code. It includes hashing/password helpers, JWTs, encryption, random codes, email, Stripe Checkout/webhook utilities, PDFs and DOCX, quizzes, SQLite API-key/credits helpers, and the Developer API client.
6
+
7
+ ## Install from the ZIP (works now, even before PyPI publishing)
8
+
9
+ 1. Extract the ZIP. Open a terminal in the extracted folder containing `pyproject.toml`.
10
+ 2. Install it in your active Python environment:
11
+
12
+ ```powershell
13
+ python -m pip install .
14
+ ```
15
+
16
+ **Windows virtual environment (no activation required):**
17
+
18
+ ```powershell
19
+ py -m venv .venv
20
+ .\.venv\Scripts\python.exe -m pip install .
21
+ .\.venv\Scripts\python.exe -c "import daniel_sources as ds; print(ds.hash('SHA256', 'hello'))"
22
+ ```
23
+
24
+ This automatically installs all eight declared third-party dependencies, *into the selected Python environment*: `cryptography`, `Werkzeug`, `PyJWT`, `requests`, `stripe`, `pypdf`, `python-docx`, and `python-dotenv`. Dependencies may require an internet connection if pip hasn't cached them. You do **not** need to install a separate requirements file.
25
+
26
+ **If you have the wheel instead** (from the included `dist` folder):
27
+
28
+ ```powershell
29
+ python -m pip install .\dist\daniel_sources-1.2.0-py3-none-any.whl
30
+ ```
31
+
32
+ ## Code examples
33
+
34
+ ```python
35
+ import daniel_sources as ds
36
+
37
+ print(ds.hash("SHA256", "hello"))
38
+ code = ds.generate_code()
39
+ key = ds.generate_encryption_key()
40
+ print(ds.decrypt(ds.encrypt("hello", key), key))
41
+ ```
42
+
43
+ ## Virtual environments and `.env` files
44
+
45
+ Make a `.env` file beside your project (not inside the installed library):
46
+
47
+ ```dotenv
48
+ STRIPE_SECRET_KEY=sk_test_your_own_key_here
49
+ STRIPE_WEBHOOK_SECRET=whsec_your_own_signing_secret_here
50
+ ```
51
+
52
+ `import daniel_sources` automatically loads the `.env` file in your **current working directory**, without overwriting existing environment variables. It does not look inside other projects or search parent folders. This is separate from the Python virtual environment `.venv` folder.
53
+
54
+ ```python
55
+ import os
56
+ import daniel_sources as ds # loads .env in your project folder, if present
57
+
58
+ print("Stripe configured?", bool(os.getenv("STRIPE_SECRET_KEY")))
59
+ print(ds.hash("SHA256", "hello"))
60
+ ```
61
+
62
+ If you keep configuration in a nonstandard file or need to reload it after import, use `ds.load_env("config/dev.env")`. Use `ds.load_env(".env", override=True)` only when you intentionally want the file to replace process variables.
63
+
64
+ To turn import-time loading **off**, set `DANIEL_SOURCES_AUTO_DOTENV=0` *before importing* the library (e.g. in your Windows terminal: `$env:DANIEL_SOURCES_AUTO_DOTENV="0"`). No network access or payment occurs on import. **Never commit real secrets to GitHub.**
65
+
66
+ ## Use `pip install daniel_sources` from anywhere
67
+
68
+ The exact command `pip install daniel_sources` works **only after** the package name has been claimed and this distribution has been uploaded to the public Python Package Index (PyPI), or an equivalent configured private index. This ZIP is **not yet published**. The included wheel and source distribution are ready to publish.
69
+
70
+ To publish on PyPI yourself:
71
+
72
+ 1. Create a PyPI account at https://pypi.org/ and configure authentication (use a protected PyPI token or trusted publishing).
73
+ 2. Review the module, license/ownership and documentation: publishing makes the **source public**.
74
+ 3. From this folder, install packaging tools and build (the prebuilt archives in `dist/` can be used instead):
75
+
76
+ ```powershell
77
+ python -m pip install --upgrade build twine
78
+ python -m build
79
+ python -m twine check dist/*
80
+ python -m twine upload dist/*
81
+ ```
82
+
83
+ 4. Once your package is live on PyPI, in any new project / virtualenv:
84
+
85
+ ```powershell
86
+ python -m pip install daniel_sources
87
+ ```
88
+
89
+ After every source update, increment the version in `pyproject.toml` and `__version__` before publishing again, then users can upgrade with `python -m pip install --upgrade daniel_sources`.
90
+
91
+ If the name is already reserved when you publish, choose a distinct PyPI distribution name (e.g., `daniel-sources-kleequiz`); the *import* can still be `import daniel_sources as ds`.
92
+
93
+ ## Install/edit your local package while developing
94
+
95
+ ```powershell
96
+ python -m pip install -e .
97
+ python test_daniel_sources.py
98
+ ```
99
+
100
+ Editable installs let you change `daniel_sources.py` and immediately use its changes in the same virtualenv. Publishing is not needed to develop locally.
101
+
102
+ ## Security and limits
103
+
104
+ - Hashing with SHA256 is **not** password storage; use `ds.password_hash` and `ds.password_verify` for passwords.
105
+ - Stripe helpers require real Stripe credentials and a server-side integration; webhook signatures must be verified before crediting purchases.
106
+ - These helpers do not automatically handle web routes, model weights, Google OAuth, or live production deployment.
107
+ - This distribution contains no real API tokens, private `.env` files, production database or user records.
108
+ - Publishing the package publicly is your decision: inspect all code for any information you don't want publicly available and decide on your license before upload.
109
+
110
+ Also see `FUNCTION_INDEX.md`, `SOURCES.md`, and `docs/ORIGINAL_LIBRARY_GUIDE.md`.
@@ -0,0 +1,34 @@
1
+ # Source map: where each reusable function originated
2
+
3
+ This library was built from **the supplied user-owned ZIP**, containing these original snapshots:
4
+
5
+ - `KleeQuiz_Production_v15_Developer_API_FLAT.zip`
6
+ - `KleeQuiz_Developers_v3_Beta_FLAT.zip`
7
+
8
+ The original source was inspected. Some functions were moved nearly as-is, while others had Flask/FastAPI application state removed and parameters added so they can run in unrelated projects. The public library is not a byte-for-byte copy of all source files.
9
+
10
+ | New API | Original code / inspiration | Port notes |
11
+ |---|---|---|
12
+ | `APIStore`, `KeyRecord`, `hash_key`, `safe_prefix`, `utc_now`, `utc_iso` | Developers `api_store.py` | Ported full local SQLite API-key, credit ledger, usage, and session store; connection context management improved. |
13
+ | `hash`, `hash_api_key`, `create_api_key` | Developers `api_store.py` and Production `app.py` hash operations | Generic SHA family API with named algorithm, full token generator. |
14
+ | `generate_code`, `hash_code`, `verify_code` | Production `app.py`: `generate_code`, `hash_code` | Flask SECRET_KEY changed to explicit `secret=` or environment variable; separate verification helper. |
15
+ | `password_hash`, `password_verify` | Production `app.py`: `werkzeug.security.generate_password_hash/check_password_hash` | Thin lazy-import compatibility wrappers. |
16
+ | `normalize_phone`, `normalize_promo_code`, `slugify`, `generate_invite_code`, `browser_label` | Production `app.py`: phone, promo and educator naming helpers, browser labeling | Removed DB/request dependencies. |
17
+ | `safe_filename`, `allowed_file`, `extract_document`, `split_chunks`, `image_data_url` | Production `app.py`: upload, PDF/DOCX, source extraction | Made file paths explicit; optional dependencies lazy-loaded. |
18
+ | `question_id`, `question_key`, `validate_question`, `build_question_type_plan`, `question_type_prompt` | Production `app.py`: IDs, validation, weighted format allocator, question prompts | Retains original quiz field conventions; type selection and validation available without the website. |
19
+ | `parse_question_types`, `balanced_plan` | Developers `app.py`: `_parse_types`, `_balanced_plan` | Uses normal `ValueError` instead of HTTPException. |
20
+ | `build_quiz_package`, `read_quiz_package_bytes`, `reference_text_from_package`, `quiz_required_plan_from_questions` | Production `app.py`: proprietary encrypted KleeQuiz Quiz V1 export/import | Explicit key required; compatible header/format/legacy key derivation. No DB attachment required. |
21
+ | `send_email` | Production `app.py`: `send_email_message` | Configurable SMTP inputs or environment values, no global Flask dependency. |
22
+ | `credits_to_cents`, `create_credits_checkout`, `paid_credits_from_webhook` | Developers `app.py`: `_money_for_credits`, `portal_recharge`, `stripe_webhook` | Extracted checkout and already-verified event metadata checks; database fulfillment remains caller's job. |
23
+ | `create_stripe_checkout`, `verify_stripe_webhook` | Production/Developers `app.py`: Stripe Checkout Session + `stripe.Webhook.construct_event` | Generalized self-contained checkout, with server-side API key and signed webhooks. |
24
+ | `generate_quiz_via_api` | Production `kleequiz_ai_api_client.py` | API endpoint, multipart upload, timeouts, and text-only response validation maintained. |
25
+ | `configure_rotating_logger` | Production `app.py`: `configure_file_logging` | Logs to a named logger rather than resetting every process-wide logger. |
26
+ | `RateLimiter` | Developers `app.py`: `_enforce_rate_limit` | Reusable instance-based thread-safe limiter. |
27
+ | `encrypt/decrypt`, `generate_encryption_key`, `derive_fernet_key` | Production `app.py`: `quiz_file_fernet` and `cryptography.fernet` usage | General encryption helpers; no keys automatically stored. |
28
+ | `jwt_create/jwt_read`, `api_request`, `save_json/load_json`, `getenv_bool` | Existing imports/configuration practices plus general adaptations | Additional reusable glue utilities. |
29
+
30
+ ## Why the original web routes are not in this module
31
+
32
+ The login endpoints, Flask database models, educator membership subscriptions, local concept-miner implementation, and many other site routes cannot be lifted as independent `def` functions: they depend on `app`, database sessions, template directories, external infrastructure and sometimes production configuration. Importing a production `app.py` would itself initialize the server, database, and logging, violating the goal of a reusable helper module.
33
+
34
+ This module deliberately offers the **portable underlying operations**, rather than promising that calling one function reproduces the entire KleeQuiz website infrastructure. To use the local AI generator rather than its HTTP API, keep the separate original runtime/pipeline files in a project configured for them.
@@ -0,0 +1,135 @@
1
+ Metadata-Version: 2.4
2
+ Name: daniel_sources
3
+ Version: 1.2.0
4
+ Summary: Reusable Python utilities for hashing, encryption, Stripe Checkout, documents, and quiz projects
5
+ Author: Daniel
6
+ Keywords: utilities,hashing,stripe,quizzes,pdf,environment
7
+ Classifier: Development Status :: 4 - Beta
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.10
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
15
+ Requires-Python: >=3.10
16
+ Description-Content-Type: text/markdown
17
+ Requires-Dist: cryptography>=42.0
18
+ Requires-Dist: Werkzeug>=3.0
19
+ Requires-Dist: PyJWT>=2.9
20
+ Requires-Dist: requests>=2.31
21
+ Requires-Dist: stripe>=12.0
22
+ Requires-Dist: pypdf>=5.0
23
+ Requires-Dist: python-docx>=1.1
24
+ Requires-Dist: python-dotenv>=1.0
25
+
26
+ # daniel_sources — pip-installable Python utility library
27
+
28
+ **Python 3.10 or newer** · **Version 1.2.0** · import as `import daniel_sources as ds`
29
+
30
+ This is a reusable standalone module adapted from your KleeQuiz production + developer source code. It includes hashing/password helpers, JWTs, encryption, random codes, email, Stripe Checkout/webhook utilities, PDFs and DOCX, quizzes, SQLite API-key/credits helpers, and the Developer API client.
31
+
32
+ ## Install from the ZIP (works now, even before PyPI publishing)
33
+
34
+ 1. Extract the ZIP. Open a terminal in the extracted folder containing `pyproject.toml`.
35
+ 2. Install it in your active Python environment:
36
+
37
+ ```powershell
38
+ python -m pip install .
39
+ ```
40
+
41
+ **Windows virtual environment (no activation required):**
42
+
43
+ ```powershell
44
+ py -m venv .venv
45
+ .\.venv\Scripts\python.exe -m pip install .
46
+ .\.venv\Scripts\python.exe -c "import daniel_sources as ds; print(ds.hash('SHA256', 'hello'))"
47
+ ```
48
+
49
+ This automatically installs all eight declared third-party dependencies, *into the selected Python environment*: `cryptography`, `Werkzeug`, `PyJWT`, `requests`, `stripe`, `pypdf`, `python-docx`, and `python-dotenv`. Dependencies may require an internet connection if pip hasn't cached them. You do **not** need to install a separate requirements file.
50
+
51
+ **If you have the wheel instead** (from the included `dist` folder):
52
+
53
+ ```powershell
54
+ python -m pip install .\dist\daniel_sources-1.2.0-py3-none-any.whl
55
+ ```
56
+
57
+ ## Code examples
58
+
59
+ ```python
60
+ import daniel_sources as ds
61
+
62
+ print(ds.hash("SHA256", "hello"))
63
+ code = ds.generate_code()
64
+ key = ds.generate_encryption_key()
65
+ print(ds.decrypt(ds.encrypt("hello", key), key))
66
+ ```
67
+
68
+ ## Virtual environments and `.env` files
69
+
70
+ Make a `.env` file beside your project (not inside the installed library):
71
+
72
+ ```dotenv
73
+ STRIPE_SECRET_KEY=sk_test_your_own_key_here
74
+ STRIPE_WEBHOOK_SECRET=whsec_your_own_signing_secret_here
75
+ ```
76
+
77
+ `import daniel_sources` automatically loads the `.env` file in your **current working directory**, without overwriting existing environment variables. It does not look inside other projects or search parent folders. This is separate from the Python virtual environment `.venv` folder.
78
+
79
+ ```python
80
+ import os
81
+ import daniel_sources as ds # loads .env in your project folder, if present
82
+
83
+ print("Stripe configured?", bool(os.getenv("STRIPE_SECRET_KEY")))
84
+ print(ds.hash("SHA256", "hello"))
85
+ ```
86
+
87
+ If you keep configuration in a nonstandard file or need to reload it after import, use `ds.load_env("config/dev.env")`. Use `ds.load_env(".env", override=True)` only when you intentionally want the file to replace process variables.
88
+
89
+ To turn import-time loading **off**, set `DANIEL_SOURCES_AUTO_DOTENV=0` *before importing* the library (e.g. in your Windows terminal: `$env:DANIEL_SOURCES_AUTO_DOTENV="0"`). No network access or payment occurs on import. **Never commit real secrets to GitHub.**
90
+
91
+ ## Use `pip install daniel_sources` from anywhere
92
+
93
+ The exact command `pip install daniel_sources` works **only after** the package name has been claimed and this distribution has been uploaded to the public Python Package Index (PyPI), or an equivalent configured private index. This ZIP is **not yet published**. The included wheel and source distribution are ready to publish.
94
+
95
+ To publish on PyPI yourself:
96
+
97
+ 1. Create a PyPI account at https://pypi.org/ and configure authentication (use a protected PyPI token or trusted publishing).
98
+ 2. Review the module, license/ownership and documentation: publishing makes the **source public**.
99
+ 3. From this folder, install packaging tools and build (the prebuilt archives in `dist/` can be used instead):
100
+
101
+ ```powershell
102
+ python -m pip install --upgrade build twine
103
+ python -m build
104
+ python -m twine check dist/*
105
+ python -m twine upload dist/*
106
+ ```
107
+
108
+ 4. Once your package is live on PyPI, in any new project / virtualenv:
109
+
110
+ ```powershell
111
+ python -m pip install daniel_sources
112
+ ```
113
+
114
+ After every source update, increment the version in `pyproject.toml` and `__version__` before publishing again, then users can upgrade with `python -m pip install --upgrade daniel_sources`.
115
+
116
+ If the name is already reserved when you publish, choose a distinct PyPI distribution name (e.g., `daniel-sources-kleequiz`); the *import* can still be `import daniel_sources as ds`.
117
+
118
+ ## Install/edit your local package while developing
119
+
120
+ ```powershell
121
+ python -m pip install -e .
122
+ python test_daniel_sources.py
123
+ ```
124
+
125
+ Editable installs let you change `daniel_sources.py` and immediately use its changes in the same virtualenv. Publishing is not needed to develop locally.
126
+
127
+ ## Security and limits
128
+
129
+ - Hashing with SHA256 is **not** password storage; use `ds.password_hash` and `ds.password_verify` for passwords.
130
+ - Stripe helpers require real Stripe credentials and a server-side integration; webhook signatures must be verified before crediting purchases.
131
+ - These helpers do not automatically handle web routes, model weights, Google OAuth, or live production deployment.
132
+ - This distribution contains no real API tokens, private `.env` files, production database or user records.
133
+ - Publishing the package publicly is your decision: inspect all code for any information you don't want publicly available and decide on your license before upload.
134
+
135
+ Also see `FUNCTION_INDEX.md`, `SOURCES.md`, and `docs/ORIGINAL_LIBRARY_GUIDE.md`.
@@ -0,0 +1,17 @@
1
+ .env.example
2
+ FUNCTION_INDEX.md
3
+ INSTALL_WINDOWS.txt
4
+ MANIFEST.in
5
+ README.md
6
+ SOURCES.md
7
+ daniel_sources.py
8
+ example_project.py
9
+ pyproject.toml
10
+ requirements.txt
11
+ test_daniel_sources.py
12
+ daniel_sources.egg-info/PKG-INFO
13
+ daniel_sources.egg-info/SOURCES.txt
14
+ daniel_sources.egg-info/dependency_links.txt
15
+ daniel_sources.egg-info/requires.txt
16
+ daniel_sources.egg-info/top_level.txt
17
+ docs/ORIGINAL_LIBRARY_GUIDE.md
@@ -0,0 +1,8 @@
1
+ cryptography>=42.0
2
+ Werkzeug>=3.0
3
+ PyJWT>=2.9
4
+ requests>=2.31
5
+ stripe>=12.0
6
+ pypdf>=5.0
7
+ python-docx>=1.1
8
+ python-dotenv>=1.0
@@ -0,0 +1 @@
1
+ daniel_sources