I have VBA code calling a Python script that works on my PC.
The Python code uses SQL Alchemy to create an Engine, connects to a database, binds the session and retrieve data using a SELECT * FROM basic query. After it reads it, the data is sent to an xlsx file.
Python code with some minor changes for security reasons:
# import dependencies
from sqlalchemy import create_engine
from sqlalchemy.orm import Session
import pandas as pd
import os
import cx_Oracle
# Creating engine connection
engine = create_engine('oracle://user:pw#IP:Port/Schema')
# Binding session
session = Session(bind=engine)
# Indicating path for Oracle client 64bits
lib_dir = r"Full_Path\instantclient_19_9"
try:
cx_Oracle.init_oracle_client(lib_dir=lib_dir)
except Exception as err:
print("Error connecting: cx_Oracle.init_oracle_client()")
print(err);
sys.exit(1);
# read sql a run query
data = pd.read_sql("SELECT * FROM Schema.V_FLUJOS_SOLICITADOS", engine)
# save path
path = r'Another_Full_Path'
# save dataframe into csv
data.to_excel(os.path.join(path, r'Flow extraction.xlsx'), index = False)
For this code, I need to tell Python where to find the Oracle client of 64 bits because my company has its database connected to a PowerBuilder program that can only use 32 bit, so I just can't change the installation, that's why I re-route.
VBA code:
Sub runScript()
Application.ScreenUpdating = False
teoricos = ThisWorkbook.Name
Dim Ret_Val
user = Environ("UserName")
Select Case user
Case "USER1"
python_route = "C:\Users\USER1\Anaconda3\python.exe"
Case "USER2"
python_route = "C:\Users\USER2\Anaconda3\python.exe"
End Select
args = """Full_path\V_FLUJOS_SOLICITADOS.py"""
Ret_Val = Shell(python_route & " " & args, vbNormalFocus)
If Ret_Val = 0 Then
MsgBox "Couldn't run python script!", vbOKOnly
End If
End Sub
The code works on my PC (User 1), but it doesn't on my partner's PC.
What I've done so far:
Installed cx_Oracle on her machine
Tested the whole code on Jupyter Notebook of her machine and it worked
Tested full access to all paths
Activated the Microsoft Shell Reference in VBA
The VBA code on her PC runs, but it just opens the command window really fast and it closes.
On my PC it takes from 3 to 5 seconds to do the whole thing, so I can see the CMD for just a bit there (and also check that the file updated which is the most clear indicator that it worked).
Related
I have consulted several topics on the subject, but I didn't see any related to launching an app on a device directly using a ppadb command.
I managed to do this code:
import ppadb
import subprocess
from ppadb.client import Client as AdbClient
# Create the connect functiun
def connect():
client = AdbClient(host='localhost', port=5037)
devices = client.devices()
for device in devices:
print (device.serial)
if len(devices) == 0:
print('no device connected')
quit()
phone = devices[0]
print (f'connected to {phone.serial}')
return phone, client
if __name__ == '__main__':
phone, client = connect()
import time
time.sleep(5)
# How to print each app on the emulator
list = phone.list_packages()
for truc in list:
print(truc)
# Launch the desired app through phone.shell using the package name
phone.shell(????????????????)
From there, I have access to each app package (com.package.name). I would like to launch it through a phone.shell() command but I can't access the correct syntax.
I can execute a tap or a keyevent and it's perfectly working, but I want to be sure my code won't be disturbed by any change in position.
From How to start an application using Android ADB tools, the shell command to launch an app is
am start -n com.package.name/com.package.name.ActivityName
Hence you would call
phone.shell("am start -n com.package.name/com.package.name.ActivityName")
A given package may have multiple activities. To find out what they are, you can use dumpsys package as follows:
def parse_activities(package, connection, retval):
out = ""
while True:
data = connection.read(1024)
if not data: break
out += data.decode('utf-8')
retval.clear()
retval += [l.split()[-1] for l in out.splitlines() if package in l and "Activity" in l]
connection.close()
activities = []
phone.shell("dumpsys package", handler=lambda c: parse_activities("com.package.name", c, activities))
print(activities)
Here is the correct and easiest answer:
phone.shell('monkey -p com.package.name 1')
This method will launch the app without needing to have acces to the ActivityName
Using AndroidViewClient/cluebra, you can launch the MAIN Activity of a package as follows:
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
from com.dtmilano.android.viewclient import ViewClient
ViewClient.connectToDeviceOrExit()[0].startActivity(package='com.example.package')
This connects to the device (waiting if necessary) and then invokes startActivity() just using the package name.
startActivity() can also receive a component which is used when you know the package and the activity.
I'm trying to get a code scheduled in windows:
import requests
from datetime import date
import pandas as pd
import sqlalchemy
from sqlalchemy import create_engine
server= 'xxxxx'
database='xxxxx'
driver_sql= 'ODBC Driver 17 for SQL Server'
database_con= f'mssql://#{server}/{database}?driver={driver_sql}'
engine= sqlalchemy.create_engine(database_con)
connection = engine.connect()
adr='https://api.swaggystocks.com/wsb/sentiment/ticker'
r = requests.get(adr)
json = r.json()
pdbasses= pd.DataFrame(json["data"])
pdbasses["timestamp"] = pd.to_datetime("today")
pdbasses["timestamp"] = pdbasses["timestamp"].dt.strftime("%Y-%m-%d")
pdbasses.to_sql("swaggy", connection, if_exists='append',index=False)
direct =r'D:\SQL\getdatafromhere\file'+str(date.today())+".csv"
pdbasses.to_csv(direct, index=False)
the problem is, when I put it through pyinstaller it says I'm missing packages that I can't even install via pip MySQLdb,Psycob2 etc.
Then when the exe file gets put out, I run it and it just blips for a second and doesn't do anything. The code works in PyCharm. I tried running pyinstaller through pycharm, but I get a Linux exe file/spec file. I tried converting that one to an exe file, but still doens't work.
Thank you for your time
I have a simple python script that puts data in a database. Both the script and
the database have owner www-data. When I run sudo python and write the
commands one by one it works, but if I run python monitor.py or sudo python monitor.py it doesn't work; it says, "attempt to write a read only database".
This is my script: (it receives data from arduino)
from serial import Serial
from time import sleep
import sqlite3
serial_port = '/dev/ttyACM0';
serial_bauds = 9600;
# store the temperature in the database
def log_light(value):
conn=sqlite3.connect('/var/db/arduino.db')
curs=conn.cursor()
curs.execute("UPDATE sensor1 set status = (?)", (value,))
# commit the changes
conn.commit()
conn.close()
def main():
s = Serial(serial_port, serial_bauds);
s.write('T');
sleep(0.05);
line = s.readline();
temperature = line;
s.write('H');
sleep(0.05);
line = s.readline();
humidity = line;
s.write('L');
sleep(0.05);
line = s.readline();
light = line;
log_light(light);
if __name__=="__main__":
main()
It sounds like a permission problem. Write access is granted only to the user, which is root. You need to change the user to be directly yourself, not root. You can do this using chmod on many *nix systems.
You could also gove write access to anyone in the group.
I have a vanilla python that connects to a sqlite database.
Everything works fine until I try to run it as a daemon. Here is the code I'm using to do that:
def start(self):
if self.lockfile.is_locked():
exit_with_code(7, self.pid_file)
# If we're running in debug, run in the foreground, else daemonise
if self.options['debug']:
try:
self.main()
except KeyboardInterrupt:
pass
finally:
self.close_gracefully()
else:
context = daemon.DaemonContext(
files_preserve = [self.logger.socket(), self.lockfile]
)
context.signal_map = {
signal.SIGTERM: self.close_gracefully
}
with context: self.main()
I can run it in the foreground with python -m starter -debug and everything is fine, my app writes into the database, but when I leave the debug flag off I see the following when I try to write:
no such table: Frontends
I know that the frontends table exists because I've opened the database up. I assume that python is finding the database, because there would be an entirely different error message otherwise.
All my files are owned by vagrant, and ls -l shows the following:
-rwxrwxrwx 1 vagrant vagrant 9216 Nov 9 18:09 development.sqlite
Anyone got any tips?
Update
As requested, here is the code for my db
import os
import sqlite3
class Database(object):
def __init__(self, db_file='/vagrant/my_daemon/db/development.sqlite'):
self.db = sqlite3.connect(db_file)
if os.path.exists(db_file):
print "db exists"
And when I run this it prints "db exists". I instantiate the database in starter.py with a call to Database().
Python daemon closes all open file descriptors (except stdin, stout and stderr) when you daemonise.
I spent ages trying to figure out which files to keep open to prevent my database from being inaccessible, and in the end I found that it's easier to initialise the database inside the daemon context rather than outside. That way I don't need to worry about which files should stay open.
Now everything is working fine.
I have developed a python script for making a serial communication to a digital pump. I now need to make an executable out of it. However even though it works perfectly well when running it with python and py2exe does produce the .exe properly when I run the executable the following error occurs:
File: pump_model.pyc in line 96 in connect_new
File: serial\__init__.pyc in line 71 in serial_for_url
ValueError: invalid URL protocol 'loop' not known
The relevant piece of my code is the following:
# New serial connection
def connect_new(self, port_name):
"""Function for configuring a new serial connection."""
try:
self.ser = serial.Serial(port = port_name,\
baudrate = 9600,\
parity = 'N',\
stopbits = 1,\
bytesize = 8,\
timeout = self.timeout_time)
except serial.SerialException:
self.ser = serial.serial_for_url('loop://',\
timeout = self.timeout_time) # This line BLOWS!
except:
print sys.exc_info()[0]
finally:
self.initialize_pump()
I should note that the application was written in OSX and was tested on Windows with the Canopy Python Distribution.
I had the exact same problem with "socket://" rather than "loop://"
I wasn't able to get the accepted answer to work however the following seems to succeed:
1) Add an explicit import of the offending urlhandler.* module
import serial
# explicit import for py2exe - to fix "socket://" url issue
import serial.urlhandler.protocol_socket
# explicit import for py2exe - to fix "loop://" url issue (OP's particular prob)
import serial.urlhandler.protocol_loop
# use serial_for_url in normal manner
self._serial = serial.serial_for_url('socket://192.168.1.99:12000')
2) Generate a setup script for py2exe (see https://pypi.python.org/pypi/py2exe/) -- I've installed py2exe to a virtualenv:
path\to\env\Scripts\python.exe -m py2exe myscript.py -W mysetup.py
3) edit mysetup.py to include option
zipfile="library.zip" # default generated value is None
(see also http://www.py2exe.org/index.cgi/ListOfOptions)
3) build it:
path\to\env\Scripts\python.exe mysetup.py py2exe
4) run it
dist\myscript.exe
Found it!
It seems that for some reason the 'loop://' arguement can't be recognised after the .exe production.
I figured out by studying the pyserial/init.py script that when issuing the command serial.serial_for_url(‘loop://') you essentially call:
sys.modules['serial.urlhandler.protocol_loop’].Serial(“loop://“)
So you have to first import the serial.urlhandler.protocol_loop
and then issue that command in place of the one malfunctioning.
So you can now type:
__import__('serial.urlhandler.protocol_loop')
sys.modules[‘serial.urlhandler.protocol_loop’].Serial("loop://")
After this minor workaround it worked fine.