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.
- daniel_sources-1.2.0/.env.example +10 -0
- daniel_sources-1.2.0/FUNCTION_INDEX.md +89 -0
- daniel_sources-1.2.0/INSTALL_WINDOWS.txt +22 -0
- daniel_sources-1.2.0/MANIFEST.in +12 -0
- daniel_sources-1.2.0/PKG-INFO +135 -0
- daniel_sources-1.2.0/README.md +110 -0
- daniel_sources-1.2.0/SOURCES.md +34 -0
- daniel_sources-1.2.0/daniel_sources.egg-info/PKG-INFO +135 -0
- daniel_sources-1.2.0/daniel_sources.egg-info/SOURCES.txt +17 -0
- daniel_sources-1.2.0/daniel_sources.egg-info/dependency_links.txt +1 -0
- daniel_sources-1.2.0/daniel_sources.egg-info/requires.txt +8 -0
- daniel_sources-1.2.0/daniel_sources.egg-info/top_level.txt +1 -0
- daniel_sources-1.2.0/daniel_sources.py +1352 -0
- daniel_sources-1.2.0/docs/ORIGINAL_LIBRARY_GUIDE.md +172 -0
- daniel_sources-1.2.0/example_project.py +9 -0
- daniel_sources-1.2.0/pyproject.toml +37 -0
- daniel_sources-1.2.0/requirements.txt +3 -0
- daniel_sources-1.2.0/setup.cfg +4 -0
- daniel_sources-1.2.0/test_daniel_sources.py +197 -0
|
@@ -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 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
daniel_sources
|