bhsim 1.0.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.
- bhsim-1.0.0/LICENSE +21 -0
- bhsim-1.0.0/PKG-INFO +328 -0
- bhsim-1.0.0/README.md +310 -0
- bhsim-1.0.0/pyproject.toml +27 -0
- bhsim-1.0.0/setup.cfg +4 -0
- bhsim-1.0.0/src/bhsim/__init__.py +5 -0
- bhsim-1.0.0/src/bhsim/__main__.py +4 -0
- bhsim-1.0.0/src/bhsim/cli.py +26 -0
- bhsim-1.0.0/src/bhsim/engine.py +589 -0
- bhsim-1.0.0/src/bhsim/simulator.py +34 -0
- bhsim-1.0.0/src/bhsim.egg-info/PKG-INFO +328 -0
- bhsim-1.0.0/src/bhsim.egg-info/SOURCES.txt +18 -0
- bhsim-1.0.0/src/bhsim.egg-info/dependency_links.txt +1 -0
- bhsim-1.0.0/src/bhsim.egg-info/entry_points.txt +2 -0
- bhsim-1.0.0/src/bhsim.egg-info/requires.txt +7 -0
- bhsim-1.0.0/src/bhsim.egg-info/top_level.txt +1 -0
- bhsim-1.0.0/tests/test_engine.py +99 -0
- bhsim-1.0.0/tests/test_integrated.py +49 -0
- bhsim-1.0.0/tests/test_library_api.py +14 -0
- bhsim-1.0.0/tests/test_names.py +31 -0
bhsim-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Rahul Byrapuneni
|
|
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.
|
bhsim-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bhsim
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Privacy-first synthetic behavioral health operations simulator
|
|
5
|
+
Author: Rahul Byrapuneni
|
|
6
|
+
Maintainer: Rahul Byrapuneni
|
|
7
|
+
License: MIT
|
|
8
|
+
Keywords: synthetic-data,behavioral-health,sqlite,power-bi
|
|
9
|
+
Requires-Python: >=3.10
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Provides-Extra: dev
|
|
13
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
14
|
+
Provides-Extra: ui
|
|
15
|
+
Requires-Dist: streamlit>=1.35; extra == "ui"
|
|
16
|
+
Requires-Dist: pandas>=2.0; extra == "ui"
|
|
17
|
+
Dynamic: license-file
|
|
18
|
+
|
|
19
|
+
# BHSim
|
|
20
|
+
|
|
21
|
+
<p align="center">
|
|
22
|
+
<img src="assets/bhsim-banner.png" alt="BHSim - Python library for synthetic behavioral health data" width="850">
|
|
23
|
+
</p>
|
|
24
|
+
|
|
25
|
+
**Synthetic behavioral health data for SQL, analytics, and application testing.**
|
|
26
|
+
|
|
27
|
+
[](https://pypi.org/project/bhsim/)
|
|
28
|
+

|
|
29
|
+
[](LICENSE)
|
|
30
|
+
[](https://github.com/rahulbyrapuneni/bhsim/actions)
|
|
31
|
+
|
|
32
|
+
**[Install from PyPI](https://pypi.org/project/bhsim/) · [Source code](https://github.com/rahulbyrapuneni/bhsim) · [Report an issue](https://github.com/rahulbyrapuneni/bhsim/issues)**
|
|
33
|
+
|
|
34
|
+
BHSim is an open-source Python library that generates **fictional, interconnected behavioral health records**. It gives analysts, developers, students, and educators a ready-to-query dataset without asking them to find or handle real patient information.
|
|
35
|
+
|
|
36
|
+
In a few lines of Python, you can create a SQLite database containing individuals, programs, enrollments, employees, appointments, productivity records, and screening assessments. Use it to practice SQL joins, prototype Power BI dashboards, develop analytics features, or test software that expects relational healthcare-style data.
|
|
37
|
+
|
|
38
|
+
> **Release status:** `1.0.0rc3` is a public **release candidate**. Install this specific version using the command below. BHSim is intended for development, demonstrations, and education—not clinical decisions, official quality reporting, or billing.
|
|
39
|
+
|
|
40
|
+
## Why BHSim?
|
|
41
|
+
|
|
42
|
+
Sample spreadsheets are useful for learning individual SQL queries, but real analytics often depends on **relationships between records**. An individual may participate in several programs, a staff member may serve multiple programs, and each appointment must connect to the right people and enrollment history.
|
|
43
|
+
|
|
44
|
+
BHSim generates those relationships for you, so you can spend more time learning, querying, building, and testing—and less time assembling fake data by hand.
|
|
45
|
+
|
|
46
|
+
**Common uses:**
|
|
47
|
+
|
|
48
|
+
- **SQL practice:** Join visits with individuals, employees, programs, and enrollments.
|
|
49
|
+
- **BI dashboards:** Explore attendance, no-shows, program activity, staff workload, and screening trends.
|
|
50
|
+
- **Application testing:** Test database queries, ETL pipelines, APIs, and analytics features with fictional records.
|
|
51
|
+
- **Teaching and portfolio projects:** Demonstrate healthcare-style reporting without sharing protected health information (PHI).
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
## Quick start
|
|
55
|
+
|
|
56
|
+
**Requirements:** Python 3.10 or newer.
|
|
57
|
+
|
|
58
|
+
BHSim is available on PyPI. No database server, paid API,
|
|
59
|
+
or real patient information is required.
|
|
60
|
+
|
|
61
|
+
### Install BHSim
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pip install bhsim==1.0.0rc3
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
BHSim is currently available as a public release candidate.
|
|
68
|
+
|
|
69
|
+
### Generate your first dataset
|
|
70
|
+
|
|
71
|
+
Create a file named `example.py`:
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
from bhsim import BHSimulator
|
|
75
|
+
|
|
76
|
+
sim = BHSimulator(
|
|
77
|
+
clients=1000,
|
|
78
|
+
employees=80,
|
|
79
|
+
history_months=12,
|
|
80
|
+
future_days=30,
|
|
81
|
+
seed=42
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
sim.generate("behavioral_health.db")
|
|
85
|
+
|
|
86
|
+
print(sim.validate())
|
|
87
|
+
|
|
88
|
+
sim.to_csv("output")
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Run:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
python example.py
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
This generates a SQLite database containing connected synthetic
|
|
98
|
+
behavioral health records and exports CSV files for analysis.
|
|
99
|
+
|
|
100
|
+
You can explore the data with SQLite, Python, Excel, or Power BI.
|
|
101
|
+
|
|
102
|
+
You will get:
|
|
103
|
+
|
|
104
|
+
- **`behavioral_health.db`** — a SQLite database with related synthetic tables.
|
|
105
|
+
- **`output/`** — CSV exports you can load into spreadsheets or BI tools.
|
|
106
|
+
- **Validation results** — a report checking the dataset's core consistency rules. A passing result includes `"valid": true` and an empty `issues` list.
|
|
107
|
+
|
|
108
|
+
**Note:** BHSim does not overwrite an existing database file. Use a new filename if you want to generate another dataset.
|
|
109
|
+
|
|
110
|
+
### Prefer a command-line workflow?
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
python -m bhsim generate demo.db --clients 100 --seed 42
|
|
114
|
+
python -m bhsim validate demo.db
|
|
115
|
+
python -m bhsim export-csv demo.db output
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
You can also use the installed `bhsim` command when it is available on your system's PATH.
|
|
119
|
+
|
|
120
|
+
## What's inside the database?
|
|
121
|
+
|
|
122
|
+
| Area | Tables | What you'll find |
|
|
123
|
+
| --- | --- | --- |
|
|
124
|
+
| Individuals and programs | `individuals`, `programs`, `individual_programs` | Fictional people, MH/SA/IDD programs, admissions, discharges, and re-enrollments |
|
|
125
|
+
| Workforce | `employees`, `employee_programs`, `employee_supervision` | Staff members, program assignments, and reporting relationships |
|
|
126
|
+
| Appointments | `visits`, `visit_types`, `locations` | Scheduled and completed visits, no-shows, cancellations, rescheduling, and service times |
|
|
127
|
+
| Productivity | `productivity_rules`, `visit_productivity` | Illustrative productivity rules and visit-linked units |
|
|
128
|
+
| Screening assessments | `assessment_instruments`, `assessment_questions`, `answer_options`, `assessments`, `assessment_responses`, `assessment_scores` | PHQ-9 and GAD-7 items, answer options, responses, and scores |
|
|
129
|
+
| Generation details | `simulation_metadata` | Information about the simulation run |
|
|
130
|
+
|
|
131
|
+
There is also an **`assessment_responses_readable`** SQL view that brings together assessment questions and selected answers.
|
|
132
|
+
|
|
133
|
+
Records use primary and foreign keys. IDs are fixed-width, numeric-looking **text** values—not sequential row numbers. Names can repeat, so use IDs rather than names for joins.
|
|
134
|
+
|
|
135
|
+
## Explore your data with SQL
|
|
136
|
+
|
|
137
|
+
Open `behavioral_health.db` in a SQLite-compatible tool such as [SQLime](https://sqlime.org/), DB Browser for SQLite, or Python's built-in `sqlite3` module.
|
|
138
|
+
|
|
139
|
+
### 1. Appointments by program
|
|
140
|
+
|
|
141
|
+
```sql
|
|
142
|
+
SELECT
|
|
143
|
+
p.program_code,
|
|
144
|
+
p.description AS program_name,
|
|
145
|
+
COUNT(*) AS total_appointments,
|
|
146
|
+
SUM(CASE WHEN v.visit_status = 'COMPLETED' THEN 1 ELSE 0 END) AS completed,
|
|
147
|
+
SUM(CASE WHEN v.visit_status = 'NO_SHOW' THEN 1 ELSE 0 END) AS no_shows
|
|
148
|
+
FROM visits AS v
|
|
149
|
+
JOIN programs AS p
|
|
150
|
+
ON p.program_id = v.program_id
|
|
151
|
+
GROUP BY p.program_code, p.description
|
|
152
|
+
ORDER BY total_appointments DESC;
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**What it tells you:** Which programs have the most scheduled activity, completed appointments, and no-shows.
|
|
156
|
+
|
|
157
|
+
### 2. No-show rate by program
|
|
158
|
+
|
|
159
|
+
```sql
|
|
160
|
+
SELECT
|
|
161
|
+
p.program_code,
|
|
162
|
+
COUNT(*) AS eligible_appointments,
|
|
163
|
+
SUM(CASE WHEN v.visit_status = 'NO_SHOW' THEN 1 ELSE 0 END) AS no_shows,
|
|
164
|
+
ROUND(
|
|
165
|
+
100.0 * SUM(CASE WHEN v.visit_status = 'NO_SHOW' THEN 1 ELSE 0 END)
|
|
166
|
+
/ COUNT(*),
|
|
167
|
+
2
|
|
168
|
+
) AS no_show_percentage
|
|
169
|
+
FROM visits AS v
|
|
170
|
+
JOIN programs AS p
|
|
171
|
+
ON p.program_id = v.program_id
|
|
172
|
+
WHERE v.visit_status IN ('COMPLETED', 'NO_SHOW')
|
|
173
|
+
GROUP BY p.program_code
|
|
174
|
+
ORDER BY no_show_percentage DESC;
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
**What it tells you:** The percentage of eligible appointments marked as no-shows. This example uses **completed + no-show** visits as the denominator; actual organizations may define their reporting measures differently.
|
|
178
|
+
|
|
179
|
+
### 3. Visit history with individual and employee names
|
|
180
|
+
|
|
181
|
+
```sql
|
|
182
|
+
SELECT
|
|
183
|
+
i.individual_id,
|
|
184
|
+
i.full_name AS individual_name,
|
|
185
|
+
p.program_code,
|
|
186
|
+
v.visit_status,
|
|
187
|
+
v.scheduled_start,
|
|
188
|
+
e.full_name AS employee_name
|
|
189
|
+
FROM visits AS v
|
|
190
|
+
JOIN individuals AS i ON i.individual_id = v.individual_id
|
|
191
|
+
JOIN programs AS p ON p.program_id = v.program_id
|
|
192
|
+
JOIN employees AS e ON e.employee_id = v.employee_id
|
|
193
|
+
ORDER BY v.scheduled_start DESC
|
|
194
|
+
LIMIT 20;
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
**What it tells you:** How appointments connect to the individual receiving services, the program, and the assigned employee.
|
|
198
|
+
|
|
199
|
+
### 4. Explore PHQ-9 and GAD-7 responses
|
|
200
|
+
|
|
201
|
+
```sql
|
|
202
|
+
SELECT
|
|
203
|
+
instrument_code,
|
|
204
|
+
question_text,
|
|
205
|
+
selected_answer,
|
|
206
|
+
score_value
|
|
207
|
+
FROM assessment_responses_readable
|
|
208
|
+
LIMIT 20;
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**What it tells you:** Readable questions, answer choices, and simulated response scores, without writing several joins yourself.
|
|
212
|
+
|
|
213
|
+
PHQ-9 has nine scored items (complete total **0–27**), while GAD-7 has seven (complete total **0–21**). Incomplete submissions do not have complete total scores. These are simulated screening responses, **not diagnoses or clinically validated trajectories**.
|
|
214
|
+
|
|
215
|
+
## Customize your simulation
|
|
216
|
+
|
|
217
|
+
| Python argument | Example | Meaning |
|
|
218
|
+
| --- | --- | --- |
|
|
219
|
+
| `clients` | `1000` | Number of fictional individuals |
|
|
220
|
+
| `employees` | `80` | Number of fictional staff members |
|
|
221
|
+
| `history_months` | `12` | Historical period to simulate |
|
|
222
|
+
| `future_days` | `30` | Number of days of future appointments |
|
|
223
|
+
| `reference_date` | `"2026-10-10"` | Reference date in `YYYY-MM-DD` format |
|
|
224
|
+
| `seed` | `42` | Random seed for repeatable results |
|
|
225
|
+
|
|
226
|
+
Using the same version, settings, and seed produces a reproducible simulation. Change the seed to produce a different fictional dataset.
|
|
227
|
+
|
|
228
|
+
Some operational assumptions—including program hours, probabilities, and productivity calculations—are predefined in this release rather than exposed as user settings.
|
|
229
|
+
|
|
230
|
+
## Check data quality
|
|
231
|
+
|
|
232
|
+
BHSim includes built-in validation:
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
python -m bhsim validate demo.db
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
You can also independently inspect a SQLite database with a few simple queries.
|
|
239
|
+
|
|
240
|
+
**Check broken foreign-key relationships** (expected: no rows):
|
|
241
|
+
|
|
242
|
+
```sql
|
|
243
|
+
PRAGMA foreign_key_check;
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
**Check completed visits with missing or invalid service times** (expected: `0`):
|
|
247
|
+
|
|
248
|
+
```sql
|
|
249
|
+
SELECT COUNT(*) AS invalid_completed_visits
|
|
250
|
+
FROM visits
|
|
251
|
+
WHERE visit_status = 'COMPLETED'
|
|
252
|
+
AND (
|
|
253
|
+
actual_start IS NULL
|
|
254
|
+
OR actual_end IS NULL
|
|
255
|
+
OR actual_end <= actual_start
|
|
256
|
+
);
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
**Check visits without a matching enrollment** (expected: `0` under the current simulation rules):
|
|
260
|
+
|
|
261
|
+
```sql
|
|
262
|
+
SELECT COUNT(*) AS visits_outside_enrollment
|
|
263
|
+
FROM visits AS v
|
|
264
|
+
WHERE NOT EXISTS (
|
|
265
|
+
SELECT 1
|
|
266
|
+
FROM individual_programs AS ip
|
|
267
|
+
WHERE ip.individual_id = v.individual_id
|
|
268
|
+
AND ip.program_id = v.program_id
|
|
269
|
+
AND DATE(v.scheduled_start) >= DATE(ip.start_date)
|
|
270
|
+
AND (
|
|
271
|
+
ip.end_date IS NULL
|
|
272
|
+
OR DATE(v.scheduled_start) <= DATE(ip.end_date)
|
|
273
|
+
)
|
|
274
|
+
);
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
These checks validate **structural and business-rule consistency**. They do not demonstrate that the generated rates or outcomes represent real behavioral health populations.
|
|
278
|
+
|
|
279
|
+
## Use BHSim with Power BI
|
|
280
|
+
|
|
281
|
+
1. Generate the data and export it to CSV using `sim.to_csv("output")`.
|
|
282
|
+
2. In Power BI Desktop, select **Get data → Text/CSV** and load the files you need.
|
|
283
|
+
3. Use the ID columns to create relationships between individuals, visits, programs, and employees.
|
|
284
|
+
4. Build visuals for program activity, appointment statuses, staff productivity, or assessment trends.
|
|
285
|
+
|
|
286
|
+
You can also access SQLite directly through a compatible connector or ODBC configuration, if you prefer not to export CSV files.
|
|
287
|
+
|
|
288
|
+
## Develop and contribute
|
|
289
|
+
|
|
290
|
+
Clone the repository and install development dependencies:
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
git clone https://github.com/rahulbyrapuneni/bhsim.git
|
|
294
|
+
cd bhsim
|
|
295
|
+
python -m pip install -e ".[dev]"
|
|
296
|
+
python -m pytest -q
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
The main library lives in `src/bhsim/`. An **optional** Streamlit demo is available in the repository:
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
python -m pip install -e ".[ui]"
|
|
303
|
+
python -m streamlit run app.py
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
The demo is not required to install or use BHSim as a Python library.
|
|
307
|
+
|
|
308
|
+
Suggestions, bug reports, documentation improvements, and pull requests are welcome through [GitHub Issues](https://github.com/rahulbyrapuneni/bhsim/issues). Please **never submit real patient information or PHI** in issues, sample files, or tests.
|
|
309
|
+
|
|
310
|
+
## Important limitations
|
|
311
|
+
|
|
312
|
+
- **Synthetic, not sourced from patients:** BHSim generates fictional records and does not retrieve information from electronic health records.
|
|
313
|
+
- **Not a clinical model:** Demographic distributions, attendance behavior, utilization, and assessment trends are illustrative—not validated predictions of real populations.
|
|
314
|
+
- **Not for care decisions:** PHQ-9 and GAD-7 outputs must not be used for diagnosis, clinical decision support, or treatment recommendations.
|
|
315
|
+
- **Not billing guidance:** Productivity rules and units are examples, not payer-approved reimbursement logic.
|
|
316
|
+
- **Simplified workflows:** The current scheduling and program-enrollment rules do not cover every real-world exception or organization-specific workflow.
|
|
317
|
+
- **Schema versions matter:** Existing databases are not migrated automatically. Current releases use `full_name`; older generated datasets may contain `synthetic_name`.
|
|
318
|
+
- **Assessment rights:** Questionnaire wording and instrument-related rights belong to their respective owners. Confirm any applicable usage or redistribution requirements, particularly for clinical or commercial uses.
|
|
319
|
+
|
|
320
|
+
## License and credits
|
|
321
|
+
|
|
322
|
+
BHSim is open-source software released under the [MIT License](LICENSE). Third-party assessment rights and attribution are separate from the software license.
|
|
323
|
+
|
|
324
|
+
**Creator and maintainer:** [Rahul Byrapuneni](https://github.com/rahulbyrapuneni)
|
|
325
|
+
|
|
326
|
+
Created with behavioral health analytics domain direction and AI-assisted software development.
|
|
327
|
+
|
|
328
|
+
**Links:** [PyPI](https://pypi.org/project/bhsim/) · [GitHub](https://github.com/rahulbyrapuneni/bhsim) · [Issues](https://github.com/rahulbyrapuneni/bhsim/issues)
|
bhsim-1.0.0/README.md
ADDED
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
# BHSim
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="assets/bhsim-banner.png" alt="BHSim - Python library for synthetic behavioral health data" width="850">
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
**Synthetic behavioral health data for SQL, analytics, and application testing.**
|
|
8
|
+
|
|
9
|
+
[](https://pypi.org/project/bhsim/)
|
|
10
|
+

|
|
11
|
+
[](LICENSE)
|
|
12
|
+
[](https://github.com/rahulbyrapuneni/bhsim/actions)
|
|
13
|
+
|
|
14
|
+
**[Install from PyPI](https://pypi.org/project/bhsim/) · [Source code](https://github.com/rahulbyrapuneni/bhsim) · [Report an issue](https://github.com/rahulbyrapuneni/bhsim/issues)**
|
|
15
|
+
|
|
16
|
+
BHSim is an open-source Python library that generates **fictional, interconnected behavioral health records**. It gives analysts, developers, students, and educators a ready-to-query dataset without asking them to find or handle real patient information.
|
|
17
|
+
|
|
18
|
+
In a few lines of Python, you can create a SQLite database containing individuals, programs, enrollments, employees, appointments, productivity records, and screening assessments. Use it to practice SQL joins, prototype Power BI dashboards, develop analytics features, or test software that expects relational healthcare-style data.
|
|
19
|
+
|
|
20
|
+
> **Release status:** `1.0.0rc3` is a public **release candidate**. Install this specific version using the command below. BHSim is intended for development, demonstrations, and education—not clinical decisions, official quality reporting, or billing.
|
|
21
|
+
|
|
22
|
+
## Why BHSim?
|
|
23
|
+
|
|
24
|
+
Sample spreadsheets are useful for learning individual SQL queries, but real analytics often depends on **relationships between records**. An individual may participate in several programs, a staff member may serve multiple programs, and each appointment must connect to the right people and enrollment history.
|
|
25
|
+
|
|
26
|
+
BHSim generates those relationships for you, so you can spend more time learning, querying, building, and testing—and less time assembling fake data by hand.
|
|
27
|
+
|
|
28
|
+
**Common uses:**
|
|
29
|
+
|
|
30
|
+
- **SQL practice:** Join visits with individuals, employees, programs, and enrollments.
|
|
31
|
+
- **BI dashboards:** Explore attendance, no-shows, program activity, staff workload, and screening trends.
|
|
32
|
+
- **Application testing:** Test database queries, ETL pipelines, APIs, and analytics features with fictional records.
|
|
33
|
+
- **Teaching and portfolio projects:** Demonstrate healthcare-style reporting without sharing protected health information (PHI).
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
## Quick start
|
|
37
|
+
|
|
38
|
+
**Requirements:** Python 3.10 or newer.
|
|
39
|
+
|
|
40
|
+
BHSim is available on PyPI. No database server, paid API,
|
|
41
|
+
or real patient information is required.
|
|
42
|
+
|
|
43
|
+
### Install BHSim
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
pip install bhsim==1.0.0rc3
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
BHSim is currently available as a public release candidate.
|
|
50
|
+
|
|
51
|
+
### Generate your first dataset
|
|
52
|
+
|
|
53
|
+
Create a file named `example.py`:
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
from bhsim import BHSimulator
|
|
57
|
+
|
|
58
|
+
sim = BHSimulator(
|
|
59
|
+
clients=1000,
|
|
60
|
+
employees=80,
|
|
61
|
+
history_months=12,
|
|
62
|
+
future_days=30,
|
|
63
|
+
seed=42
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
sim.generate("behavioral_health.db")
|
|
67
|
+
|
|
68
|
+
print(sim.validate())
|
|
69
|
+
|
|
70
|
+
sim.to_csv("output")
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Run:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
python example.py
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
This generates a SQLite database containing connected synthetic
|
|
80
|
+
behavioral health records and exports CSV files for analysis.
|
|
81
|
+
|
|
82
|
+
You can explore the data with SQLite, Python, Excel, or Power BI.
|
|
83
|
+
|
|
84
|
+
You will get:
|
|
85
|
+
|
|
86
|
+
- **`behavioral_health.db`** — a SQLite database with related synthetic tables.
|
|
87
|
+
- **`output/`** — CSV exports you can load into spreadsheets or BI tools.
|
|
88
|
+
- **Validation results** — a report checking the dataset's core consistency rules. A passing result includes `"valid": true` and an empty `issues` list.
|
|
89
|
+
|
|
90
|
+
**Note:** BHSim does not overwrite an existing database file. Use a new filename if you want to generate another dataset.
|
|
91
|
+
|
|
92
|
+
### Prefer a command-line workflow?
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
python -m bhsim generate demo.db --clients 100 --seed 42
|
|
96
|
+
python -m bhsim validate demo.db
|
|
97
|
+
python -m bhsim export-csv demo.db output
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
You can also use the installed `bhsim` command when it is available on your system's PATH.
|
|
101
|
+
|
|
102
|
+
## What's inside the database?
|
|
103
|
+
|
|
104
|
+
| Area | Tables | What you'll find |
|
|
105
|
+
| --- | --- | --- |
|
|
106
|
+
| Individuals and programs | `individuals`, `programs`, `individual_programs` | Fictional people, MH/SA/IDD programs, admissions, discharges, and re-enrollments |
|
|
107
|
+
| Workforce | `employees`, `employee_programs`, `employee_supervision` | Staff members, program assignments, and reporting relationships |
|
|
108
|
+
| Appointments | `visits`, `visit_types`, `locations` | Scheduled and completed visits, no-shows, cancellations, rescheduling, and service times |
|
|
109
|
+
| Productivity | `productivity_rules`, `visit_productivity` | Illustrative productivity rules and visit-linked units |
|
|
110
|
+
| Screening assessments | `assessment_instruments`, `assessment_questions`, `answer_options`, `assessments`, `assessment_responses`, `assessment_scores` | PHQ-9 and GAD-7 items, answer options, responses, and scores |
|
|
111
|
+
| Generation details | `simulation_metadata` | Information about the simulation run |
|
|
112
|
+
|
|
113
|
+
There is also an **`assessment_responses_readable`** SQL view that brings together assessment questions and selected answers.
|
|
114
|
+
|
|
115
|
+
Records use primary and foreign keys. IDs are fixed-width, numeric-looking **text** values—not sequential row numbers. Names can repeat, so use IDs rather than names for joins.
|
|
116
|
+
|
|
117
|
+
## Explore your data with SQL
|
|
118
|
+
|
|
119
|
+
Open `behavioral_health.db` in a SQLite-compatible tool such as [SQLime](https://sqlime.org/), DB Browser for SQLite, or Python's built-in `sqlite3` module.
|
|
120
|
+
|
|
121
|
+
### 1. Appointments by program
|
|
122
|
+
|
|
123
|
+
```sql
|
|
124
|
+
SELECT
|
|
125
|
+
p.program_code,
|
|
126
|
+
p.description AS program_name,
|
|
127
|
+
COUNT(*) AS total_appointments,
|
|
128
|
+
SUM(CASE WHEN v.visit_status = 'COMPLETED' THEN 1 ELSE 0 END) AS completed,
|
|
129
|
+
SUM(CASE WHEN v.visit_status = 'NO_SHOW' THEN 1 ELSE 0 END) AS no_shows
|
|
130
|
+
FROM visits AS v
|
|
131
|
+
JOIN programs AS p
|
|
132
|
+
ON p.program_id = v.program_id
|
|
133
|
+
GROUP BY p.program_code, p.description
|
|
134
|
+
ORDER BY total_appointments DESC;
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**What it tells you:** Which programs have the most scheduled activity, completed appointments, and no-shows.
|
|
138
|
+
|
|
139
|
+
### 2. No-show rate by program
|
|
140
|
+
|
|
141
|
+
```sql
|
|
142
|
+
SELECT
|
|
143
|
+
p.program_code,
|
|
144
|
+
COUNT(*) AS eligible_appointments,
|
|
145
|
+
SUM(CASE WHEN v.visit_status = 'NO_SHOW' THEN 1 ELSE 0 END) AS no_shows,
|
|
146
|
+
ROUND(
|
|
147
|
+
100.0 * SUM(CASE WHEN v.visit_status = 'NO_SHOW' THEN 1 ELSE 0 END)
|
|
148
|
+
/ COUNT(*),
|
|
149
|
+
2
|
|
150
|
+
) AS no_show_percentage
|
|
151
|
+
FROM visits AS v
|
|
152
|
+
JOIN programs AS p
|
|
153
|
+
ON p.program_id = v.program_id
|
|
154
|
+
WHERE v.visit_status IN ('COMPLETED', 'NO_SHOW')
|
|
155
|
+
GROUP BY p.program_code
|
|
156
|
+
ORDER BY no_show_percentage DESC;
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**What it tells you:** The percentage of eligible appointments marked as no-shows. This example uses **completed + no-show** visits as the denominator; actual organizations may define their reporting measures differently.
|
|
160
|
+
|
|
161
|
+
### 3. Visit history with individual and employee names
|
|
162
|
+
|
|
163
|
+
```sql
|
|
164
|
+
SELECT
|
|
165
|
+
i.individual_id,
|
|
166
|
+
i.full_name AS individual_name,
|
|
167
|
+
p.program_code,
|
|
168
|
+
v.visit_status,
|
|
169
|
+
v.scheduled_start,
|
|
170
|
+
e.full_name AS employee_name
|
|
171
|
+
FROM visits AS v
|
|
172
|
+
JOIN individuals AS i ON i.individual_id = v.individual_id
|
|
173
|
+
JOIN programs AS p ON p.program_id = v.program_id
|
|
174
|
+
JOIN employees AS e ON e.employee_id = v.employee_id
|
|
175
|
+
ORDER BY v.scheduled_start DESC
|
|
176
|
+
LIMIT 20;
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**What it tells you:** How appointments connect to the individual receiving services, the program, and the assigned employee.
|
|
180
|
+
|
|
181
|
+
### 4. Explore PHQ-9 and GAD-7 responses
|
|
182
|
+
|
|
183
|
+
```sql
|
|
184
|
+
SELECT
|
|
185
|
+
instrument_code,
|
|
186
|
+
question_text,
|
|
187
|
+
selected_answer,
|
|
188
|
+
score_value
|
|
189
|
+
FROM assessment_responses_readable
|
|
190
|
+
LIMIT 20;
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**What it tells you:** Readable questions, answer choices, and simulated response scores, without writing several joins yourself.
|
|
194
|
+
|
|
195
|
+
PHQ-9 has nine scored items (complete total **0–27**), while GAD-7 has seven (complete total **0–21**). Incomplete submissions do not have complete total scores. These are simulated screening responses, **not diagnoses or clinically validated trajectories**.
|
|
196
|
+
|
|
197
|
+
## Customize your simulation
|
|
198
|
+
|
|
199
|
+
| Python argument | Example | Meaning |
|
|
200
|
+
| --- | --- | --- |
|
|
201
|
+
| `clients` | `1000` | Number of fictional individuals |
|
|
202
|
+
| `employees` | `80` | Number of fictional staff members |
|
|
203
|
+
| `history_months` | `12` | Historical period to simulate |
|
|
204
|
+
| `future_days` | `30` | Number of days of future appointments |
|
|
205
|
+
| `reference_date` | `"2026-10-10"` | Reference date in `YYYY-MM-DD` format |
|
|
206
|
+
| `seed` | `42` | Random seed for repeatable results |
|
|
207
|
+
|
|
208
|
+
Using the same version, settings, and seed produces a reproducible simulation. Change the seed to produce a different fictional dataset.
|
|
209
|
+
|
|
210
|
+
Some operational assumptions—including program hours, probabilities, and productivity calculations—are predefined in this release rather than exposed as user settings.
|
|
211
|
+
|
|
212
|
+
## Check data quality
|
|
213
|
+
|
|
214
|
+
BHSim includes built-in validation:
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
python -m bhsim validate demo.db
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
You can also independently inspect a SQLite database with a few simple queries.
|
|
221
|
+
|
|
222
|
+
**Check broken foreign-key relationships** (expected: no rows):
|
|
223
|
+
|
|
224
|
+
```sql
|
|
225
|
+
PRAGMA foreign_key_check;
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
**Check completed visits with missing or invalid service times** (expected: `0`):
|
|
229
|
+
|
|
230
|
+
```sql
|
|
231
|
+
SELECT COUNT(*) AS invalid_completed_visits
|
|
232
|
+
FROM visits
|
|
233
|
+
WHERE visit_status = 'COMPLETED'
|
|
234
|
+
AND (
|
|
235
|
+
actual_start IS NULL
|
|
236
|
+
OR actual_end IS NULL
|
|
237
|
+
OR actual_end <= actual_start
|
|
238
|
+
);
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
**Check visits without a matching enrollment** (expected: `0` under the current simulation rules):
|
|
242
|
+
|
|
243
|
+
```sql
|
|
244
|
+
SELECT COUNT(*) AS visits_outside_enrollment
|
|
245
|
+
FROM visits AS v
|
|
246
|
+
WHERE NOT EXISTS (
|
|
247
|
+
SELECT 1
|
|
248
|
+
FROM individual_programs AS ip
|
|
249
|
+
WHERE ip.individual_id = v.individual_id
|
|
250
|
+
AND ip.program_id = v.program_id
|
|
251
|
+
AND DATE(v.scheduled_start) >= DATE(ip.start_date)
|
|
252
|
+
AND (
|
|
253
|
+
ip.end_date IS NULL
|
|
254
|
+
OR DATE(v.scheduled_start) <= DATE(ip.end_date)
|
|
255
|
+
)
|
|
256
|
+
);
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
These checks validate **structural and business-rule consistency**. They do not demonstrate that the generated rates or outcomes represent real behavioral health populations.
|
|
260
|
+
|
|
261
|
+
## Use BHSim with Power BI
|
|
262
|
+
|
|
263
|
+
1. Generate the data and export it to CSV using `sim.to_csv("output")`.
|
|
264
|
+
2. In Power BI Desktop, select **Get data → Text/CSV** and load the files you need.
|
|
265
|
+
3. Use the ID columns to create relationships between individuals, visits, programs, and employees.
|
|
266
|
+
4. Build visuals for program activity, appointment statuses, staff productivity, or assessment trends.
|
|
267
|
+
|
|
268
|
+
You can also access SQLite directly through a compatible connector or ODBC configuration, if you prefer not to export CSV files.
|
|
269
|
+
|
|
270
|
+
## Develop and contribute
|
|
271
|
+
|
|
272
|
+
Clone the repository and install development dependencies:
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
git clone https://github.com/rahulbyrapuneni/bhsim.git
|
|
276
|
+
cd bhsim
|
|
277
|
+
python -m pip install -e ".[dev]"
|
|
278
|
+
python -m pytest -q
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
The main library lives in `src/bhsim/`. An **optional** Streamlit demo is available in the repository:
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
python -m pip install -e ".[ui]"
|
|
285
|
+
python -m streamlit run app.py
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
The demo is not required to install or use BHSim as a Python library.
|
|
289
|
+
|
|
290
|
+
Suggestions, bug reports, documentation improvements, and pull requests are welcome through [GitHub Issues](https://github.com/rahulbyrapuneni/bhsim/issues). Please **never submit real patient information or PHI** in issues, sample files, or tests.
|
|
291
|
+
|
|
292
|
+
## Important limitations
|
|
293
|
+
|
|
294
|
+
- **Synthetic, not sourced from patients:** BHSim generates fictional records and does not retrieve information from electronic health records.
|
|
295
|
+
- **Not a clinical model:** Demographic distributions, attendance behavior, utilization, and assessment trends are illustrative—not validated predictions of real populations.
|
|
296
|
+
- **Not for care decisions:** PHQ-9 and GAD-7 outputs must not be used for diagnosis, clinical decision support, or treatment recommendations.
|
|
297
|
+
- **Not billing guidance:** Productivity rules and units are examples, not payer-approved reimbursement logic.
|
|
298
|
+
- **Simplified workflows:** The current scheduling and program-enrollment rules do not cover every real-world exception or organization-specific workflow.
|
|
299
|
+
- **Schema versions matter:** Existing databases are not migrated automatically. Current releases use `full_name`; older generated datasets may contain `synthetic_name`.
|
|
300
|
+
- **Assessment rights:** Questionnaire wording and instrument-related rights belong to their respective owners. Confirm any applicable usage or redistribution requirements, particularly for clinical or commercial uses.
|
|
301
|
+
|
|
302
|
+
## License and credits
|
|
303
|
+
|
|
304
|
+
BHSim is open-source software released under the [MIT License](LICENSE). Third-party assessment rights and attribution are separate from the software license.
|
|
305
|
+
|
|
306
|
+
**Creator and maintainer:** [Rahul Byrapuneni](https://github.com/rahulbyrapuneni)
|
|
307
|
+
|
|
308
|
+
Created with behavioral health analytics domain direction and AI-assisted software development.
|
|
309
|
+
|
|
310
|
+
**Links:** [PyPI](https://pypi.org/project/bhsim/) · [GitHub](https://github.com/rahulbyrapuneni/bhsim) · [Issues](https://github.com/rahulbyrapuneni/bhsim/issues)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "bhsim"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "Privacy-first synthetic behavioral health operations simulator"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = {text = "MIT"}
|
|
12
|
+
authors = [{name = "Rahul Byrapuneni"}]
|
|
13
|
+
maintainers = [{name = "Rahul Byrapuneni"}]
|
|
14
|
+
keywords = ["synthetic-data", "behavioral-health", "sqlite", "power-bi"]
|
|
15
|
+
|
|
16
|
+
[project.optional-dependencies]
|
|
17
|
+
dev = ["pytest>=8"]
|
|
18
|
+
ui = ["streamlit>=1.35", "pandas>=2.0"]
|
|
19
|
+
|
|
20
|
+
[project.scripts]
|
|
21
|
+
bhsim = "bhsim.cli:main"
|
|
22
|
+
|
|
23
|
+
[tool.setuptools.packages.find]
|
|
24
|
+
where = ["src"]
|
|
25
|
+
|
|
26
|
+
[tool.pytest.ini_options]
|
|
27
|
+
testpaths = ["tests"]
|
bhsim-1.0.0/setup.cfg
ADDED