Skip to content

Commit

Permalink
feature/package-compiler-compatibility (#128)
Browse files Browse the repository at this point in the history
1.) added RelocatableFolders to make sure this package works with PackageCompiler.jl
2.) Now spawning cron tasks in any available thread of just the main thread
3.) added redoc docs option, but still default to swagger
4.) bumped version to 1.2
  • Loading branch information
ndortega authored Sep 28, 2023
1 parent 4294dbb commit 77a19dd
Show file tree
Hide file tree
Showing 11 changed files with 1,929 additions and 23 deletions.
12 changes: 12 additions & 0 deletions Manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,21 @@ uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"
deps = ["Serialization"]
uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"

[[RelocatableFolders]]
deps = ["SHA", "Scratch"]
git-tree-sha1 = "90bc7a7c96410424509e4263e277e43250c05691"
uuid = "05181044-ff0b-4ac5-8273-598c1e38db00"
version = "1.0.0"

[[SHA]]
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"

[[Scratch]]
deps = ["Dates"]
git-tree-sha1 = "30449ee12237627992a99d5e30ae63e4d78cd24a"
uuid = "6c6a2e73-6563-6170-7368-637461726353"
version = "1.2.0"

[[Serialization]]
uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"

Expand Down
6 changes: 4 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
name = "Oxygen"
uuid = "df9a0d86-3283-4920-82dc-4555fc0d1d8b"
authors = ["Nathan Ortega <[email protected]>"]
version = "1.1.11"
version = "1.2"

[deps]
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3"
JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
MIMEs = "6c6e2e6c-3030-632d-7369-2d6c69616d65"
RelocatableFolders = "05181044-ff0b-4ac5-8273-598c1e38db00"
Sockets = "6462fe0b-24de-5631-8697-dd941f90decc"

[compat]
HTTP = "^1"
JSON3 = "^1.9"
MIMEs = "^0.1.4"
julia = "^1.6.6"
RelocatableFolders = "^1"
julia = "^1.6"
1,820 changes: 1,820 additions & 0 deletions data/[email protected]/redoc.standalone.js

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions data/[email protected]/swagger-ui-bundle.js

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions data/[email protected]/swagger-ui.css

Large diffs are not rendered by default.

61 changes: 49 additions & 12 deletions src/autodoc.jl
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
module AutoDoc
using HTTP
using Dates
using RelocatableFolders

include("cron.jl"); using .Cron
include("util.jl"); using .Util

export registerschema, docspath, schemapath, getschema,
swaggerhtml, configdocs, mergeschema, setschema, router,
enabledocs, disabledocs, isdocsenabled, registermountedfolder,
swaggerhtml, redochtml, getschemapath, configdocs, mergeschema, setschema,
router, enabledocs, disabledocs, isdocsenabled, registermountedfolder,
getrepeatasks, hasmiddleware, compose, resetstatevariables,
@cron, stopcronjobs, startcronjobs, getcronjobs, resetcronstate

const SWAGGER_VERSION = "[email protected]"
const REDOC_VERSION = "[email protected]"

# Generate a reliable path to our internal data folder that works when the
# package is used with PackageCompiler.jl
const DATA_PATH = @path abspath(joinpath(@__DIR__, "..", "data"))


struct TaggedRoute
httpmethods::Vector{String}
tags::Vector{String}
Expand All @@ -35,6 +44,10 @@ global cronjobs = []
global schema = defaultSchema
global const custommiddlware = Ref{Dict{String, Tuple}}(Dict())

function getschemapath()::String
return "$docspath$schemapath"
end

function getrepeatasks()
return repeattasks
end
Expand All @@ -46,7 +59,7 @@ end
function resetstatevariables()
global enable_auto_docs = true
global docspath = "/docs"
global schemapath = "/docs/schema"
global schemapath = "/schema"
global mountedfolders = Set{String}()
global taggedroutes = Dict{String, TaggedRoute}()
global repeattasks = []
Expand Down Expand Up @@ -97,7 +110,7 @@ Configure the default docs and schema endpoints
"""
function configdocs(docs_url::String = docspath, schema_url::String = schemapath)
global docspath = docs_url
global schemapath = "$docs_url$schema_url"
global schemapath = schemapath
end

"""
Expand Down Expand Up @@ -361,8 +374,8 @@ Used to generate & register schema related for a specific endpoint
"""
function registerschema(path::String, httpmethod::String, parameters, returntype::Array)

# skip docs & schema paths
if path in [docspath, schemapath]
# skip any doc related endpoints
if startswith(path, docspath)
return
end

Expand Down Expand Up @@ -422,30 +435,54 @@ end
Read in a static file from the /data folder
"""
function readstaticfile(filepath::String) :: String
path = abspath(joinpath(@__DIR__, "..", "data", filepath))
path = joinpath(DATA_PATH, filepath)
return read(open(path), String)
end

function redochtml() :: HTTP.Response
redocjs = readstaticfile("$REDOC_VERSION/redoc.standalone.js")

return html("""
<!DOCTYPE html>
<html lang="en">
<head>
<title>Docs</title>
<meta charset="utf-8"/>
<meta name="description" content="Docs" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
</head>
<body>
<redoc spec-url="$(getschemapath())"></redoc>
<script>$redocjs</script>
</body>
</html>
""")
end

"""
Return HTML page to render the autogenerated docs
"""
function swaggerhtml() :: HTTP.Response

# load static content files
swaggerjs = readstaticfile("[email protected]/swagger-ui-bundle.js")
swaggerstyles = readstaticfile("[email protected]/swagger-ui.css")
swaggerjs = readstaticfile("$SWAGGER_VERSION/swagger-ui-bundle.js")
swaggerstyles = readstaticfile("$SWAGGER_VERSION/swagger-ui.css")

return html("""
<!DOCTYPE html>
<html lang="en">
<head>
<title>Docs</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="SwaggerUI" />
<meta name="description" content="Docs" />
<style>$swaggerstyles</style>
<title>SwaggerUI</title>
</head>
<body>
Expand All @@ -454,7 +491,7 @@ function swaggerhtml() :: HTTP.Response
<script>
window.onload = () => {
window.ui = SwaggerUIBundle({
url: window.location.origin + "$schemapath",
url: window.location.origin + "$(getschemapath())",
dom_id: '#swagger-ui',
});
};
Expand Down
10 changes: 9 additions & 1 deletion src/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,15 @@ function setupswagger()
return swaggerhtml()
end

@get "$schemapath" function()
@get "$docspath/swagger" function()
return swaggerhtml()
end

@get "$docspath/redoc" function()
return redochtml()
end

@get "$(getschemapath())" function()
return getschema()
end

Expand Down
2 changes: 1 addition & 1 deletion src/cron.jl
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ function startcronjobs()
message = isnothing(name) ? "$expression" : "id: $i, expr: $expression, name: $name"
printstyled("[ Cron: ", color = :green, bold = true)
println(message)
t = @async begin
t = Threads.@spawn begin
while true
# get the current datetime object
current_time::DateTime = now()
Expand Down
12 changes: 12 additions & 0 deletions test/Manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,21 @@ uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"
deps = ["Serialization"]
uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"

[[RelocatableFolders]]
deps = ["SHA", "Scratch"]
git-tree-sha1 = "90bc7a7c96410424509e4263e277e43250c05691"
uuid = "05181044-ff0b-4ac5-8273-598c1e38db00"
version = "1.0.0"

[[SHA]]
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"

[[Scratch]]
deps = ["Dates"]
git-tree-sha1 = "30449ee12237627992a99d5e30ae63e4d78cd24a"
uuid = "6c6a2e73-6563-6170-7368-637461726353"
version = "1.2.0"

[[Serialization]]
uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"

Expand Down
1 change: 1 addition & 0 deletions test/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3"
JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
MIMEs = "6c6e2e6c-3030-632d-7369-2d6c69616d65"
RelocatableFolders = "05181044-ff0b-4ac5-8273-598c1e38db00"
Sockets = "6462fe0b-24de-5631-8697-dd941f90decc"
StructTypes = "856f2bd8-1eba-4b0a-8007-ebc267875bd4"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
Expand Down
22 changes: 15 additions & 7 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ end

localhost = "http://127.0.0.1:8080"

configdocs("/swagger", "/schema")
configdocs("/docs", "/schema")

StructTypes.StructType(::Type{Person}) = StructTypes.Struct()

Expand Down Expand Up @@ -573,7 +573,7 @@ catch e
@test e isa ArgumentError
end

## Swagger related tests
## docs related tests

# should be set to true by default
@test isdocsenabled() == true
Expand All @@ -588,10 +588,10 @@ disabledocs()
@async serve(async=false)
sleep(1)

r = internalrequest(HTTP.Request("GET", "/swagger"))
r = internalrequest(HTTP.Request("GET", "/docs"))
@test r.status == 404

r = internalrequest(HTTP.Request("GET", "/swagger/schema"))
r = internalrequest(HTTP.Request("GET", "/docs/schema"))
@test r.status == 404

terminate()
Expand Down Expand Up @@ -662,9 +662,17 @@ stoptasks()
r = internalrequest(HTTP.Request("GET", "/get"))
@test r.status == 200

r = internalrequest(HTTP.Request("GET", "/swagger"))
r = internalrequest(HTTP.Request("GET", "/docs"))
@test r.status == 200

r = internalrequest(HTTP.Request("GET", "/docs/swagger"))
@test r.status == 200

r = internalrequest(HTTP.Request("GET", "/docs/redoc"))
@test r.status == 200

r = internalrequest(HTTP.Request("GET", "/docs/schema"))
@test r.status == 200

invocation = []

Expand Down Expand Up @@ -694,10 +702,10 @@ r = internalrequest(HTTP.Request("GET", "/multiply/3/6"), middleware=[handler1,
@test invocation == [1,2,3] # enusre the handlers are called in the correct order
@test text(r) == "18.0"

r = internalrequest(HTTP.Request("GET", "/swagger"), middleware=[handler1])
r = internalrequest(HTTP.Request("GET", "/docs"), middleware=[handler1])
@test r.status == 200

r = internalrequest(HTTP.Request("GET", "/swagger/schema"))
r = internalrequest(HTTP.Request("GET", "/docs/schema"))
@test r.status == 200
@test Dict(r.headers)["Content-Type"] == "application/json; charset=utf-8"

Expand Down

2 comments on commit 77a19dd

@ndortega
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/92368

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v1.2.0 -m "<description of version>" 77a19ddef27d44202cf2eac7dd090de92f5e6b2b
git push origin v1.2.0

Please sign in to comment.