Skip to content

Notes from JuliaCon Global 2025 #3

Description

@mkitti

These notes came from the JuliaCon Global 2025 hackathon in Pittsburgh.
https://julialang.slack.com/archives/C097GBGDGCT

Bjorn Paulson started working on this and I eventually joined.

julia> python_command = "import appose.python_worker; appose.python_worker.main()"
"import appose.python_worker; appose.python_worker.main()"

julia> begin
           to_python = Pipe()
           from_python = Pipe()
           err_python = Pipe()
           pl = pipeline(`pixi run python -c $python_command`, stdin=to_python, stdout=from_python, stderr=from_python)
           p = run(pl, wait=false)
       end
Process(`pixi run python -c 'import appose.python_worker; appose.python_worker.main()'`, ProcessRunning)
julia> begin
           python_command = "import appose.python_worker; appose.python_worker.main()"
           to_python = Pipe()
           from_python = Pipe()
           err_python = Pipe()
           pl = pipeline(`pixi run python -c $python_command`, stdin=to_python, stdout=from_python, stderr=from_python)
           p = run(pl, wait=false)
           @async while true
               readline(from_python) |> println
           end
       end
julia> begin
           using JSON3, UUIDs
           python_command = "import appose.python_worker; appose.python_worker.main()"
           to_python = Pipe()
           from_python = Pipe()
           err_python = Pipe()
           pl = pipeline(`pixi run python -c $python_command`, stdin=to_python, stdout=from_python, stderr=from_python)
           p = run(pl, wait=false)
           ch = Channel()
           Threads.@spawn while true
               #readline(from_python) |> println
               push!(ch, JSON3.read(readline(from_python)))
           end
       end
julia> function appose_execute(script, inputs=Dict{String, Any}())
           d = Dict{String, Any}(
               "task" => string(uuid4()),
               "requestType" => "EXECUTE",
               "script" => script,
               "inputs" => inputs
           )
           JSON3.write(d) * "\n"
       end
appose_execute (generic function with 2 methods)
julia> python_command = """
       import appose;
       shm = appose.SharedMemory(create = True, rsize=2*2*20*25)
       data = appose.NDArray("uint16", [2,20,25], shm)
       data.ndarray()[0,0,0] = 567
       task.outputs["result"] = data
       """
"import appose;\nshm = appose.SharedMemory(create = True, rsize=2*2*20*25)\ndata = appose.NDArray(\"uint16\", [2,20,25], shm)\ndata.ndarray()[0,0,0] = 567\ntask.outputs[\"result\"] = data\n"

julia> write(to_python, appose_execute(python_command))
284

julia> result = take!(ch)
JSON3.Object{Base.CodeUnits{UInt8, String}, Vector{UInt64}} with 2 entries:
  :task         => "a21fcae5-fb03-45f6-acb9-76a8fcf4d60a"
  :responseType => "LAUNCH"

julia> result = take!(ch)
JSON3.Object{Base.CodeUnits{UInt8, String}, Vector{UInt64}} with 3 entries:
  :outputs      => {…
  :task         => "a21fcae5-fb03-45f6-acb9-76a8fcf4d60a"
  :responseType => "COMPLETION"
julia> using SharedArrays

julia> arr = SharedArray{Int16}("/dev/shm/" * result.outputs.result.shm.name, (25, 20, 2));

julia> arr[1]
567
julia> using JSON3, UUIDs

julia> function process_appose_execute(d::Dict{String})
           expr = Meta.parse(d["script"])
           inputs = d["input"]
           mod = Module()
           Core.eval(mod, quote
               task = (; outputs = Dict{String, Any}(), inputs = $inputs)
           end)
           for (k, v) in inputs
               Core.eval(mod, Expr(:(=), [Symbol(k), Meta.parse(v)]))
           end
           Core.eval(mod, Meta.parse(d["script"]))
           outputs = mod.task.outputs
           return Dict{String, Any}(
               "task" => d["task"],
               "responseType" => "COMPLETION",
               "outputs" => outputs
           )
       end
process_appose_execute (generic function with 2 methods)

julia> process_appose_execute(d::Dict{String}, ::Type{String}) = JSON3.write(process_appose_execute(d))
process_appose_execute (generic function with 2 methods)

julia> process_appose_execute(Dict("task" => string(uuid4()), "script" => "task.outputs[\"result\"] = 5 + 5", "input" => Dict{String,Any}()))
Dict{String, Any} with 3 entries:
  "task"         => "5de55234-33b8-49fa-af88-7fbd9f422a3e"
  "responseType" => "COMPLETION"
  "outputs"      => Dict{String, Any}("result"=>10)

julia> process_appose_execute(Dict("task" => string(uuid4()), "script" => "task.outputs[\"result\"] = 5 + 5", "input" => Dict{String,Any}()), String)
"{\"task\":\"68490a94-afaf-4349-b8b8-4610a2e3a2ba\",\"responseType\":\"COMPLETION\",\"outputs\":{\"result\":10}}"

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions