How to run python from Flutter (Android) - python

I want to call a python function that uses numpy and pandas from my flutter app and get the output of this function.
I found a way to do that by using ffi package but I don't know how.
some says that I can do this by making a .dylib file from the python project then use this code to call it
final path = absolute('native/libadd.dylib');
final dylib = DynamicLibrary.open(path);
final add = dylib.lookupFunction('add');
but I am getting this error
: Error: Expected type 'NativeFunction<Function>' to be a valid and instantiated subtype of 'NativeType'.
lib/home_screen.dart:32
- 'NativeFunction' is from 'dart:ffi'.
- 'Function' is from 'dart:core'.
final add = dylib.lookupFunction('add');
so I think it's not available on Android

You should try using Flet for this. It is totally writted in Python language and still provide complete flutter functionality and code. Basic app code from it looks something like:
import flet as ft
def main(page: ft.Page):
page.title = "Flet counter example"
page.vertical_alignment = ft.MainAxisAlignment.CENTER
txt_number = ft.TextField(value="0", text_align=ft.TextAlign.RIGHT, width=100)
def minus_click(e):
txt_number.value = str(int(txt_number.value) - 1)
page.update()
def plus_click(e):
txt_number.value = str(int(txt_number.value) + 1)
page.update()
page.add(
ft.Row(
[
ft.IconButton(ft.icons.REMOVE, on_click=minus_click),
txt_number,
ft.IconButton(ft.icons.ADD, on_click=plus_click),
],
alignment=ft.MainAxisAlignment.CENTER,
)
)
ft.app(target=main)
It's just like a numpy or pandas library that you can import right into your project

Related

Python Clarifai program stopped working inspite of no changes made

I have the following Python code to label images using Clarifai. It was a working code and had been usable for the past 6-8 months. However, for the last few days, I have been getting the error mentioned below. Note that I have not made any changes to the working version of the code for the error to creep in.
#python program to analyse an image and label it
'''
Dependencies:
pip install flask
pip install clarifai-grpc
pip install logging
'''
import json
from flask import Flask, render_template, request
import logging
import os
from clarifai_grpc.channel.clarifai_channel import ClarifaiChannel
from clarifai_grpc.grpc.api import resources_pb2, service_pb2, service_pb2_grpc
from clarifai_grpc.grpc.api.status import status_pb2, status_code_pb2
channel = ClarifaiChannel.get_json_channel()
stub = service_pb2_grpc.V2Stub(channel)
# This will be used by every Clarifai endpoint call.
# The word 'Key' is required to precede the authentication key.
metadata = (('authorization', 'Key API_KEY_HERE'),)
webapp = Flask(__name__) #creating a web application for the current python file
#decorators
#webapp.route('/')
def index():
return render_template('index.html', len=0)
#webapp.route('/' , methods = ['POST'])
def search():
if request.form['searchByURL']:
url = request.form['searchByURL']
my_request = service_pb2.PostModelOutputsRequest(
# This is the model ID of a publicly available General model.
#You may use any other public or custom model ID.
model_id='aaa03c23b3724a16a56b629203edc62c',
inputs=[
resources_pb2.Input(data=resources_pb2.Data(image=resources_pb2.Image(url=url)))
])
response = stub.PostModelOutputs(my_request, metadata=metadata)
if response.status.code != status_code_pb2.SUCCESS:
message = ["You have reached the limit for today!"]
return render_template('/index.html' , len = 1, searchResults = message)
concepts = []
for concept in response.outputs[0].data.concepts:
concepts.append(concept.name)
concepts = concepts[0:10]
return render_template('/index.html' , len = len(concepts), searchResults = concepts )
elif request.files['searchByImage']:
file = request.files['searchByImage']
file.save(file.filename)
#IMAGE INPUT:
with open(file.filename, "rb") as f:
file_bytes = f.read()
post_model_outputs_response = stub.PostModelOutputs(
service_pb2.PostModelOutputsRequest(
model_id="aaa03c23b3724a16a56b629203edc62c",
version_id="aa7f35c01e0642fda5cf400f543e7c40", # This is optional. Defaults to the latest model version.
inputs=[
resources_pb2.Input(
data=resources_pb2.Data(
image=resources_pb2.Image(
base64=file_bytes
)
)
)
]
),
metadata=metadata
)
if post_model_outputs_response.status.code != status_code_pb2.SUCCESS:
message = ["You have reached the limit for today!"]
return render_template('/index.html' , len = 1, searchResults = message)
# Since we have one input, one output will exist here.
output = post_model_outputs_response.outputs[0]
os.remove(file.filename)
concepts = []
#Predicted concepts:
for concept in output.data.concepts:
concepts.append(concept.name)
concepts = concepts[0:10]
return render_template('/index.html' , len = len(concepts), searchResults = concepts )
else:
return render_template('/index.html' , len = 1, searchResults = ["No Image entered!"] )
#run the server
if __name__ == "__main__":
logging.basicConfig(filename = 'error.log' , level = logging.DEBUG, )
webapp.run(debug=True)
Error:
Exception has occurred: ImportError
dlopen(/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/grpc/_cython/cygrpc.cpython-310-darwin.so, 0x0002): tried: '/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/grpc/_cython/cygrpc.cpython-310-darwin.so' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64e'))
File "/Users/eshaangupta/Desktop/Python-Level-4/Image Analyser.py", line 15, in <module>
from clarifai_grpc.channel.clarifai_channel import ClarifaiChannel
It looks like you are trying to run this on a different architecture than you've been in the past. You've been running on x86 (looks like likely MacOS) and now have moved to an arm architecture. I'm guessing you've upgraded to an M1 chip macbook, although maybe you've moved over to a different ARM based chip.
(mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64e'))
This is a problem with a file in grpc - specifically the library file cygrpc.cpython-310-darwin.so. I'd recommend removing gRPC and re-installing and see if that helps to resolve it.
Something like this might work:
python -m pip install --force-reinstall grpcio
(This is assuming python points to python3.10 in your system).
although I'm not sure how you've installed it so that is just a guess.

Azure Machine Learning Studio Designer Error: code_expired

I am trying to register a data set via the Azure Machine Learning Studio designer but keep getting an error. Here is my code, used in a "Execute Python Script" module:
import pandas as pd
from azureml.core.dataset import Dataset
from azureml.core import Workspace
def azureml_main(dataframe1 = None, dataframe2 = None):
ws = Workspace.get(name = <my_workspace_name>, subscription_id = <my_id>, resource_group = <my_RG>)
ds = Dataset.from_pandas_dataframe(dataframe1)
ds.register(workspace = ws,
name = "data set name",
description = "example description",
create_new_version = True)
return dataframe1,
But I get the following error in the Workspace.get line:
Authentication Exception: Unknown error occurred during authentication. Error detail: Unexpected polling state code_expired.
Since I am inside the workspace and in the designer, I do not usually need to do any kind of authentication (or even reference the workspace). Can anybody offer some direction? Thanks!
when you're inside a "Execute Python Script" module or PythonScriptStep, the authentication for fetching the workspace is already done for you (unless you're trying to authenticate to different Azure ML workspace.
from azureml.core import Run
run = Run.get_context()
ws = run.experiment.workspace
You should be able to use that ws object to register a Dataset.

how to avoid importing self, intra-package relationships

The directory structure is like so:
AppCenter/
main.pyw
|
|
_apps/
__init__.py
TabularApp.py
UserAdministrationApp.py
RegisterApp.py
FnAdminApp.py
PyUi/
The contents of __init__.py:
import sys
sys.path.insert(1, '.')
__all__ = ['TabularApp',
'UserAdministrationApp',
'RegisterApp',
'FnAdminApp']
The problems pop up:
When main.pyw tries to from _apps import *.
In UserAdministrationApp.py i am trying to dynamically add tooltips to some QListWidget items like so:
for app in self.__APPS__:
app_icon = str(os.path.join(app_icons, f"{app}.png")).replace('\\', '/')
icon = QIcon(app_icon)
if app != self.__class__:
ttip_txt = eval(f'_apps.{app}.__doc__')
else:
ttip_txt = self.__doc__
item = QListWidgetItem(icon, app)
item.setText(app)
item.setToolTip(ttip_txt)
wdg.addItem(item)
The self.__APPS__ is just a copy of _apps.__all__.
The first problem I encountered was that i would get an AttributeError saying module x has no attribute y in ttip_txt = eval(f'_apps.{app}.__doc__') I resolved this by from _apps import * in UserAdministrationApp module. At this point I had already renamed this module for testing purposes and everything worked, but when I changed the name back to UserAdministrationApp.py I got another AttributeError saying module __apps has no attribute UserAdministrationApp.
Questions
I tried reading the python import docs but nothing in it really spoke to me.
I am sensing it has something to do with the script trying to import itself.
But i am still intrigued by these questions:
Why did the import fail in the first case, when i have import _apps?
Why in the second case does it not at least see itself and then produce an ImportError instead of AtributeError?
What is the optimal way to handle these types of situations?
Okay I found a solution, and though i think it is a bit dirty and not in best style, it works.
First
remove the from _apps import * and just from _apps import __all__.
Then
In initialization of the main class from the module UserAdministrationApp import in a loop skipping self.__class_.__name__
self.__APPS__ = _apps.__all__
self.class_name = self.__class__.__name__
for app in self.__APPS__:
if self.class_name != app:
exec(f'import _apps.{app}')
Finally
for app in self.__APPS__:
app_icon = str(os.path.join(app_icons, f"{app}.png")).replace('\\', '/')
icon = QIcon(app_icon)
if app != self.class_name:
ttip_txt = eval(f'_apps.{app}.__doc__')
else:
ttip_txt = self.__doc__
Having found the solution, I would still like to hear why the error was in the first place, for educational purposes.
So if anybody at any time glances over this and knows how to...you are more than welcome.

Pulling QGIS plugin logic into stand alone Application

I'm new to QT, Python, and QGIS. I installed the "Plugin Builder" plugin and generated a Dockwidget. I am able to change the widget using qtcreator and am learning how to implement the signals and slots to work with my own plugin.
Now, to my question. Is there and easy way I can remove the QGIS iface and use my plugin's logic outside of QGIS? I'm not actually using any of the PyQGIS libraries at the moment, but I want to keep my QT interface and Python code/structure generated by the "Plugin Builder". Is there a way to do that?
Thanks.
Yes, there is a way to do it. But so far what I have found is that we need to copy entire Qgis library to the final software package. It is very important to set the correct path for qgis application inside the code as follows:
QgsApplication.setPrefixPath(r"C:\OSGeo4W\apps\qgis", True)
QgsApplication.initQgis()
QgsProject.instance().setFileName(strProjectName)
Also we need to write the file and close it at the end
QgsProject.instance().write()
QgsApplication.exitQgis()
Here's snapshot of the stand alone package I have created. The code needs some modification for some variables to work.
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *
from qgis.gui import *
import os, datetime
class CreateQgs():
def initQgsFile(self, outputFolder, stopRadius):
strProjectName = str(outputFolder) + "\\" + "PhotoLocationMap.qgs"
QgsApplication.setPrefixPath(r"C:\OSGeo4W\apps\qgis", True)
QgsApplication.initQgis()
QgsProject.instance().setFileName(strProjectName)
highwayShapeFilePath = "C:/Shapefiles/Highway.shp"
arterialShapeFilePath = "C:/Shapefiles/StreetsMajor.shp"
highwayLayer = QgsVectorLayer(self.highwayShapeFilePath, 'HighwayDB' , 'ogr')
arterialLayer = QgsVectorLayer(self.arterialShapeFilePath, 'ArterialDB', 'ogr')
symbols = highwayLayer.rendererV2().symbols()
sym = symbols[0]
sym.setColor(QColor.fromRgb(255,94,94))
highwayLayer.triggerRepaint()
symbols = arterialLayer.rendererV2().symbols()
sym = symbols[0]
sym.setColor(QColor.fromRgb(76,138,245))
arterialLayer.triggerRepaint()
mapInstance = QgsMapLayerRegistry.instance()
mapInstance.instance().addMapLayer(arterialLayer)
mapInstance.instance().addMapLayer(highwayLayer)
QgsProject.instance().write()
QgsApplication.exitQgis()
def unitTest():
app = QgsApplication(sys.argv, True)
photoFolderPath = 'C:\Test\QGis\TestPics'
CreateQgsFile = CreateQgs()
CreateQgsFile.initQgsFile(photoFolderPath, 128)
if __name__ == "__main__":
unitTest()

iTunes win32com Python - AddTrack not working

I've been using the following code to try and create a new playlist in iTunes and a song from the main library - its example code i've found but i keep getting the following error when it runs. I've had a look through the iTunes COM interface documentation and it seems that AddTrack is only available under IITLibraryPlaylist but all of the example code Ive found is as below. Can anyone help>
Error: AttributeError: win32com.ge_py.iTunes 1.13 Type Library.IITPlaylist instance at 0x34035192 object has no attribute 'AddTrack'
Python Code:
import win32com.client
itunes = win32com.client.gencache.EnsureDispatch ("iTunes.Application")
mainLibrary = itunes.LibraryPlaylist
tracks = mainLibrary.Tracks
playlist = itunes.CreatePlaylist("Sonic Jams")
song = tracks.ItemByName('Teen Age Riot')
playlist.AddTrack(song)
in C#
Cast to IITUserPlayList
IITUserPlaylist rclibrary = (IITUserPlaylist)itunes.LibrarySource.Playlists.ItemByName["name"];
rclibrary.AddTrack(item);
i managed to get it using this code if anyone else needs it.
playlist = win32com.client.CastTo(itunes.CreatePlaylist("New List"), 'IITLibraryPlaylist')
song = tracks.ItemByName('Silver Rocket')
playlist.AddTrack(song)

Categories