Dim opt As PyOptions = Py.CreateOptions("C:\Users\ilan1\AppData\Local\Programs\Python\Python314\python.exe")
i did it like this:@hatzisn the solution for such cases is usually to implement it with async methods that do not block the python process. PyBridge support such methods with Py.RunCodeAwait and Wrapper.RunAwait.
Wait For (pyw.Fetch) Complete (Result As PyWrapper)
StopMessageLoop
StartMessageLoop
for /l %i in (1,1,50) do curl "http://localhost/ai/apitest1?text=בערב קיץ חמים ישב דניאל על ספסל העץ שבקצה החצר והרוח נשאה ריח של יסמין והירח עלה לאט מעל הגגות"
welcome back @ilan ...b4x is better with company!i did it like this:
B4X:Wait For (pyw.Fetch) Complete (Result As PyWrapper)
and also added at the end of the function:
B4X:StopMessageLoop
after its done i call again:
B4X:StartMessageLoop
the important thing is NOT TO RUN A ASYNC METHOD INSIDE THE HANDLER!!
i tried running 50 calls to the server at the same time and all went through and all responded back.
B4X:for /l %i in (1,1,50) do curl "http://localhost/ai/apitest1?text=בערב קיץ חמים ישב דניאל על ספסל העץ שבקצה החצר והרוח נשאה ריח של יסמין והירח עלה לאט מעל הגגות"
if there is a better solution, could you please upload a simple version how to make async calls to PyBridge?
I agree that PyBridge is a great library and open many options that were previously difficult to achieve.
@hatzisn the solution for such cases is usually to implement it with async methods that do not block the python process. PyBridge support such methods with Py.RunCodeAwait and Wrapper.RunAwait.
Wait For (py.RunCodeAwait("DoSomething", Array(sString1, sString2, sString3), sCode)) Complete (lRet As PyWrapper)
Wait For (py.RunCode("DoSomething", Array(sString1, sString2, sString3), sCode).Fetch) Complete (lRet As PyWrapper)
i though about using websocket but because its not a feature that make sense to use in my scenario because all i do is a get request to the api and return a value i dont need to stay connected so using handler is more the right way in my case.websockets with call backs work better for python... but always is how your want your app to works..
it should look like this:Would it be possible to post an example?
If I run it with Await then is this code correct?
B4X:Wait For (py.RunCodeAwait("DoSomething", Array(sString1, sString2, sString3), sCode)) Complete (lRet As PyWrapper)
While with run code I do this to get the list returned from Python (with Fetch):
B4X:Wait For (py.RunCode("DoSomething", Array(sString1, sString2, sString3), sCode).Fetch) Complete (lRet As PyWrapper)
The DoSomething sub in Python calls an OnLine http service that answers after some time.
Sub Handle(req As ServletRequest, resp As ServletResponse)
resp.ContentType = "application/json; charset=utf-8"
Dim action As String = req.RequestURI.ToLowerCase
If action.EndsWith("/test") Then
Dim txt As String = req.GetParameter("text")
If txt.Length = 0 Then
resp.Write("{""error"":""missing text""}")
Return
End If
runTest(txt,resp)
StartMessageLoop
Else
resp.Write("{""error"":""unknown endpoint""}")
End If
End Sub
Sub runTest(txt As String,resp As ServletResponse)
Dim pyw As PyWrapper = test1(txt)
Wait For (pyw.Fetch) Complete (Result As PyWrapper)
Dim jg As JSONGenerator
jg.Initialize(CreateMap("text":txt))
resp.ContentType = "application/json; charset=utf-8"
resp.Write(jg.ToPrettyString(2))
StopMessageLoop
End Sub
Sub test1(txt As String) As PyWrapper
Dim code As String = $"
def test1(text):
return text
"$
Return Main.Py.RunCode("test1",Array(txt),code)
End Sub
Two important links about servers and PyBridge:
[PyBridge][server] Using PyBridge in web apps
PyBridge must be accessed from a single thread. In server solutions, each handler runs in its own thread so we need to add some barriers to ensure proper usage. The way to implement it is by adding a background worker dedicated to PyBridge. Other handlers make requests to this worker using...www.b4x.com [PyBridge] [Server] Online charts with Plotly
Porting of this desktop example: https://www.b4x.com/android/forum/threads/pybridge-visualization-of-hierarchical-data-with-plotly.167965/ to jServer. PyBridge runs with a background worker and the interaction with this worker is done with CallSubDelayed. This ensures that the code will be...www.b4x.com
check also post #8 this may solve your issueThe first I have tried it in the past but the second I have not. Quite Impressive.
I tried to find "Await" in both examples but I could not find it. Can you please post also an example with RunCodeAwait.
Maybe when I return home I will try it with my code to check it.
check also post #8 this may solve your issue
You also execute py.RunCode...
This is the problem i am facing now. Everything works in debug mode but in release it doesnot work. Stopmessageloop ends the server and without it it even doesnot work in debug mode.Your solution is not 100% correct. It will fail if multiple calls are made concurrently. Remember that with jServer requests are handled concurrently (in release mode).
The safe solution is to use a background worker that owns and manages PyBridge. Other handles call it with CallSubDelayed and wait for its response.
For simple cases, you can configure the handler to be a single thread handler: srvr.AddHandler("/test/*", "testHandler", True), but this is not scalable.
why not combine them ?This is the problem i am facing now. Everything works in debug mode but in release it doesnot work. Stopmessageloop ends the server and without it it even doesnot work in debug mode.
What would be the right way to do using handlers and not websocket?
I will create a small exampleWhat would be the right way to do using handlers and not websocket?
The only caveat is if the python code has long processing time you cannot implement it easily in a WebApp because the calls are sequential.
The safe solution is to use a background worker that owns and manages PyBridge. Other handles call it with CallSubDelayed and wait for its response.
I've created a related "code snippet": [PyBridge][Server] PyBridge with standard handlers - ErelI think this thread is becoming something that deserves a place in the B4J [PyBridge] forum
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?