Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow --patients to consume text files with IDs in it #2

Merged
merged 2 commits into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,5 @@ dist

downloads/*
config/*
!config/example-config.ts
.DS_Store
volume/
145 changes: 0 additions & 145 deletions config/example-config.ts

This file was deleted.

43 changes: 33 additions & 10 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import humanizeDuration from "humanize-duration"
import {
ndjsonEntries,
print,
readLine,
sweep
} from "./utils"

Expand All @@ -23,10 +24,11 @@ program.version(pkg.version)
program.option("-p, --path [path]", "Path to directory containing the config file")
program.option(
"--patients [paths...]",
"Path to ndjson file with patients. If passed, the bulk data part of the export " +
"will be skipped and these patients will be used instead. Can be specified " +
"multiple times for multiple patient files. Paths should be relative to the " +
"input directory.",
"Path to an NDJSON file with Patients or a text file with Patient IDs. " +
"If passed, the bulk data part of the export will be skipped and " +
"these patients will be used instead. " +
"Can be specified multiple times for multiple patient files. " +
"Paths should be relative to the input directory.",
[]
)

Expand Down Expand Up @@ -79,6 +81,31 @@ async function loadConfig(configDir: string): Promise<Config> {
return config
}

/**
Parses either an ndjson/jsonl file or a basic text file, and returns the Patient IDs found.
* @param path The path to the file to read
*/
function *readPatientIdsFromFile(path: string): IterableIterator<string> {

if (path.endsWith(".ndjson") || path.endsWith(".jsonl")) {
for (const patient of ndjsonEntries(path)) {
if (!patient || typeof patient !== "object" || patient.resourceType !== "Patient") {
// istanbul ignore next
throw new Error(format(`A non-patient entry found in the Patient ndjson file: %o`, patient))
}
yield patient.id;
}
}
else {
const lines = readLine(path);
for (const line of lines) {
const trimmed = line.trim();
if (trimmed)
yield trimmed;
}
}
}

async function main(args: Record<string, any>) {

const inputDir = getInputDirectory(args.path)
Expand Down Expand Up @@ -156,15 +183,11 @@ async function main(args: Record<string, any>) {
// next available url (if any) whenever we are ready to download it
const downloadUrls = (function*() {
for (const loc of files) {
for (const patient of ndjsonEntries(loc)) {
if (!patient || typeof patient !== "object" || patient.resourceType !== "Patient") {
// istanbul ignore next
throw new Error(format(`A non-patient entry found in the Patient ndjson file: %o`, patient))
}
for (const patientId of readPatientIdsFromFile(loc)) {
counts.Patient++
counts["Total FHIR Resources"]++
for (const resourceType of Object.keys(config.resources)) {
const query = config.resources[resourceType].replace("#{patientId}", patient.id)
const query = config.resources[resourceType].replace("#{patientId}", patientId)
yield `${resourceType}${query}`
}
}
Expand Down
Loading