Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nested string response #9

Merged
merged 8 commits into from
Sep 25, 2024
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
9 changes: 2 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,12 @@ jobs:
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install Redocly
run: npm install -g @redocly/cli@latest

- name: Lint OpenAPI with Redocly
run: redocly lint openapi.yaml

- name: Install spectral
run: npm install -g @stoplight/spectral-cli
run: npx --package @redocly/cli@latest redocly lint openapi.yaml

- name: Lint OpenAPI with Spectral
run: spectral lint openapi.yaml
run: npx --package @stoplight/spectral-cli spectral lint openapi.yaml

- name: Setup Python
uses: actions/setup-python@v5
Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,7 @@ __pycache__
/venv
python/.venv/
python/heat.toml
RemoteBMI.jl/example/Project.toml
RemoteBMI.jl/example/Project.toml
RemoteBMI.jl/example/heat.toml
openapi-generator-cli.jar
openapitools.json
3 changes: 2 additions & 1 deletion RemoteBMI.jl/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ BestieTemplate.generate("RemoteBMI.jl")
The openapi server stubs where generated using the following command:

```shell
npx @openapitools/openapi-generator-cli generate -i ./openapi.yaml -g julia-server -o julia-server --additional-properties=packageName=BmiServer --additional-properties=exportModels=true
wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.8.0/openapi-generator-cli-7.8.0.jar -O openapi-generator-cli.jar
java -jar ./openapi-generator-cli.jar generate -i ./openapi.yaml -g julia-server -o julia-server --additional-properties=packageName=BmiServer --additional-properties=exportModels=true
# Copy the generated files to RemoteBMI.jl/src/
```
17 changes: 14 additions & 3 deletions RemoteBMI.jl/example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ add https://github.com/csdms/bmi-example-julia#b5d963e6bf864f5d42769e6cc0814dd7b
dev ..
CTRL-D
# Run server
export BMI_SERVER_PORT=50555
export BMI_PORT=50555
julia --project=$PWD heat_bmi_server.jl
```

Expand All @@ -24,16 +24,27 @@ Interact with it using the Python client.

```python
from remotebmi.client.client import RemoteBmiClient
from remotebmi.client.reserve import reserve_values
from remotebmi.reserve import reserve_values

client = RemoteBmiClient('http://localhost:50555')
# TODO use placeholder for path
# client.initialize('<absolute path>/heat.toml')
client.initialize('/home/stefanv/git/eWaterCycle/remotebmi/python/heat.toml')
# TODO Julia server throws error here
client.get_component_name()
'The 2D Heat Equation'
client.update()
client.get_current_time()
0.25
client.get_time_units()
's'
client.get_var_location('plate_surface__temperature')
'node'
client.get_var_type('plate_surface__temperature')
numpy.float64
client.get_var_grid('plate_surface__temperature')
0
client.get_grid_type(0)
'uniform_rectilinear'
dest = reserve_values(client, 'plate_surface__temperature')
r = client.get_value('plate_surface__temperature', dest)
r
Expand Down
24 changes: 14 additions & 10 deletions RemoteBMI.jl/src/BmiServer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ The following server methods must be implemented:

- **get_component_name**
- *invocation:* GET /get_component_name
- *signature:* get_component_name(req::HTTP.Request;) -> String
- *signature:* get_component_name(req::HTTP.Request;) -> GetComponentNameResponse
- **get_input_item_count**
- *invocation:* GET /get_input_item_count
- *signature:* get_input_item_count(req::HTTP.Request;) -> Int64
Expand All @@ -36,13 +36,13 @@ The following server methods must be implemented:
- *signature:* get_grid_size(req::HTTP.Request, grid::Int64;) -> Int64
- **get_grid_type**
- *invocation:* GET /get_grid_type/{grid}
- *signature:* get_grid_type(req::HTTP.Request, grid::Int64;) -> BmiGetGridTypeResponse
- *signature:* get_grid_type(req::HTTP.Request, grid::Int64;) -> GetGridTypeResponse
- **finalize**
- *invocation:* DELETE /finalize
- *signature:* finalize(req::HTTP.Request;) -> Nothing
- **initialize**
- *invocation:* POST /initialize
- *signature:* initialize(req::HTTP.Request, bmi_initialize_request::BmiInitializeRequest;) -> Nothing
- *signature:* initialize(req::HTTP.Request, initialize_request::InitializeRequest;) -> Nothing
- **update**
- *invocation:* POST /update
- *signature:* update(req::HTTP.Request;) -> Nothing
Expand All @@ -63,7 +63,7 @@ The following server methods must be implemented:
- *signature:* set_value(req::HTTP.Request, name::String, request_body::Vector{Float64};) -> Nothing
- **set_value_at_indices**
- *invocation:* POST /set_value_at_indices/{name}
- *signature:* set_value_at_indices(req::HTTP.Request, name::String, bmi_set_value_at_indices_request::BmiSetValueAtIndicesRequest;) -> Nothing
- *signature:* set_value_at_indices(req::HTTP.Request, name::String, set_value_at_indices_request::SetValueAtIndicesRequest;) -> Nothing
- **get_current_time**
- *invocation:* GET /get_current_time
- *signature:* get_current_time(req::HTTP.Request;) -> Float64
Expand All @@ -78,7 +78,7 @@ The following server methods must be implemented:
- *signature:* get_time_step(req::HTTP.Request;) -> Float64
- **get_time_units**
- *invocation:* GET /get_time_units
- *signature:* get_time_units(req::HTTP.Request;) -> String
- *signature:* get_time_units(req::HTTP.Request;) -> GetTimeUnitsResponse
- **get_grid_origin**
- *invocation:* GET /get_grid_origin/{grid}
- *signature:* get_grid_origin(req::HTTP.Request, grid::Int64;) -> Vector{Float64}
Expand Down Expand Up @@ -123,10 +123,10 @@ The following server methods must be implemented:
- *signature:* get_var_nbytes(req::HTTP.Request, name::String;) -> Int64
- **get_var_type**
- *invocation:* GET /get_var_type/{name}
- *signature:* get_var_type(req::HTTP.Request, name::String;) -> String
- *signature:* get_var_type(req::HTTP.Request, name::String;) -> GetVarTypeResponse
- **get_var_units**
- *invocation:* GET /get_var_units/{name}
- *signature:* get_var_units(req::HTTP.Request, name::String;) -> String
- *signature:* get_var_units(req::HTTP.Request, name::String;) -> GetVarUnitsResponse
"""
module BmiServer

Expand Down Expand Up @@ -187,10 +187,14 @@ function register(router::HTTP.Router, impl; path_prefix::String="", optional_mi
end

# export models
export BmiGetGridTypeResponse
export BmiInitializeRequest
export BmiSetValueAtIndicesRequest
export GetComponentNameResponse
export GetGridTypeResponse
export GetTimeUnitsResponse
export GetVarLocationResponseLocation
export GetVarTypeResponse
export GetVarUnitsResponse
export InitializeRequest
export ProblemDetails
export SetValueAtIndicesRequest

end # module BmiServer
35 changes: 19 additions & 16 deletions RemoteBMI.jl/src/RemoteBMI.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import BasicModelInterface as BMI

# TODO move route implementations to own module

function initialize(req::HTTP.Request, bmi_initialize_request::BmiInitializeRequest)::Nothing
function initialize(req::HTTP.Request, initialize_request::InitializeRequest)::Nothing
global m
m = BMI.initialize(MyModel, bmi_initialize_request.config_file)
m = BMI.initialize(MyModel, initialize_request.config_file)
return nothing
end

function get_component_name(req::HTTP.Request;)::String
return BMI.get_component_name(m)
function get_component_name(req::HTTP.Request)::GetComponentNameResponse
return GetComponentNameResponse(BMI.get_component_name(m))
end

function get_input_item_count(req::HTTP.Request;)::Int64
Expand Down Expand Up @@ -89,8 +89,8 @@ function get_grid_size(req::HTTP.Request, grid::Int64;)::Int64
return BMI.get_grid_size(m, grid)
end

function get_grid_type(req::HTTP.Request, grid::Int64;)::BmiGetGridTypeResponse
return BMI.get_grid_type(m, grid)
function get_grid_type(req::HTTP.Request, grid::Int64;)::GetGridTypeResponse
return GetGridTypeResponse(type=BMI.get_grid_type(m, grid))
end

function finalize(req::HTTP.Request;)::Nothing
Expand Down Expand Up @@ -119,6 +119,7 @@ function reserve_grid_coords(m, grid::Int64, dim_index::Int8)::Vector{Float64}
size = BMI.get_grid_node_count(m, grid)
else
error("Unsupported grid type: $mtype")
end
return zeros(Float64, size)
end

Expand All @@ -141,15 +142,17 @@ function set_value(req::HTTP.Request, name::String, request_body::Vector{Float64
BMI.set_value(m, name, request_body)
end

function set_value_at_indices(req::HTTP.Request, name::String, bmi_set_value_at_indices_request::BmiSetValueAtIndicesRequest;)::Nothing
BMI.set_value_at_indices(m, name, bmi_set_value_at_indices_request)
function set_value_at_indices(req::HTTP.Request, name::String, set_value_at_indices_request::SetValueAtIndicesRequest;)::Nothing
BMI.set_value_at_indices(m, name, set_value_at_indices_request)
end

function get_current_time(req::HTTP.Request;)::Float64
return BMI.get_current_time(m)
end

function get_end_time(req::HTTP.Request;)::Float64
# Julia Heat model returns Inf, but that is not a valid JSON number.
# Therefore, it gets converted to null in the JSON response.
return BMI.get_end_time(m)
end

Expand All @@ -161,8 +164,8 @@ function get_time_step(req::HTTP.Request;)::Float64
return BMI.get_time_step(m)
end

function get_time_units(req::HTTP.Request;)::String
return BMI.get_time_units(m)
function get_time_units(req::HTTP.Request;)::GetTimeUnitsResponse
return GetTimeUnitsResponse(BMI.get_time_units(m))
end

function get_grid_origin(req::HTTP.Request, grid::Int64;)::Vector{Float64}
Expand Down Expand Up @@ -247,17 +250,17 @@ function get_var_itemsize(req::HTTP.Request, name::String;)::Int64
end

function get_var_location(req::HTTP.Request, name::String;)::GetVarLocationResponseLocation
return BMI.get_var_location(m, name)
return GetVarLocationResponseLocation(BMI.get_var_location(m, name))
end

function get_var_nbytes(req::HTTP.Request, name::String;)::Int64
return BMI.get_var_nbytes(m, name)
end

function get_var_type(req::HTTP.Request, name::String;)::String
function get_var_type(req::HTTP.Request, name::String;)::GetVarTypeResponse
raw_type = BMI.get_var_type(m, name)
map = Dict(
"Float64" => "float64",
"Float64" => "double",
"Float32" => "float32",
"Int64" => "int64",
"Int32" => "int32",
Expand All @@ -267,11 +270,11 @@ function get_var_type(req::HTTP.Request, name::String;)::String
if type == Any
error("Invalid data type returned by model: $raw_type, allowed types are: Float64, Float32, Int64, Int32")
end
return type
return GetVarTypeResponse(type)
end

function get_var_units(req::HTTP.Request, name::String;)::String
return BMI.get_var_units(m, name)
function get_var_units(req::HTTP.Request, name::String;)::GetVarUnitsResponse
return GetVarUnitsResponse(BMI.get_var_units(m, name))
end

function run(model, host, port)
Expand Down
4 changes: 4 additions & 0 deletions RemoteBMI.jl/src/apis/api_GettersApi.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ function get_value_validate(handler)
function get_value_validate_handler(req::HTTP.Request)
openapi_params = req.context[:openapi_params]

OpenAPI.validate_param("name", "get_value", :minLength, openapi_params["name"], 1)

return handler(req)
end
end
Expand Down Expand Up @@ -46,6 +48,8 @@ function get_value_at_indices_validate(handler)
function get_value_at_indices_validate_handler(req::HTTP.Request)
openapi_params = req.context[:openapi_params]

OpenAPI.validate_param("name", "get_value_at_indices", :minLength, openapi_params["name"], 1)

return handler(req)
end
end
Expand Down
4 changes: 2 additions & 2 deletions RemoteBMI.jl/src/apis/api_IRFApi.jl
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ end
function initialize_read(handler)
function initialize_read_handler(req::HTTP.Request)
openapi_params = Dict{String,Any}()
openapi_params["BmiInitializeRequest"] = OpenAPI.Servers.to_param_type(BmiInitializeRequest, String(req.body))
openapi_params["InitializeRequest"] = OpenAPI.Servers.to_param_type(InitializeRequest, String(req.body))
req.context[:openapi_params] = openapi_params

return handler(req)
Expand All @@ -49,7 +49,7 @@ end
function initialize_invoke(impl; post_invoke=nothing)
function initialize_invoke_handler(req::HTTP.Request)
openapi_params = req.context[:openapi_params]
ret = impl.initialize(req::HTTP.Request, openapi_params["BmiInitializeRequest"];)
ret = impl.initialize(req::HTTP.Request, openapi_params["InitializeRequest"];)
resp = OpenAPI.Servers.server_response(ret)
return (post_invoke === nothing) ? resp : post_invoke(req, resp)
end
Expand Down
8 changes: 6 additions & 2 deletions RemoteBMI.jl/src/apis/api_SettersApi.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ function set_value_validate(handler)
function set_value_validate_handler(req::HTTP.Request)
openapi_params = req.context[:openapi_params]

OpenAPI.validate_param("name", "set_value", :minLength, openapi_params["name"], 1)

return handler(req)
end
end
Expand All @@ -36,7 +38,7 @@ function set_value_at_indices_read(handler)
openapi_params = Dict{String,Any}()
path_params = HTTP.getparams(req)
openapi_params["name"] = OpenAPI.Servers.to_param(String, path_params, "name", required=true, )
openapi_params["BmiSetValueAtIndicesRequest"] = OpenAPI.Servers.to_param_type(BmiSetValueAtIndicesRequest, String(req.body))
openapi_params["SetValueAtIndicesRequest"] = OpenAPI.Servers.to_param_type(SetValueAtIndicesRequest, String(req.body))
req.context[:openapi_params] = openapi_params

return handler(req)
Expand All @@ -47,14 +49,16 @@ function set_value_at_indices_validate(handler)
function set_value_at_indices_validate_handler(req::HTTP.Request)
openapi_params = req.context[:openapi_params]

OpenAPI.validate_param("name", "set_value_at_indices", :minLength, openapi_params["name"], 1)

return handler(req)
end
end

function set_value_at_indices_invoke(impl; post_invoke=nothing)
function set_value_at_indices_invoke_handler(req::HTTP.Request)
openapi_params = req.context[:openapi_params]
ret = impl.set_value_at_indices(req::HTTP.Request, openapi_params["name"], openapi_params["BmiSetValueAtIndicesRequest"];)
ret = impl.set_value_at_indices(req::HTTP.Request, openapi_params["name"], openapi_params["SetValueAtIndicesRequest"];)
resp = OpenAPI.Servers.server_response(ret)
return (post_invoke === nothing) ? resp : post_invoke(req, resp)
end
Expand Down
12 changes: 12 additions & 0 deletions RemoteBMI.jl/src/apis/api_VariableInformationApi.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ function get_var_grid_validate(handler)
function get_var_grid_validate_handler(req::HTTP.Request)
openapi_params = req.context[:openapi_params]

OpenAPI.validate_param("name", "get_var_grid", :minLength, openapi_params["name"], 1)

return handler(req)
end
end
Expand Down Expand Up @@ -45,6 +47,8 @@ function get_var_itemsize_validate(handler)
function get_var_itemsize_validate_handler(req::HTTP.Request)
openapi_params = req.context[:openapi_params]

OpenAPI.validate_param("name", "get_var_itemsize", :minLength, openapi_params["name"], 1)

return handler(req)
end
end
Expand Down Expand Up @@ -73,6 +77,8 @@ function get_var_location_validate(handler)
function get_var_location_validate_handler(req::HTTP.Request)
openapi_params = req.context[:openapi_params]

OpenAPI.validate_param("name", "get_var_location", :minLength, openapi_params["name"], 1)

return handler(req)
end
end
Expand Down Expand Up @@ -101,6 +107,8 @@ function get_var_nbytes_validate(handler)
function get_var_nbytes_validate_handler(req::HTTP.Request)
openapi_params = req.context[:openapi_params]

OpenAPI.validate_param("name", "get_var_nbytes", :minLength, openapi_params["name"], 1)

return handler(req)
end
end
Expand Down Expand Up @@ -129,6 +137,8 @@ function get_var_type_validate(handler)
function get_var_type_validate_handler(req::HTTP.Request)
openapi_params = req.context[:openapi_params]

OpenAPI.validate_param("name", "get_var_type", :minLength, openapi_params["name"], 1)

return handler(req)
end
end
Expand Down Expand Up @@ -157,6 +167,8 @@ function get_var_units_validate(handler)
function get_var_units_validate_handler(req::HTTP.Request)
openapi_params = req.context[:openapi_params]

OpenAPI.validate_param("name", "get_var_units", :minLength, openapi_params["name"], 1)

return handler(req)
end
end
Expand Down
Loading