Tracking API
User and permission management lives in Users and permissions.
Projects
DearDiary.get_project — Function
get_project(id::Integer)::Optional{Project}Get a Project by id.
Arguments
id::Integer: The id of the project to query.
Returns
A Project object. If the record does not exist, return nothing.
get_project(client::Client, id::Integer)::Optional{Project}Fetch a Project via GET /project/{id} on the API behind client. Returns nothing when the server replies 404 (record missing or viewer lacks ReadPermission) and raises ClientError for other failures.
DearDiary.get_projects — Function
get_projects(user::User)::Array{Project,1}Return the projects visible to user.
Admins see every project. Non-admins see only projects where they have a UserPermission record with ReadPermission granted; projects without a matching permission row are omitted entirely so the dashboard never shows cards the viewer cannot open.
Arguments
user::User: The viewer.
Returns
An array of Project objects scoped to the user's read access.
get_projects(client::Client)::Array{Project,1}List every Project the authenticated viewer can read via GET /project/. Admins receive every project; non-admins receive only those with ReadPermission granted.
DearDiary.create_project — Function
create_project(user_id::Integer, name::AbstractString)::NamedTuple{id::Optional{<:Int64},status::DataType}Create a Project.
Arguments
user_id::Integer: The id of the user creating the project. The user must have admin privileges.name::AbstractString: The name of the project.
Returns
- The created project ID. If an error occurs,
nothingis returned. - An
UpsertResult.Createdif the record was successfully created,Duplicateif the record already exists,Unprocessableif the record violates a constraint, andErrorif an error occurred while creating the record.
create_project(name::AbstractString)::NamedTuple{id::Optional{<:Int64},status::DataType}Create a Project. Uses the "default" user to create the project.
Arguments
name::AbstractString: The name of the project.
Returns
- The created project ID. If an error occurs,
nothingis returned. - An
UpsertResult.Createdif the record was successfully created,Duplicateif the record already exists,Unprocessableif the record violates a constraint, andErrorif an error occurred while creating the record.
create_project(client::Client, name::AbstractString)::Int64Create a Project named name via POST /project/. The route requires an admin viewer; non-admin callers receive 403 ADMIN_REQUIRED. Returns the new project id.
DearDiary.update_project — Function
update_project(id::Int, name::Optional{AbstractString}, description::Optional{AbstractString})::Type{<:UpsertResult}Update a Project record.
Arguments
id::Integer: The id of the project to update.name::Optional{AbstractString}: The new name for the project.description::Optional{AbstractString}: The new description for the project.
Returns
An UpsertResult. Updated if the record was successfully updated (or no changes were made), Duplicate if the record already exists, Unprocessable if the record violates a constraint, and Error if an error occurred while creating the record.
update_project(client::Client, id::Integer; name=nothing, description=nothing)::NothingPatch a Project via PATCH /project/{id}. Any keyword left as nothing is left untouched server-side. Admin-only. Raises ClientError on failure.
DearDiary.delete_project — Function
delete_project(id::Integer)::BoolDelete a Project record. Also deletes all associated UserPermission and Experiment records.
Arguments
id::Integer: The id of the project to delete.
Returns
true if the record was successfully deleted, false otherwise.
delete_project(client::Client, id::Integer)::NothingDelete a Project (cascading UserPermission and Experiment records) via DELETE /project/{id}. Admin-only. Raises ClientError on failure.
Experiments
DearDiary.get_experiment — Function
get_experiment(id::Integer)::Optional{Experiment}Get a Experiment by id.
Arguments
id::Integer: The id of the experiment to query.
Returns
A Experiment object. If the record does not exist, return nothing.
get_experiment(client::Client, id::Integer)::Optional{Experiment}Fetch an Experiment via GET /experiment/{id}. Returns nothing when the server replies 404 (record missing or viewer lacks ReadPermission on the owning project) and raises ClientError for other failures.
DearDiary.get_experiments — Function
get_experiments(project_id::Integer)::Array{Experiment, 1}Get all Experiment for a given project.
Arguments
project_id::Integer: The id of the project to query.
Returns
An array of Experiment objects.
get_experiments(project_id::Integer, page::Pagination)::PaginatedResponse{Experiment}Get a page of Experiment records for a project, with total count populated.
Arguments
project_id::Integer: The id of the project to query.page::Pagination: The page bounds (limit + offset).
Returns
A PaginatedResponse of Experiment.
get_experiments(client::Client, project_id::Integer)::Array{Experiment,1}Returns the first page (default limit) of Experiment records under project_id, discarding the pagination envelope.
get_experiments(client::Client, project_id::Integer, page::Pagination)::PaginatedResponse{Experiment}Fetch a page of Experiment records under project_id via GET /experiment/project/{project_id}?limit=…&offset=…. Requires ReadPermission on the project.
DearDiary.create_experiment — Function
create_experiment(project_id::Integer, status_id::Integer, name::AbstractString)::NamedTuple{id::Optional{<:Int64},status::DataType}Create a Experiment.
Arguments
project_id::Integer: The id of the project to create the experiment for.status_id::Integer: The status of the experiment.name::AbstractString: The name of the experiment.
Returns
- The created experiment ID. If an error occurs,
nothingis returned. - An
UpsertResult.Createdif the record was successfully created,Duplicateif the record already exists,Unprocessableif the record violates a constraint, andErrorif an error occurred while creating the record.
create_experiment(project_id::Integer, status::ExperimentStatus, name::AbstractString)::NamedTuple{id::Optional{<:Int64},status::DataType}Create a Experiment.
Arguments
project_id::Integer: The id of the project to create the experiment for.status::ExperimentStatus: The status of the experiment.name::AbstractString: The name of the experiment.
Returns
- The created experiment ID. If an error occurs,
nothingis returned. - An
UpsertResult.Createdif the record was successfully created,Duplicateif the record already exists,Unprocessableif the record violates a constraint, andErrorif an error occurred while creating the record.
create_experiment(client::Client, project_id::Integer, status_id::Integer, name::AbstractString)::Int64Create an Experiment under project_id via POST /experiment/project/{project_id}. status_id must equal Integer(IN_PROGRESS); the server rejects experiments created already terminated. Requires CreatePermission on the project. Returns the new experiment id.
create_experiment(client::Client, project_id::Integer, status::ExperimentStatus, name::AbstractString)::Int64ExperimentStatus-typed overload of create_experiment. The server only accepts IN_PROGRESS; the other variants exist for symmetry with the local API.
DearDiary.update_experiment — Function
update_experiment(id::Integer, status_id::Optional{Integer}, name::Optional{AbstractString}, description::Optional{AbstractString}, end_date::Optional{DateTime})::Type{<:UpsertResult}Update a Experiment record.
Arguments
id::Integer: The id of the experiment to update.status_id::Optional{Integer}: The new status of the experiment.name::Optional{AbstractString}: The new name of the experiment.description::Optional{AbstractString}: The new description of the experiment.end_date::Optional{DateTime}: The new end date of the experiment.
Returns
An UpsertResult. Updated if the record was successfully updated (or no changes were made), Duplicate if the record already exists, Unprocessable if the record violates a constraint, and Error if an error occurred while creating the record.
update_experiment(id::Integer, status::ExperimentStatus, name::Optional{AbstractString}, description::Optional{AbstractString}, end_date::Optional{DateTime})::Type{<:UpsertResult}Update a Experiment record.
Arguments
id::Integer: The id of the experiment to update.status::ExperimentStatus: The new status of the experiment.name::Optional{AbstractString}: The new name of the experiment.description::Optional{AbstractString}: The new description of the experiment.end_date::Optional{DateTime}: The new end date of the experiment.
Returns
An UpsertResult. Updated if the record was successfully updated (or no changes were made), Duplicate if the record already exists, Unprocessable if the record violates a constraint, and Error if an error occurred while creating the record.
update_experiment(client::Client, id::Integer; status_id=nothing, name=nothing, description=nothing, end_date=nothing)::NothingPatch an Experiment via PATCH /experiment/{id}. Any keyword left as nothing is left untouched server-side. Reopening (status_id == Integer(IN_PROGRESS) on a row that previously had an end_date) clears end_date automatically. Requires UpdatePermission on the owning project.
update_experiment(client::Client, id::Integer, status::ExperimentStatus; name=nothing, description=nothing, end_date=nothing)::NothingExperimentStatus-typed overload of update_experiment.
DearDiary.delete_experiment — Function
delete_experiment(id::Integer)::BoolDelete a Experiment record. Also deletes all associated Iteration and Resource records.
Arguments
id::Integer: The id of the experiment to delete.
Returns
true if the record was successfully deleted, false otherwise.
delete_experiment(client::Client, id::Integer)::NothingDelete an Experiment (and its Iterations + Resources) via DELETE /experiment/{id}. Requires DeletePermission on the owning project.
Iterations
DearDiary.get_iteration — Function
get_iteration(id::Integer)::Optional{Iteration}Get a Iteration by id.
Arguments
id::Integer: The id of the iteration to query.
Returns
A Iteration object. If the record does not exist, return nothing.
get_iteration(client::Client, id::Integer)::Optional{Iteration}Fetch an Iteration via GET /iteration/{id}. Returns nothing when the server replies 404 and raises ClientError for other failures. Requires ReadPermission on the iteration's project.
DearDiary.get_iterations — Function
get_iterations(experiment_id::Integer)::Array{Iteration, 1}Get all Iteration for a given experiment.
Arguments
experiment_id::Integer: The id of the experiment to query.
Returns
An array of Iteration objects.
get_iterations(experiment_id::Integer, page::Pagination)::PaginatedResponse{Iteration}Get a page of Iteration records for an experiment, with total count populated.
Arguments
experiment_id::Integer: The id of the experiment to query.page::Pagination: The page bounds (limit + offset).
Returns
A PaginatedResponse of Iteration.
get_iterations(client::Client, experiment_id::Integer)::Array{Iteration,1}Returns the first page (default limit) of Iteration records under experiment_id, discarding the pagination envelope.
get_iterations(client::Client, experiment_id::Integer, page::Pagination)::PaginatedResponse{Iteration}Fetch a page of Iteration records under experiment_id via GET /iteration/experiment/{experiment_id}?limit=…&offset=….
DearDiary.get_child_iterations — Function
get_child_iterations(parent_id::Integer)::Array{Iteration, 1}Return the direct children of parent_id: iterations whose parent_iteration_id points at it, ordered by id ascending. Returns an empty array when no children exist.
Arguments
parent_id::Integer: The id of the parent iteration.
Returns
An array of child Iteration objects.
get_child_iterations(client::Client, parent_id::Integer)::Array{Iteration,1}Fetch the direct children of parent_id via GET /iteration/{parent_id}/children. Returns an empty array when no children exist. Requires ReadPermission on the iteration's project.
DearDiary.create_iteration — Function
create_iteration(experiment_id::Integer; parent_iteration_id=nothing)::NamedTuple{id::Optional{<:Int64},status::DataType}Create a Iteration.
When parent_iteration_id is supplied, the new row is a child run, used to model HPO trials, nested-CV folds, or distributed-worker fan-outs. The parent must already exist and must belong to the same experiment_id; cross-experiment lineage is rejected with Unprocessable.
Arguments
experiment_id::Integer: The id of the experiment to create the iteration for.parent_iteration_id::Optional{Integer}: When set, the id of the parent iteration.
Returns
- The created iteration ID, or
nothingon failure. - An
UpsertResult.
create_iteration(client::Client, experiment_id::Integer; parent_iteration_id=nothing)::IterationOpen a fresh Iteration under experiment_id via POST /iteration/experiment/{experiment_id} and fetch the freshly-created row so the caller can immediately use its id and created_date. The parent experiment must be IN_PROGRESS. Requires CreatePermission on the owning project.
When parent_iteration_id is supplied, the new row is registered as a child of the given iteration (HPO trial, distributed worker, nested CV fold). The parent must belong to the same experiment_id.
DearDiary.update_iteration — Function
update_iteration(id::Integer, notes::Optional{AbstractString}, end_date::Optional{DateTime}; status_id=nothing, error_message=nothing)::Type{<:UpsertResult}Update a Iteration record.
Once an iteration has been finalised (end_date is set), the row is locked: further updates return Unprocessable. The intended terminal-state flow is to pass end_date, status_id, and (when applicable) error_message together in a single call.
Arguments
id::Integer: The id of the iteration to update.notes::Optional{AbstractString}: The new notes for the iteration.end_date::Optional{DateTime}: The new end date for the iteration.status_id::Optional{Integer}: The newIterationStatusvalue. Must be one of the four valid integers (1..4) ornothing.error_message::Optional{AbstractString}: The captured exception text when the iteration ended in aFAILEDstate.
Returns
An UpsertResult.
update_iteration(id::Integer, notes::Optional{AbstractString}, end_date::Optional{DateTime}, status::IterationStatus; error_message=nothing)::Type{<:UpsertResult}IterationStatus-typed overload of update_iteration.
update_iteration(client::Client, id::Integer; notes=nothing, end_date=nothing, status=nothing, error_message=nothing)::NothingPatch an Iteration via PATCH /iteration/{id}. Any keyword left as nothing is left untouched server-side. Once an iteration has an end_date set, the server locks it: further updates fail with ClientError "INVALID_PAYLOAD". Requires UpdatePermission on the owning project.
status accepts an IterationStatus enum value; the integer is sent on the wire.
DearDiary.delete_iteration — Function
delete_iteration(id::Integer)::BoolDelete a Iteration record. Children whose parent_iteration_id points at this row have their reference set to NULL by the service layer before the delete; they continue to exist as standalone iterations until explicitly deleted.
Arguments
id::Integer: The id of the iteration to delete. Also deletes all associatedParameterandMetricrecords.
Returns
true if the record was successfully deleted, false otherwise.
delete_iteration(client::Client, id::Integer)::NothingDelete an Iteration (and its Parameters + Metrics) via DELETE /iteration/{id}. Requires DeletePermission on the owning project.
DearDiary.with_iteration — Function
with_iteration(f::Function, experiment_id::Integer; parent_iteration_id=nothing, snapshot=parent_iteration_id |> isnothing)Open a fresh Iteration under experiment_id via create_iteration, pass it to f, and finalise the iteration's end_date and status_id regardless of whether the body returns normally or throws. On a clean return the iteration is marked SUCCEEDED; on an exception it is marked FAILED with the captured exception text in error_message, and the exception is rethrown so the caller still sees it.
By default the function calls snapshot_environment! on the new iteration right after creation, but only when it has no parent. Driver runs capture the env; child runs inherit it. Pass snapshot=true to force a per-child capture (each child gets its own snapshot, useful when workers run in different processes) or snapshot=false to skip entirely.
Arguments
f::Function: A unary function that receives the freshly-createdIteration.experiment_id::Integer: The id of theExperimentthat owns the iteration.parent_iteration_id::Optional{Integer}: When set, the new iteration is registered as a child of the given parent, useful for HPO sweeps and distributed-worker fan-outs.snapshot::Bool: Whether to callsnapshot_environment!after creation. Defaults totruefor driver iterations andfalsefor children.
Returns
Whatever f returns.
with_iteration(f::Function, client::Client, experiment_id::Integer; parent_iteration_id=nothing, snapshot=parent_iteration_id |> isnothing)Open a fresh Iteration under experiment_id, invoke f(iteration), and finalise the iteration regardless of whether the body returns normally or throws. On a clean return the iteration is marked SUCCEEDED; on an exception it is marked FAILED with the captured exception text in error_message, and the exception is rethrown so the caller still sees it.
By default the helper attaches an EnvironmentSnapshot to the new iteration immediately after creation, but only when it has no parent: driver runs capture the env, child runs inherit it. Pass snapshot=true to force a per-child capture or snapshot=false to skip entirely.
When parent_iteration_id is supplied, the new iteration is registered as a child of the given parent, useful for HPO sweeps and distributed-worker fan-outs.
Example
client = DearDiary.connect("http://127.0.0.1:9000"; username="default", password="default")
result = with_iteration(client, experiment_id) do iter
create_parameter(client, iter.id, "lr", 1e-3)
for epoch in 1:10
create_metric(client, iter.id, "loss", train_step!(model))
end
model
endTags
DearDiary.get_tag — Function
get_tag(id::Integer)::Optional{Tag}Get a Tag by id.
Arguments
id::Integer: The id of the tag to query.
Returns
A Tag object. If the record does not exist, return nothing.
get_tag(value::AbstractString)::Optional{Tag}Get a Tag by value.
Arguments
value::AbstractString: The value of the tag to query.
Returns
A Tag object. If the record does not exist, return nothing.
get_tag(client::Client, id::Integer)::Optional{Tag}Fetch a Tag by id via GET /tag/{id}. Returns nothing when the server replies 404 and raises ClientError for other failures. Admin-only route.
The value-based local overload (get_tag(value)) has no REST counterpart; iterate the parent-scoped get_tags listings to discover a tag by its value.
DearDiary.get_tags — Function
get_tags(::Type{<:Project}, project_id::Integer)::Array{Tag, 1}Get all Tag for a given project.
Arguments
::Type{<:Project}: The project type.project_id::Integer: The id of the project to query.
Returns
An array of Tag objects.
get_tags(::Type{<:Experiment}, experiment_id::Integer)::Array{Tag, 1}Get all Tag for a given experiment.
Arguments
::Type{<:Experiment}: The experiment type.experiment_id::Integer: The id of the experiment to query.
Returns
An array of Tag objects.
get_tags(::Type{<:Iteration}, iteration_id::Integer)::Array{Tag, 1}Get all Tag for a given iteration.
Arguments
::Type{<:Iteration}: The iteration type.iteration_id::Integer: The id of the iteration to query.
Returns
An array of Tag objects.
get_tags(client::Client, ::Type{T}, parent_id::Integer)::Array{Tag,1} where {T<:Union{Project,Experiment,Iteration}}List every Tag attached to parent_id of kind T, via GET /tag/{kind}/{parent_id}. Requires ReadPermission on the owning project.
DearDiary.create_tag — Function
create_tag(value::AbstractString)::NamedTuple{id::Optional{<:Int64},status::DataType}Create a Tag.
Arguments
value::AbstractString: The value of the tag.
Returns
- The created tag ID. If an error occurs,
nothingis returned. - An
UpsertResult.Createdif the record was successfully created,Duplicateif the record already exists,Unprocessableif the record violates a constraint, andErrorif an error occurred while creating the record.
DearDiary.add_tag — Function
add_tag(::Type{<:Project}, project_id::Integer, tag_value::AbstractString)::NamedTuple{id::Optional{<:Int64},status::DataType}Add a tag to a project.
Arguments
::Type{<:Project}: The project type.project_id::Integer: The id of the project to add the tag to.tag_value::AbstractString: The value of the tag to add.
Returns
- The created project_tag association ID. If an error occurs,
nothingis returned. - An
UpsertResult.Createdif the record was successfully created,Duplicateif the record already exists,Unprocessableif the record violates a constraint, andErrorif an error occurred while creating the record.
add_tag(::Type{<:Experiment}, experiment_id::Integer, tag_value::AbstractString)::NamedTuple{id::Optional{<:Int64},status::DataType}Add a tag to an experiment.
Arguments
::Type{<:Experiment}: The experiment type.experiment_id::Integer: The id of the experiment to add the tag to.tag_value::AbstractString: The value of the tag to add.
Returns
- The created experiment_tag association ID. If an error occurs,
nothingis returned. - An
UpsertResult.Createdif the record was successfully created,Duplicateif the record already exists,Unprocessableif the record violates a constraint, andErrorif an error occurred while creating the record.
add_tag(::Type{<:Iteration}, iteration_id::Integer, tag_value::AbstractString)::NamedTuple{id::Optional{<:Int64},status::DataType}Add a tag to an iteration.
Arguments
::Type{<:Iteration}: The iteration type.iteration_id::Integer: The id of the iteration to add the tag to.tag_value::AbstractString: The value of the tag to add.
Returns
- The created iteration_tag association ID. If an error occurs,
nothingis returned. - An
UpsertResult.Createdif the record was successfully created,Duplicateif the record already exists,Unprocessableif the record violates a constraint, andErrorif an error occurred while creating the record.
add_tag(client::Client, ::Type{T}, parent_id::Integer, value::AbstractString)::Int64 where {T<:Union{Project,Experiment,Iteration}}Attach a tag value to parent_id of kind T, via POST /tag/{kind}/{parent_id}. The server upserts the underlying Tag row if it does not exist already. Returns the association id. Requires CreatePermission on the owning project; for iterations the parent must not be terminated.
The local standalone create_tag(value) has no REST counterpart; tags only exist attached to a parent.
DearDiary.delete_tag — Function
delete_tag(id::Integer)::BoolDelete a Tag record.
Arguments
id::Integer: The id of the tag to delete.
Returns
true if the record was successfully deleted, false otherwise.
delete_tag(client::Client, id::Integer)::NothingDelete a Tag (and its parent associations) via DELETE /tag/{id}. Admin-only.