Skip to content
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
2 changes: 1 addition & 1 deletion .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ ignore=docs

[DESIGN]
# Our Base class needs a few more attributes than the default allows
max-attributes=8
max-attributes=9

[MESSAGES CONTROL]

Expand Down
36 changes: 34 additions & 2 deletions redcap/methods/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,22 @@
class Base:
"""Base attributes and methods for the REDCap API"""

def __init__(self, url: str, token: str, verify_ssl: Union[bool, str] = True):
def __init__(
self,
url: str,
token: str,
verify_ssl: Union[bool, str] = True,
**request_kwargs,
):
"""Initialize a Project, validate url and token"""
self._validate_url_and_token(url, token)
self._url = url
self._token = token
self.verify_ssl = verify_ssl

self._validate_request_kwargs(**request_kwargs)
self._request_kwargs = request_kwargs

# attributes which require API calls
self._metadata = None
self._forms = None
Expand Down Expand Up @@ -137,6 +147,25 @@ def _validate_url_and_token(url: str, token: str) -> None:
f"{ expected_token_len } characters long",
)

@staticmethod
def _validate_request_kwargs(**request_kwargs):
"""Run basic validation on user supplied kwargs for requests"""
# list of kwargs hardcoded in _RCRequest.execute(...) and self._call_api(...)
hardcoded_kwargs = [
"url",
"data",
"verify, verify_ssl",
"return_headers",
"files",
"file",
]
unallowed_kwargs = [
kwarg for kwarg in request_kwargs if kwarg in hardcoded_kwargs
]
assert (
len(unallowed_kwargs) == 0
), f"Not allowed to define {unallowed_kwargs} when initiating object"

# pylint: disable=import-outside-toplevel
@staticmethod
def _read_csv(buf: StringIO, **df_kwargs) -> "pd.DataFrame":
Expand Down Expand Up @@ -513,5 +542,8 @@ def _call_api(

rcr = _RCRequest(url=self.url, payload=payload, config=config)
return rcr.execute(
verify_ssl=self.verify_ssl, return_headers=return_headers, file=file
verify_ssl=self.verify_ssl,
return_headers=return_headers,
file=file,
**self._request_kwargs,
)
7 changes: 6 additions & 1 deletion redcap/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ def execute(
verify_ssl: Union[bool, str],
return_headers: Literal[True],
file: Optional[FileUpload],
**kwargs,
) -> Tuple[Union[Json, str, bytes], dict]:
...

Expand All @@ -170,6 +171,7 @@ def execute(
verify_ssl: Union[bool, str],
return_headers: Literal[False],
file: Optional[FileUpload],
**kwargs,
) -> Union[List[Dict[str, Any]], str, bytes]:
...

Expand All @@ -178,6 +180,7 @@ def execute(
verify_ssl: Union[bool, str],
return_headers: bool,
file: Optional[FileUpload],
**kwargs,
):
"""Execute the API request and return data

Expand All @@ -187,6 +190,8 @@ def execute(
Whether or not response headers should be returned along
with the request content
file: A file object to send along with the request
**kwargs: passed to requesets.request() to control
the configuration to perform requests to the api

Returns:
Data object from JSON decoding process if format=='json',
Expand All @@ -198,7 +203,7 @@ def execute(
exist, field doesn't exist, etc.
"""
response = self.session.post(
self.url, data=self.payload, verify=verify_ssl, files=file
self.url, data=self.payload, verify=verify_ssl, files=file, **kwargs
)

content = self.get_content(
Expand Down