coregrai 2.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,455 @@
1
+ Metadata-Version: 2.4
2
+ Name: coregrai
3
+ Version: 2.0.0
4
+ Summary: AI-powered study assistant for the ACR Core Exam and diagnostic radiology
5
+ Home-page: https://coregrai.com
6
+ Author: GRAi Team
7
+ Author-email: GRAi Team <support@coregrai.com>
8
+ License-Expression: MIT
9
+ Project-URL: Homepage, https://coregrai.com
10
+ Project-URL: Documentation, https://docs.coregrai.com
11
+ Project-URL: Repository, https://github.com/coregrai/grai-cli
12
+ Project-URL: Changelog, https://github.com/coregrai/grai-cli/blob/main/CHANGELOG.md
13
+ Project-URL: Issues, https://github.com/coregrai/grai-cli/issues
14
+ Keywords: radiology,medical,education,ACR,exam,study,AI,differential-diagnosis
15
+ Classifier: Development Status :: 4 - Beta
16
+ Classifier: Environment :: Console
17
+ Classifier: Intended Audience :: Healthcare Industry
18
+ Classifier: Intended Audience :: Education
19
+ Classifier: Topic :: Education
20
+ Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
21
+ Classifier: Programming Language :: Python :: 3
22
+ Classifier: Programming Language :: Python :: 3.8
23
+ Classifier: Programming Language :: Python :: 3.9
24
+ Classifier: Programming Language :: Python :: 3.10
25
+ Classifier: Programming Language :: Python :: 3.11
26
+ Classifier: Programming Language :: Python :: 3.12
27
+ Classifier: Operating System :: OS Independent
28
+ Requires-Python: >=3.8
29
+ Description-Content-Type: text/markdown
30
+ License-File: LICENSE
31
+ Requires-Dist: click>=8.0.0
32
+ Requires-Dist: requests>=2.28.0
33
+ Requires-Dist: rich>=13.0.0
34
+ Provides-Extra: secure
35
+ Requires-Dist: keyring>=23.0.0; extra == "secure"
36
+ Provides-Extra: dev
37
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
38
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
39
+ Requires-Dist: black>=23.0.0; extra == "dev"
40
+ Requires-Dist: flake8>=6.0.0; extra == "dev"
41
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
42
+ Requires-Dist: build>=1.0.0; extra == "dev"
43
+ Requires-Dist: twine>=4.0.0; extra == "dev"
44
+ Dynamic: author
45
+ Dynamic: home-page
46
+ Dynamic: license-file
47
+ Dynamic: requires-python
48
+
49
+ # GRAi CLI
50
+
51
+ > AI-powered study assistant for the ACR Core Exam and diagnostic radiology
52
+
53
+ [![PyPI version](https://badge.fury.io/py/grai-cli.svg)](https://badge.fury.io/py/grai-cli)
54
+ [![Python Versions](https://img.shields.io/pypi/pyversions/grai-cli.svg)](https://pypi.org/project/grai-cli/)
55
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
56
+
57
+ ## Overview
58
+
59
+ GRAi CLI brings the power of AI-assisted radiology education to your terminal. Study for the ACR Core Exam with interactive chat, practice quizzes, and comprehensive lessons - all from the command line.
60
+
61
+ ### Features
62
+
63
+ - **Interactive Chat**: Ask questions about any radiology topic and get AI-powered explanations
64
+ - **Practice Quizzes**: Board-style questions with adaptive difficulty
65
+ - **Comprehensive Lessons**: 572+ pre-generated lessons covering all ACR topics
66
+ - **Progress Tracking**: Monitor your study statistics and performance
67
+ - **Offline Export**: Save lessons to markdown files for offline study
68
+ - **Beautiful Terminal UI**: Rich, colorful interface with syntax highlighting
69
+
70
+ ## Installation
71
+
72
+ ### From PyPI (Recommended)
73
+
74
+ ```bash
75
+ pip install grai-cli
76
+ ```
77
+
78
+ ### From Source
79
+
80
+ ```bash
81
+ git clone https://github.com/yourusername/grai-cli.git
82
+ cd grai-cli
83
+ pip install -e .
84
+ ```
85
+
86
+ ### Requirements
87
+
88
+ - Python 3.8 or higher
89
+ - Active internet connection (for API access)
90
+ - GRAi account (free registration at https://coregrai.com)
91
+
92
+ ## Quick Start
93
+
94
+ ### 1. Login
95
+
96
+ ```bash
97
+ grai login
98
+ ```
99
+
100
+ You'll be prompted for your email and password. Don't have an account? Register at https://coregrai.com
101
+
102
+ ### 2. Ask Questions
103
+
104
+ ```bash
105
+ # Single question
106
+ grai chat "What are the CT findings in pulmonary embolism?"
107
+
108
+ # Interactive chat session
109
+ grai chat -i
110
+ ```
111
+
112
+ ### 3. Take a Quiz
113
+
114
+ ```bash
115
+ # Random quiz (5 questions)
116
+ grai quiz
117
+
118
+ # Topic-specific quiz
119
+ grai quiz --topic chest-ct --count 10
120
+
121
+ # Adaptive difficulty based on your performance
122
+ grai quiz --adaptive
123
+ ```
124
+
125
+ ### 4. Study Lessons
126
+
127
+ ```bash
128
+ # List all available lessons
129
+ grai lesson --list
130
+
131
+ # Search for lessons
132
+ grai lesson --search "cardiac"
133
+
134
+ # Read a specific lesson
135
+ grai lesson chest-radiography-basics
136
+ ```
137
+
138
+ ### 5. Check Your Progress
139
+
140
+ ```bash
141
+ grai stats
142
+ ```
143
+
144
+ ## Usage Guide
145
+
146
+ ### Chat Commands
147
+
148
+ **Single Query:**
149
+ ```bash
150
+ grai chat "Explain MRI sequences"
151
+ ```
152
+
153
+ **Interactive Mode:**
154
+ ```bash
155
+ grai chat -i
156
+ ```
157
+
158
+ **With Sources:**
159
+ ```bash
160
+ grai chat --sources "What is the ACR TI-RADS classification?"
161
+ ```
162
+
163
+ **Specify Model:**
164
+ ```bash
165
+ grai chat --model gemini "Describe CT protocols"
166
+ ```
167
+
168
+ ### Quiz Commands
169
+
170
+ **Basic Quiz:**
171
+ ```bash
172
+ grai quiz
173
+ ```
174
+
175
+ **Topic-Specific:**
176
+ ```bash
177
+ # Available topics: chest-xray, chest-ct, neuro-ct, neuro-mri,
178
+ # abdominal-ct, abdominal-mri, msk, nuclear-medicine, ultrasound, etc.
179
+ grai quiz --topic neuro-mri
180
+ ```
181
+
182
+ **Set Difficulty:**
183
+ ```bash
184
+ grai quiz --difficulty hard --count 10
185
+ ```
186
+
187
+ **Adaptive Mode:**
188
+ ```bash
189
+ # Questions adjust based on your performance
190
+ grai quiz --adaptive
191
+ ```
192
+
193
+ ### Lesson Commands
194
+
195
+ **List Lessons:**
196
+ ```bash
197
+ grai lesson --list
198
+ ```
199
+
200
+ **Search Lessons:**
201
+ ```bash
202
+ grai lesson --search "mri"
203
+ grai lesson --search "cardiac" --category cardiothoracic
204
+ ```
205
+
206
+ **Read a Lesson:**
207
+ ```bash
208
+ grai lesson chest-radiography-basics
209
+ ```
210
+
211
+ **Export Lesson:**
212
+ ```bash
213
+ grai export chest-radiography-basics --output ~/study/chest.md
214
+ ```
215
+
216
+ ### Configuration
217
+
218
+ **Show Current Config:**
219
+ ```bash
220
+ grai config --show
221
+ ```
222
+
223
+ **Change Server URL:**
224
+ ```bash
225
+ grai config --server https://your-server.com
226
+ ```
227
+
228
+ **View Statistics:**
229
+ ```bash
230
+ grai stats
231
+ ```
232
+
233
+ **Logout:**
234
+ ```bash
235
+ grai logout
236
+ ```
237
+
238
+ ## Advanced Usage
239
+
240
+ ### Custom Server
241
+
242
+ If you're running your own GRAi instance:
243
+
244
+ ```bash
245
+ grai config --server http://localhost:5000
246
+ grai login
247
+ ```
248
+
249
+ ### Batch Operations
250
+
251
+ Study multiple topics in sequence:
252
+
253
+ ```bash
254
+ # Create a study script
255
+ #!/bin/bash
256
+ grai quiz --topic chest-ct --count 5
257
+ grai quiz --topic chest-xray --count 5
258
+ grai quiz --topic neuro-ct --count 5
259
+ grai stats
260
+ ```
261
+
262
+ ### Export Study Materials
263
+
264
+ Export all cardiothoracic lessons:
265
+
266
+ ```bash
267
+ #!/bin/bash
268
+ for lesson in $(grai lesson --list --category cardiothoracic | grep -oP '^\S+'); do
269
+ grai export "$lesson" --output "study/${lesson}.md"
270
+ done
271
+ ```
272
+
273
+ ## Configuration File
274
+
275
+ GRAi CLI stores configuration in `~/.grai/config.json`:
276
+
277
+ ```json
278
+ {
279
+ "server_url": "https://coregrai.com",
280
+ "default_model": "deepseek",
281
+ "show_sources": false,
282
+ "color_output": true,
283
+ "auth_token": "<your-token>",
284
+ "user_email": "your@email.com"
285
+ }
286
+ ```
287
+
288
+ ## Features in Detail
289
+
290
+ ### Interactive Chat
291
+
292
+ The interactive chat mode provides a conversational interface:
293
+
294
+ ```
295
+ > You: What causes pneumothorax on chest x-ray?
296
+
297
+ GRAi: Pneumothorax appears on chest radiographs as...
298
+ [detailed explanation with key findings]
299
+
300
+ Sources:
301
+ 1. Chest Radiography Fundamentals
302
+ 2. Emergency Radiology - Pneumothorax
303
+ 3. ACR Appropriateness Criteria
304
+
305
+ > You: How do you measure it?
306
+ ...
307
+ ```
308
+
309
+ ### Practice Quizzes
310
+
311
+ Board-style questions with immediate feedback:
312
+
313
+ ```
314
+ Question 1/10:
315
+ A 45-year-old male presents with chest pain...
316
+ Which finding is most concerning?
317
+
318
+ 1. Cardiomegaly
319
+ 2. Pleural effusion
320
+ 3. Pneumomediastinum
321
+ 4. Atelectasis
322
+
323
+ Your answer: 3
324
+
325
+ Correct! Pneumomediastinum in the setting of chest pain
326
+ may indicate esophageal perforation, which requires urgent
327
+ evaluation.
328
+ ```
329
+
330
+ ### Progress Tracking
331
+
332
+ Monitor your improvement:
333
+
334
+ ```
335
+ Your Study Statistics
336
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━
337
+ Questions Answered 847
338
+ Lessons Completed 42
339
+ Study Streak 14 days
340
+ Average Score 84.5%
341
+ Total Study Time 23h 15m
342
+
343
+ Areas to Focus On:
344
+ - Nuclear Medicine Physics
345
+ - Interventional Radiology
346
+ - Ultrasound Artifacts
347
+ ```
348
+
349
+ ## Troubleshooting
350
+
351
+ ### Connection Issues
352
+
353
+ ```bash
354
+ # Check server connectivity
355
+ curl https://coregrai.com/api/health
356
+
357
+ # Try alternative server
358
+ grai config --server https://backup.coregrai.com
359
+ ```
360
+
361
+ ### Authentication Problems
362
+
363
+ ```bash
364
+ # Re-login
365
+ grai logout
366
+ grai login
367
+ ```
368
+
369
+ ### Clear Configuration
370
+
371
+ ```bash
372
+ # Remove config file
373
+ rm ~/.grai/config.json
374
+
375
+ # Login again
376
+ grai login
377
+ ```
378
+
379
+ ## Development
380
+
381
+ ### Setup Development Environment
382
+
383
+ ```bash
384
+ git clone https://github.com/yourusername/grai-cli.git
385
+ cd grai-cli
386
+ python -m venv venv
387
+ source venv/bin/activate # On Windows: venv\Scripts\activate
388
+ pip install -r requirements-dev.txt
389
+ pip install -e .
390
+ ```
391
+
392
+ ### Run Tests
393
+
394
+ ```bash
395
+ pytest
396
+ pytest --cov=grai_cli
397
+ ```
398
+
399
+ ### Code Formatting
400
+
401
+ ```bash
402
+ black grai_cli/
403
+ flake8 grai_cli/
404
+ ```
405
+
406
+ ### Build Package
407
+
408
+ ```bash
409
+ python -m build
410
+ twine check dist/*
411
+ ```
412
+
413
+ ### Publish to PyPI
414
+
415
+ ```bash
416
+ # Test PyPI
417
+ twine upload --repository testpypi dist/*
418
+
419
+ # Production PyPI
420
+ twine upload dist/*
421
+ ```
422
+
423
+ ## Contributing
424
+
425
+ Contributions are welcome! Please feel free to submit a Pull Request.
426
+
427
+ 1. Fork the repository
428
+ 2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
429
+ 3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
430
+ 4. Push to the branch (`git push origin feature/AmazingFeature`)
431
+ 5. Open a Pull Request
432
+
433
+ ## License
434
+
435
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
436
+
437
+ ## Support
438
+
439
+ - **Documentation**: https://docs.coregrai.com
440
+ - **Issues**: https://github.com/yourusername/grai-cli/issues
441
+ - **Email**: support@coregrai.com
442
+
443
+ ## Changelog
444
+
445
+ See [CHANGELOG.md](CHANGELOG.md) for a list of changes.
446
+
447
+ ## Acknowledgments
448
+
449
+ - Built with [Click](https://click.palletsprojects.com/)
450
+ - Beautiful terminal output powered by [Rich](https://rich.readthedocs.io/)
451
+ - ACR content based on official ACR guidelines and appropriateness criteria
452
+
453
+ ---
454
+
455
+ **Made with ❤️ for radiology residents everywhere**
@@ -0,0 +1,12 @@
1
+ coregrai-2.0.0.dist-info/licenses/LICENSE,sha256=nDSoZ7aXIrx2Ei9YgwtmYPy3u0UvaPYO7_L-yfPNECY,1087
2
+ grai_cli/__init__.py,sha256=S9QJvY87bXYFTSLxPQRkYSJ740cHUxiZp6HxP3Q8LrI,1529
3
+ grai_cli/__main__.py,sha256=7sbobcqXuIuhPRY_ye1vzg6Jk_P4fvI0gOODs7ENklo,174
4
+ grai_cli/auth.py,sha256=HzsTSARz9QD_hg4iQzLLN79jsf7cN1O_MV20FfLB0N0,2391
5
+ grai_cli/cli.py,sha256=MVB89rqztxrB-dT1TBtDzKzdH5CJbLT8jrNJAGyKNeM,20881
6
+ grai_cli/client.py,sha256=-ko18X8eGgLR0JZz6vr0k-DOclbkU2RYBEDGw2V_hQI,7902
7
+ grai_cli/config.py,sha256=UkQOJOVumvsLWFcYAp3N8_p09p-UBF514-TV3lyCUII,2023
8
+ coregrai-2.0.0.dist-info/METADATA,sha256=YK17PIAgYgV6lE02dYIwmQGXFmfgqIKyBP8xtgiiDzY,9977
9
+ coregrai-2.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
10
+ coregrai-2.0.0.dist-info/entry_points.txt,sha256=bdyTzcZdwIyAL_CGrJR4qujOE0p-w_AUmka4WwyT_L4,43
11
+ coregrai-2.0.0.dist-info/top_level.txt,sha256=JfIomgA4AYIJ1Uz5xwvrre6ERYONhbeGxt74gqAdf8M,9
12
+ coregrai-2.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ grai = grai_cli.cli:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 GRAi 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.
@@ -0,0 +1 @@
1
+ grai_cli
grai_cli/__init__.py ADDED
@@ -0,0 +1,54 @@
1
+ """
2
+ GRAi CLI - Command-line interface for Diagnostic Radiology AI Assistant
3
+
4
+ A powerful command-line tool for radiology residents preparing for the ACR Core Exam.
5
+ Features include AI-powered chat, practice quizzes, comprehensive lessons, and
6
+ differential diagnosis generation.
7
+ """
8
+
9
+ __version__ = "2.0.0"
10
+ __author__ = "GRAi Team"
11
+ __email__ = "support@coregrai.com"
12
+ __description__ = "AI-powered study assistant for the ACR Core Exam and diagnostic radiology"
13
+
14
+
15
+ def __getattr__(name):
16
+ """Lazy import for public API."""
17
+ if name == "main":
18
+ from .cli import main
19
+ return main
20
+ elif name == "cli":
21
+ from .cli import cli
22
+ return cli
23
+ elif name == "GraiClient":
24
+ from .client import GraiClient
25
+ return GraiClient
26
+ elif name == "Config":
27
+ from .config import Config
28
+ return Config
29
+ elif name == "authenticate":
30
+ from .auth import authenticate
31
+ return authenticate
32
+ elif name == "logout":
33
+ from .auth import logout
34
+ return logout
35
+ elif name == "check_auth":
36
+ from .auth import check_auth
37
+ return check_auth
38
+ elif name == "get_current_user":
39
+ from .auth import get_current_user
40
+ return get_current_user
41
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
42
+
43
+
44
+ __all__ = [
45
+ "main",
46
+ "cli",
47
+ "GraiClient",
48
+ "Config",
49
+ "authenticate",
50
+ "logout",
51
+ "check_auth",
52
+ "get_current_user",
53
+ "__version__",
54
+ ]
grai_cli/__main__.py ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ GRAi CLI entry point
4
+
5
+ Allows running with: python -m grai_cli
6
+ """
7
+
8
+ from grai_cli.cli import main
9
+
10
+ if __name__ == '__main__':
11
+ main()
grai_cli/auth.py ADDED
@@ -0,0 +1,93 @@
1
+ """
2
+ Authentication handling for GRAi CLI
3
+ """
4
+
5
+ import requests
6
+ from typing import Tuple
7
+
8
+
9
+ def authenticate(config, email: str, password: str) -> Tuple[bool, str]:
10
+ """
11
+ Authenticate user with email and password
12
+
13
+ Args:
14
+ config: Configuration object
15
+ email: User email
16
+ password: User password
17
+
18
+ Returns:
19
+ Tuple of (success, message)
20
+ """
21
+ server_url = config.get('server_url', 'https://coregrai.com')
22
+ url = f"{server_url}/api/auth/login"
23
+
24
+ try:
25
+ response = requests.post(url, json={
26
+ 'email': email,
27
+ 'password': password
28
+ })
29
+
30
+ if response.status_code == 200:
31
+ data = response.json()
32
+ if data.get('success'):
33
+ token = data.get('token')
34
+ user = data.get('user', {})
35
+
36
+ # Save credentials
37
+ config.set('auth_token', token)
38
+ config.set('user_email', user.get('email'))
39
+ config.set('user_name', user.get('username'))
40
+
41
+ return True, "Login successful"
42
+
43
+ # Login failed
44
+ error_data = response.json() if response.headers.get('content-type', '').startswith('application/json') else {}
45
+ error_msg = error_data.get('error', 'Invalid credentials')
46
+ return False, error_msg
47
+
48
+ except requests.exceptions.ConnectionError:
49
+ return False, "Could not connect to server"
50
+ except Exception as e:
51
+ return False, f"Authentication error: {str(e)}"
52
+
53
+
54
+ def logout(config) -> None:
55
+ """
56
+ Log out user by clearing credentials
57
+
58
+ Args:
59
+ config: Configuration object
60
+ """
61
+ config.delete('auth_token')
62
+ config.delete('user_email')
63
+ config.delete('user_name')
64
+
65
+
66
+ def check_auth(config) -> bool:
67
+ """
68
+ Check if user is authenticated
69
+
70
+ Args:
71
+ config: Configuration object
72
+
73
+ Returns:
74
+ True if authenticated, False otherwise
75
+ """
76
+ return config.get('auth_token') is not None
77
+
78
+
79
+ def get_current_user(config) -> dict:
80
+ """
81
+ Get current authenticated user info
82
+
83
+ Args:
84
+ config: Configuration object
85
+
86
+ Returns:
87
+ User info dictionary
88
+ """
89
+ return {
90
+ 'email': config.get('user_email'),
91
+ 'name': config.get('user_name'),
92
+ 'token': config.get('auth_token')
93
+ }