Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OSError: access violation when calling Julia code in Dash app #507

Open
crabbixOCE opened this issue Oct 26, 2022 · 12 comments
Open

OSError: access violation when calling Julia code in Dash app #507

crabbixOCE opened this issue Oct 26, 2022 · 12 comments

Comments

@crabbixOCE
Copy link

Trying to call any julia code from inside a Dash app results in
OSError: exception: access violation reading 0x0000000000000018.

This error occurs no matter what code I try to call, even things like
Julia().eval("2+2")
so I know it's not a result of Julia errors.

My current workaround is running a second Quart app and sending POST requests to trigger asynchronous callbacks containing my Julia functions, which for some reason actually allow me to run my julia code. It seems ridiculous that I can't simply run my Julia code inside the dash app and if there's a known fix to this I'd very much like to hear it.

@mkitti
Copy link
Member

mkitti commented Nov 23, 2022

Can you provide a minimum working example?

@magnusbbc
Copy link

I am having the exact same issue. JuliaCall has a similar issue

@mkitti
Copy link
Member

mkitti commented Mar 20, 2023

I need specific steps to reproduce, please.

@magnusbbc
Copy link

magnusbbc commented Mar 20, 2023

sure!

Here is a minimum example (modified from here)

from dash import Dash, dcc, html, Input, Output
from julia import Main

app = Dash(__name__)

app.layout = html.Div([
    html.H6("Change the value in the text box to see callbacks in action!"),
    html.Div([
        "Input: ",
        dcc.Input(id='my-input', value='initial value', type='text')
    ]),
    html.Br(),
    html.Div(id='my-output'),

])


@app.callback(
    Output(component_id='my-output', component_property='children'),
    Input(component_id='my-input', component_property='value')
)
def update_output_div(input_value):
    print(Main.eval("2+2"))
    return f'Output: {input_value}'


if __name__ == '__main__':
    app.run_server(debug=True)

When you interact with the callback you should see : the OSError: exception: access violation reading 0x0000000000000018 error shown in the app

@mkitti
Copy link
Member

mkitti commented Mar 20, 2023

Is it possible that Dash may be using multiple threads here? Is Julia eval bring called on a separate thread than the one where Julia was initialized during the callback?

@magnusbbc
Copy link

I also suspected this may be the case, however it seems to me that the default configuration of Dash (as shown in the above example) should only use a single thread

@mkitti
Copy link
Member

mkitti commented Mar 21, 2023

I know this is not a great workaround, but have you considered using
https://github.com/plotly/Dash.jl

Could you also detail environment system and report your operating system? Did you use pip or conda to set this up?

@crabbixOCE
Copy link
Author

Hey, not sure how useful this is for your case but the solution I went with in the end was simply to use HTTP.jl to set up a simple server, and just passed necessary data to and from the Dash app via HTTP requests. I found Dash.jl to be significantly underdeveloped for my requirements.

@magnusbbc
Copy link

I know this is not a great workaround, but have you considered using https://github.com/plotly/Dash.jl

Could you also detail environment system and report your operating system? Did you use pip or conda to set this up?

I am on windows using julia 1.8.5 and python 3.11 (also tried 3.10). I used pip to configure my environment

Like crabbixOCE, i also found Dash.jl to be too underderveloped for me

@magnusbbc
Copy link

magnusbbc commented Mar 21, 2023

Hey, not sure how useful this is for your case but the solution I went with in the end was simply to use HTTP.jl to set up a simple server, and just passed necessary data to and from the Dash app via HTTP requests. I found Dash.jl to be significantly underdeveloped for my requirements.

Cool! I think that sounds like a decent for now solution. How do you do type conversions? Could you possibly provide a small example?

@crabbixOCE
Copy link
Author

crabbixOCE commented Mar 21, 2023

Sure, I would send a json object from the python side, like

q = requests.post(

'http://127.0.0.1:8000/start',
json=json.dumps({'data':data_obj}),
verify=False,
timeout=10
)

And then use the JSON3 package to parse it on the julia side:

const router = HTTP.Router()
HTTP.@register(router, "POST", "/start", bar)

HTTP.serve(router, ip"127.0.0.1", 8000)

function bar(req)
json_received = JSON3.read(JSON3.read(req.body))
data = json_received["data"]

Don't ask me why the JSON3.read is double-nested, that's just the way it seems to work lmao.

For more complicated structures this might fail; in this case consider using a database or csv files as an intermediate. Hope this helps!

@lxvm
Copy link

lxvm commented Apr 26, 2023

Has anyone tried the MWE again with Julia v1.9? The new language feature allowing the number of threads to change during execution may help this work. Using juliacall and writing dash callbacks with simple functions like addition worked for me, but I ran into problems with anything involving strings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants