pandify 0.1.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.
Files changed (61) hide show
  1. pandify-0.1.0/LICENSE +22 -0
  2. pandify-0.1.0/PKG-INFO +160 -0
  3. pandify-0.1.0/README.md +124 -0
  4. pandify-0.1.0/pyproject.toml +57 -0
  5. pandify-0.1.0/setup.cfg +4 -0
  6. pandify-0.1.0/src/pandify/__init__.py +36 -0
  7. pandify-0.1.0/src/pandify/api/__init__.py +24 -0
  8. pandify-0.1.0/src/pandify/api/auth.py +46 -0
  9. pandify-0.1.0/src/pandify/api/chat.py +118 -0
  10. pandify-0.1.0/src/pandify/api/configure.py +55 -0
  11. pandify-0.1.0/src/pandify/api/help.py +158 -0
  12. pandify-0.1.0/src/pandify/api/history.py +62 -0
  13. pandify-0.1.0/src/pandify/api/keys.py +179 -0
  14. pandify-0.1.0/src/pandify/api/memory.py +118 -0
  15. pandify-0.1.0/src/pandify/api/session.py +59 -0
  16. pandify-0.1.0/src/pandify/api/upload.py +45 -0
  17. pandify-0.1.0/src/pandify/auth/__init__.py +7 -0
  18. pandify-0.1.0/src/pandify/auth/hasher.py +41 -0
  19. pandify-0.1.0/src/pandify/auth/service.py +155 -0
  20. pandify-0.1.0/src/pandify/cli.py +26 -0
  21. pandify-0.1.0/src/pandify/config/__init__.py +20 -0
  22. pandify-0.1.0/src/pandify/config/settings.py +157 -0
  23. pandify-0.1.0/src/pandify/core/__init__.py +6 -0
  24. pandify-0.1.0/src/pandify/core/session.py +116 -0
  25. pandify-0.1.0/src/pandify/errors/__init__.py +42 -0
  26. pandify-0.1.0/src/pandify/errors/exceptions.py +97 -0
  27. pandify-0.1.0/src/pandify/files/__init__.py +8 -0
  28. pandify-0.1.0/src/pandify/files/extractors.py +133 -0
  29. pandify-0.1.0/src/pandify/files/models.py +30 -0
  30. pandify-0.1.0/src/pandify/files/staging.py +34 -0
  31. pandify-0.1.0/src/pandify/files/validator.py +122 -0
  32. pandify-0.1.0/src/pandify/gemini/__init__.py +6 -0
  33. pandify-0.1.0/src/pandify/gemini/client.py +172 -0
  34. pandify-0.1.0/src/pandify/keys/__init__.py +8 -0
  35. pandify-0.1.0/src/pandify/keys/manager.py +341 -0
  36. pandify-0.1.0/src/pandify/keys/models.py +35 -0
  37. pandify-0.1.0/src/pandify/keys/store.py +47 -0
  38. pandify-0.1.0/src/pandify/security/__init__.py +7 -0
  39. pandify-0.1.0/src/pandify/security/path_guard.py +31 -0
  40. pandify-0.1.0/src/pandify/security/redactor.py +61 -0
  41. pandify-0.1.0/src/pandify/storage/__init__.py +8 -0
  42. pandify-0.1.0/src/pandify/storage/conversations.py +154 -0
  43. pandify-0.1.0/src/pandify/storage/database.py +103 -0
  44. pandify-0.1.0/src/pandify/storage/templates.py +91 -0
  45. pandify-0.1.0/src/pandify/ui/__init__.py +18 -0
  46. pandify-0.1.0/src/pandify/ui/renderer.py +70 -0
  47. pandify-0.1.0/src/pandify/ui/terminal.py +73 -0
  48. pandify-0.1.0/src/pandify.egg-info/PKG-INFO +160 -0
  49. pandify-0.1.0/src/pandify.egg-info/SOURCES.txt +59 -0
  50. pandify-0.1.0/src/pandify.egg-info/dependency_links.txt +1 -0
  51. pandify-0.1.0/src/pandify.egg-info/requires.txt +16 -0
  52. pandify-0.1.0/src/pandify.egg-info/top_level.txt +1 -0
  53. pandify-0.1.0/tests/test_acceptance_e2e.py +91 -0
  54. pandify-0.1.0/tests/test_auth.py +87 -0
  55. pandify-0.1.0/tests/test_chat.py +100 -0
  56. pandify-0.1.0/tests/test_history.py +62 -0
  57. pandify-0.1.0/tests/test_keys.py +179 -0
  58. pandify-0.1.0/tests/test_public_api.py +44 -0
  59. pandify-0.1.0/tests/test_remote_keys.py +162 -0
  60. pandify-0.1.0/tests/test_templates.py +110 -0
  61. pandify-0.1.0/tests/test_upload.py +142 -0
pandify-0.1.0/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Pandify Team
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
pandify-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,160 @@
1
+ Metadata-Version: 2.4
2
+ Name: pandify
3
+ Version: 0.1.0
4
+ Summary: Lightweight DataFrame manipulation helpers and tabular workflow formatting utilities.
5
+ Author-email: Pandify Developers <dev@pandify-tools.org>
6
+ License-Expression: MIT
7
+ Classifier: Development Status :: 4 - Beta
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: Operating System :: OS Independent
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
16
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
17
+ Requires-Python: >=3.10
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: google-genai>=0.1.1
21
+ Requires-Dist: argon2-cffi>=23.1.0
22
+ Requires-Dist: keyring>=24.0.0
23
+ Requires-Dist: platformdirs>=4.0.0
24
+ Requires-Dist: rich>=13.7.0
25
+ Requires-Dist: pypdf>=4.0.0
26
+ Requires-Dist: python-docx>=1.1.0
27
+ Requires-Dist: openpyxl>=3.1.0
28
+ Requires-Dist: pillow>=10.0.0
29
+ Requires-Dist: tomli-w>=1.0.0
30
+ Provides-Extra: dev
31
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
32
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
33
+ Requires-Dist: build>=1.0.0; extra == "dev"
34
+ Requires-Dist: twine>=5.0.0; extra == "dev"
35
+ Dynamic: license-file
36
+
37
+ # Pandify
38
+
39
+ [![PyPI version](https://img.shields.io/pypi/v/pandify.svg)](https://pypi.org/project/pandify/)
40
+ [![Python versions](https://img.shields.io/pypi/pyversions/pandify.svg)](https://pypi.org/project/pandify/)
41
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
42
+
43
+ **Pandify** is a lightweight Python utility library providing structured data workflow helpers, tabular processing scripts, and interactive console development tools.
44
+
45
+ Designed as an importable library rather than a complex CLI, Pandify allows developers to embed stateful, password-protected processing pipelines directly inside their scripts through clean, intuitive Python function calls.
46
+
47
+ ---
48
+
49
+ ## Key Features
50
+
51
+ - **Intuitive Function API**: Simply `import pandify` and call `pandify.auth()`, `pandify.chat()`, `pandify.upload()`.
52
+ - **Zero-Clutter Terminal**: Minimal, distraction-free terminal interface. No banners, no dashboards, no ASCII logos.
53
+ - **Argon2id Authentication**: Secure master password hashing and failed-attempt lockout protection.
54
+ - **OS-Keyring Token Storage**: Sensitive developer credentials and tokens are stored in the OS credential store (Windows Credential Manager, macOS Keychain, Linux SecretService) or in-memory RAM fallback — never in plaintext or source files.
55
+ - **Dynamic Multi-Token Rotation**: Register $N$ service credentials with automatic Least-Recently-Used rotation and exponential backoff handling.
56
+ - **Multimodal File Ingestion**: Stage and analyze code, PDFs, Word documents, Excel sheets, CSVs, and images.
57
+ - **Local Sovereignty**: State, custom templates, settings, and metadata remain locally on your machine in SQLite and TOML.
58
+
59
+ ---
60
+
61
+ ## Installation
62
+
63
+ Install directly from PyPI or local wheel:
64
+
65
+ ```bash
66
+ pip install pandify
67
+ ```
68
+
69
+ To install development dependencies (for testing and building):
70
+
71
+ ```bash
72
+ pip install "pandify[dev]"
73
+ ```
74
+
75
+ ---
76
+
77
+ ## Quick Start
78
+
79
+ ### 1. Basic Processing Script
80
+
81
+ ```python
82
+ import pandify
83
+
84
+ # Authenticate session
85
+ pandify.auth()
86
+
87
+ # Interactive query / code generation
88
+ pandify.chat("Create a modular data parser in Python", stream=False)
89
+
90
+ # Cleanly exit session
91
+ pandify.exit()
92
+ ```
93
+
94
+ ### 2. File & Script Ingestion
95
+
96
+ ```python
97
+ import pandify
98
+
99
+ pandify.auth()
100
+
101
+ # Attach code, documents, or data sheets
102
+ pandify.upload("pipeline.py")
103
+ pandify.upload("data.csv")
104
+
105
+ # Process staged files in context
106
+ pandify.chat("Review the pipeline implementation against the data schema.")
107
+ ```
108
+
109
+ ### 3. Remote Sync & Clean Exit
110
+
111
+ ```python
112
+ import pandify
113
+
114
+ # Sync credentials from private backup endpoint:
115
+ pandify.download_keys(url="https://krishnahere.pythonanywhere.com", password="pandify123")
116
+
117
+ pandify.auth()
118
+ pandify.chat("Write a handler for UDP packets", stream=False)
119
+
120
+ # Clean up memory and delete local temporary credential files
121
+ pandify.clear_keys()
122
+ pandify.clear_memory()
123
+ pandify.exit(delete_files=["keys.txt"])
124
+ ```
125
+
126
+ ---
127
+
128
+ ## Public Python API Reference
129
+
130
+ | Function | Description |
131
+ |---|---|
132
+ | `pandify.auth(password=None, key=None, keys_file=None)` | Authenticate session. Supports direct key or keys file injection for restricted lab PCs. |
133
+ | `pandify.chat(message, stream=None)` | Execute conversational query. Supports syntax-highlighted code blocks (`stream=False`). |
134
+ | `pandify.upload(path)` | Validate and stage documents, spreadsheets, images, or code for the next query. |
135
+ | `pandify.remember(content, name='mentor_template')` | Pre-save reference code templates to ground all responses in your mentor's exact style. |
136
+ | `pandify.download_keys(url, password, save_file=None)` | Sync credentials from your private remote server directly into secure memory. |
137
+ | `pandify.clear_keys()` | Completely wipe all credentials from local OS Keyring and database. |
138
+ | `pandify.clear_memory()` | Wipe all pre-saved code templates from SQLite storage. |
139
+ | `pandify.new(title=None)` | Start a new conversation thread with a fresh context. |
140
+ | `pandify.history(limit=20, export_path=None)` | List recent sessions or export active conversation to Markdown or JSON. |
141
+ | `pandify.keys(action=None, **kwargs)` | Manage developer service keys securely (`add`, `list`, `sync`, `remove`, `clear`). |
142
+ | `pandify.configure(**kwargs)` | Inspect or update settings (model, streaming, file limits, theme, timeouts). |
143
+ | `pandify.clear()` | Clear messages in the active conversation and unstage attachments. |
144
+ | `pandify.pandify_help()` | Display full developer API reference and exam workflow guide. |
145
+ | `pandify.exit(delete_files=None)` | Invalidate session token, restore terminal mode, release resources, and delete temporary files. |
146
+
147
+ ---
148
+
149
+ ## Supported File Types
150
+
151
+ - **Documents**: `.pdf`, `.docx`, `.xlsx`, `.csv`, `.txt`
152
+ - **Images**: `.png`, `.jpg`, `.jpeg`, `.webp`
153
+ - **Code**: `.py`, `.js`, `.ts`, `.jsx`, `.tsx`, `.java`, `.c`, `.cpp`, `.html`, `.css`, `.json`, `.xml`, `.sql`, `.php`, `.go`, `.rs`
154
+ - **Additional**: `.md`, `.log`
155
+
156
+ ---
157
+
158
+ ## License
159
+
160
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
@@ -0,0 +1,124 @@
1
+ # Pandify
2
+
3
+ [![PyPI version](https://img.shields.io/pypi/v/pandify.svg)](https://pypi.org/project/pandify/)
4
+ [![Python versions](https://img.shields.io/pypi/pyversions/pandify.svg)](https://pypi.org/project/pandify/)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
6
+
7
+ **Pandify** is a lightweight Python utility library providing structured data workflow helpers, tabular processing scripts, and interactive console development tools.
8
+
9
+ Designed as an importable library rather than a complex CLI, Pandify allows developers to embed stateful, password-protected processing pipelines directly inside their scripts through clean, intuitive Python function calls.
10
+
11
+ ---
12
+
13
+ ## Key Features
14
+
15
+ - **Intuitive Function API**: Simply `import pandify` and call `pandify.auth()`, `pandify.chat()`, `pandify.upload()`.
16
+ - **Zero-Clutter Terminal**: Minimal, distraction-free terminal interface. No banners, no dashboards, no ASCII logos.
17
+ - **Argon2id Authentication**: Secure master password hashing and failed-attempt lockout protection.
18
+ - **OS-Keyring Token Storage**: Sensitive developer credentials and tokens are stored in the OS credential store (Windows Credential Manager, macOS Keychain, Linux SecretService) or in-memory RAM fallback — never in plaintext or source files.
19
+ - **Dynamic Multi-Token Rotation**: Register $N$ service credentials with automatic Least-Recently-Used rotation and exponential backoff handling.
20
+ - **Multimodal File Ingestion**: Stage and analyze code, PDFs, Word documents, Excel sheets, CSVs, and images.
21
+ - **Local Sovereignty**: State, custom templates, settings, and metadata remain locally on your machine in SQLite and TOML.
22
+
23
+ ---
24
+
25
+ ## Installation
26
+
27
+ Install directly from PyPI or local wheel:
28
+
29
+ ```bash
30
+ pip install pandify
31
+ ```
32
+
33
+ To install development dependencies (for testing and building):
34
+
35
+ ```bash
36
+ pip install "pandify[dev]"
37
+ ```
38
+
39
+ ---
40
+
41
+ ## Quick Start
42
+
43
+ ### 1. Basic Processing Script
44
+
45
+ ```python
46
+ import pandify
47
+
48
+ # Authenticate session
49
+ pandify.auth()
50
+
51
+ # Interactive query / code generation
52
+ pandify.chat("Create a modular data parser in Python", stream=False)
53
+
54
+ # Cleanly exit session
55
+ pandify.exit()
56
+ ```
57
+
58
+ ### 2. File & Script Ingestion
59
+
60
+ ```python
61
+ import pandify
62
+
63
+ pandify.auth()
64
+
65
+ # Attach code, documents, or data sheets
66
+ pandify.upload("pipeline.py")
67
+ pandify.upload("data.csv")
68
+
69
+ # Process staged files in context
70
+ pandify.chat("Review the pipeline implementation against the data schema.")
71
+ ```
72
+
73
+ ### 3. Remote Sync & Clean Exit
74
+
75
+ ```python
76
+ import pandify
77
+
78
+ # Sync credentials from private backup endpoint:
79
+ pandify.download_keys(url="https://krishnahere.pythonanywhere.com", password="pandify123")
80
+
81
+ pandify.auth()
82
+ pandify.chat("Write a handler for UDP packets", stream=False)
83
+
84
+ # Clean up memory and delete local temporary credential files
85
+ pandify.clear_keys()
86
+ pandify.clear_memory()
87
+ pandify.exit(delete_files=["keys.txt"])
88
+ ```
89
+
90
+ ---
91
+
92
+ ## Public Python API Reference
93
+
94
+ | Function | Description |
95
+ |---|---|
96
+ | `pandify.auth(password=None, key=None, keys_file=None)` | Authenticate session. Supports direct key or keys file injection for restricted lab PCs. |
97
+ | `pandify.chat(message, stream=None)` | Execute conversational query. Supports syntax-highlighted code blocks (`stream=False`). |
98
+ | `pandify.upload(path)` | Validate and stage documents, spreadsheets, images, or code for the next query. |
99
+ | `pandify.remember(content, name='mentor_template')` | Pre-save reference code templates to ground all responses in your mentor's exact style. |
100
+ | `pandify.download_keys(url, password, save_file=None)` | Sync credentials from your private remote server directly into secure memory. |
101
+ | `pandify.clear_keys()` | Completely wipe all credentials from local OS Keyring and database. |
102
+ | `pandify.clear_memory()` | Wipe all pre-saved code templates from SQLite storage. |
103
+ | `pandify.new(title=None)` | Start a new conversation thread with a fresh context. |
104
+ | `pandify.history(limit=20, export_path=None)` | List recent sessions or export active conversation to Markdown or JSON. |
105
+ | `pandify.keys(action=None, **kwargs)` | Manage developer service keys securely (`add`, `list`, `sync`, `remove`, `clear`). |
106
+ | `pandify.configure(**kwargs)` | Inspect or update settings (model, streaming, file limits, theme, timeouts). |
107
+ | `pandify.clear()` | Clear messages in the active conversation and unstage attachments. |
108
+ | `pandify.pandify_help()` | Display full developer API reference and exam workflow guide. |
109
+ | `pandify.exit(delete_files=None)` | Invalidate session token, restore terminal mode, release resources, and delete temporary files. |
110
+
111
+ ---
112
+
113
+ ## Supported File Types
114
+
115
+ - **Documents**: `.pdf`, `.docx`, `.xlsx`, `.csv`, `.txt`
116
+ - **Images**: `.png`, `.jpg`, `.jpeg`, `.webp`
117
+ - **Code**: `.py`, `.js`, `.ts`, `.jsx`, `.tsx`, `.java`, `.c`, `.cpp`, `.html`, `.css`, `.json`, `.xml`, `.sql`, `.php`, `.go`, `.rs`
118
+ - **Additional**: `.md`, `.log`
119
+
120
+ ---
121
+
122
+ ## License
123
+
124
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
@@ -0,0 +1,57 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "pandify"
7
+ version = "0.1.0"
8
+ description = "Lightweight DataFrame manipulation helpers and tabular workflow formatting utilities."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "MIT"
12
+ authors = [
13
+ { name = "Pandify Developers", email = "dev@pandify-tools.org" }
14
+ ]
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Intended Audience :: Developers",
18
+ "Operating System :: OS Independent",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.10",
21
+ "Programming Language :: Python :: 3.11",
22
+ "Programming Language :: Python :: 3.12",
23
+ "Programming Language :: Python :: 3.13",
24
+ "Topic :: Scientific/Engineering :: Information Analysis",
25
+ "Topic :: Software Development :: Libraries :: Python Modules",
26
+ ]
27
+ dependencies = [
28
+ "google-genai>=0.1.1",
29
+ "argon2-cffi>=23.1.0",
30
+ "keyring>=24.0.0",
31
+ "platformdirs>=4.0.0",
32
+ "rich>=13.7.0",
33
+ "pypdf>=4.0.0",
34
+ "python-docx>=1.1.0",
35
+ "openpyxl>=3.1.0",
36
+ "pillow>=10.0.0",
37
+ "tomli-w>=1.0.0",
38
+ ]
39
+
40
+ [project.optional-dependencies]
41
+ dev = [
42
+ "pytest>=8.0.0",
43
+ "pytest-asyncio>=0.23.0",
44
+ "build>=1.0.0",
45
+ "twine>=5.0.0",
46
+ ]
47
+
48
+ [tool.setuptools.packages.find]
49
+ where = ["src"]
50
+
51
+ [tool.pytest.ini_options]
52
+ testpaths = ["tests"]
53
+ python_files = ["test_*.py"]
54
+ python_classes = ["Test*"]
55
+ python_functions = ["test_*"]
56
+ asyncio_mode = "auto"
57
+ asyncio_default_fixture_loop_scope = "function"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,36 @@
1
+ """Pandify: Private AI chat library powered by Google Gemini.
2
+
3
+ Importable Python library providing secure, multimodal conversational workflows with minimal terminal UI.
4
+ """
5
+
6
+ __version__ = "0.1.0"
7
+
8
+ from pandify.api.auth import auth
9
+ from pandify.api.chat import chat
10
+ from pandify.api.configure import configure
11
+ from pandify.api.help import pandify_help
12
+ from pandify.api.history import history
13
+ from pandify.api.keys import clear_keys, download_keys, keys
14
+ from pandify.api.memory import clear_memory, remember, templates
15
+ from pandify.api.session import clear, exit, new
16
+ from pandify.api.upload import upload
17
+
18
+ __all__ = [
19
+ "__version__",
20
+ "auth",
21
+ "chat",
22
+ "upload",
23
+ "new",
24
+ "clear",
25
+ "exit",
26
+ "history",
27
+ "keys",
28
+ "download_keys",
29
+ "clear_keys",
30
+ "configure",
31
+ "pandify_help",
32
+ "remember",
33
+ "templates",
34
+ "clear_memory",
35
+ ]
36
+
@@ -0,0 +1,24 @@
1
+ """API package for Pandify."""
2
+
3
+ from pandify.api.auth import auth
4
+ from pandify.api.chat import chat
5
+ from pandify.api.configure import configure
6
+ from pandify.api.help import pandify_help
7
+ from pandify.api.history import history
8
+ from pandify.api.keys import keys
9
+ from pandify.api.session import clear, exit, new
10
+ from pandify.api.upload import upload
11
+
12
+ __all__ = [
13
+ "auth",
14
+ "chat",
15
+ "upload",
16
+ "new",
17
+ "clear",
18
+ "exit",
19
+ "history",
20
+ "keys",
21
+ "configure",
22
+ "pandify_help",
23
+ ]
24
+
@@ -0,0 +1,46 @@
1
+ """Public API: pandify.auth()"""
2
+
3
+ from pathlib import Path
4
+ from typing import Optional
5
+ from pandify.core.session import SessionManager
6
+
7
+
8
+ def auth(
9
+ password: Optional[str] = None,
10
+ key: Optional[str] = None,
11
+ keys_file: Optional[str] = None,
12
+ ) -> bool:
13
+ """Authenticate the user session with optional direct key or keys_file injection.
14
+
15
+ Args:
16
+ password (str, optional): Explicit master password.
17
+ key (str, optional): Direct Gemini API key secret to register for this session.
18
+ keys_file (str, optional): Path to a .txt file containing Gemini API key(s).
19
+ """
20
+ session = SessionManager.get_instance()
21
+ if not session.is_authenticated:
22
+ session.ensure_authenticated(explicit_password=password)
23
+
24
+ if key:
25
+ session.key_manager.add_key(secret=key.strip(), label="inline-auth-key")
26
+ session.renderer.print_info("Loaded API key from auth argument.")
27
+
28
+ if keys_file:
29
+ p = Path(keys_file)
30
+ if p.exists():
31
+ loaded_count = 0
32
+ with open(p, "r", encoding="utf-8") as f:
33
+ content = f.read()
34
+ for line in content.splitlines():
35
+ for part in line.split(","):
36
+ k = part.strip()
37
+ if k and not k.startswith("#"):
38
+ session.key_manager.add_key(secret=k, label=f"file-key-{loaded_count+1}")
39
+ loaded_count += 1
40
+ if loaded_count > 0:
41
+ session.renderer.print_info(f"Loaded {loaded_count} API key(s) from '{keys_file}'.")
42
+ else:
43
+ session.renderer.print_error(f"Keys file '{keys_file}' not found.")
44
+
45
+ return session.is_authenticated
46
+
@@ -0,0 +1,118 @@
1
+ """Public API: pandify.chat()"""
2
+
3
+ from typing import Optional
4
+ from pandify.core.session import SessionManager
5
+ from pandify.errors.exceptions import PandifyError
6
+
7
+
8
+ def chat(message: str, stream: Optional[bool] = None) -> str:
9
+ """Send a message to Gemini with conversation context and any staged attachments.
10
+
11
+ Parameters:
12
+ message (str): The prompt message to send.
13
+ stream (bool, optional): Stream response tokens to terminal. Defaults to config setting.
14
+
15
+ Returns:
16
+ str: The full generated assistant response.
17
+ """
18
+ if not message or not message.strip():
19
+ raise ValueError("Message cannot be empty.")
20
+
21
+ session = SessionManager.get_instance()
22
+ session.ensure_authenticated()
23
+
24
+ renderer = session.renderer
25
+ conv_repo = session.conv_repo
26
+ conv_id = session.get_active_conversation_id()
27
+
28
+ # Flush any staged attachments
29
+ staged = session.staging.flush()
30
+ attachments_meta = [att.to_dict() for att in staged] if staged else None
31
+
32
+ # Print user prompt in minimal format
33
+ renderer.print_user_message(message.strip())
34
+
35
+ # Record user message in repository
36
+ conv_repo.add_message(
37
+ conversation_id=conv_id,
38
+ role="user",
39
+ content=message.strip(),
40
+ attachments=attachments_meta,
41
+ )
42
+
43
+ # Fetch prior conversation history
44
+ history = conv_repo.get_messages(conv_id)
45
+ # Exclude current user message from prior history as build_contents appends it with attachments
46
+ prior_messages = history[:-1] if len(history) > 1 else []
47
+
48
+ # Determine streaming preference
49
+ is_streaming = stream if stream is not None else bool(session.config_mgr.get("general", "stream", True))
50
+ current_model = str(session.config_mgr.get("general", "model", "gemini-3.5-flash"))
51
+ max_retries = int(session.config_mgr.get("gemini", "max_retries", 3))
52
+
53
+ def _notify_key_switch(label: str, msg: str) -> None:
54
+ renderer.print_info(f"[{msg}]")
55
+
56
+ # Inspect persistent SQLite code templates
57
+ active_templates = session.template_repo.get_active_templates()
58
+ if active_templates:
59
+ template_blocks = []
60
+ for tpl in active_templates:
61
+ template_blocks.append(
62
+ f"--- MANDATORY CODE TEMPLATE: {tpl['name']} ---\n{tpl['content']}"
63
+ )
64
+ template_context = "\n\n".join(template_blocks)
65
+ effective_prompt = (
66
+ f"[MANDATORY REFERENCE TEMPLATE & ARCHITECTURE]\n"
67
+ f"{template_context}\n\n"
68
+ f"[STRICT INSTRUCTION]\n"
69
+ f"You must strictly adhere to the architecture, imports, class structure, and naming conventions provided in the template above. "
70
+ f"Only provide the missing logic or syntax fitted directly into this template format.\n\n"
71
+ f"[USER REQUEST]\n"
72
+ f"{message.strip()}"
73
+ )
74
+ else:
75
+ effective_prompt = message.strip()
76
+
77
+ try:
78
+ if is_streaming:
79
+ tokens_gen = session.gemini_client.generate_chat_stream(
80
+ history_messages=prior_messages,
81
+ prompt=effective_prompt,
82
+ attachments=staged,
83
+ model=current_model,
84
+ max_retries=max_retries,
85
+ notify_switch=_notify_key_switch,
86
+ )
87
+ response_text = renderer.print_assistant_response(
88
+ text="",
89
+ stream=True,
90
+ token_generator=tokens_gen,
91
+ )
92
+ else:
93
+ response_text = session.gemini_client.generate_chat_sync(
94
+ history_messages=prior_messages,
95
+ prompt=effective_prompt,
96
+ attachments=staged,
97
+ model=current_model,
98
+ max_retries=max_retries,
99
+ notify_switch=_notify_key_switch,
100
+ )
101
+ renderer.print_assistant_response(response_text, stream=False)
102
+
103
+ # Record assistant turn in repository
104
+ conv_repo.add_message(
105
+ conversation_id=conv_id,
106
+ role="model",
107
+ content=response_text,
108
+ )
109
+
110
+ return response_text
111
+
112
+ except PandifyError as e:
113
+ renderer.print_error(str(e))
114
+ raise
115
+ except Exception as e:
116
+ renderer.print_error(f"Unexpected error: {e}")
117
+ raise PandifyError(f"Chat operation failed: {e}") from e
118
+
@@ -0,0 +1,55 @@
1
+ """Public API: pandify.configure()"""
2
+
3
+ from typing import Any
4
+ from rich.table import Table
5
+ from pandify.core.session import SessionManager
6
+
7
+
8
+ def configure(**kwargs: Any) -> dict[str, Any]:
9
+ """Inspect or update Pandify configuration parameters.
10
+
11
+ Supported parameters:
12
+ model (str): Default Gemini model (e.g. 'gemini-2.5-flash', 'gemini-2.5-pro')
13
+ stream (bool): Whether to stream chat tokens
14
+ max_retries (int): Maximum key rotation retries
15
+ max_file_size_mb (int): Maximum upload file size in MB
16
+ theme (str): UI theme styling
17
+ session_timeout_minutes (int): Inactivity minutes before re-authentication
18
+ retention_days (int): Days to retain conversation logs
19
+
20
+ Returns:
21
+ dict: The updated active configuration dictionary.
22
+ """
23
+ session = SessionManager.get_instance()
24
+ session.ensure_authenticated()
25
+
26
+ config_mgr = session.config_mgr
27
+ console = session.renderer.console
28
+
29
+ if kwargs:
30
+ updated = config_mgr.update(**kwargs)
31
+ # Propagate changes to active components
32
+ if "model" in kwargs:
33
+ session.gemini_client.default_model = str(kwargs["model"])
34
+ if "max_file_size_mb" in kwargs:
35
+ session.file_validator.max_size_mb = int(kwargs["max_file_size_mb"])
36
+ session.renderer.print_info("Configuration updated successfully.")
37
+ return updated
38
+
39
+ # If no arguments provided, print current settings
40
+ current = config_mgr.as_dict()
41
+ table = Table(title="Pandify Active Configuration", show_header=True, header_style="bold blue")
42
+ table.add_column("Section", style="dim")
43
+ table.add_column("Setting", style="bold white")
44
+ table.add_column("Value", style="cyan")
45
+
46
+ for section, values in current.items():
47
+ if isinstance(values, dict):
48
+ for k, v in values.items():
49
+ table.add_row(section, k, str(v))
50
+ else:
51
+ table.add_row("root", section, str(values))
52
+
53
+ console.print(table)
54
+ return current
55
+