Skip to content

Commit 8872302

Browse files
authored
add swagger-editor invocation to tools (#18)
* add swagger-editor invocation to tools allows opening swagger editor with a supplied specification file * add toc to readme [skip ci]
1 parent a7193f2 commit 8872302

File tree

2 files changed

+172
-18
lines changed

2 files changed

+172
-18
lines changed

README.md

Lines changed: 80 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,30 @@
33
[![Build Status](https://github.com/JuliaComputing/OpenAPI.jl/workflows/CI/badge.svg)](https://github.com/JuliaComputing/OpenAPI.jl/actions?query=workflow%3ACI+branch%3Amain)
44
[![codecov.io](http://codecov.io/github/JuliaComputing/OpenAPI.jl/coverage.svg?branch=main)](http://codecov.io/github/JuliaComputing/OpenAPI.jl?branch=main)
55

6-
This is the Julia library needed with code generated by the [OpenAPI generator](https://openapi-generator.tech/).
6+
This is the Julia library needed along with code generated by the [OpenAPI generator](https://openapi-generator.tech/) to help define, produce and consume OpenAPI interfaces.
77

88
The goal of OpenAPI is to define a standard, language-agnostic interface to REST APIs which allows both humans and computers to discover and understand the capabilities of the service without access to source code, documentation, or through network traffic inspection. When properly defined via OpenAPI, a consumer can understand and interact with the remote service with a minimal amount of implementation logic. Similar to what interfaces have done for lower-level programming, OpenAPI removes the guesswork in calling the service.
99

1010
Check out [OpenAPI-Spec](https://github.com/OAI/OpenAPI-Specification) for additional information about the OpenAPI project, including additional libraries with support for other languages and more.
1111

1212
> Note: This package supersedes the [Swagger.jl](https://github.com/JuliaComputing/Swagger.jl) package. OpenAPI.jl and the associated generator can address both OpenAPI 2.x (Swagger) and OpenAPI 3.x specifications. Code dependent on Swagger.jl would not directly work with OpenAPI.jl, but migration should not be too difficult.
1313
14+
---
15+
## Table of Contents
16+
17+
- [Code Generation](#code-generation)
18+
- [Generated Code Structure](#generated-code-structure)
19+
- [Models](#models)
20+
- [Validations](#validations)
21+
- [Client APIs](#client-apis)
22+
- [Server APIs](#server-apis)
23+
- [Examples](#examples)
24+
- [Tools](#tools)
25+
- [Swagger UI](#swagger-ui)
26+
- [Swagger Editor](#swagger-editor)
27+
- [TODO](#todo)
28+
---
29+
1430
## Code Generation
1531

1632
Use [instructions](https://openapi-generator.tech/docs/generators) provided for the Julia OpenAPI code generator plugin to generate Julia code.
@@ -170,7 +186,7 @@ An API call involves the following steps:
170186
- Convert (deserialize) the response data into the return type and return.
171187
- In case of any errors, throw an instance of `ApiException`
172188

173-
## Server APIs
189+
### Server APIs
174190

175191
The server code is generated as a package. It contains API stubs and validations of API inputs. It requires the caller to
176192
have implemented the APIs, the signatures of which are provided in the generated package module docstring.
@@ -208,18 +224,35 @@ The Petstore is a common example that most OpenAPI implementations use to test a
208224
- Client: [docs](test/client/petstore_v3/petstore/README.md), [implementation](test/client/petstore_v3)
209225
- Server: [docs](test/server/petstore_v3/petstore/README.md), [implementation](test/server/petstore_v3)
210226

211-
## Swagger UI
227+
## Tools
228+
229+
### Swagger UI
212230

213231
[Swagger UI](https://swagger.io/tools/swagger-ui/) allows visualization and interaction with the API’s resources without having any of the implementation logic in place. OpenAPI.jl includes convenience methods to launch Swagger UI from Julia.
214232

215233
Use `OpenAPI.swagger_ui` to open Swagger UI. It uses the standard `swaggerapi/swagger-ui` docker image and requires docker engine to be installed.
216234

217235
```julia
236+
# specify a specification file to start with
218237
OpenAPI.swagger_ui(
219-
spec::String; # the OpenAPI specification to use
238+
spec::AbstractString; # the OpenAPI specification to use
220239
port::Int=8080, # port to use
221240
use_sudo::Bool=false # whether to use sudo while invoking docker
222241
)
242+
243+
# specify a folder and specification file name to start with
244+
OpenAPI.swagger_ui(
245+
spec_dir::AbstractString; # folder containing the specification file
246+
spec_file::AbstractString; # the specification file
247+
port::Int=8080, # port to use
248+
use_sudo::Bool=false # whether to use sudo while invoking docker
249+
)
250+
```
251+
252+
It returns the URL that should be opened in a browser to access the Swagger UI. Combining it with a tool like [DefaultApplication.jl](https://github.com/tpapp/DefaultApplication.jl) can help open a browser tab directly from Julia.
253+
254+
```julia
255+
DefaultApplication.open(OpenAPI.swagger_ui("/my/openapi/spec.json"))
223256
```
224257

225258
To stop the Swagger UI container, use `OpenAPI.stop_swagger_ui`.
@@ -230,6 +263,49 @@ OpenAPI.stop_swagger_ui(;
230263
)
231264
```
232265

266+
### Swagger Editor
267+
268+
[Swagger Editor](https://swagger.io/tools/swagger-editor/) allows editing of OpenAPI specifications and simultaneous visualization and interaction with the API’s resources without having any of the client implementation logic in place. OpenAPI.jl includes convenience methods to launch Swagger Editor from Julia.
269+
270+
Use `OpenAPI.swagger_editor` to open Swagger Editor. It uses the standard `swaggerapi/swagger-editor` docker image and requires docker engine to be installed.
271+
272+
```julia
273+
# specify a specification file to start with
274+
OpenAPI.swagger_editor(
275+
spec::AbstractString; # the OpenAPI specification to use
276+
port::Int=8080, # port to use
277+
use_sudo::Bool=false # whether to use sudo while invoking docker
278+
)
279+
280+
# specify a folder and specification file name to start with
281+
OpenAPI.swagger_editor(
282+
spec_dir::AbstractString; # folder containing the specification file
283+
spec_file::AbstractString; # the specification file
284+
port::Int=8080, # port to use
285+
use_sudo::Bool=false # whether to use sudo while invoking docker
286+
)
287+
288+
# start without specifying any initial specification file
289+
OpenAPI.swagger_editor(
290+
port::Int=8080, # port to use
291+
use_sudo::Bool=false # whether to use sudo while invoking docker
292+
)
293+
```
294+
295+
It returns the URL that should be opened in a browser to access the Swagger UI. Combining it with a tool like [DefaultApplication.jl](https://github.com/tpapp/DefaultApplication.jl) can help open a browser tab directly from Julia.
296+
297+
```julia
298+
DefaultApplication.open(OpenAPI.swagger_editor("/my/openapi/spec.json"))
299+
```
300+
301+
To stop the Swagger Editor container, use `OpenAPI.stop_swagger_editor`.
302+
303+
```julia
304+
OpenAPI.stop_swagger_editor(;
305+
use_sudo::Bool=false # whether to use sudo while invoking docker
306+
)
307+
```
308+
233309
## TODO
234310

235311
Not all OpenAPI features are supported yet, e.g.:

src/tools.jl

Lines changed: 92 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,50 @@
1-
const SWAGGER_UI_IMAGE = "swaggerapi/swagger-ui"
1+
const SwaggerImage = (UI="swaggerapi/swagger-ui", Editor="swaggerapi/swagger-editor")
22

33
docker_cmd(; use_sudo::Bool=false) = use_sudo ? `sudo docker` : `docker`
44

5-
function stop_swagger_ui(; use_sudo::Bool=false)
5+
"""
6+
stop_swagger_ui(; use_sudo=false)
7+
8+
Stop and remove the Swagger UI container, if it is running.
9+
Returns true if the container was stopped and removed, false otherwise.
10+
"""
11+
stop_swagger_ui(; use_sudo::Bool=false) = _stop_swagger(SwaggerImage.UI; use_sudo=use_sudo)
12+
13+
"""
14+
stop_swagger_editor(; use_sudo=false)
15+
16+
Stop and remove the Swagger Editor container, if it is running.
17+
Returns true if the container was stopped and removed, false otherwise.
18+
"""
19+
stop_swagger_editor(; use_sudo::Bool=false) = _stop_swagger(SwaggerImage.Editor; use_sudo=use_sudo)
20+
21+
"""
22+
stop_swagger(; use_sudo=false)
23+
24+
Stop and remove Swagger UI or Editor containers, if they are running.
25+
Returns true if any container was stopped and removed, false otherwise.
26+
"""
27+
function stop_swagger(; use_sudo::Bool=false)
28+
stopped = stop_swagger_ui(; use_sudo=use_sudo)
29+
stopped |= stop_swagger_editor(; use_sudo=use_sudo)
30+
return stopped
31+
end
32+
33+
function _stop_swagger(image_name::AbstractString; use_sudo::Bool=false)
634
docker = docker_cmd(; use_sudo=use_sudo)
7-
find_cmd = `$docker ps -a -q -f ancestor=$SWAGGER_UI_IMAGE`
35+
find_cmd = `$docker ps -a -q -f ancestor=$image_name`
836
container_id = strip(String(read(find_cmd)))
937

1038
if !isempty(container_id)
1139
stop_cmd = `$docker stop $container_id`
1240
stop_res = strip(String(read(stop_cmd)))
1341

1442
if stop_res == container_id
15-
@debug("Stopped Swagger UI container")
43+
@debug("Stopped Swagger container")
1644
elseif isempty(stop_res)
17-
@debug("Swagger UI container not running")
45+
@debug("Swagger container not running")
1846
else
19-
@error("Failed to stop Swagger UI container: $stop_res")
47+
@error("Failed to stop Swagger container: $stop_res")
2048
return false
2149
end
2250

@@ -26,27 +54,77 @@ function stop_swagger_ui(; use_sudo::Bool=false)
2654
rm_res = strip(String(read(rm_cmd)))
2755

2856
if rm_res == container_id
29-
@debug("Removed Swagger UI container")
57+
@debug("Removed Swagger container")
3058
elseif isempty(rm_res)
31-
@debug("Swagger UI container not found")
59+
@debug("Swagger container not found")
3260
else
33-
@error("Failed to remove Swagger UI container: $rm_res")
61+
@error("Failed to remove Swagger container: $rm_res")
3462
return false
3563
end
3664
end
3765

3866
return true
3967
else
40-
@debug("Swagger UI container not found")
68+
@debug("Swagger container not found")
4169
end
4270

4371
return false
4472
end
4573

46-
function swagger_ui(spec::String; port::Int=8080, use_sudo::Bool=false)
47-
docker = docker_cmd(; use_sudo=use_sudo)
48-
stop_swagger_ui(; use_sudo=use_sudo)
49-
cmd = `$docker run -d --rm -p $port:8080 -e SWAGGER_JSON=/tmp/spec.json -v $spec:/tmp/spec.json $SWAGGER_UI_IMAGE`
74+
function _start_swagger(cmd, port)
5075
run(cmd)
5176
return "http://localhost:$port"
5277
end
78+
79+
"""
80+
swagger_ui(spec; port=8080, use_sudo=false)
81+
swagger_ui(spec_dir, spec_file; port=8080, use_sudo=false)
82+
83+
Start a Swagger UI container for the given OpenAPI spec file. Returns the URL of the Swagger UI.
84+
85+
Optional arguments:
86+
- `port`: The port to use for the Swagger UI. Defaults to 8080.
87+
- `use_sudo`: Whether to use `sudo` to run Docker commands. Defaults to false.
88+
"""
89+
function swagger_ui(spec::AbstractString; port::Int=8080, use_sudo::Bool=false)
90+
spec = abspath(spec)
91+
spec_dir = dirname(spec)
92+
spec_file = basename(spec)
93+
return swagger_ui(spec_dir, spec_file; port=port, use_sudo=use_sudo)
94+
end
95+
96+
function swagger_ui(spec_dir::AbstractString, spec_file::AbstractString; port::Int=8080, use_sudo::Bool=false)
97+
docker = docker_cmd(; use_sudo=use_sudo)
98+
cmd = `$docker run -d --rm -p $port:8080 -e SWAGGER_JSON=/spec/$spec_file -v $spec_dir:/spec $(SwaggerImage.UI)`
99+
return _start_swagger(cmd, port)
100+
end
101+
102+
"""
103+
swagger_editor(; port=8080, use_sudo=false)
104+
swagger_editor(spec; port=8080, use_sudo=false)
105+
swagger_editor(spec_dir, spec_file; port=8080, use_sudo=false)
106+
107+
Start a Swagger Editor container with an optional OpenAPI spec file. Returns the URL of the Swagger Editor.
108+
109+
Optional arguments:
110+
- `port`: The port to use for the Swagger Editor. Defaults to 8080.
111+
- `use_sudo`: Whether to use `sudo` to run Docker commands. Defaults to false.
112+
"""
113+
function swagger_editor(spec::AbstractString; port::Int=8080, use_sudo::Bool=false)
114+
spec = abspath(spec)
115+
spec_dir = dirname(spec)
116+
spec_file = basename(spec)
117+
return swagger_editor(spec_dir, spec_file; port=port, use_sudo=use_sudo)
118+
end
119+
120+
function swagger_editor(spec_dir::AbstractString, spec_file::AbstractString; port::Int=8080, use_sudo::Bool=false)
121+
docker = docker_cmd(; use_sudo=use_sudo)
122+
cmd = `$docker run -d --rm -p $port:8080 -e SWAGGER_FILE=/spec/$spec_file -v $spec_dir:/spec $(SwaggerImage.Editor)`
123+
return _start_swagger(cmd, port)
124+
end
125+
126+
function swagger_editor(; port::Int=8080, use_sudo::Bool=false)
127+
docker = docker_cmd(; use_sudo=use_sudo)
128+
cmd = `$docker run -d --rm -p $port:8080 $(SwaggerImage.Editor)`
129+
return _start_swagger(cmd, port)
130+
end

0 commit comments

Comments
 (0)