Skip to content

Commit 608e0bd

Browse files
committed
ENH: Julia 0.7 compatible version
1 parent 616b9b3 commit 608e0bd

File tree

6 files changed

+150
-205
lines changed

6 files changed

+150
-205
lines changed

REQUIRE

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
julia 0.6
2-
Requests 0.3.5
1+
julia 0.7
2+
HTTP
33
JSON
44
PlotlyJS 0.2.0
5-
Compat 0.7.20
65
Reexport

src/Plotly.jl

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
# __precompile__(true)
2-
31
module Plotly
42

5-
using URIParser
3+
using HTTP
64
using Reexport
75
using JSON
86
@reexport using PlotlyJS
7+
using DelimitedFiles, Pkg, Base64 # stdlib
8+
99
export set_credentials_file, RemotePlot, download_plot, savefig_remote, post
1010

1111
const _SRC_ATTRS = let
@@ -30,15 +30,15 @@ function openurl(url::String)
3030
end
3131
end
3232

33-
openurl(url::URI) = openurl(string(url))
33+
openurl(url::HTTP.URI) = openurl(string(url))
3434

3535
"""
3636
Proxy for a plot stored on the Plotly cloud.
3737
"""
3838
struct RemotePlot
39-
url::URI
39+
url::HTTP.URI
4040
end
41-
RemotePlot(url::String) = RemotePlot(URI(url))
41+
RemotePlot(url::String) = RemotePlot(HTTP.URI(url))
4242

4343
"""
4444
fid(rp::RemotePlot)
@@ -60,36 +60,36 @@ Display a plot stored in the Plotly cloud in a browser window.
6060
Base.open(p::RemotePlot) = openurl(p.url)
6161

6262
"""
63-
Post a local Plotly plot to the Plotly cloud.
63+
Post a local Plotly plot to the Plotly cloud using V2 api.
6464
65-
Must be signed in first.
65+
Must be signed in first. See `Plotly.signin` for details on how to do that
6666
"""
67-
function post(p::Plot; fileopt=get_config().fileopt, filename=nothing, kwargs...)
67+
function post_v2(p::Plot; fileopt=get_config().fileopt, filename=nothing, kwargs...)
6868
JSON.lower(p)
6969
fileopt = Symbol(fileopt)
7070
grid_fn = string(filename, "_", "Grid")
7171
clean_p = srcify(p; fileopt=fileopt, grid_fn=grid_fn, kwargs...)
7272
if fileopt == :overwrite
73-
file_data = try_lookup(filename)
73+
file_data = try_lookup(filename) ## Api call 1
7474
if file_data == nothing
7575
fileopt = :create
7676
else
77-
res = plot_update(file_data["fid"], figure=clean_p)
77+
res = plot_update(file_data["fid"], figure=clean_p) ## Api call 2
7878
return RemotePlot(res["web_url"])
7979
end
8080
end
8181
if fileopt == :create || fileopt == :new
8282
if filename == nothing
83-
res = plot_create(clean_p; kwargs...)
83+
res = plot_create(clean_p; kwargs...) ## Api call 2 (or 1)
8484
else
8585
parent_path = dirname(filename)
8686
if !isempty(parent_path)
8787
res = plot_create(
8888
clean_p; parent_path=parent_path,
8989
filename=basename(filename), kwargs...
90-
)
90+
) ## Api call 2 (or 1)
9191
else
92-
res = plot_create(clean_p; filename=filename, kwargs...)
92+
res = plot_create(clean_p; filename=filename, kwargs...) ## Api call 2 (or 1)
9393
end
9494
end
9595

@@ -99,7 +99,7 @@ function post(p::Plot; fileopt=get_config().fileopt, filename=nothing, kwargs...
9999
end
100100
end
101101

102-
function post_v1(p::Plot; kwargs...)
102+
function post(p::Plot; kwargs...)
103103
# call JSON.lower to apply themes
104104
JSON.lower(p)
105105
config = get_config()
@@ -119,27 +119,29 @@ function post_v1(p::Plot; kwargs...)
119119
data = merge(
120120
default_opts,
121121
Dict(
122-
"un" => creds.username,
123-
"key" => creds.api_key,
124-
"args" => json(p.data),
125-
"kwargs" => json(opt)
122+
:un => creds.username,
123+
:key => creds.api_key,
124+
:args => JSON.json(p.data),
125+
:kwargs => JSON.json(opt)
126126
)
127127
)
128128

129-
r = post(endpoint, data=data)
130-
body = Requests.json(r)
131-
if Requests.statuscode(r) 200
129+
res = HTTP.request("POST", endpoint,
130+
["Content-Type" => "application/x-www-form-urlencoded"],
131+
HTTP.URIs.escapeuri(data))
132+
body = JSON.parse(String(deepcopy(res.body)))
133+
if res.status 200
132134
throw(PlotlyError("Non-sucessful status code: $(statuscode(r))"))
133135
elseif "error" keys(body) && body["error"] ""
134136
throw(PlotlyError(body["error"]))
135137
elseif "detail" keys(body) && body["detail"] ""
136138
throw(PlotlyError(body["detail"]))
137139
end
138-
return RemotePlot(URI(body["url"]))
140+
return RemotePlot(HTTP.URI(body["url"]))
139141
end
140142

141143
post(p::PlotlyJS.SyncPlot; kwargs...) = post(p.plot; kwargs...)
142-
post_v1(p::PlotlyJS.SyncPlot; kwargs...) = post_v1(p.plot; kwargs...)
144+
post_v2(p::PlotlyJS.SyncPlot; kwargs...) = post_v2(p.plot; kwargs...)
143145

144146
"""
145147
srcify!(p::Plot; fileopt::Symbol=:overwrite, grid_fn=nothing, kwargs...)
@@ -177,7 +179,7 @@ function extract_grid_data!(p::Plot)
177179
error("bad key...")
178180
end
179181
end
180-
function add_to_grid!(k1::Vector, v::Associative)
182+
function add_to_grid!(k1::Vector, v::AbstractDict)
181183
for (k2, v2) in v
182184
add_to_grid!(vcat(k1, k2), v2)
183185
end

src/utils.jl

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,33 +31,37 @@ const DEFAULT_CONFIG = PlotlyConfig(
3131
:create
3232
)
3333

34-
function Base.merge(config::PlotlyConfig, other::Associative)
34+
function Base.merge(config::PlotlyConfig, other::AbstractDict)
3535
PlotlyConfig(
36-
[get(other, string(name), getfield(config, name)) for name in fieldnames(config)]...
36+
[
37+
get(other, string(name), getfield(config, name))
38+
for name in fieldnames(PlotlyConfig)
39+
]...
3740
)
3841
end
3942

40-
Base.show(io::IO, config::PlotlyConfig) = dump(IOContext(io, limit=true), config)
43+
Base.show(io::IO, config::PlotlyConfig) = dump(IOContext(io, :limit=>true), config)
4144

4245
function Base.Dict(config::PlotlyConfig)
43-
Dict(k => getfield(config, k) for k in fieldnames(config))
46+
Dict(k => getfield(config, k) for k in fieldnames(PlotlyConfig))
4447
end
4548

4649
"""
4750
signin(username::String, api_key::String, endpoints=nothing)
4851
4952
Define session credentials/endpoint configuration, where endpoint is a Dict
5053
"""
51-
function signin(username::String, api_key::String, endpoints::Union{Void,Associative}=nothing)
54+
function signin(
55+
username::String, api_key::String,
56+
endpoints::Union{Nothing,AbstractDict}=nothing
57+
)
5258
global plotlycredentials = PlotlyCredentials(username, api_key)
5359

5460
# if endpoints are specified both the base and api domains must be
5561
# specified
5662
if endpoints != nothing
5763
try
58-
base_domain = endpoints["plotly_domain"]
59-
api_domain = endpoints["plotly_api_domain"]
60-
global plotlyconfig = PlotlyConfig(base_domain, api_domain)
64+
merge(DEFAULT_CONFIG, endpoints)
6165
catch
6266
error("You must specify both the base and api endpoints.")
6367
end
@@ -72,7 +76,7 @@ Return the session credentials if defined --> otherwise use .credentials specs
7276
function get_credentials()
7377
if !isdefined(Plotly, :plotlycredentials)
7478

75-
creds = get_credentials_file()
79+
creds = merge(get_credentials_file(), get_credentials_env())
7680

7781
try
7882
username = creds["username"]
@@ -106,12 +110,12 @@ function get_config()
106110
end
107111

108112
"""
109-
set_credentials_file(input_creds::Associative)
113+
set_credentials_file(input_creds::AbstractDict)
110114
111115
Save Plotly endpoint configuration as JSON key-value pairs in
112116
userhome/.plotly/.credentials. This includes username and api_key.
113117
"""
114-
function set_credentials_file(input_creds::Associative)
118+
function set_credentials_file(input_creds::AbstractDict)
115119
credentials_folder = joinpath(homedir(), ".plotly")
116120
credentials_file = joinpath(credentials_folder, ".credentials")
117121

@@ -128,13 +132,13 @@ function set_credentials_file(input_creds::Associative)
128132
end
129133

130134
"""
131-
set_config_file(input_config::Associative)
135+
set_config_file(input_config::AbstractDict)
132136
133137
Save Plotly endpoint configuration as JSON key-value pairs in
134138
userhome/.plotly/.config. This includes the plotly_domain, and
135139
plotly_api_domain.
136140
"""
137-
function set_config_file(input_config::Associative)
141+
function set_config_file(input_config::AbstractDict)
138142
config_folder = joinpath(homedir(), ".plotly")
139143
config_file = joinpath(config_folder, ".config")
140144

@@ -167,6 +171,20 @@ function get_credentials_file()
167171
isfile(cred_file) ? JSON.parsefile(cred_file) : Dict()
168172
end
169173

174+
function get_credentials_env()
175+
out = Dict()
176+
keymap = Dict(
177+
"PLOTLY_USERNAME" => "username",
178+
"PLOTLY_APIKEY" => "api_key",
179+
)
180+
for k in ["PLOTLY_USERNAME", "PLOTLY_APIKEY"]
181+
if haskey(ENV, k)
182+
out[keymap[k]] = ENV[k]
183+
end
184+
end
185+
out
186+
end
187+
170188
"""
171189
get_config_file()
172190

0 commit comments

Comments
 (0)