Records
REDCap API methods for Project records
Records (Base)
Responsible for all API methods under 'Records' in the API Playground
Source code in redcap/methods/records.py
class Records(Base):
"""Responsible for all API methods under 'Records' in the API Playground"""
def _backfill_fields(self, fields: Optional[List[str]], forms: Optional[List[str]]):
"""
Properly backfill fields to explicitly request the primary keys and
"form_complete" fields of the project. REDCap won't include fields like
the record_id if they're not on the form being requested, despite the user
almost always wanting that field to be included. When record_id is requested,
that automatically adds other fields like redcap_event_name, redcap_repeat_instrument,
and redcap_repeat_instance to the reponse as well.
Args:
fields: requested fields
forms: requested forms
Returns: A list of all fields to request, including
self.def_field (record_id) and the "form_complete" fields
"""
if forms and not fields:
return [f"{ form }_complete" for form in forms] + [self.def_field]
if fields and self.def_field not in fields:
return fields + [self.def_field]
if not fields:
return self.field_names + [f"{ form }_complete" for form in self.forms]
return fields
# pylint: disable=too-many-locals
def export_records(
self,
format_type: Literal["json", "csv", "xml", "df"] = "json",
records: Optional[List[str]] = None,
fields: Optional[Union[List[str], str]] = None,
forms: Optional[Union[List[str], str]] = None,
events: Optional[List[str]] = None,
raw_or_label: Literal["raw", "label", "both"] = "raw",
raw_or_label_headers: Literal["raw", "label"] = "raw",
event_name: Literal["label", "unique"] = "label",
record_type: Literal["flat", "eav"] = "flat",
export_survey_fields: bool = False,
export_data_access_groups: bool = False,
export_checkbox_labels: bool = False,
filter_logic: Optional[str] = None,
date_begin: Optional[datetime] = None,
date_end: Optional[datetime] = None,
decimal_character: Optional[Literal[",", "."]] = None,
export_blank_for_gray_form_status: Optional[bool] = None,
df_kwargs: Optional[Dict[str, Any]] = None,
):
# pylint: disable=line-too-long
r"""
Export data from the REDCap project.
Args:
format_type:
Format of returned data. `'json'` returns json-decoded
objects while `'csv'` and `'xml'` return other formats.
`'df'` will attempt to return a `pandas.DataFrame`
records:
Array of record names specifying specific records to export.
By default, all records are exported
fields:
Single field name or array of field names specifying specific
fields to pull.
By default, all fields are exported
forms:
Single form name or array of form names to export. If in the
web UI, the form name has a space in it, replace the space
with an underscore.
By default, all forms are exported
events:
An array of unique event names from which to export records
Note:
This only applies to longitudinal projects
raw_or_label:
Export the raw coded values or labels for the options of
multiple choice fields, or both
raw_or_label_headers:
Export the column names of the instrument as their raw
value or their labeled value
event_name:
Export the unique event name or the event label
record_type:
Database output structure type
export_survey_fields:
Specifies whether or not to export the survey identifier
field (e.g., "redcap_survey_identifier") or survey timestamp
fields (e.g., form_name+"_timestamp") when surveys are
utilized in the project
export_data_access_groups:
Specifies whether or not to export the
`"redcap_data_access_group"` field when data access groups
are utilized in the project
Note:
This flag is only viable if the user whose token is
being used to make the API request is *not* in a data
access group. If the user is in a group, then this flag
will revert to its default value.
export_checkbox_labels:
Specify whether to export checkbox values as their label on
export.
filter_logic:
Filter which records are returned using REDCap conditional syntax
date_begin:
Filter on records created after a date
date_end:
Filter on records created before a date
decimal_character:
Force all numbers into same decimal format
export_blank_for_gray_form_status:
Whether or not to export blank values for instrument complete status fields
that have a gray status icon
df_kwargs:
Passed to `pandas.read_csv` to control construction of
returned DataFrame.
By default, `{'index_col': self.def_field}`
Returns:
Union[List[Dict[str, Any]], str, pd.DataFrame]: Exported data
Examples:
>>> proj.export_records()
[{'record_id': '1', 'redcap_event_name': 'event_1_arm_1', 'redcap_repeat_instrument': '',
'redcap_repeat_instance': 1, 'field_1': '1',
'checkbox_field___1': '0', 'checkbox_field___2': '1', 'upload_field': 'test_upload.txt',
'form_1_complete': '2'},
{'record_id': '2', 'redcap_event_name': 'event_1_arm_1', 'redcap_repeat_instrument': '',
'redcap_repeat_instance': 1, 'field_1': '0',
'checkbox_field___1': '0', 'checkbox_field___2': '0', 'upload_field': 'myupload.txt',
'form_1_complete': '0'}]
>>> proj.export_records(filter_logic="[field_1] = 1")
[{'record_id': '1', 'redcap_event_name': 'event_1_arm_1', 'redcap_repeat_instrument': '',
'redcap_repeat_instance': 1, 'field_1': '1',
'checkbox_field___1': '0', 'checkbox_field___2': '1', 'upload_field': 'test_upload.txt',
'form_1_complete': '2'}]
>>> proj.export_records(
... format_type="csv",
... fields=["field_1", "checkbox_field"],
... raw_or_label="label"
... )
'record_id,redcap_event_name,redcap_repeat_instrument,redcap_repeat_instance,field_1,checkbox_field___1,checkbox_field___2\n1,"Event 1",,1,Yes,Unchecked,Checked\n2,"Event 1",,1,No,Unchecked,Unchecked\n'
>>> import pandas as pd
>>> pd.set_option("display.max_columns", 3)
>>> proj.export_records(format_type="df")
redcap_repeat_instrument ... form_1_complete
record_id redcap_event_name ...
1 event_1_arm_1 NaN ... 2
2 event_1_arm_1 NaN ... 0
...
"""
# pylint: enable=line-too-long
payload: Dict[str, Any] = self._initialize_payload(
content="record", format_type=format_type, record_type=record_type
)
if isinstance(fields, str):
fields = [fields]
if isinstance(forms, str):
forms = [forms]
fields = self._backfill_fields(fields, forms)
keys_to_add = (
records,
fields,
forms,
events,
raw_or_label,
raw_or_label_headers,
event_name,
export_survey_fields,
export_data_access_groups,
export_checkbox_labels,
filter_logic,
decimal_character,
export_blank_for_gray_form_status,
)
str_keys = (
"records",
"fields",
"forms",
"events",
"rawOrLabel",
"rawOrLabelHeaders",
"eventName",
"exportSurveyFields",
"exportDataAccessGroups",
"exportCheckboxLabel",
"filterLogic",
"decimalCharacter",
"exportBlankForGrayFormStatus",
)
for key, data in zip(str_keys, keys_to_add):
if data:
if key in ("fields", "records", "forms", "events"):
data = cast(List[str], data)
for i, value in enumerate(data):
payload[f"{ key }[{ i }]"] = value
else:
payload[key] = data
if date_begin:
payload["dateRangeBegin"] = date_begin.strftime("%Y-%m-%d %H:%M:%S")
if date_end:
payload["dateRangeEnd"] = date_end.strftime("%Y-%m-%d %H:%M:%S")
return_type = self._lookup_return_type(format_type, request_type="export")
response = cast(Union[Json, str], self._call_api(payload, return_type))
return self._return_data(
response=response,
content="record",
format_type=format_type,
df_kwargs=df_kwargs,
record_type=record_type,
)
# pylint: enable=too-many-locals
def import_records(
self,
to_import: Union[str, List[Dict[str, Any]], "pd.DataFrame"],
return_format_type: Literal["json", "csv", "xml"] = "json",
return_content: Literal["count", "ids", "auto_ids", "nothing"] = "count",
overwrite: Literal["normal", "overwrite"] = "normal",
import_format: Literal["json", "csv", "xml", "df"] = "json",
date_format: Literal["YMD", "DMY", "MDY"] = "YMD",
force_auto_number: bool = False,
):
"""
Import data into the REDCap Project
Args:
to_import:
Note:
If you pass a df, csv, or xml string, you should use the
`import_format` parameter appropriately.
Note:
Keys of the dictionaries should be subset of project's,
fields, but this isn't a requirement. If you provide keys
that aren't defined fields, the returned response will
contain an `'error'` key.
return_format_type:
Response format. By default, response will be json-decoded.
return_content:
By default, the response contains a 'count' key with the number of
records just imported. By specifying 'ids', a list of ids
imported will be returned. 'nothing' will only return
the HTTP status code and no message.
overwrite:
`'overwrite'` will erase values previously stored in the
database if not specified in the to_import dictionaries.
import_format:
Format of incoming data. By default, to_import will be json-encoded
date_format:
Describes the formatting of dates. By default, date strings
are formatted as 'YYYY-MM-DD' corresponding to 'YMD'. If date
strings are formatted as 'MM/DD/YYYY' set this parameter as
'MDY' and if formatted as 'DD/MM/YYYY' set as 'DMY'. No
other formattings are allowed.
force_auto_number:
Enables automatic assignment of record IDs
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.
Raises:
RedcapError: Bad request made, double check field names and other inputs
Returns:
Union[Dict, str]: response from REDCap API, json-decoded if `return_format` == `'json'`
Examples:
>>> new_record = [{"record_id": 3, "redcap_repeat_instance": 1, "field_1": 1}]
>>> proj.import_records(new_record)
{'count': 1}
"""
payload = self._initialize_import_payload(
to_import=to_import,
import_format=import_format,
return_format_type=return_format_type,
content="record",
)
payload["overwriteBehavior"] = overwrite
payload["returnContent"] = return_content
payload["dateFormat"] = date_format
payload["forceAutoNumber"] = force_auto_number
return_type = self._lookup_return_type(
format_type=return_format_type,
request_type="import",
import_records_format=return_content,
)
response = cast(Union[Json, str], self._call_api(payload, return_type))
return response
def delete_records(
self,
records: List[str],
arm: Optional[str] = None,
instrument: Optional[str] = None,
event: Optional[str] = None,
repeat_instance: Optional[int] = None,
delete_logging: bool = False,
return_format_type: Literal["json", "csv", "xml"] = "json",
):
# pylint: disable=line-too-long
"""
Delete records from the project.
Args:
records: List of record IDs to delete from the project
arm:
the arm number of the arm in which the record(s) should be deleted.
(This can only be used if the project is longitudinal with more than one arm.)
NOTE: If the arm parameter is not provided, the specified records will be
deleted from all arms in which they exist. Whereas, if arm is provided,
they will only be deleted from the specified arm.
instrument:
the unique instrument name (column B in the Data Dictionary) of an
instrument (as a string) if you wish to delete the data for all fields
on the specified instrument for the records specified.
event:
the unique event name - only for longitudinal projects. NOTE: If
instrument is provided for a longitudinal project, the event parameter
is mandatory.
repeat_instance:
the repeating instance number for a repeating instrument or repeating event.
NOTE: If project has repeating instruments/events, it will remove only the
data for that repeating instance.
delete_logging:
provide a value of False ("keep logging") or True ("delete logging"). This
activity when deleting the record?" setting enabled by an administrator on
the Edit Project Settings page. The default value for PyCap is False
return_format_type:
Response format. By default, response will be json-decoded.
Returns:
Union[int, str]: Number of records deleted
Examples:
>>> new_records = [
... {"record_id": 3, "redcap_repeat_instance": 1, "field_1": 1},
... {"record_id": 4, "redcap_repeat_instance": 1}
... ]
>>> proj.import_records(new_records)
{'count': 2}
>>> proj.delete_records(["3", "4"])
2
>>> new_record = [
... {"record_id": 3, "redcap_event_name": "event_1_arm_1", "redcap_repeat_instance": 1, "field_1": 1,},
... {"record_id": 3, "redcap_event_name": "event_1_arm_1", "redcap_repeat_instance": 2, "field_1": 0,},
... ]
>>> proj.import_records(new_record)
{'count': 1}
>>> proj.delete_records(records=["3"], event="event_1_arm_1", repeat_instance=2)
1
>>> proj.export_records(records=["3"])
[{'record_id': '3', 'redcap_event_name': 'event_1_arm_1', 'redcap_repeat_instrument': '', 'redcap_repeat_instance': 1,
'field_1': '1', 'checkbox_field___1': '0', 'checkbox_field___2': '0', 'upload_field': '', 'form_1_complete': '0'}]
>>> proj.delete_records(records=["3"])
1
"""
# pylint: enable=line-too-long
payload = self._initialize_payload(
content="record", return_format_type=return_format_type
)
payload["action"] = "delete"
if delete_logging:
payload["delete_logging"] = "1"
else:
payload["delete_logging"] = "0"
if arm:
payload["arm"] = arm
if instrument:
payload["instrument"] = instrument
if event:
payload["event"] = event
if repeat_instance:
payload["repeat_instance"] = repeat_instance
# Turn list of records into dict, and append to payload
records_dict = {
f"records[{ idx }]": record for idx, record in enumerate(records)
}
payload.update(records_dict)
return_type = self._lookup_return_type(
format_type=return_format_type, request_type="delete"
)
response = cast(Union[Json, str], self._call_api(payload, return_type))
return response
def generate_next_record_name(self) -> str:
"""
Get the next record name
Returns:
The next record name for a project with auto-numbering records enabled
Examples:
>>> proj.generate_next_record_name()
'3'
"""
# Force the csv format here since if the project uses data access groups
# or just non-standard record names then the result will not be JSON-compliant
payload = self._initialize_payload(
content="generateNextRecordName", format_type="csv"
)
return cast(str, self._call_api(payload, return_type="str"))
def_field: str
inherited
property
readonly
The 'record_id' field equivalent for a project
field_names: List[str]
inherited
property
readonly
Project field names
!!! note These are survey field names, not export field names
forms: List[str]
inherited
property
readonly
Project form names
is_longitudinal: bool
inherited
property
readonly
Whether or not this project is longitudinal
metadata: Json
inherited
property
readonly
Project metadata in JSON format
token: str
inherited
property
readonly
API token to a project
url: str
inherited
property
readonly
API URL to a REDCap server
delete_records(self, records, arm=None, instrument=None, event=None, repeat_instance=None, delete_logging=False, return_format_type='json')
Delete records from the project.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
records |
List[str] |
List of record IDs to delete from the project |
required |
arm |
Optional[str] |
the arm number of the arm in which the record(s) should be deleted. (This can only be used if the project is longitudinal with more than one arm.) NOTE: If the arm parameter is not provided, the specified records will be deleted from all arms in which they exist. Whereas, if arm is provided, they will only be deleted from the specified arm. |
None |
instrument |
Optional[str] |
the unique instrument name (column B in the Data Dictionary) of an instrument (as a string) if you wish to delete the data for all fields on the specified instrument for the records specified. |
None |
event |
Optional[str] |
the unique event name - only for longitudinal projects. NOTE: If instrument is provided for a longitudinal project, the event parameter is mandatory. |
None |
repeat_instance |
Optional[int] |
the repeating instance number for a repeating instrument or repeating event. NOTE: If project has repeating instruments/events, it will remove only the data for that repeating instance. |
None |
delete_logging |
bool |
provide a value of False ("keep logging") or True ("delete logging"). This activity when deleting the record?" setting enabled by an administrator on the Edit Project Settings page. The default value for PyCap is False |
False |
return_format_type |
Literal['json', 'csv', 'xml'] |
Response format. By default, response will be json-decoded. |
'json' |
Returns:
Type | Description |
---|---|
Union[int, str] |
Number of records deleted |
Examples:
>>> new_records = [
... {"record_id": 3, "redcap_repeat_instance": 1, "field_1": 1},
... {"record_id": 4, "redcap_repeat_instance": 1}
... ]
>>> proj.import_records(new_records)
{'count': 2}
>>> proj.delete_records(["3", "4"])
2
>>> new_record = [
... {"record_id": 3, "redcap_event_name": "event_1_arm_1", "redcap_repeat_instance": 1, "field_1": 1,},
... {"record_id": 3, "redcap_event_name": "event_1_arm_1", "redcap_repeat_instance": 2, "field_1": 0,},
... ]
>>> proj.import_records(new_record)
{'count': 1}
>>> proj.delete_records(records=["3"], event="event_1_arm_1", repeat_instance=2)
1
>>> proj.export_records(records=["3"])
[{'record_id': '3', 'redcap_event_name': 'event_1_arm_1', 'redcap_repeat_instrument': '', 'redcap_repeat_instance': 1,
'field_1': '1', 'checkbox_field___1': '0', 'checkbox_field___2': '0', 'upload_field': '', 'form_1_complete': '0'}]
>>> proj.delete_records(records=["3"])
1
Source code in redcap/methods/records.py
def delete_records(
self,
records: List[str],
arm: Optional[str] = None,
instrument: Optional[str] = None,
event: Optional[str] = None,
repeat_instance: Optional[int] = None,
delete_logging: bool = False,
return_format_type: Literal["json", "csv", "xml"] = "json",
):
# pylint: disable=line-too-long
"""
Delete records from the project.
Args:
records: List of record IDs to delete from the project
arm:
the arm number of the arm in which the record(s) should be deleted.
(This can only be used if the project is longitudinal with more than one arm.)
NOTE: If the arm parameter is not provided, the specified records will be
deleted from all arms in which they exist. Whereas, if arm is provided,
they will only be deleted from the specified arm.
instrument:
the unique instrument name (column B in the Data Dictionary) of an
instrument (as a string) if you wish to delete the data for all fields
on the specified instrument for the records specified.
event:
the unique event name - only for longitudinal projects. NOTE: If
instrument is provided for a longitudinal project, the event parameter
is mandatory.
repeat_instance:
the repeating instance number for a repeating instrument or repeating event.
NOTE: If project has repeating instruments/events, it will remove only the
data for that repeating instance.
delete_logging:
provide a value of False ("keep logging") or True ("delete logging"). This
activity when deleting the record?" setting enabled by an administrator on
the Edit Project Settings page. The default value for PyCap is False
return_format_type:
Response format. By default, response will be json-decoded.
Returns:
Union[int, str]: Number of records deleted
Examples:
>>> new_records = [
... {"record_id": 3, "redcap_repeat_instance": 1, "field_1": 1},
... {"record_id": 4, "redcap_repeat_instance": 1}
... ]
>>> proj.import_records(new_records)
{'count': 2}
>>> proj.delete_records(["3", "4"])
2
>>> new_record = [
... {"record_id": 3, "redcap_event_name": "event_1_arm_1", "redcap_repeat_instance": 1, "field_1": 1,},
... {"record_id": 3, "redcap_event_name": "event_1_arm_1", "redcap_repeat_instance": 2, "field_1": 0,},
... ]
>>> proj.import_records(new_record)
{'count': 1}
>>> proj.delete_records(records=["3"], event="event_1_arm_1", repeat_instance=2)
1
>>> proj.export_records(records=["3"])
[{'record_id': '3', 'redcap_event_name': 'event_1_arm_1', 'redcap_repeat_instrument': '', 'redcap_repeat_instance': 1,
'field_1': '1', 'checkbox_field___1': '0', 'checkbox_field___2': '0', 'upload_field': '', 'form_1_complete': '0'}]
>>> proj.delete_records(records=["3"])
1
"""
# pylint: enable=line-too-long
payload = self._initialize_payload(
content="record", return_format_type=return_format_type
)
payload["action"] = "delete"
if delete_logging:
payload["delete_logging"] = "1"
else:
payload["delete_logging"] = "0"
if arm:
payload["arm"] = arm
if instrument:
payload["instrument"] = instrument
if event:
payload["event"] = event
if repeat_instance:
payload["repeat_instance"] = repeat_instance
# Turn list of records into dict, and append to payload
records_dict = {
f"records[{ idx }]": record for idx, record in enumerate(records)
}
payload.update(records_dict)
return_type = self._lookup_return_type(
format_type=return_format_type, request_type="delete"
)
response = cast(Union[Json, str], self._call_api(payload, return_type))
return response
export_records(self, format_type='json', records=None, fields=None, forms=None, events=None, raw_or_label='raw', raw_or_label_headers='raw', event_name='label', record_type='flat', export_survey_fields=False, export_data_access_groups=False, export_checkbox_labels=False, filter_logic=None, date_begin=None, date_end=None, decimal_character=None, export_blank_for_gray_form_status=None, df_kwargs=None)
Export data from the REDCap project.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
format_type |
Literal['json', 'csv', 'xml', 'df'] |
Format of returned data. |
'json' |
records |
Optional[List[str]] |
Array of record names specifying specific records to export. By default, all records are exported |
None |
fields |
Union[List[str], str] |
Single field name or array of field names specifying specific fields to pull. By default, all fields are exported |
None |
forms |
Union[List[str], str] |
Single form name or array of form names to export. If in the web UI, the form name has a space in it, replace the space with an underscore. By default, all forms are exported |
None |
events |
Optional[List[str]] |
An array of unique event names from which to export records Note: This only applies to longitudinal projects |
None |
raw_or_label |
Literal['raw', 'label', 'both'] |
Export the raw coded values or labels for the options of multiple choice fields, or both |
'raw' |
raw_or_label_headers |
Literal['raw', 'label'] |
Export the column names of the instrument as their raw value or their labeled value |
'raw' |
event_name |
Literal['label', 'unique'] |
Export the unique event name or the event label |
'label' |
record_type |
Literal['flat', 'eav'] |
Database output structure type |
'flat' |
export_survey_fields |
bool |
Specifies whether or not to export the survey identifier field (e.g., "redcap_survey_identifier") or survey timestamp fields (e.g., form_name+"_timestamp") when surveys are utilized in the project |
False |
export_data_access_groups |
bool |
Specifies whether or not to export the
Note: This flag is only viable if the user whose token is being used to make the API request is not in a data access group. If the user is in a group, then this flag will revert to its default value. |
False |
export_checkbox_labels |
bool |
Specify whether to export checkbox values as their label on export. |
False |
filter_logic |
Optional[str] |
Filter which records are returned using REDCap conditional syntax |
None |
date_begin |
Optional[datetime.datetime] |
Filter on records created after a date |
None |
date_end |
Optional[datetime.datetime] |
Filter on records created before a date |
None |
decimal_character |
Optional[Literal[',', '.']] |
Force all numbers into same decimal format |
None |
export_blank_for_gray_form_status |
Optional[bool] |
Whether or not to export blank values for instrument complete status fields that have a gray status icon |
None |
df_kwargs |
Optional[Dict[str, Any]] |
Passed to |
None |
Returns:
Type | Description |
---|---|
Union[List[Dict[str, Any]], str, pd.DataFrame] |
Exported data |
Examples:
>>> proj.export_records()
[{'record_id': '1', 'redcap_event_name': 'event_1_arm_1', 'redcap_repeat_instrument': '',
'redcap_repeat_instance': 1, 'field_1': '1',
'checkbox_field___1': '0', 'checkbox_field___2': '1', 'upload_field': 'test_upload.txt',
'form_1_complete': '2'},
{'record_id': '2', 'redcap_event_name': 'event_1_arm_1', 'redcap_repeat_instrument': '',
'redcap_repeat_instance': 1, 'field_1': '0',
'checkbox_field___1': '0', 'checkbox_field___2': '0', 'upload_field': 'myupload.txt',
'form_1_complete': '0'}]
>>> proj.export_records(filter_logic="[field_1] = 1")
[{'record_id': '1', 'redcap_event_name': 'event_1_arm_1', 'redcap_repeat_instrument': '',
'redcap_repeat_instance': 1, 'field_1': '1',
'checkbox_field___1': '0', 'checkbox_field___2': '1', 'upload_field': 'test_upload.txt',
'form_1_complete': '2'}]
>>> proj.export_records(
... format_type="csv",
... fields=["field_1", "checkbox_field"],
... raw_or_label="label"
... )
'record_id,redcap_event_name,redcap_repeat_instrument,redcap_repeat_instance,field_1,checkbox_field___1,checkbox_field___2\n1,"Event 1",,1,Yes,Unchecked,Checked\n2,"Event 1",,1,No,Unchecked,Unchecked\n'
>>> import pandas as pd
>>> pd.set_option("display.max_columns", 3)
>>> proj.export_records(format_type="df")
redcap_repeat_instrument ... form_1_complete
record_id redcap_event_name ...
1 event_1_arm_1 NaN ... 2
2 event_1_arm_1 NaN ... 0
...
Source code in redcap/methods/records.py
def export_records(
self,
format_type: Literal["json", "csv", "xml", "df"] = "json",
records: Optional[List[str]] = None,
fields: Optional[Union[List[str], str]] = None,
forms: Optional[Union[List[str], str]] = None,
events: Optional[List[str]] = None,
raw_or_label: Literal["raw", "label", "both"] = "raw",
raw_or_label_headers: Literal["raw", "label"] = "raw",
event_name: Literal["label", "unique"] = "label",
record_type: Literal["flat", "eav"] = "flat",
export_survey_fields: bool = False,
export_data_access_groups: bool = False,
export_checkbox_labels: bool = False,
filter_logic: Optional[str] = None,
date_begin: Optional[datetime] = None,
date_end: Optional[datetime] = None,
decimal_character: Optional[Literal[",", "."]] = None,
export_blank_for_gray_form_status: Optional[bool] = None,
df_kwargs: Optional[Dict[str, Any]] = None,
):
# pylint: disable=line-too-long
r"""
Export data from the REDCap project.
Args:
format_type:
Format of returned data. `'json'` returns json-decoded
objects while `'csv'` and `'xml'` return other formats.
`'df'` will attempt to return a `pandas.DataFrame`
records:
Array of record names specifying specific records to export.
By default, all records are exported
fields:
Single field name or array of field names specifying specific
fields to pull.
By default, all fields are exported
forms:
Single form name or array of form names to export. If in the
web UI, the form name has a space in it, replace the space
with an underscore.
By default, all forms are exported
events:
An array of unique event names from which to export records
Note:
This only applies to longitudinal projects
raw_or_label:
Export the raw coded values or labels for the options of
multiple choice fields, or both
raw_or_label_headers:
Export the column names of the instrument as their raw
value or their labeled value
event_name:
Export the unique event name or the event label
record_type:
Database output structure type
export_survey_fields:
Specifies whether or not to export the survey identifier
field (e.g., "redcap_survey_identifier") or survey timestamp
fields (e.g., form_name+"_timestamp") when surveys are
utilized in the project
export_data_access_groups:
Specifies whether or not to export the
`"redcap_data_access_group"` field when data access groups
are utilized in the project
Note:
This flag is only viable if the user whose token is
being used to make the API request is *not* in a data
access group. If the user is in a group, then this flag
will revert to its default value.
export_checkbox_labels:
Specify whether to export checkbox values as their label on
export.
filter_logic:
Filter which records are returned using REDCap conditional syntax
date_begin:
Filter on records created after a date
date_end:
Filter on records created before a date
decimal_character:
Force all numbers into same decimal format
export_blank_for_gray_form_status:
Whether or not to export blank values for instrument complete status fields
that have a gray status icon
df_kwargs:
Passed to `pandas.read_csv` to control construction of
returned DataFrame.
By default, `{'index_col': self.def_field}`
Returns:
Union[List[Dict[str, Any]], str, pd.DataFrame]: Exported data
Examples:
>>> proj.export_records()
[{'record_id': '1', 'redcap_event_name': 'event_1_arm_1', 'redcap_repeat_instrument': '',
'redcap_repeat_instance': 1, 'field_1': '1',
'checkbox_field___1': '0', 'checkbox_field___2': '1', 'upload_field': 'test_upload.txt',
'form_1_complete': '2'},
{'record_id': '2', 'redcap_event_name': 'event_1_arm_1', 'redcap_repeat_instrument': '',
'redcap_repeat_instance': 1, 'field_1': '0',
'checkbox_field___1': '0', 'checkbox_field___2': '0', 'upload_field': 'myupload.txt',
'form_1_complete': '0'}]
>>> proj.export_records(filter_logic="[field_1] = 1")
[{'record_id': '1', 'redcap_event_name': 'event_1_arm_1', 'redcap_repeat_instrument': '',
'redcap_repeat_instance': 1, 'field_1': '1',
'checkbox_field___1': '0', 'checkbox_field___2': '1', 'upload_field': 'test_upload.txt',
'form_1_complete': '2'}]
>>> proj.export_records(
... format_type="csv",
... fields=["field_1", "checkbox_field"],
... raw_or_label="label"
... )
'record_id,redcap_event_name,redcap_repeat_instrument,redcap_repeat_instance,field_1,checkbox_field___1,checkbox_field___2\n1,"Event 1",,1,Yes,Unchecked,Checked\n2,"Event 1",,1,No,Unchecked,Unchecked\n'
>>> import pandas as pd
>>> pd.set_option("display.max_columns", 3)
>>> proj.export_records(format_type="df")
redcap_repeat_instrument ... form_1_complete
record_id redcap_event_name ...
1 event_1_arm_1 NaN ... 2
2 event_1_arm_1 NaN ... 0
...
"""
# pylint: enable=line-too-long
payload: Dict[str, Any] = self._initialize_payload(
content="record", format_type=format_type, record_type=record_type
)
if isinstance(fields, str):
fields = [fields]
if isinstance(forms, str):
forms = [forms]
fields = self._backfill_fields(fields, forms)
keys_to_add = (
records,
fields,
forms,
events,
raw_or_label,
raw_or_label_headers,
event_name,
export_survey_fields,
export_data_access_groups,
export_checkbox_labels,
filter_logic,
decimal_character,
export_blank_for_gray_form_status,
)
str_keys = (
"records",
"fields",
"forms",
"events",
"rawOrLabel",
"rawOrLabelHeaders",
"eventName",
"exportSurveyFields",
"exportDataAccessGroups",
"exportCheckboxLabel",
"filterLogic",
"decimalCharacter",
"exportBlankForGrayFormStatus",
)
for key, data in zip(str_keys, keys_to_add):
if data:
if key in ("fields", "records", "forms", "events"):
data = cast(List[str], data)
for i, value in enumerate(data):
payload[f"{ key }[{ i }]"] = value
else:
payload[key] = data
if date_begin:
payload["dateRangeBegin"] = date_begin.strftime("%Y-%m-%d %H:%M:%S")
if date_end:
payload["dateRangeEnd"] = date_end.strftime("%Y-%m-%d %H:%M:%S")
return_type = self._lookup_return_type(format_type, request_type="export")
response = cast(Union[Json, str], self._call_api(payload, return_type))
return self._return_data(
response=response,
content="record",
format_type=format_type,
df_kwargs=df_kwargs,
record_type=record_type,
)
generate_next_record_name(self)
Get the next record name
Returns:
Type | Description |
---|---|
str |
The next record name for a project with auto-numbering records enabled |
Examples:
Source code in redcap/methods/records.py
def generate_next_record_name(self) -> str:
"""
Get the next record name
Returns:
The next record name for a project with auto-numbering records enabled
Examples:
>>> proj.generate_next_record_name()
'3'
"""
# Force the csv format here since if the project uses data access groups
# or just non-standard record names then the result will not be JSON-compliant
payload = self._initialize_payload(
content="generateNextRecordName", format_type="csv"
)
return cast(str, self._call_api(payload, return_type="str"))
import_records(self, to_import, return_format_type='json', return_content='count', overwrite='normal', import_format='json', date_format='YMD', force_auto_number=False)
Import data into the REDCap Project
Parameters:
Name | Type | Description | Default |
---|---|---|---|
to_import |
Union[str, List[Dict[str, Any]], pd.DataFrame] |
Note:
If you pass a df, csv, or xml string, you should use the
|
required |
return_format_type |
Literal['json', 'csv', 'xml'] |
Response format. By default, response will be json-decoded. |
'json' |
return_content |
Literal['count', 'ids', 'auto_ids', 'nothing'] |
By default, the response contains a 'count' key with the number of records just imported. By specifying 'ids', a list of ids imported will be returned. 'nothing' will only return the HTTP status code and no message. |
'count' |
overwrite |
Literal['normal', 'overwrite'] |
|
'normal' |
import_format |
Literal['json', 'csv', 'xml', 'df'] |
Format of incoming data. By default, to_import will be json-encoded |
'json' |
date_format |
Literal['YMD', 'DMY', 'MDY'] |
Describes the formatting of dates. By default, date strings are formatted as 'YYYY-MM-DD' corresponding to 'YMD'. If date strings are formatted as 'MM/DD/YYYY' set this parameter as 'MDY' and if formatted as 'DD/MM/YYYY' set as 'DMY'. No other formattings are allowed. |
'YMD' |
force_auto_number |
bool |
Enables automatic assignment of record IDs 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. |
False |
Exceptions:
Type | Description |
---|---|
RedcapError |
Bad request made, double check field names and other inputs |
Returns:
Type | Description |
---|---|
Union[Dict, str] |
response from REDCap API, json-decoded if |
Examples:
>>> new_record = [{"record_id": 3, "redcap_repeat_instance": 1, "field_1": 1}]
>>> proj.import_records(new_record)
{'count': 1}
Source code in redcap/methods/records.py
def import_records(
self,
to_import: Union[str, List[Dict[str, Any]], "pd.DataFrame"],
return_format_type: Literal["json", "csv", "xml"] = "json",
return_content: Literal["count", "ids", "auto_ids", "nothing"] = "count",
overwrite: Literal["normal", "overwrite"] = "normal",
import_format: Literal["json", "csv", "xml", "df"] = "json",
date_format: Literal["YMD", "DMY", "MDY"] = "YMD",
force_auto_number: bool = False,
):
"""
Import data into the REDCap Project
Args:
to_import:
Note:
If you pass a df, csv, or xml string, you should use the
`import_format` parameter appropriately.
Note:
Keys of the dictionaries should be subset of project's,
fields, but this isn't a requirement. If you provide keys
that aren't defined fields, the returned response will
contain an `'error'` key.
return_format_type:
Response format. By default, response will be json-decoded.
return_content:
By default, the response contains a 'count' key with the number of
records just imported. By specifying 'ids', a list of ids
imported will be returned. 'nothing' will only return
the HTTP status code and no message.
overwrite:
`'overwrite'` will erase values previously stored in the
database if not specified in the to_import dictionaries.
import_format:
Format of incoming data. By default, to_import will be json-encoded
date_format:
Describes the formatting of dates. By default, date strings
are formatted as 'YYYY-MM-DD' corresponding to 'YMD'. If date
strings are formatted as 'MM/DD/YYYY' set this parameter as
'MDY' and if formatted as 'DD/MM/YYYY' set as 'DMY'. No
other formattings are allowed.
force_auto_number:
Enables automatic assignment of record IDs
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.
Raises:
RedcapError: Bad request made, double check field names and other inputs
Returns:
Union[Dict, str]: response from REDCap API, json-decoded if `return_format` == `'json'`
Examples:
>>> new_record = [{"record_id": 3, "redcap_repeat_instance": 1, "field_1": 1}]
>>> proj.import_records(new_record)
{'count': 1}
"""
payload = self._initialize_import_payload(
to_import=to_import,
import_format=import_format,
return_format_type=return_format_type,
content="record",
)
payload["overwriteBehavior"] = overwrite
payload["returnContent"] = return_content
payload["dateFormat"] = date_format
payload["forceAutoNumber"] = force_auto_number
return_type = self._lookup_return_type(
format_type=return_format_type,
request_type="import",
import_records_format=return_content,
)
response = cast(Union[Json, str], self._call_api(payload, return_type))
return response