1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.
  2. Anuncie Aqui
    Anuncie aqui você Também: fdantas@4each.com.br

[Python] Run a Quart web server in Python with Chaquopy on Android (Kotlin)

Discussão em 'Python' iniciado por Stack, Setembro 15, 2024.

  1. Stack

    Stack Membro Participativo

    I am trying to make an Android app with a Quart app running on Python with Chaquopy but as soon as i add a call to Kotlin from Python i get Error starting Python server: Can't create handler inside thread Thread[Thread-4,5,main] that has not called Looper.prepare() from MainActivity. So i added a call to Looper but that gives me Error starting Python server: Method addObserver must be called on the main thread even though the call to run the Quart app is in the thread where the Python interpreter is started.

    Kotlin:

    package com.example.chatterbot

    import android.annotation.SuppressLint
    import android.net.http.SslError
    import android.os.Bundle
    import android.os.Looper
    import android.util.Log
    import android.webkit.SslErrorHandler
    import android.webkit.WebView
    import android.webkit.WebViewClient
    import androidx.appcompat.app.AppCompatActivity
    import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
    import com.chaquo.python.Python
    import com.chaquo.python.android.AndroidPlatform

    class MainActivity : AppCompatActivity() {

    private val tag: String = "MainActivity" // Define a tag for your logs
    private var serverPort: Int? = null
    private lateinit var webView: WebView
    private lateinit var swipeRefreshLayout: SwipeRefreshLayout

    @SuppressLint("SetJavaScriptEnabled")
    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // Run the Python server in a background thread
    Thread {
    Looper.prepare()
    Log.i(tag, "Starting server")
    Log.i(tag, "IS STARTED")
    Log.i(tag, Python.isStarted().toString())
    if (! Python.isStarted()) {
    Python.start(AndroidPlatform(this))
    }
    try {
    val py = Python.getInstance()
    py.getModule("app").callAttr("run")
    } catch (e: Exception) {
    Log.e(tag, "Error starting Python server: ${e.message}")
    }
    Looper.loop()
    }.start()

    // Set webview
    Log.i(tag, "Starting webview")
    webView = findViewById(R.id.webview)
    webView.webViewClient = object : WebViewClient() {
    override fun onReceivedSslError(
    view: WebView?,
    handler: SslErrorHandler?,
    error: SslError?
    ) {
    // Ignore SSL certificate errors (not recommended for production)
    handler?.proceed()
    }
    }
    webView.settings.javaScriptEnabled = true
    webView.loadUrl("file:///android_asset/iframe/iframe.html")
    swipeRefreshLayout = findViewById(R.id.swipe_refresh_layout)
    swipeRefreshLayout.setOnRefreshListener {
    webView.reload() // Reload the current page
    swipeRefreshLayout.isRefreshing = false // Stop the refreshing animation
    }
    }

    fun closeLoader() {
    Log.i(tag, "Close loader")
    webView.evaluateJavascript("closeLoader();", null)
    }

    }


    Python:

    from hypercorn.asyncio import serve
    from hypercorn.config import Config
    from quart import Quart, render_template
    from com.example.chatterbot import MainActivity

    activity = MainActivity()

    app = Quart(__name__)

    config = Config()
    config.bind = [f"0.0.0.0:8000"]
    config.debug = True

    @app.route('/')
    async def index():
    return await render_template('index.html')

    @app.after_serving
    async def after_startup():
    # This code will run after the server is fully loaded and ready to receive requests
    print("Server ready")
    activity.closeLoader() # <-- **The problem comes when i add this**

    def run():
    app.run(host="0.0.0.0", port=8000, debug=True)

    Continue reading...

Compartilhe esta Página