Skip to content

Commit

Permalink
Update CDS retreival to new API
Browse files Browse the repository at this point in the history
  • Loading branch information
maxstb committed Jan 3, 2025
1 parent 4aafbdb commit ed3f211
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 36 deletions.
3 changes: 1 addition & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
name = "CDSAPI"
uuid = "8a7b9de3-9c00-473e-88b4-7eccd7ef2fea"
authors = ["Micky Yun Chan <[email protected]> and contributors"]
version = "1.0.1"
version = "2.0.0"

[deps]
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3"
JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"

Expand Down
36 changes: 18 additions & 18 deletions src/CDSAPI.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ module CDSAPI

using HTTP
using JSON
using Base64

"""
retrieve(name, params, filename; max_sleep = 120.)
Expand All @@ -14,45 +13,46 @@ directory as `filename`.
The client periodically requests the status of the retrieve request.
`max_sleep` is the maximum time (in seconds) between the status updates.
"""
function retrieve(name, params, filename; max_sleep = 120.)
function retrieve(name, params, filename; max_sleep=120.0)
creds = Dict()
open(joinpath(homedir(),".cdsapirc")) do f
open(joinpath(homedir(), ".cdsapirc")) do f
for line in readlines(f)
key, val = strip.(split(line,':', limit=2))
key, val = strip.(split(line, ':', limit=2))
creds[key] = val
end
end

apikey = string("Basic ", base64encode(creds["key"]))
response = HTTP.request(
"POST",
creds["url"] * "/resources/$name",
["Authorization" => apikey],
body=JSON.json(params),
creds["url"] * "/retrieve/v1/processes/$name/execute/",
["PRIVATE-TOKEN" => creds["key"]],
body=JSON.json(Dict("inputs" => params)),
verbose=1)

resp_dict = JSON.parse(String(response.body))
data = Dict("state" => "queued")
sleep_seconds = 1.
data = Dict("status" => "queued")
sleep_seconds = 1.0

while data["state"] != "completed"
data = HTTP.request("GET", creds["url"] * "/tasks/" * string(resp_dict["request_id"]), ["Authorization" => apikey])
while data["status"] != "successful"
data = HTTP.request("GET", creds["url"] * "/retrieve/v1/jobs/" * string(resp_dict["jobID"]), ["PRIVATE-TOKEN" => creds["key"]])
data = JSON.parse(String(data.body))
println("request queue status ", data["state"])
println("request queue status ", data["status"])

if data["state"] == "failed"
if data["status"] == "failed"
error("Request to dataset $name failed. Check " *
"https://cds.climate.copernicus.eu/cdsapp#!/yourrequests " *
"for more information (after login).")
end

sleep_seconds = min(1.5 * sleep_seconds,max_sleep)
if data["state"] != "completed"
sleep_seconds = min(1.5 * sleep_seconds, max_sleep)
if data["status"] != "successful"
sleep(sleep_seconds)
end
end

HTTP.download(data["location"], filename)
response = HTTP.request("GET", creds["url"] * "/retrieve/v1/jobs/" * string(resp_dict["jobID"]) * "/results/", ["PRIVATE-TOKEN" => creds["key"]])
body = JSON.parse(String(response.body))
HTTP.download(body["asset"]["value"]["href"], filename)
return data
end

Expand Down Expand Up @@ -88,7 +88,7 @@ function py2ju(dictstr)
# if there's no pair after the last comma
if findnext(":", dictstr_cpy, lastcomma_pos) == nothing
# remove the comma
dictstr_cpy = dictstr_cpy[firstindex(dictstr_cpy):(lastcomma_pos - 1)] * dictstr_cpy[(lastcomma_pos + 1):lastindex(dictstr_cpy)]
dictstr_cpy = dictstr_cpy[firstindex(dictstr_cpy):(lastcomma_pos-1)] * dictstr_cpy[(lastcomma_pos+1):lastindex(dictstr_cpy)]
end

# removes trailing comma from a list
Expand Down
18 changes: 9 additions & 9 deletions test/py2ju.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@testset "Py2Ju" begin
pydict_str = """{
'format': 'grib',
'data_format': 'grib',
'product_type': 'monthly_averaged_reanalysis',
'variable': 'divergence',
'pressure_level': '1',
Expand All @@ -12,14 +12,14 @@
],
'time': '00:00',
}"""
julia_dict = Dict("format"=> "grib",
"month" => "06",
"time" => "00:00",
"year" => "2020",
"pressure_level" => "1",
"area" => Any[90, -180, -90, 180],
"product_type" => "monthly_averaged_reanalysis",
"variable" => "divergence")
julia_dict = Dict("data_format" => "grib",
"month" => "06",
"time" => "00:00",
"year" => "2020",
"pressure_level" => "1",
"area" => Any[90, -180, -90, 180],
"product_type" => "monthly_averaged_reanalysis",
"variable" => "divergence")
py2ju_result = CDSAPI.py2ju(pydict_str)

@test typeof(py2ju_result) <: Dict
Expand Down
11 changes: 4 additions & 7 deletions test/retrieve.jl
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
@testset "Retrieve" begin
datadir = joinpath(@__DIR__,"data")
datadir = joinpath(@__DIR__, "data")

@testset "ERA5 monthly preasure data" begin
filepath = joinpath(datadir, "era5.grib")
response = CDSAPI.retrieve("reanalysis-era5-pressure-levels-monthly-means",
CDSAPI.py2ju("""{
'format': 'grib',
'data_format': 'grib',
'product_type': 'monthly_averaged_reanalysis',
'variable': 'divergence',
'pressure_level': '1',
Expand All @@ -20,7 +20,6 @@
filepath)

@test typeof(response) <: Dict
@test response["content_type"] == "application/x-grib"
@test isfile(filepath)

GribFile(filepath) do datafile
Expand All @@ -43,12 +42,11 @@
'emissions_scenario': 'rcp_2_6',
'period': '2071_2100',
'return_period': '100',
'format': 'zip',
'data_format': 'zip',
}"""),
filepath)

@test typeof(response) <: Dict
@test response["content_type"] == "application/zip"
@test isfile(filepath)

# extract contents
Expand Down Expand Up @@ -76,12 +74,11 @@
'time_aggregation': '1_year_average',
'vertical_level': '0_m',
'bias_correction': 'bias_adjustment_based_on_gamma_distribution',
'format': 'tgz',
'data_format': 'tgz',
}"""),
filepath)

@test typeof(response) <: Dict
@test response["content_type"] == "application/gzip"
@test isfile(filepath)

# extract contents
Expand Down

0 comments on commit ed3f211

Please sign in to comment.