Skip to content

Files

REDCap API methods for Project files

Files (Base)

Responsible for all API methods under 'Files' in the API Playground

Source code in redcap/methods/files.py
class Files(Base):
    """Responsible for all API methods under 'Files' in the API Playground"""

    def _check_file_field(self, field: str) -> None:
        """Check that field exists and is a file field"""
        # Since we initialize self.field_names as None, pylint worries that this will
        # produce an error
        # pylint: disable=unsupported-membership-test
        is_field = field in self.field_names
        # pylint: enable=unsupported-membership-test
        is_file = self._filter_metadata(key="field_type", field_name=field) == "file"
        if not (is_field and is_file):
            msg = f"'{ field }' is not a field or not a 'file' field"
            raise ValueError(msg)

    def export_file(
        self,
        record: str,
        field: str,
        event: Optional[str] = None,
        repeat_instance: Optional[int] = None,
    ) -> FileMap:
        """
        Export the contents of a file stored for a particular record

        Note:
            Unlike other export methods, this only works on a single record.

        Args:
            record: Record ID
            field: Field name containing the file to be exported.
            event: For longitudinal projects, the unique event name
            repeat_instance:
                (Only for projects with repeating instruments/events)
                The repeat instance number of the repeating event (if longitudinal)
                or the repeating instrument (if classic or longitudinal).

        Returns:
            Content of the file and content-type dictionary

        Raises:
            ValueError: Incorrect file field
            RedcapError: Bad Request e.g. invalid record_id

        Examples:
            If your project has events, then you must specifiy the event of interest.
            Otherwise, you can leave the event parameter blank

            >>> proj.export_file(record="1", field="upload_field", event="event_1_arm_1")
            (b'test upload\\n', {'name': 'test_upload.txt', 'charset': 'UTF-8'})
        """
        self._check_file_field(field)
        # load up payload
        payload = self._initialize_payload(content="file")
        # there's no format field in this call
        payload["action"] = "export"
        payload["field"] = field
        payload["record"] = record
        if event:
            payload["event"] = event
        if repeat_instance:
            payload["repeat_instance"] = str(repeat_instance)
        content, headers = cast(
            FileMap, self._call_api(payload=payload, return_type="file_map")
        )
        # REDCap adds some useful things in content-type
        content_map = {}
        if "content-type" in headers:
            splat = [
                key_values.strip() for key_values in headers["content-type"].split(";")
            ]
            key_values = [
                (key_values.split("=")[0], key_values.split("=")[1].replace('"', ""))
                for key_values in splat
                if "=" in key_values
            ]
            content_map = dict(key_values)

        return content, content_map

    def import_file(
        self,
        record: str,
        field: str,
        file_name: str,
        file_object: "TextIOWrapper",
        event: Optional[str] = None,
        repeat_instance: Optional[Union[int, str]] = None,
    ) -> EmptyJson:
        """
        Import the contents of a file represented by file_object to a
        particular records field

        Args:
            record: Record ID
            field: Field name where the file will go
            file_name: File name visible in REDCap UI
            file_object: File object as returned by `open`
            event: For longitudinal projects, the unique event name
            repeat_instance:
                (Only for projects with repeating instruments/events)
                The repeat instance number of the repeating event (if longitudinal)
                or the repeating instrument (if classic or longitudinal).

        Returns:
            Empty JSON object

        Raises:
            ValueError: Incorrect file field
            RedcapError: Bad Request e.g. invalid record_id

        Examples:
            If your project has events, then you must specifiy the event of interest.
            Otherwise, you can leave the event parameter blank

            >>> import tempfile
            >>> tmp_file = tempfile.TemporaryFile()
            >>> proj.import_file(
            ...     record="2",
            ...     field="upload_field",
            ...     file_name="myupload.txt",
            ...     file_object=tmp_file,
            ...     event="event_1_arm_1",
            ... )
            [{}]
        """
        self._check_file_field(field)
        # load up payload
        payload: Dict[str, Any] = self._initialize_payload(content="file")
        payload["action"] = "import"
        payload["field"] = field
        payload["record"] = record
        if event:
            payload["event"] = event
        if repeat_instance:
            payload["repeat_instance"] = repeat_instance
        file_upload_dict: FileUpload = {"file": (file_name, file_object)}

        return cast(
            EmptyJson,
            self._call_api(
                payload=payload, return_type="empty_json", file=file_upload_dict
            ),
        )

    def delete_file(
        self,
        record: str,
        field: str,
        event: Optional[str] = None,
    ) -> EmptyJson:
        """
        Delete a file from REDCap

        Note:
            There is no undo button to this.

        Args:
            record: Record ID
            field: Field name
            event: For longitudinal projects, the unique event name

        Returns:
            Empty JSON object

        Raises:
            ValueError: Incorrect file field
            RedcapError: Bad Request e.g. invalid record_id

        Examples:
            Import a tempfile and then delete it

            >>> import tempfile
            >>> tmp_file = tempfile.TemporaryFile()
            >>> proj.import_file(
            ...     record="2",
            ...     field="upload_field",
            ...     file_name="myupload.txt",
            ...     file_object=tmp_file,
            ...     event="event_1_arm_1",
            ... )
            [{}]
            >>> proj.delete_file(record="2", field="upload_field", event="event_1_arm_1")
            [{}]
        """
        self._check_file_field(field)
        # Load up payload
        payload = self._initialize_payload(content="file")
        payload["action"] = "delete"
        payload["record"] = record
        payload["field"] = field
        if event:
            payload["event"] = event

        return cast(
            EmptyJson, self._call_api(payload=payload, return_type="empty_json")
        )

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_file(self, record, field, event=None)

Delete a file from REDCap

!!! note There is no undo button to this.

Parameters:

Name Type Description Default
record str

Record ID

required
field str

Field name

required
event Optional[str]

For longitudinal projects, the unique event name

None

Returns:

Type Description
List[dict]

Empty JSON object

Exceptions:

Type Description
ValueError

Incorrect file field

RedcapError

Bad Request e.g. invalid record_id

Examples:

Import a tempfile and then delete it

>>> import tempfile
>>> tmp_file = tempfile.TemporaryFile()
>>> proj.import_file(
...     record="2",
...     field="upload_field",
...     file_name="myupload.txt",
...     file_object=tmp_file,
...     event="event_1_arm_1",
... )
[{}]
>>> proj.delete_file(record="2", field="upload_field", event="event_1_arm_1")
[{}]
Source code in redcap/methods/files.py
def delete_file(
    self,
    record: str,
    field: str,
    event: Optional[str] = None,
) -> EmptyJson:
    """
    Delete a file from REDCap

    Note:
        There is no undo button to this.

    Args:
        record: Record ID
        field: Field name
        event: For longitudinal projects, the unique event name

    Returns:
        Empty JSON object

    Raises:
        ValueError: Incorrect file field
        RedcapError: Bad Request e.g. invalid record_id

    Examples:
        Import a tempfile and then delete it

        >>> import tempfile
        >>> tmp_file = tempfile.TemporaryFile()
        >>> proj.import_file(
        ...     record="2",
        ...     field="upload_field",
        ...     file_name="myupload.txt",
        ...     file_object=tmp_file,
        ...     event="event_1_arm_1",
        ... )
        [{}]
        >>> proj.delete_file(record="2", field="upload_field", event="event_1_arm_1")
        [{}]
    """
    self._check_file_field(field)
    # Load up payload
    payload = self._initialize_payload(content="file")
    payload["action"] = "delete"
    payload["record"] = record
    payload["field"] = field
    if event:
        payload["event"] = event

    return cast(
        EmptyJson, self._call_api(payload=payload, return_type="empty_json")
    )

export_file(self, record, field, event=None, repeat_instance=None)

Export the contents of a file stored for a particular record

!!! note Unlike other export methods, this only works on a single record.

Parameters:

Name Type Description Default
record str

Record ID

required
field str

Field name containing the file to be exported.

required
event Optional[str]

For longitudinal projects, the unique event name

None
repeat_instance Optional[int]

(Only for projects with repeating instruments/events) The repeat instance number of the repeating event (if longitudinal) or the repeating instrument (if classic or longitudinal).

None

Returns:

Type Description
Tuple[bytes, dict]

Content of the file and content-type dictionary

Exceptions:

Type Description
ValueError

Incorrect file field

RedcapError

Bad Request e.g. invalid record_id

Examples:

If your project has events, then you must specifiy the event of interest. Otherwise, you can leave the event parameter blank

>>> proj.export_file(record="1", field="upload_field", event="event_1_arm_1")
(b'test upload\n', {'name': 'test_upload.txt', 'charset': 'UTF-8'})
Source code in redcap/methods/files.py
def export_file(
    self,
    record: str,
    field: str,
    event: Optional[str] = None,
    repeat_instance: Optional[int] = None,
) -> FileMap:
    """
    Export the contents of a file stored for a particular record

    Note:
        Unlike other export methods, this only works on a single record.

    Args:
        record: Record ID
        field: Field name containing the file to be exported.
        event: For longitudinal projects, the unique event name
        repeat_instance:
            (Only for projects with repeating instruments/events)
            The repeat instance number of the repeating event (if longitudinal)
            or the repeating instrument (if classic or longitudinal).

    Returns:
        Content of the file and content-type dictionary

    Raises:
        ValueError: Incorrect file field
        RedcapError: Bad Request e.g. invalid record_id

    Examples:
        If your project has events, then you must specifiy the event of interest.
        Otherwise, you can leave the event parameter blank

        >>> proj.export_file(record="1", field="upload_field", event="event_1_arm_1")
        (b'test upload\\n', {'name': 'test_upload.txt', 'charset': 'UTF-8'})
    """
    self._check_file_field(field)
    # load up payload
    payload = self._initialize_payload(content="file")
    # there's no format field in this call
    payload["action"] = "export"
    payload["field"] = field
    payload["record"] = record
    if event:
        payload["event"] = event
    if repeat_instance:
        payload["repeat_instance"] = str(repeat_instance)
    content, headers = cast(
        FileMap, self._call_api(payload=payload, return_type="file_map")
    )
    # REDCap adds some useful things in content-type
    content_map = {}
    if "content-type" in headers:
        splat = [
            key_values.strip() for key_values in headers["content-type"].split(";")
        ]
        key_values = [
            (key_values.split("=")[0], key_values.split("=")[1].replace('"', ""))
            for key_values in splat
            if "=" in key_values
        ]
        content_map = dict(key_values)

    return content, content_map

import_file(self, record, field, file_name, file_object, event=None, repeat_instance=None)

Import the contents of a file represented by file_object to a particular records field

Parameters:

Name Type Description Default
record str

Record ID

required
field str

Field name where the file will go

required
file_name str

File name visible in REDCap UI

required
file_object TextIOWrapper

File object as returned by open

required
event Optional[str]

For longitudinal projects, the unique event name

None
repeat_instance Union[int, str]

(Only for projects with repeating instruments/events) The repeat instance number of the repeating event (if longitudinal) or the repeating instrument (if classic or longitudinal).

None

Returns:

Type Description
List[dict]

Empty JSON object

Exceptions:

Type Description
ValueError

Incorrect file field

RedcapError

Bad Request e.g. invalid record_id

Examples:

If your project has events, then you must specifiy the event of interest. Otherwise, you can leave the event parameter blank

>>> import tempfile
>>> tmp_file = tempfile.TemporaryFile()
>>> proj.import_file(
...     record="2",
...     field="upload_field",
...     file_name="myupload.txt",
...     file_object=tmp_file,
...     event="event_1_arm_1",
... )
[{}]
Source code in redcap/methods/files.py
def import_file(
    self,
    record: str,
    field: str,
    file_name: str,
    file_object: "TextIOWrapper",
    event: Optional[str] = None,
    repeat_instance: Optional[Union[int, str]] = None,
) -> EmptyJson:
    """
    Import the contents of a file represented by file_object to a
    particular records field

    Args:
        record: Record ID
        field: Field name where the file will go
        file_name: File name visible in REDCap UI
        file_object: File object as returned by `open`
        event: For longitudinal projects, the unique event name
        repeat_instance:
            (Only for projects with repeating instruments/events)
            The repeat instance number of the repeating event (if longitudinal)
            or the repeating instrument (if classic or longitudinal).

    Returns:
        Empty JSON object

    Raises:
        ValueError: Incorrect file field
        RedcapError: Bad Request e.g. invalid record_id

    Examples:
        If your project has events, then you must specifiy the event of interest.
        Otherwise, you can leave the event parameter blank

        >>> import tempfile
        >>> tmp_file = tempfile.TemporaryFile()
        >>> proj.import_file(
        ...     record="2",
        ...     field="upload_field",
        ...     file_name="myupload.txt",
        ...     file_object=tmp_file,
        ...     event="event_1_arm_1",
        ... )
        [{}]
    """
    self._check_file_field(field)
    # load up payload
    payload: Dict[str, Any] = self._initialize_payload(content="file")
    payload["action"] = "import"
    payload["field"] = field
    payload["record"] = record
    if event:
        payload["event"] = event
    if repeat_instance:
        payload["repeat_instance"] = repeat_instance
    file_upload_dict: FileUpload = {"file": (file_name, file_object)}

    return cast(
        EmptyJson,
        self._call_api(
            payload=payload, return_type="empty_json", file=file_upload_dict
        ),
    )