From 565c7f6189616646b4ade0f733e0c31c8e152205 Mon Sep 17 00:00:00 2001 From: Nate Vack Date: Fri, 12 Dec 2025 16:41:08 -0600 Subject: [PATCH] Add background_import param to import_records() Setting this to True will ask REDCap to import records in the background; this will work similarly to the background import in the Data Import Tool. Because this flag is not supported in old REDCap versions, if you do not specify it, it will not be added to your request parameters at all and you will get the default REDCap behavior. Currently, REDCap defaults to foreground imports. --- redcap/methods/records.py | 6 +++ tests/unit/test_simple_project.py | 62 +++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/redcap/methods/records.py b/redcap/methods/records.py index 5dd6664..6d7ff19 100644 --- a/redcap/methods/records.py +++ b/redcap/methods/records.py @@ -258,6 +258,7 @@ def import_records( import_format: Literal["json", "csv", "xml", "df"] = "json", date_format: Literal["YMD", "DMY", "MDY"] = "YMD", force_auto_number: bool = False, + background_process: Optional[bool] = None, ): """ Import data into the REDCap Project @@ -295,6 +296,8 @@ def import_records( of imported records by REDCap. If this is set to true, and auto-numbering for records is enabled for the project, auto-numbering of imported records will be enabled. + background_process: + Specifies whether to do the import as background process. Raises: RedcapError: Bad request made, double check field names and other inputs @@ -317,6 +320,9 @@ def import_records( payload["returnContent"] = return_content payload["dateFormat"] = date_format payload["forceAutoNumber"] = force_auto_number + if background_process is not None: + # This option is not supported in old REDCap versions (< 14.something) + payload["backgroundProcess"] = int(background_process) return_type = self._lookup_return_type( format_type=return_format_type, diff --git a/tests/unit/test_simple_project.py b/tests/unit/test_simple_project.py index 64af1bf..78be40f 100644 --- a/tests/unit/test_simple_project.py +++ b/tests/unit/test_simple_project.py @@ -615,6 +615,68 @@ def test_df_import(simple_project): assert not "error" in response +def test_import_records_background_process_true(simple_project, mocker): + """Test that background_process=True passes backgroundProcess=1 in payload""" + mocked_api_call = mocker.patch.object( + simple_project, "_call_api", return_value={"count": 1} + ) + + data = [{"record_id": "1", "test": "value"}] + simple_project.import_records(data, background_process=True) + + args, _ = mocked_api_call.call_args + payload = args[0] + + assert "backgroundProcess" in payload + assert payload["backgroundProcess"] == 1 + + +def test_import_records_background_process_false(simple_project, mocker): + """Test that background_process=False passes backgroundProcess=0 in payload""" + mocked_api_call = mocker.patch.object( + simple_project, "_call_api", return_value={"count": 1} + ) + + data = [{"record_id": "1", "test": "value"}] + simple_project.import_records(data, background_process=False) + + args, _ = mocked_api_call.call_args + payload = args[0] + + assert "backgroundProcess" in payload + assert payload["backgroundProcess"] == 0 + + +def test_import_records_background_process_none(simple_project, mocker): + """Test that background_process=None does not add backgroundProcess to payload""" + mocked_api_call = mocker.patch.object( + simple_project, "_call_api", return_value={"count": 1} + ) + + data = [{"record_id": "1", "test": "value"}] + simple_project.import_records(data, background_process=None) + + args, _ = mocked_api_call.call_args + payload = args[0] + + assert "backgroundProcess" not in payload + + +def test_import_records_background_process_default(simple_project, mocker): + """Test that not specifying background_process does not add it to payload""" + mocked_api_call = mocker.patch.object( + simple_project, "_call_api", return_value={"count": 1} + ) + + data = [{"record_id": "1", "test": "value"}] + simple_project.import_records(data) + + args, _ = mocked_api_call.call_args + payload = args[0] + + assert "backgroundProcess" not in payload + + def test_reports_json_export(simple_project): report = simple_project.export_report(report_id="1")