Skip to content

Commit a6579ec

Browse files
committed
Implementing searchruns
1 parent ddde82b commit a6579ec

File tree

6 files changed

+99
-17
lines changed

6 files changed

+99
-17
lines changed

src/MLFlowClient.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ export
7070
deleterun,
7171
setruntag,
7272
restorerun,
73+
searchruns,
7374
deleteruntag
7475

7576
include("services/loggers.jl")

src/services/experiment.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,8 @@ is the default.
168168
unspecified, return only active experiments.
169169
170170
# Returns
171-
- vector of [`MLFlowExperiment`](@ref) experiments that were found in the MLFlow instance
171+
- Vector of [`Experiment`](@ref) that were found in the MLFlow instance.
172+
- The next page token if there are more results.
172173
"""
173174
function searchexperiments(instance::MLFlow; max_results::Int64=20000,
174175
page_token::String="", filter::String="", order_by::Array{String}=String[],
@@ -183,7 +184,7 @@ function searchexperiments(instance::MLFlow; max_results::Int64=20000,
183184

184185
result = mlfget(instance, "experiments/search"; parameters...)
185186

186-
experiments = result["experiments"] |> (x -> [Experiment(y) for y in x])
187+
experiments = get(result, "experiments", []) |> (x -> [Experiment(y) for y in x])
187188
next_page_token = get(result, "next_page_token", nothing)
188189

189190
return experiments, next_page_token

src/services/run.jl

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,48 @@ function deleteruntag(instance::MLFlow, run_id::String, key::String)::Bool
141141
end
142142
deleteruntag(instance::MLFlow, run::Run, key::String)::Bool =
143143
deleteruntag(instance, run.info.run_id, key)
144+
145+
"""
146+
searchruns(instance::MLFlow; experiment_ids::Array{String}=String[],
147+
filter::String="", run_view_type::ViewType=ACTIVE_ONLY,
148+
max_results::Int=1000, order_by::Array{String}=String[],
149+
page_token::String="")
150+
151+
Search for runs that satisfy expressions. Search expressions can use Metric and
152+
Param keys.
153+
154+
# Arguments
155+
- `instance`: [`MLFlow`](@ref) configuration.
156+
- `experiment_ids`: List of experiment IDs to search over.
157+
- `filter`: A filter expression over params, metrics, and tags, that allows
158+
returning a subset of runs. See [MLFlow documentation](https://mlflow.org/docs/latest/rest-api.html#search-runs).
159+
- `run_view_type`: Whether to display only active, only deleted, or all runs.
160+
Defaults to only active runs.
161+
- `max_results`: Maximum number of runs desired.
162+
- `order_by`: List of columns to be ordered by, including attributes, params,
163+
metrics, and tags with an optional “DESC” or “ASC” annotation, where “ASC” is
164+
the default.
165+
- `page_token`: Token indicating the page of runs to fetch.
166+
167+
# Returns
168+
- Vector of [`Run`](@ref) that were found in the specified experiments.
169+
- The next page token if there are more results.
170+
"""
171+
function searchruns(instance::MLFlow; experiment_ids::Array{String}=String[],
172+
filter::String="", run_view_type::ViewType=ACTIVE_ONLY,
173+
max_results::Int=1000, order_by::Array{String}=String[],
174+
page_token::String="")::Tuple{Array{Run}, Union{String, Nothing}}
175+
parameters = (; experiment_ids, filter,
176+
:run_view_type => run_view_type |> Integer, max_results, page_token)
177+
178+
if order_by |> !isempty
179+
parameters = (; order_by, parameters...)
180+
end
181+
182+
result = mlfpost(instance, "runs/search"; parameters...)
183+
184+
runs = get(result, "runs", []) |> (x -> [Run(y) for y in x])
185+
next_page_token = get(result, "next_page_token", nothing)
186+
187+
return runs, next_page_token
188+
end

src/types/mlflow.jl

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,10 @@ struct MLFlow
3232
headers::Dict
3333
end
3434
MLFlow(apiroot; apiversion=2.0, headers=Dict()) = MLFlow(apiroot, apiversion, headers)
35-
function MLFlow()
36-
apiroot = "http://localhost:5000/api"
37-
if haskey(ENV, "MLFLOW_TRACKING_URI")
38-
apiroot = ENV["MLFLOW_TRACKING_URI"]
39-
end
40-
return MLFlow(apiroot)
41-
end
35+
MLFlow(; apiroot="http://localhost:5000/api", apiversion=2.0, headers=Dict()) =
36+
MLFlow((haskey(ENV, "MLFLOW_TRACKING_URI") ?
37+
ENV["MLFLOW_TRACKING_URI"] : apiroot), apiversion, headers)
38+
4239
Base.show(io::IO, t::MLFlow) = show(io, ShowCase(t, [:apiroot,:apiversion], new_lines=true))
4340

4441
abstract type LoggingData end

test/services/loggers.jl

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ end
102102
run = refresh(mlf, run)
103103
last_metric = run.data.metrics |> last
104104
last_param = run.data.params |> last
105-
last_tag = run.data.tags |> first
105+
last_tag = run.data.tags[
106+
findall(x -> !occursin("mlflow.runName", x.key), run.data.tags)[1]]
106107

107108
@test last_metric isa Metric
108109
@test last_metric.key == "ana"
@@ -127,7 +128,8 @@ end
127128
run = refresh(mlf, run)
128129
last_metric = run.data.metrics |> last
129130
last_param = run.data.params |> last
130-
last_tag = run.data.tags |> first
131+
last_tag = run.data.tags[
132+
findall(x -> !occursin("mlflow.runName", x.key), run.data.tags)[1]]
131133

132134
@test last_metric isa Metric
133135
@test last_metric.key == "ana"
@@ -152,7 +154,8 @@ end
152154
run = refresh(mlf, run)
153155
last_metric = run.data.metrics |> last
154156
last_param = run.data.params |> last
155-
last_tag = run.data.tags |> first
157+
last_tag = run.data.tags[
158+
findall(x -> !occursin("mlflow.runName", x.key), run.data.tags)[1]]
156159

157160
@test last_metric isa Metric
158161
@test last_metric.key == "ana"
@@ -179,7 +182,8 @@ end
179182
run = refresh(mlf, run)
180183
last_metric = run.data.metrics |> last
181184
last_param = run.data.params |> last
182-
last_tag = run.data.tags |> first
185+
last_tag = run.data.tags[
186+
findall(x -> !occursin("mlflow.runName", x.key), run.data.tags)[1]]
183187

184188
@test last_metric isa Metric
185189
@test last_metric.key == "ana"

test/services/run.jl

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,10 @@ end
102102
run = refresh(mlf, run)
103103

104104
@test run.data.tags |> !isempty
105-
@test (run.data.tags |> first).key == "tag"
106-
@test (run.data.tags |> first).value == "value"
105+
last_tag = run.data.tags[
106+
findall(x -> !occursin("mlflow.runName", x.key), run.data.tags)[1]]
107+
@test last_tag.key == "tag"
108+
@test last_tag.value == "value"
107109

108110
deleterun(mlf, run)
109111
end
@@ -115,8 +117,10 @@ end
115117
run = refresh(mlf, run)
116118

117119
@test run.data.tags |> !isempty
118-
@test (run.data.tags |> first).key == "tag"
119-
@test (run.data.tags |> first).value == "value"
120+
last_tag = run.data.tags[
121+
findall(x -> !occursin("mlflow.runName", x.key), run.data.tags)[1]]
122+
@test last_tag.key == "tag"
123+
@test last_tag.value == "value"
120124

121125
deleterun(mlf, run)
122126
end
@@ -151,3 +155,33 @@ end
151155
end
152156
deleteexperiment(mlf, experiment_id)
153157
end
158+
159+
@testset verbose = true "search runs" begin
160+
@ensuremlf
161+
162+
experiment_ids = [
163+
createexperiment(mlf, UUIDs.uuid4() |> string),
164+
createexperiment(mlf, UUIDs.uuid4() |> string),
165+
]
166+
for experiment_id in experiment_ids
167+
createrun(mlf, experiment_id)
168+
end
169+
170+
@testset "default search" begin
171+
runs, next_page_token = searchruns(mlf; experiment_ids=experiment_ids)
172+
173+
@test length(runs) == 2
174+
@test next_page_token |> isnothing
175+
end
176+
177+
@testset "with pagination" begin
178+
runs, next_page_token = searchruns(mlf; experiment_ids=experiment_ids,
179+
max_results=1)
180+
181+
@test length(runs) == 1
182+
@test next_page_token |> !isnothing
183+
@test next_page_token isa String
184+
end
185+
186+
experiment_ids .|> (id -> deleteexperiment(mlf, id))
187+
end

0 commit comments

Comments
 (0)