Skip to content

Commit

Permalink
Merge pull request #38 from bcbi/dev
Browse files Browse the repository at this point in the history
data parameter accepts file handles
  • Loading branch information
AshlinHarris authored Sep 2, 2024
2 parents 78c03b0 + 4ef1034 commit a6bfb23
Show file tree
Hide file tree
Showing 25 changed files with 246 additions and 1,117 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "REDCap"
uuid = "ba918724-fbf9-5e4a-a61c-87e95654e718"
authors = ["Cory Cothrum", "Dilum Aluthge <dilum@aluthge.com>", "Ashlin Harris <ashlin_harris@brown.edu>"]
version = "2.2.2"
version = "2.3.0"

[deps]
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
Expand Down
32 changes: 16 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,17 @@ export_logging(token=project_token)

## Syntax
Each REDCap method accepts a number of parameters that follow a shared naming convention.
Generally, a parameter of a given name shares a similar role in all methods where it can be used.
Parameters can hold various datatypes and might even be composed of multiple named attributes.

REDCap.jl is designed to closely follow the design and syntax patterns of REDCap.
Every REDCap API method is available as a function that supplies certain required parameters and checks user inputs for validity.

Return values and REDCap messages are returned as Strings directly, but the documentation shows how these can be parsed in useful ways.

Function arguments are named after REDCap method parameters.
These are passed as named arguments and take values with intuitive types, with a few exceptions to note:
These are passed as named arguments and take values with intuitive types.

### `token` and `url`
Nearly all REDCap methods accept a token that is unique to the project and user.

### Token and URL
Almost all REDCap methods accept a token that is unique to the project and user.
A super token can be used to generate a project and project-level token.
The URL must exactly match this example:
```https://example.example/redcap/api/```

Expand All @@ -44,13 +42,15 @@ You can make them avaiable to REDCap.jl by putting the following lines in [your
ENV["REDCAP_API_TOKEN"] = "C0FFEEC0AC0AC0DEC0FFEEC0AC0AC0DE"
ENV["REDCAP_API_URL"] = "http://example.com/redcap/api/"
```
They can also be passed as ordinary arguments.
They can also be passed as ordinary named arguments.

A few methods accept a super token, including `create_project`, which can be used to generate a project and project-level token.
If you have a super token, you might wish to keep that in your startup file, generating and saving project-level tokens as needed.

### `data`
The `data` parameter accepts a collection (Dict, NamedTuple, etc.) or a String.
If you use a a collection, it will be translated internally into whatever `format` you use (xml by default).
A NamedTuple is the most elegant format:
The `data` parameter contains a list of attributes.
In REDCap.jl, this can be a NamedTuple (or any derived type), a file handle, or a String.
If you use a NamedTuple, it will be translated internally into whatever `format` you use (xml by default).
```julia
import_project_info(
data=(
Expand All @@ -60,7 +60,7 @@ import_project_info(
returnFormat=:csv,
)
```
But please keep in mind that a NamedTuple must contain at least one comma:
But please keep in mind that a NamedTuple with one value must contain a comma:
```julia
import_project_info(
data=(
Expand All @@ -73,7 +73,7 @@ A `Dict` value is fine as well.
```julia
import_project_info(data=Dict(:project_title=>"New name"), returnFormat=:csv)
```
String values are accepted. If the string is a file name, the contents of the file are sent; otherwise, it is sent directly as part of the API request.
String values are accepted. If the string is a file name, the contents of the file are sent; otherwise, the value is sent directly as part of the API request.
```julia
data_string = """
[{"data_access_group_name":"CA Site","unique_group_name":"ca_site"},
Expand Down Expand Up @@ -102,14 +102,14 @@ Generally, the `format` parameter designates user input and the `returnFormat` p
However, this is not consistent within REDCap.
REDCap.jl functions are designed to not accept any parameters that have no effect on the result.

## `content` and `action`
### `content` and `action`
The `content` and `action` parameters are what define each REDCap method, for the most part.
In REDCap.jl, these are passed internally and don't need to be supplied by the user.
Instead, they're fixed for each function.

### Troubleshooting

## Troubleshooting
If a function call doesn't produce the expected results, try making debug messages visible for this package by running `ENV["JULIA_DEBUG"] = REDCap`.
The data parameter is converted to a formatted string, so you might try different format parameters (`:csv`, `:json`, or `:xml`).
Feel free to create an issue for any unexpected errors, or for feature requests.

## Acknowledgments
Expand Down
1 change: 1 addition & 0 deletions src/REDCap.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ using URIs

include("types.jl")

include("export.jl")
include("request.jl")
include("utils.jl")
include("api_methods/arms.jl")
Expand Down
79 changes: 7 additions & 72 deletions src/api_methods/arms.jl
Original file line number Diff line number Diff line change
@@ -1,89 +1,24 @@
export delete_arms,
export_arms,
import_arms

function delete_arms(;
url::redcap_url_input=get_url(),
token::redcap_token_input=get_token(),
arms=nothing,
)

function delete_arms(; url=get_url(), token=get_token(), arms=nothing,)
REDCap.request(;
url=REDCap_url(url),
token=REDCap_token(token),
content=REDCap_content(:arm),
action=REDCap_action(:import),
arms=arms,
kwargs = (;token=REDCap_token(token), content=:arm, action=:import, arms,),
)
end

function export_arms(;
url::redcap_url_input=get_url(),
token::redcap_token_input=get_token(),
format::redcap_format_input=nothing,
returnFormat::redcap_returnFormat_input=nothing,
arms=nothing,
)

function export_arms(; url=get_url(), token=get_token(), format=nothing, returnFormat=nothing, arms=nothing,)
REDCap.request(;
url=REDCap_url(url),
token=REDCap_token(token),
content=REDCap_content(:arm),
format=REDCap_format(format),
arms=arms,
returnFormat=REDCap_format(returnFormat),
kwargs = (; token=REDCap_token(token), content=:arm, format=REDCap_format(format), arms, returnFormat=REDCap_format(returnFormat),),
)
end

#All examples use JSON
#TODO: what is the proper format for multi-item XML? I can't find this anywhere...
function import_arms(;
url::redcap_url_input=get_url(),
token::redcap_token_input=get_token(),
format::redcap_format_input=nothing,
data::redcap_data_input=nothing, #TODO: is this required, given the action parameter?
returnFormat::redcap_returnFormat_input=nothing,
override=0,
)

# #TODO: is this ata paratamet required, given the action parameter?
function import_arms(; url=get_url(), token=get_token(), format=nothing, data=nothing, returnFormat=nothing, override=0,)
REDCap.request(;
url=REDCap_url(url),
token=REDCap_token(token),
content=REDCap_content(:arm),
override=override,
action=REDCap_action(:import),
format=REDCap_format(format),
data=REDCap_data(data,REDCap_format(format),xml_tag="arms"),
returnFormat=REDCap_format(returnFormat),
kwargs = (; token=REDCap_token(token), content=:arm, override, action=:import, format=REDCap_format(format), returnFormat=REDCap_format(returnFormat),),
)
end

#=
julia> arms = export_arms()
POSTing
POSTd
1-element Array{Any,1}:
Dict{String,Any}(Pair{String,Any}("name", "Arm 1"),Pair{String,Any}("arm_num", 1))
julia> newarm
Dict{String,Any} with 2 entries:
"name" => "Arm 1"
"arm_num" => 1
julia> push!(arms, newarm)
2-element Array{Any,1}:
Dict{String,Any}(Pair{String,Any}("name", "Arm 1"),Pair{String,Any}("arm_num", "1"))
Dict{String,Any}(Pair{String,Any}("name", "Arm 2"),Pair{String,Any}("arm_num", "2"))
julia> import_arms(arms)
POSTing
POSTd
2 <- this should indicate 2 arms added.
julia> export_arms()
POSTing
POSTd
1-element Array{Any,1}:
Dict{String,Any}(Pair{String,Any}("name", "Arm 1"),Pair{String,Any}("arm_num", 1))
=#
84 changes: 15 additions & 69 deletions src/api_methods/data_access_groups.jl
Original file line number Diff line number Diff line change
@@ -1,101 +1,47 @@
export delete_DAGs,
export_DAGs,
export_user_DAG_assignment,
import_DAGs,
import_user_DAG_assignment,
switch_DAG

function delete_DAGs(;
url::redcap_url_input=get_url(),
token::redcap_token_input=get_token(),
dags=nothing)

function delete_DAGs(; url=get_url(), token=get_token(), dags=nothing)
REDCap.request(;
url=REDCap_url(url),
token=REDCap_token(token),
content=REDCap_content(:dag),
action=REDCap_action(:delete),
dags=dags,
kwargs = (; token=REDCap_token(token), content=:dag, action=:delete, dags,),
)
end

function export_DAGs(;
url::redcap_url_input=get_url(),
token::redcap_token_input=get_token(),
format::redcap_format_input=nothing,
#TODO: This is one of those ones that only take a format parameter
)

#TODO: only accepts format, not returnFormat
function export_DAGs(; url=get_url(), token=get_token(), format=nothing,)
REDCap.request(;
url=REDCap_url(url),
token=REDCap_token(token),
content=REDCap_content(:dag),
format=REDCap_format(format),
#returnFormat=REDCap_format(returnFormat),
kwargs = (; token=REDCap_token(token), content=:dag, format=REDCap_format(format),),
)
end

function export_user_DAG_assignment(;
url::redcap_url_input=get_url(),
token::redcap_token_input=get_token(),
format::redcap_format_input=nothing,
)

function export_user_DAG_assignment(; url=get_url(), token=get_token(), format=nothing,)
REDCap.request(;
url=REDCap_url(url),
token=REDCap_token(token),
content=REDCap_content(:userDagMapping),
format=REDCap_format(format),
kwargs = (; token=REDCap_token(token), content=:userDagMapping, format=REDCap_format(format),),
)
end

function import_DAGs(;
url::redcap_url_input=get_url(),
token::redcap_token_input=get_token(),
data::redcap_data_input=nothing, # TODO: required?
format::redcap_format_input=nothing,
returnFormat::redcap_returnFormat_input=nothing,
)

#TODO: data require here?
function import_DAGs(; url=get_url(), token=get_token(), data=nothing, format=nothing, returnFormat=nothing,)
REDCap.request(;
url=REDCap_url(url),
token=REDCap_token(token),
content=REDCap_content(:dag),
action=REDCap_action(:import),
format=REDCap_format(format),
data=REDCap_data(data,REDCap_format(format),xml_tag="dags"),
returnFormat=REDCap_format(returnFormat),
kwargs = (; token=REDCap_token(token), content=:dag, action=:import, format=REDCap_format(format), returnFormat=REDCap_format(returnFormat),),
)
end

function import_user_DAG_assignment(;
url::redcap_url_input=get_url(),
token::redcap_token_input=get_token(),
data::redcap_data_input=nothing, # TODO: required?
format::redcap_format_input=nothing,
returnFormat::redcap_returnFormat_input=nothing,
)

#TODO: data require here?
function import_user_DAG_assignment(; url=get_url(), token=get_token(), data=nothing, format=nothing, returnFormat=nothing,)
REDCap.request(;
url=REDCap_url(url),
token=REDCap_token(token),
content=REDCap_content(:userDagMapping),
format=REDCap_format(format),
data=REDCap_data(data,REDCap_format(format),xml_tag="items"),
returnFormat=REDCap_format(returnFormat),
kwargs = (; token=REDCap_token(token), content=:userDagMapping, format=REDCap_format(format), returnFormat=REDCap_format(returnFormat),),
)
end

function switch_DAG(;
data::redcap_data_input,
url::redcap_url_input=get_url(),
dag=nothing)
function switch_DAG(; data, url=get_url(), dag=nothing)
REDCap.request(;
url=REDCap_url(url),
token=REDCap_token(token),
content=REDCap_content(:dag),
action=REDCap_action(:switch),
dag=dag,
kwargs = (; token=REDCap_token(token), content=:dag, action=:switch, dag,),
)
end

Expand Down
47 changes: 7 additions & 40 deletions src/api_methods/events.jl
Original file line number Diff line number Diff line change
@@ -1,58 +1,25 @@
export delete_events,
import_events,
export_events

function delete_events(;
url::redcap_url_input=get_url(),
token::redcap_token_input=get_token(),
events=nothing,
)

function delete_events(; url=get_url(), token=get_token(), events=nothing,)
REDCap.request(;
url=REDCap_url(url),
token=REDCap_token(token),
content=REDCap_content(:event),
action=REDCap_action(:import),
events=events,
kwargs = (; token=REDCap_token(token), content=:event, action=:import, events,),
)
end

function export_events(;
url::redcap_url_input=get_url(),
token::redcap_token_input=get_token(),
format::redcap_format_input=nothing,
returnFormat::redcap_returnFormat_input=nothing,
arms=nothing,
)
function export_events(; url=get_url(), token=get_token(), format=nothing, returnFormat=nothing, arms=nothing,)

REDCap.request(;
url=REDCap_url(url),
token=REDCap_token(token),
format=REDCap_format(format),
returnFormat=REDCap_format(returnFormat),
content=REDCap_content(:event),
arms=arms,
kwargs = (; token=REDCap_token(token), format=REDCap_format(format), returnFormat=REDCap_format(returnFormat), content=:event, arms,),
)
end

function import_events(;
url::redcap_url_input=get_url(),
token::redcap_token_input=get_token(),
format::redcap_format_input=nothing,
returnFormat::redcap_returnFormat_input=nothing,
data=nothing, #TODO: required?
override=0,
)
#TODO: data parameter required?
function import_events(; url=get_url(), token=get_token(), format=nothing, returnFormat=nothing, data=nothing, override=0,)

REDCap.request(;
url=REDCap_url(url),
token=REDCap_token(token),
format=REDCap_format(format),
returnFormat=REDCap_format(returnFormat),
content=REDCap_content(:event),
action=REDCap_action(:import),
override=override,
data=REDCap_data(data,REDCap_format(format),xml_tag="events"),
kwargs = (; token=REDCap_token(token), format=REDCap_format(format), returnFormat=REDCap_format(returnFormat), content=:event, action=:import, override,),
)
end

Loading

0 comments on commit a6bfb23

Please sign in to comment.