pylantir 0.1.3__tar.gz → 0.2.1__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 (65) hide show
  1. pylantir-0.2.1/PKG-INFO +584 -0
  2. pylantir-0.2.1/README.md +527 -0
  3. {pylantir-0.1.3 → pylantir-0.2.1}/pyproject.toml +13 -2
  4. {pylantir-0.1.3 → pylantir-0.2.1}/src/pylantir/__init__.py +1 -1
  5. pylantir-0.2.1/src/pylantir/api_server.py +769 -0
  6. pylantir-0.2.1/src/pylantir/auth_db_setup.py +188 -0
  7. pylantir-0.2.1/src/pylantir/auth_models.py +80 -0
  8. pylantir-0.2.1/src/pylantir/auth_utils.py +210 -0
  9. pylantir-0.2.1/src/pylantir/cli/run.py +597 -0
  10. pylantir-0.2.1/src/pylantir/config/config_example_with_cors.json +108 -0
  11. {pylantir-0.1.3 → pylantir-0.2.1}/src/pylantir/config/mwl_config.json +18 -0
  12. pylantir-0.2.1/src/pylantir/db_concurrency.py +180 -0
  13. pylantir-0.2.1/src/pylantir/db_setup.py +121 -0
  14. pylantir-0.2.1/src/pylantir/redcap_to_db.py +458 -0
  15. pylantir-0.1.3/.devcontainer/Dockerfile +0 -12
  16. pylantir-0.1.3/.devcontainer/devcontainer.json +0 -44
  17. pylantir-0.1.3/.github/dependabot.yml +0 -22
  18. pylantir-0.1.3/.github/template-sync.yml +0 -21
  19. pylantir-0.1.3/.github/workflows/CI.yml +0 -21
  20. pylantir-0.1.3/.github/workflows/publish.yml +0 -33
  21. pylantir-0.1.3/.github/workflows/schedule-update-actions.yml +0 -25
  22. pylantir-0.1.3/.github/workflows/semantic-pr-check.yml +0 -17
  23. pylantir-0.1.3/.github/workflows/sphinx.yml +0 -18
  24. pylantir-0.1.3/.github/workflows/template-sync.yml +0 -12
  25. pylantir-0.1.3/.gitignore +0 -129
  26. pylantir-0.1.3/.pre-commit-config.yaml +0 -60
  27. pylantir-0.1.3/.pypirc +0 -10
  28. pylantir-0.1.3/.vscode/launch.json +0 -19
  29. pylantir-0.1.3/.vscode/settings.json +0 -29
  30. pylantir-0.1.3/CODE_OF_CONDUCT.md +0 -9
  31. pylantir-0.1.3/PKG-INFO +0 -193
  32. pylantir-0.1.3/README.md +0 -145
  33. pylantir-0.1.3/SECURITY.md +0 -41
  34. pylantir-0.1.3/SUPPORT.md +0 -25
  35. pylantir-0.1.3/docs/Makefile +0 -20
  36. pylantir-0.1.3/docs/conf.py +0 -67
  37. pylantir-0.1.3/docs/devcontainer.md +0 -16
  38. pylantir-0.1.3/docs/developer.md +0 -3
  39. pylantir-0.1.3/docs/index.rst +0 -20
  40. pylantir-0.1.3/docs/make.bat +0 -35
  41. pylantir-0.1.3/docs/modules.rst +0 -7
  42. pylantir-0.1.3/docs/pre-commit-config.md +0 -6
  43. pylantir-0.1.3/docs/pylint.md +0 -507
  44. pylantir-0.1.3/docs/pyproject.md +0 -9
  45. pylantir-0.1.3/docs/python_package.hello_world.rst +0 -21
  46. pylantir-0.1.3/docs/python_package.rst +0 -29
  47. pylantir-0.1.3/docs/requirements.txt +0 -3
  48. pylantir-0.1.3/docs/vscode.md +0 -1
  49. pylantir-0.1.3/docs/workflows.md +0 -4
  50. pylantir-0.1.3/pylantir.png +0 -0
  51. pylantir-0.1.3/src/README.md +0 -1
  52. pylantir-0.1.3/src/pylantir/cli/run.py +0 -291
  53. pylantir-0.1.3/src/pylantir/db_setup.py +0 -46
  54. pylantir-0.1.3/src/pylantir/redcap_to_db.py +0 -324
  55. pylantir-0.1.3/tests/client.py +0 -63
  56. pylantir-0.1.3/tests/client2.py +0 -46
  57. pylantir-0.1.3/tests/conftest.py +0 -30
  58. pylantir-0.1.3/tests/mpps_tester.py +0 -147
  59. pylantir-0.1.3/tests/query_db.py +0 -44
  60. pylantir-0.1.3/tests/test_methods.py +0 -32
  61. {pylantir-0.1.3 → pylantir-0.2.1}/LICENSE +0 -0
  62. {pylantir-0.1.3 → pylantir-0.2.1}/src/pylantir/cli/__init__.py +0 -0
  63. {pylantir-0.1.3 → pylantir-0.2.1}/src/pylantir/models.py +0 -0
  64. {pylantir-0.1.3 → pylantir-0.2.1}/src/pylantir/mwl_server.py +0 -0
  65. {pylantir-0.1.3 → pylantir-0.2.1}/src/pylantir/populate_db.py +0 -0
@@ -0,0 +1,584 @@
1
+ Metadata-Version: 2.4
2
+ Name: pylantir
3
+ Version: 0.2.1
4
+ Summary: Python - DICOM Modality WorkList with Optional API
5
+ Author-email: Milton Camacho <miltoncamachoicc@gmail.com>
6
+ Requires-Python: >=3.11.1
7
+ Description-Content-Type: text/markdown
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3 :: Only
12
+ Classifier: Programming Language :: Python :: 3.8
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ License-File: LICENSE
17
+ Requires-Dist: pynetdicom
18
+ Requires-Dist: sqlalchemy
19
+ Requires-Dist: PyCap
20
+ Requires-Dist: uuid
21
+ Requires-Dist: coloredlogs
22
+ Requires-Dist: python-dotenv
23
+ Requires-Dist: pandas
24
+ Requires-Dist: fastapi>=0.104.1 ; extra == "api"
25
+ Requires-Dist: uvicorn[standard]>=0.24.0 ; extra == "api"
26
+ Requires-Dist: passlib[bcrypt]==1.7.4 ; extra == "api"
27
+ Requires-Dist: bcrypt==4.0.1 ; extra == "api"
28
+ Requires-Dist: python-jose[cryptography]==3.5.0 ; extra == "api"
29
+ Requires-Dist: python-multipart>=0.0.6 ; extra == "api"
30
+ Requires-Dist: psutil>=5.9.0 ; extra == "monitoring"
31
+ Requires-Dist: pyspark>=3.0.0 ; extra == "spark"
32
+ Requires-Dist: bandit[toml]==1.7.5 ; extra == "test"
33
+ Requires-Dist: black==23.3.0 ; extra == "test"
34
+ Requires-Dist: check-manifest==0.49 ; extra == "test"
35
+ Requires-Dist: flake8-bugbear==23.5.9 ; extra == "test"
36
+ Requires-Dist: flake8-docstrings ; extra == "test"
37
+ Requires-Dist: flake8-formatter_junit_xml ; extra == "test"
38
+ Requires-Dist: flake8 ; extra == "test"
39
+ Requires-Dist: flake8-pyproject ; extra == "test"
40
+ Requires-Dist: pre-commit==3.3.1 ; extra == "test"
41
+ Requires-Dist: pylint==3.3.6 ; extra == "test"
42
+ Requires-Dist: pylint_junit ; extra == "test"
43
+ Requires-Dist: pytest-cov==4.0.0 ; extra == "test"
44
+ Requires-Dist: pytest-mock<3.10.1 ; extra == "test"
45
+ Requires-Dist: pytest-runner ; extra == "test"
46
+ Requires-Dist: pytest==7.3.1 ; extra == "test"
47
+ Requires-Dist: pytest-github-actions-annotate-failures ; extra == "test"
48
+ Requires-Dist: shellcheck-py==0.9.0.2 ; extra == "test"
49
+ Project-URL: Documentation, https://github.com/miltoncamacho/pylantir/tree/main#readme
50
+ Project-URL: Source, https://github.com/miltoncamacho/pylantir
51
+ Project-URL: Tracker, https://github.com/miltoncamacho/pylantir/issues
52
+ Provides-Extra: api
53
+ Provides-Extra: monitoring
54
+ Provides-Extra: spark
55
+ Provides-Extra: test
56
+
57
+ <div style="text-align: center;">
58
+ <h1>Pylantir</h1>
59
+ </div>
60
+ <div style="text-align: center;">
61
+ <img src="pylantir.png" alt="Pylantir" width="50%">
62
+ </div>
63
+
64
+ This project's goal is to significantly reduce the number of human-related errors when manualy registering participants for medical imaging procedures.
65
+
66
+ It effectively provides a python based DICOM Modality Worklist Server (SCP) and Modality Performed Procedure Step (SCP) able to receive requests from medical imaging equipemnt based on DICOM network comunication (e.g., a C-FIND, N-CREATE, N-SET requests).
67
+
68
+ It will build/update a database based on the information entered in the study-related REDCap database using a REDCap API (You will require to have API access to the study).
69
+
70
+ ## Getting Started
71
+
72
+ To get started simply install using:
73
+
74
+ ```bash
75
+ pip install pylantir
76
+ ```
77
+
78
+ ### Optional Dependencies
79
+
80
+ Pylantir offers several optional dependency groups for enhanced functionality:
81
+
82
+ #### API Support
83
+ For REST API and web interface capabilities:
84
+ ```bash
85
+ pip install pylantir[api]
86
+ ```
87
+ Includes: FastAPI, Uvicorn, JWT authentication, password hashing
88
+
89
+ #### Memory Monitoring
90
+ For enhanced memory usage monitoring and cleanup during REDCap synchronization:
91
+ ```bash
92
+ pip install pylantir[monitoring]
93
+ ```
94
+ Includes: psutil for system resource monitoring
95
+
96
+ #### Big Data Processing
97
+ For Spark-based data processing capabilities:
98
+ ```bash
99
+ pip install pylantir[spark]
100
+ ```
101
+ Includes: PySpark for large-scale data processing
102
+
103
+ #### Multiple Options
104
+ Install multiple optional dependency groups:
105
+ ```bash
106
+ # API + Memory Monitoring
107
+ pip install pylantir[api,monitoring]
108
+
109
+ # All optional dependencies
110
+ pip install pylantir[api,monitoring,spark]
111
+ ```
112
+
113
+ #### Development and Testing
114
+ For running tests and development:
115
+ ```bash
116
+ pip install pylantir[test]
117
+ ```
118
+ Includes: pytest, coverage tools, and testing utilities
119
+
120
+ You need to provide your REDCap API URL and API token before starting the server.
121
+ Set up environmental variables before starting the server:
122
+
123
+ ```bash
124
+ export REDCAP_API_URL=<your API url>
125
+ export REDCAP_API_TOKEN=<your API token>
126
+ ```
127
+
128
+ Start a server called with AEtitle MWL_SERVER.
129
+
130
+ ```bash
131
+ pylantir start --ip 127.0.0.1 --port 4242 --AEtitle MWL_SERVER --pylantir_config Path/to/your/config.json
132
+ ```
133
+
134
+ ## Tests
135
+
136
+ If you want to run the tests make sure to clone the repository and run them from there.
137
+
138
+ Git clone the repository:
139
+
140
+ ```bash
141
+ git clone https://github.com/miltoncamacho/pylantir
142
+ cd pylantir/tests
143
+ ```
144
+
145
+ Query the worklist database to check that you have some entries using:
146
+
147
+ ```bash
148
+ python query-db.py
149
+ ```
150
+
151
+ Then, you can get a StudyUID from one of the entries to test the MPPS workflow. For example: 1.2.840.10008.3.1.2.3.4.55635351412689303463019139483773956632
152
+
153
+ Take this and run a create action to mark the worklist Procedure Step Status as IN_PROGRESS
154
+
155
+ ```bash
156
+ python test-mpps.py --AEtitle MWL_SERVER --mpps_action create --callingAEtitle MWL_TESTER --ip 127.0.0.1 --port 4242 --study_uid 1.2.840.10008.3.1.2.3.4.55635351412689303463019139483773956632
157
+ ```
158
+
159
+ You can verify that this in fact modified your database re-running:
160
+
161
+ ```bash
162
+ python query-db.py
163
+ ```
164
+
165
+ Finally, you can also simulate the pocedure completion efectively updating the Procedure Step Status to COMPLETED or DISCONTINUED:
166
+
167
+ ```bash
168
+ python test-mpps.py --AEtitle MWL_SERVER --mpps_action set --mpps_status COMPLETED --callingAEtitle MWL_TESTER --ip 127.0.0.1 --port 4242 --study_uid 1.2.840.10008.3.1.2.3.4.55635351412689303463019139483773956632 --sop_uid 1.2.840.10008.3.1.2.3.4.187176383255263644225774937658729238426
169
+ ```
170
+
171
+ ## Usage
172
+
173
+ ```bash
174
+ usage: pylantir [-h] [--AEtitle AETITLE] [--ip IP] [--port PORT] [--pylantir_config PYLANTIR_CONFIG] [--mpps_action {create,set}] [--mpps_status {COMPLETED,DISCONTINUED}] [--callingAEtitle CALLINGAETITLE] [--study_uid STUDY_UID] [--sop_uid SOP_UID] {start,query-db,test-client,test-mpps}
175
+ ```
176
+
177
+ **pylantir** - Python DICOM Modality WorkList and Modality Performed Procedure Step compliance
178
+
179
+ ### Positional Arguments:
180
+
181
+ - **{start,query-db,test-client,test-mpps,start-api,admin-password,create-user,list-users}**: Command to run:
182
+ - **start**: Start the MWL server
183
+ - **query-db**: Query the MWL database
184
+ - **test-client**: Run tests for MWL
185
+ - **test-mpps**: Run tests for MPPS
186
+ - **start-api**: Start the FastAPI server (requires [api] dependencies)
187
+ - **admin-password**: Change admin password
188
+ - **create-user**: Create a new user (admin only)
189
+ - **list-users**: List all users (admin only)
190
+
191
+ ### Options:
192
+
193
+ - **-h, --help**: Show this help message and exit
194
+ - **--AEtitle AETITLE**: AE Title for the server
195
+ - **--ip IP**: IP/host address for the server
196
+ - **--port PORT**: Port for the server
197
+ - **--pylantir_config PYLANTIR_CONFIG**: Path to the configuration JSON file containing pylantir configs:
198
+ - **allowed_aet**: List of allowed AE titles e.g. `["MRI_SCANNER", "MRI_SCANNER_2"]`
199
+ - **site**: Site ID:string
200
+ - **protocol**: `{"site": "protocol_name", "mapping": "HIS/RIS mapping"}`
201
+ - **redcap2wl**: Dictionary of REDCap fields to worklist fields mapping e.g., `{"redcap_field": "worklist_field"}`
202
+ - **db_path**: Path to main worklist database e.g., `"/path/to/worklist.db"`
203
+ - **users_db_path**: Optional path to users authentication database e.g., `"/path/to/users.db"`
204
+ - **db_update_interval**: How often to reload the database e
205
+ - **operation_interval**: What is the time range in a day in which the database will be updated e.g., `{"start_time":[hours,minutes],"end_time":[hours,minutes]}`
206
+ - **--mpps_action {create,set}**: Action to perform for MPPS either create or set
207
+ - **--mpps_status {COMPLETED,DISCONTINUED}**: Status to set for MPPS either COMPLETED or DISCONTINUED
208
+ - **--callingAEtitle CALLINGAETITLE**: Calling AE Title for MPPS, it helps when the MWL is limited to only accept certain AE titles
209
+ - **--study_uid STUDY_UID**: StudyInstanceUID to test MPPS
210
+ - **--sop_uid SOP_UID**: SOPInstanceUID to test MPPS
211
+
212
+ ## Configuration JSON file
213
+
214
+ As a default pylantir will try to read a JSON structured file with the following structure:
215
+
216
+ ```json
217
+ {
218
+ "db_path": "/path/to/worklist.db",
219
+ "users_db_path": "/path/to/users.db",
220
+ "db_echo": "False",
221
+ "db_update_interval": 60,
222
+ "operation_interval": {"start_time": [0,0],"end_time": [23,59]},
223
+ "allowed_aet": [],
224
+ "site": "792",
225
+ "redcap2wl": {
226
+ "study_id": "study_id",
227
+ "instrument": "redcap_repeat_instrument",
228
+ "session_id" : "mri_instance",
229
+ "family_id": "family_id",
230
+ "youth_dob_y": "youth_dob_y",
231
+ "t1_date": "t1_date",
232
+ "demo_sex": "demo_sex",
233
+ "scheduled_date": "mri_date",
234
+ "scheduled_time": "mri_time",
235
+ "mri_wt_lbs": "patient_weight_lb",
236
+ "referring_physician": "referring_physician_name",
237
+ "performing_physician": "performing_physician",
238
+ "station_name": "station_name",
239
+ "status": "performed_procedure_step_status"
240
+ },
241
+ "protocol": {
242
+ "792": "BRAIN_MRI_3T",
243
+ "mapping": "GEHC"
244
+ }
245
+ }
246
+ ```
247
+
248
+ ### Memory Management (Optional)
249
+
250
+ When you install the `monitoring` optional dependency (`pip install pylantir[monitoring]`), Pylantir gains enhanced memory monitoring capabilities during REDCap synchronization:
251
+
252
+ - **Automatic Memory Cleanup**: Performs garbage collection after each sync cycle
253
+ - **Memory Usage Reporting**: Logs current memory usage before and after cleanup
254
+ - **Connection Management**: Properly closes database connections and clears session caches
255
+ - **Resource Monitoring**: Tracks system resource usage during long-running operations
256
+
257
+ This is particularly useful for production deployments with frequent synchronization intervals or large datasets, helping prevent memory leaks during continuous operation.
258
+
259
+ **Memory monitoring works automatically** - no additional configuration required. The system will use enhanced monitoring when `psutil` is available, and fall back to basic garbage collection when it's not installed.
260
+
261
+ ## FastAPI REST API (Optional)
262
+
263
+ **New in v0.2.0**: Pylantir now includes an optional REST API for programmatic access to worklist data and user management.
264
+
265
+ ### Installation with API Support
266
+
267
+ To use the API features, install with optional API dependencies:
268
+
269
+ ```bash
270
+ pip install pylantir[api]
271
+ ```
272
+
273
+ This installs additional dependencies:
274
+ - `fastapi>=0.104.1`: Modern web framework for building APIs
275
+ - `uvicorn[standard]>=0.24.0`: ASGI server for running FastAPI
276
+ - `passlib[bcrypt]==1.7.4`: Password hashing library
277
+ - `bcrypt==4.0.1`: Bcrypt hashing algorithm
278
+ - `python-jose[cryptography]==3.5.0`: JWT token handling
279
+ - `python-multipart>=0.0.6`: Form data parsing
280
+
281
+ ### Starting the API Server
282
+
283
+ ```bash
284
+ # Start API server on default port (8000)
285
+ pylantir start-api --api-host 0.0.0.0 --api-port 8000
286
+
287
+ # With custom configuration
288
+ pylantir start-api --pylantir_config /path/to/config.json --api-port 8080
289
+ ```
290
+
291
+ The API server will be available at:
292
+ - **API Endpoints**: `http://localhost:8000`
293
+ - **Interactive Documentation**: `http://localhost:8000/docs` (Swagger UI)
294
+ - **Alternative Documentation**: `http://localhost:8000/redoc` (ReDoc)
295
+
296
+ ### Authentication & Authorization
297
+
298
+ The API uses JWT (JSON Web Token) authentication with role-based access control:
299
+
300
+ #### User Roles:
301
+ - **admin**: Full access to users and worklist data (CRUD operations)
302
+ - **write**: Read and write access to worklist data only
303
+ - **read**: Read-only access to worklist data only
304
+
305
+ #### Initial Setup:
306
+ On first run, a default admin user is created:
307
+ - **Username**: `admin`
308
+ - **Password**: `admin123`
309
+
310
+ ⚠️ **Change the default password immediately:**
311
+
312
+ ```bash
313
+ pylantir admin-password --username admin
314
+ ```
315
+
316
+ ### API Endpoints
317
+
318
+ #### Authentication
319
+ - `POST /auth/login`: Authenticate and receive JWT token
320
+
321
+ #### Worklist Management
322
+ - `GET /worklist`: Retrieve worklist items with filtering
323
+ - `POST /worklist`: Create new worklist items (write/admin)
324
+ - `PUT /worklist/{id}`: Update worklist items (write/admin)
325
+ - `DELETE /worklist/{id}`: Delete worklist items (write/admin)
326
+
327
+ #### User Management (Admin Only)
328
+ - `GET /users`: List all users
329
+ - `POST /users`: Create new users
330
+ - `PUT /users/{id}`: Update users
331
+ - `DELETE /users/{id}`: Delete users
332
+
333
+ #### Health Check
334
+ - `GET /health`: API health status
335
+
336
+ ### API Usage Examples
337
+
338
+ #### 1. Login and Get Token
339
+
340
+ ```bash
341
+ curl -X POST "http://localhost:8000/auth/login" \
342
+ -H "Content-Type: application/json" \
343
+ -d '{
344
+ "username": "admin",
345
+ "password": "your_new_password",
346
+ "access_token_expire_minutes": 60
347
+ }'
348
+ ```
349
+
350
+ You can optionally send `access_token_expire_minutes` in the login payload to override the default TTL that is applied to newly minted tokens.
351
+
352
+ Response:
353
+ ```json
354
+ {
355
+ "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
356
+ "token_type": "bearer"
357
+ }
358
+ ```
359
+
360
+ #### 2. Get Worklist Items
361
+
362
+ ```bash
363
+ # Get all scheduled and in-progress items (default)
364
+ curl -X GET "http://localhost:8000/worklist" \
365
+ -H "Authorization: Bearer YOUR_TOKEN"
366
+
367
+ # Filter by specific status
368
+ curl -X GET "http://localhost:8000/worklist?status=SCHEDULED&status=COMPLETED" \
369
+ -H "Authorization: Bearer YOUR_TOKEN"
370
+
371
+ # Filter by patient ID
372
+ curl -X GET "http://localhost:8000/worklist?patient_id=PATIENT001" \
373
+ -H "Authorization: Bearer YOUR_TOKEN"
374
+ ```
375
+
376
+ #### 3. Create Worklist Item
377
+
378
+ ```bash
379
+ curl -X POST "http://localhost:8000/worklist" \
380
+ -H "Authorization: Bearer YOUR_TOKEN" \
381
+ -H "Content-Type: application/json" \
382
+ -d '{
383
+ "patient_name": "Doe^John",
384
+ "patient_id": "PATIENT001",
385
+ "patient_birth_date": "19900101",
386
+ "patient_sex": "M",
387
+ "modality": "MR",
388
+ "performed_procedure_step_status": "SCHEDULED"
389
+ }'
390
+ ```
391
+
392
+ #### 4. Update Procedure Status
393
+
394
+ ```bash
395
+ curl -X PUT "http://localhost:8000/worklist/1" \
396
+ -H "Authorization: Bearer YOUR_TOKEN" \
397
+ -H "Content-Type: application/json" \
398
+ -d '{"performed_procedure_step_status": "IN_PROGRESS"}'
399
+ ```
400
+
401
+ ### CLI User Management
402
+
403
+ #### Change Admin Password
404
+
405
+ ```bash
406
+ pylantir admin-password --username admin
407
+ # Prompts for current and new password
408
+ ```
409
+
410
+ #### Create New User
411
+
412
+ ```bash
413
+ pylantir create-user --username newuser --role write --email user@example.com
414
+ # Prompts for admin credentials and new user password
415
+ ```
416
+
417
+ #### List Users
418
+
419
+ ```bash
420
+ pylantir list-users
421
+ # Prompts for admin credentials, then displays user table
422
+ ```
423
+
424
+ ### Python Client Example
425
+
426
+ ```python
427
+ import requests
428
+
429
+ # Login
430
+ response = requests.post("http://localhost:8000/auth/login", json={
431
+ "username": "admin",
432
+ "password": "your_password",
433
+ "access_token_expire_minutes": 120
434
+ })
435
+ token = response.json()["access_token"]
436
+
437
+ # Set headers for authenticated requests
438
+ headers = {"Authorization": f"Bearer {token}"}
439
+
440
+ # Get worklist items
441
+ response = requests.get("http://localhost:8000/worklist", headers=headers)
442
+ worklist_items = response.json()
443
+
444
+ # Create new item
445
+ new_item = {
446
+ "patient_name": "Smith^Jane",
447
+ "patient_id": "PATIENT002",
448
+ "modality": "CT",
449
+ "performed_procedure_step_status": "SCHEDULED"
450
+ }
451
+ response = requests.post("http://localhost:8000/worklist",
452
+ json=new_item, headers=headers)
453
+ ```
454
+
455
+ ### API Configuration
456
+
457
+ The API server uses the same configuration file as the main DICOM server for database settings. You can configure both the main worklist database and the users authentication database paths.
458
+
459
+ #### Database Configuration Options:
460
+
461
+ 1. **Automatic Location (Default)**:
462
+ ```json
463
+ {
464
+ "db_path": "/path/to/worklist.db"
465
+ }
466
+ ```
467
+ - Users database will be created as `users.db` in the same directory
468
+ - Result: `/path/to/users.db`
469
+
470
+ 2. **Custom Users Database Path**:
471
+ ```json
472
+ {
473
+ "db_path": "/path/to/worklist.db",
474
+ "users_db_path": "/different/path/to/authentication.db"
475
+ }
476
+ ```
477
+ - Users database will be created at the specified location
478
+ - Allows separation of databases for security or organizational reasons
479
+
480
+ 3. **Environment Variable Override**:
481
+ ```bash
482
+ export USERS_DB_PATH="/custom/path/to/users.db"
483
+ ```
484
+ - Takes precedence over configuration file setting
485
+ - Useful for deployment-specific configurations
486
+
487
+ #### Configuration Precedence:
488
+ 1. `users_db_path` in configuration JSON file
489
+ 2. `USERS_DB_PATH` environment variable
490
+ 3. Default: `users.db` in same directory as main database
491
+
492
+ Example directory structures:
493
+
494
+ **Default Setup:**
495
+ ```
496
+ /path/to/databases/
497
+ ├── worklist.db # Main DICOM worklist database
498
+ └── users.db # API authentication database (auto-created)
499
+ ```
500
+
501
+ **Custom Setup:**
502
+ ```
503
+ /path/to/databases/
504
+ ├── worklist.db # Main DICOM worklist database
505
+
506
+ /secure/auth/
507
+ └── authentication.db # API authentication database (custom path)
508
+ ```
509
+
510
+ #### CORS Configuration
511
+
512
+ Control Cross-Origin Resource Sharing (CORS) for web frontend integration:
513
+
514
+ ```json
515
+ {
516
+ "db_path": "/path/to/worklist.db",
517
+ "api": {
518
+ "cors_allowed_origins": [
519
+ "http://localhost:3000",
520
+ "http://localhost:8080",
521
+ "https://radiology-dashboard.hospital.local",
522
+ "https://your-frontend-domain.com"
523
+ ],
524
+ "cors_allow_credentials": true,
525
+ "cors_allow_methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
526
+ "cors_allow_headers": ["*"]
527
+ }
528
+ }
529
+ ```
530
+
531
+ **CORS Configuration Options:**
532
+
533
+ - **`cors_allowed_origins`**: Array of allowed origin URLs for browser requests
534
+ - Use specific domains for security (avoid `["*"]` in production)
535
+ - Include all frontend application URLs that will access the API
536
+ - Supports both HTTP (development) and HTTPS (production) origins
537
+
538
+ - **`cors_allow_credentials`**: Boolean, allows cookies/auth headers in CORS requests
539
+ - Set to `true` for JWT token authentication (recommended)
540
+ - Required for browser-based authentication
541
+
542
+ - **`cors_allow_methods`**: Array of allowed HTTP methods
543
+ - Default: `["GET", "POST", "PUT", "DELETE", "OPTIONS"]`
544
+ - Include `"OPTIONS"` for preflight requests
545
+
546
+ - **`cors_allow_headers`**: Array of allowed request headers
547
+ - Default: `["*"]` allows all headers
548
+ - Can specify specific headers like `["Authorization", "Content-Type"]`
549
+
550
+ **CORS Security Best Practices:**
551
+ - Never use `["*"]` for origins in production environments
552
+ - Specify only the exact domains that need API access
553
+ - Use HTTPS origins for production deployments
554
+ - Regularly audit and update allowed origins list
555
+
556
+ **Example Production CORS Setup:**
557
+ ```json
558
+ {
559
+ "api": {
560
+ "cors_allowed_origins": [
561
+ "https://radiology.hospital.com",
562
+ "https://dashboard.hospital.com"
563
+ ],
564
+ "cors_allow_credentials": true,
565
+ "cors_allow_methods": ["GET", "POST", "PUT", "DELETE"],
566
+ "cors_allow_headers": ["Authorization", "Content-Type"]
567
+ }
568
+ }
569
+ ```
570
+
571
+ ### Security Considerations
572
+
573
+ - **Change Default Password**: Always change the default admin password
574
+ - **Use HTTPS**: In production, use HTTPS with proper SSL certificates
575
+ - **Network Security**: Restrict API access using firewalls/network policies
576
+ - **Token Management**: JWT tokens expire after 30 minutes by default
577
+ - **Database Permissions**: Ensure database files have appropriate file permissions
578
+
579
+ ## Clean Stop of the MWL and Database Sync
580
+
581
+ To cleanly stop the MWL server and ensure the database syncronization properly, press `Ctrl + C` (you might need to press it twice).
582
+
583
+ To stop the API server, use `Ctrl + C` in the terminal where it's running.
584
+