Skip to content

Commit

Permalink
Merge pull request #143 from plotly/json3
Browse files Browse the repository at this point in the history
Replacing JSON2 package with JSON3
  • Loading branch information
waralex authored Nov 2, 2021
2 parents 4190e5d + faaf0ae commit 55ee550
Show file tree
Hide file tree
Showing 19 changed files with 133 additions and 66 deletions.
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ DashTable = "1b08a953-4be3-4667-9a23-f0e2ba4deb9a"
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3"
JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
JSON2 = "2535ab7d-5cd8-5a07-80ac-9b1792aadce3"
JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
MD5 = "6ac74813-4b46-53a4-afec-0b5dc9d7885c"
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
PlotlyBase = "a03496cd-edff-5a9b-9e67-9cda94a718b5"
Expand All @@ -30,7 +30,7 @@ DashTable = "5.0.0"
DataStructures = "0.17, 0.18"
HTTP = "0.8.10, 0.9"
JSON = "0.21"
JSON2 = "0.3"
JSON3 = "1.9"
MD5 = "0.2"
PlotlyBase = "0.8.5, 0.8.6"
YAML = "0.4.7"
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,5 @@ Be careful - in Dash.jl states come first in an arguments list.

### JSON:

I use JSON2.jl for JSON serialization/deserialization, so in callbacks all JSON objects are `NamedTuples` rather than dictionaries. Within component properties you can use both `Dict` and `NamedTuple` for JSON objects.

I use JSON3.jl for JSON serialization/deserialization.
Note when declaring elements with a single properly that `layout = (title = "Test graph")` is not interpreted as a `NamedTuple` by Julia - you'll need to add a comma when declaring the layout, e.g. `layout = (title = "Test graph",)`
2 changes: 1 addition & 1 deletion docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,4 +174,4 @@ Be careful - in Dashboards states came first in arguments list

### json:

I use JSON2 for json serialization/deserialization, so in callbacks all json objects are NamedTuples not Dicts. In component props you can use both Dicts and NamedTuples for json objects. But be careful with single property objects: `layout = (title = "Test graph")` is not interpreted as NamedTuple by Julia - you need add comma at the end `layout = (title = "Test graph",)`
I use JSON3 for json serialization/deserialization. In component props you can use both Dicts and NamedTuples for json objects. But be careful with single property objects: `layout = (title = "Test graph")` is not interpreted as NamedTuple by Julia - you need add comma at the end `layout = (title = "Test graph",)`
8 changes: 6 additions & 2 deletions src/Dash.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
module Dash
using DashBase
import HTTP, JSON2, CodecZlib, MD5
import HTTP, JSON3, CodecZlib, MD5
using Sockets
using Pkg.Artifacts

const ROOT_PATH = realpath(joinpath(@__DIR__, ".."))
#const RESOURCE_PATH = realpath(joinpath(ROOT_PATH, "resources"))
include("exceptions.jl")
Expand All @@ -25,6 +26,7 @@ include("resources/application.jl")
include("handlers.jl")
include("server.jl")
include("init.jl")
include("plotly_base.jl")

@doc """
module Dash
Expand Down Expand Up @@ -107,6 +109,8 @@ function __init__()
end


JSON3.StructTypes.StructType(::Type{DashBase.Component}) = JSON3.StructTypes.Struct()
JSON3.StructTypes.excludes(::Type{DashBase.Component}) = (:name, :available_props, :wildcard_regex)


end # module
end # module
9 changes: 8 additions & 1 deletion src/app/supporttypes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ struct Wildcard
type ::Symbol
end

JSON2.write(io::IO, wild::Wildcard; kwargs...) = Base.write(io, "[\"", wild.type, "\"]")
JSON3.StructTypes.StructType(::Type{Wildcard}) = JSON3.RawType()

JSON3.rawbytes(wild::Wildcard) = string("[\"", wild.type, "\"]")

const MATCH = Wildcard(:MATCH)
const ALL = Wildcard(:ALL)
Expand Down Expand Up @@ -30,6 +32,8 @@ const Input = Dependency{TraitInput}
const State = Dependency{TraitState}
const Output = Dependency{TraitOutput}

JSON3.StructTypes.StructType(::Type{<:Dependency}) = JSON3.StructTypes.Struct()

"""
Base.==(a::Dependency, b::Dependency)
Expand Down Expand Up @@ -97,6 +101,9 @@ struct ClientsideFunction
namespace ::String
function_name ::String
end

JSON3.StructTypes.StructType(::Type{ClientsideFunction}) = JSON3.StructTypes.Struct()

struct Callback
func ::Union{Function, ClientsideFunction}
dependencies ::CallbackDeps
Expand Down
6 changes: 3 additions & 3 deletions src/handler/callback_context.jl
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,16 @@ function callback_context()
return get_context(_callback_context_storage)
end

function inputs_list_to_dict(list::Vector{Any})
function inputs_list_to_dict(list::AbstractVector)
result = Dict{String, Any}()
_item_to_dict!.(Ref(result), list)
return result
end

dep_id_string(id::NamedTuple) = sorted_json(id)
dep_id_string(id::AbstractDict) = sorted_json(id)
dep_id_string(id::AbstractString) = String(id)
function _item_to_dict!(target::Dict{String, Any}, item)
target["$(dep_id_string(item.id)).$(item.property)"] = get(item, :value, nothing)
end

_item_to_dict!(target::Dict{String, Any}, item::Vector) = _item_to_dict!.(Ref(target), item)
_item_to_dict!(target::Dict{String, Any}, item::AbstractVector) = _item_to_dict!.(Ref(target), item)
2 changes: 1 addition & 1 deletion src/handler/index_page.jl
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ function config_html(app::DashApp)
max_retry = get_devsetting(app, :hot_reload_max_retry)
)
end
return """<script id="_dash-config" type="application/json">$(JSON2.write(config))</script>"""
return """<script id="_dash-config" type="application/json">$(JSON3.write(config))</script>"""
end


Expand Down
9 changes: 5 additions & 4 deletions src/handler/processors/callback.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ function split_callback_id(callback_id::AbstractString)
end

input_to_arg(input) = get(input, :value, nothing)
input_to_arg(input::Vector) = input_to_arg.(input)
input_to_arg(input::AbstractVector) = input_to_arg.(input)

make_args(inputs, state) = vcat(input_to_arg(inputs), input_to_arg(state))

res_to_vector(res) = res
res_to_vector(res::Vector) = res

function _push_to_res!(res, value, out::Vector)
function _push_to_res!(res, value, out::AbstractVector)
_push_to_res!.(Ref(res), value, out)
end
function _push_to_res!(res, value, out)
Expand Down Expand Up @@ -47,6 +47,7 @@ function process_callback_call(app, callback_id, outputs, inputs, state)

_push_to_res!(response, res_vector, outputs)


if length(response) == 0
throw(PreventUpdate())
end
Expand All @@ -59,7 +60,7 @@ function process_callback(request::HTTP.Request, state::HandlerState)
app = state.app
response = HTTP.Response(200, ["Content-Type" => "application/json"])

params = JSON2.read(String(request.body))
params = JSON3.read(String(request.body))
inputs = get(params, :inputs, [])
state = get(params, :state, [])
output = Symbol(params[:output])
Expand All @@ -74,7 +75,7 @@ function process_callback(request::HTTP.Request, state::HandlerState)
cb_result = with_callback_context(context) do
process_callback_call(app, output, outputs_list, inputs, state)
end
response.body = Vector{UInt8}(JSON2.write(cb_result))
response.body = Vector{UInt8}(JSON3.write(cb_result))
catch e
if isa(e,PreventUpdate)
return HTTP.Response(204)
Expand Down
2 changes: 1 addition & 1 deletion src/handler/processors/layout.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ function process_layout(request::HTTP.Request, state::HandlerState)
return HTTP.Response(
200,
["Content-Type" => "application/json"],
body = JSON2.write(layout_data(state.app.layout))
body = JSON3.write(layout_data(state.app.layout))
)
end
4 changes: 2 additions & 2 deletions src/handler/processors/reload_hash.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ function process_reload_hash(request::HTTP.Request, state::HandlerState)
hard = state.reload.hard,
packages = keys(state.cache.resources.files),
files = state.reload.changed_assets
)
)
state.reload.hard = false
state.reload.changed_assets = []
return HTTP.Response(200, ["Content-Type" => "application/json"], body = JSON2.write(reload_tuple))
return HTTP.Response(200, ["Content-Type" => "application/json"], body = JSON3.write(reload_tuple))

end
2 changes: 1 addition & 1 deletion src/handler/state.jl
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ function _dependencies_json(app::DashApp)
prevent_initial_call = callback.prevent_initial_call
)
end
return JSON2.write(result)
return JSON3.write(result)
end

function _cache_tuple(app::DashApp, registry::ResourcesRegistry)
Expand Down
8 changes: 8 additions & 0 deletions src/plotly_base.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import PlotlyBase
import JSON

function DashBase.to_dash(p::PlotlyBase.Plot)
data = JSON.lower(p)
pop!(data, :config, nothing)
return data
end
20 changes: 10 additions & 10 deletions src/utils/misc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ function format_tag(name ::String, attributes::Dict{String, String}, inner::Stri
tag *= "/>"
elseif opened
tag *= ">"
else
else
tag *= ">$inner</$name>"
end
end
Expand All @@ -32,7 +32,7 @@ function validate_index(name::AbstractString, index::AbstractString, checks::Vec
string(
"Missing item", (length(missings)>1 ? "s" : ""), " ",
join(getindex.(missings, 1), ", "),
" in ", name
" in ", name
)
)
end
Expand All @@ -43,26 +43,26 @@ macro var_str(s)
end

function parse_props(s)
function make_prop(part)
function make_prop(part)
m = match(r"^(?<id>[A-Za-z]+[\w\-\:\.]*)\.(?<prop>[A-Za-z]+[\w\-\:\.]*)$", strip(part))
if isnothing(m)
error("expected <id>.<property>[,<id>.<property>...] in $(part)")
end

return (Symbol(m[:id]), Symbol(m[:prop]))
end
end

props_parts = split(s, ",", keepempty = false)

return map(props_parts) do part
return make_prop(part)
end
end
end

function generate_hash()
return strip(string(UUIDs.uuid4()), '-')
return strip(string(UUIDs.uuid4()), '-')
end

sort_by_keys(data::NamedTuple) = (;sort!(collect(pairs(data)), by = (x)->x[1])...,)
sort_by_keys(data) = (;sort!(collect(pairs(data)), by = (x)->x[1])...,)

sorted_json(data::NamedTuple) = JSON2.write(sort_by_keys(data))
sorted_json(data) = JSON3.write(sort_by_keys(data))
Loading

0 comments on commit 55ee550

Please sign in to comment.