MySql Class Object function error - python - python

I am subscribing to a data stream using a class object to insert the data into a databse using MySql. Could anyone shed some light on where my error is coming from?
traceback error:
File "/media/.........../stream.py", line 51, in database_insert
self.cursor.execute(self.insert, self.values)
AttributeError: 'NoneType' object has no attribute 'execute'
*** I have the while loop commented out because its easier. Instead, I am using an example json string in its place until my script is ready to be ran.
import asyncio
from binance import AsyncClient, BinanceSocketManager
import mysql.connector
from mysql.connector import errorcode
import datetime
import json
class Stream:
def __init__(self):
self.cnx = None
self.cursor = None
def database_connect(self):
self.cnx = mysql.connector.connect(user='root',
password='',
host='localhost',
database='')
self.cursor = self.cnx.cursor()
return self.cursor
def database_disconnect(self):
self.cnx = mysql.connector.connect(user='root',
password='',
host='localhost',
database='')
self.close = self.cnx.close()
def accounting_insert(self, query, data_tuple):
self.cursor.execute(query, data_tuple)
self.cnx.commit()
self.cnx.close()
print('Data has been successfully inserted into the database.')
def database_insert(self, ticker, timestamp, price):
self.insert = ("INSERT INTO data_" + ticker + " "
"(timestamp, price) "
"VALUES (%s, %s)")
self.values = (int(timestamp), float(price))
self.cursor.execute(self.insert, self.values)
self.cnx.commit()
self.cnx.close()
print("Values Inserted.")
def ticker(self, res):
longTicker = res['data']['s']
if longTicker == 'BTCUSDT':
return 'BTC'
elif longTicker == 'BCHUSDT':
return 'BCH'
def timestamp(self, res):
return res['data']['E']
def price(self, res):
return res['data']['p']
try:
Stream().database_connect()
except mysql.connector.Error as err:
if err.errno == errorcode.ER_ACCESS_DENIED_ERROR:
print("Something is wrong with your user name or password")
elif err.errno == errorcode.ER_BAD_DB_ERROR:
print("Database does not exist")
else:
print(err)
else:
print("success")
async def main():
client = await AsyncClient.create()
bm = BinanceSocketManager(client)
# pass a list of stream names
ms = bm.multiplex_socket(['btcusdt#trade', 'bchusdt#trade'])
# then start receiving messages
async with ms as tscm:
#while True:
#res = await tscm.recv()
#print(res)
res = {'stream': 'btcusdt#trade', 'data': {'e': 'trade', 'E': 1620716700815, 's': 'BTCUSDT', 't': 272261278, 'p': '65551.60000000', 'q': '25.76580000', 'b': 2142679715, 'a': 2142679312, 'T': 1620716700814, 'm': False, 'M': True}}
ticker = Stream().ticker(res)
timestamp = Stream().timestamp(res)
price = Stream().price(res)
print("Ticker: " + str(ticker) + " " + "Time: " + str(timestamp) + " " + "Price: $" + str(price))
Stream().database_insert(ticker, timestamp, price)
await client.close_connection()
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Stream().database_disconnect()

When you do Stream(), you are creating an instance of Stream with its own set of values for cnx and cursor. You have created Stream instances at multiple places and expected them to point to a single instance which isn't the case.
In the below snippet
s1 = Stream()
s2 = Stream()
s1 and s2 point to different instances of Stream. So, the cnx and cur of s1 will be different from that of s2.
You have to do the below changes to make your code work.
try:
stream = Stream().database_connect()
except mysql.connector.Error as err:
.....
.....
else:
print("success")
async def main():
client = await AsyncClient.create()
....
....
async with ms as tscm:
....
....
ticker = stream.ticker(res)
timestamp = stream.timestamp(res)
price = stream.price(res)
print("Ticker: " + str(ticker) + " " + "Time: " + str(timestamp) + " " + "Price: $" + str(price))
stream.database_insert(ticker, timestamp, price)
stream.database_disconnect()
await client.close_connection()
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())

Related

How to exit while loop properly?

I have a program that runs through a list of names in 'serverlist.txt'.
The user selects the database they want to search in by choosing option 1 or option 2.
The program will run through all names in the list and provide the id tied to each name.
Name: Jupiter ID: 23
Name: Mars ID: 26
Name: Mercury ID: 27
This works fine but it doesn't stop. When the list is complete, it loops through everything all over again.
How do I stop it from going through the list more than once?
import pypyodbc
import os
def replaceid(connection, servername):
try:
cursor = connection.cursor()
SQLCommand = ("SELECT Name, Location_ID "
"FROM dbo.Server_ID " # table name
"with (nolock)"
"WHERE Name = ?")
Values = [servername]
cursor.execute(SQLCommand,Values)
results = cursor.fetchone()
if results:
print (" Name: " + results[0] + " ID: " + str(results[1]))
print (" ")
locationid(results, connection, servername)
else:
print (" ID for " + servername + " does not exist.")
print (" ")
connection.close()
except:
print("Database is down or you are not connected to network.")
exit()
def start1():
os.system('cls' if os.name == 'nt' else 'clear')
array = []
local = input('\n\n Type option 1 or 2: ')
while True:
with open("serverlist.txt", "r") as f:
for servername in f:
try:
if local in ['1']:
connection = pypyodbc.connect('Driver={SQL Server};Server=db1;Database=WinOasis;Trusted_Connection=yes;')
elif local in ['2']:
connection = pypyodbc.connect('Driver={SQL Server};Server=db2;Database=WinOasis;Trusted_Connection=yes;')
else:
return
except pypyodbc.Error as ex:
sqlstate = ex.args[0]
if sqlstate == '28000':
print ("You do not have access.")
replaceid(connection, servername.strip())
return
start1()
I think your return statement on the third to last line needs to be indented one level. Otherwise your while loop will run forever, because True will always be true!
You might want to add a break statement after you call replaceid(connection, servername.strip()) in start1()
You might also want a break statement after the exception clause ends.

" Threading Error" Couldn't run the shell after converting single client shell into multi client shell by adding "threads"

"This code runs but won't be able to do anything,when I run this code what I am expecting is that I am going to get my shell but I get nothing it all worked fine before threading but when i edited this to convert it into multi_client then it all happened"
import socket
import threading
from queue import Queue
import time
NUMBER_OF_THREADS = 2
JOB_NUMBER = [1,2]
queue = Queue()
all_connections = []
all_addresses = []
def socket_create():
try:
global host
global port
global s
host = ''
port = 9999
s = socket.socket()
except socket.error as msg:
print("Socket creation error: " + str(msg))
def socket_bind():
try:
global host
global port
global s
s.bind((host,port))
s.listen(5)
except socket.error as msg:
print("Socket binding error: " + str(msg))
time.sleep(5)
socket_bind()
def accept_connections():
for c in all_connections:
c.close()
del all_connections[:]
del all_addresses[:]
while 1:
try:
conn, address = s.accept()
conn.setblocking(1)
all_connections.append(conn)
all_addresses.append(address)
print("\nConnection has been established: " + address[0])
except:
print("Errorr accepting connections")
def start_turtle():
while True:
cmd = input('turtle> ')
if cmd == 'list':
list_connections()
elif 'select' in cmd:
conn = get_target(cmd)
if conn is not None:
send_target_commands(conn)
else:
print("Command not Recognized")
def list_connections():
results = ''
for i, conn in enumerate(all_connections):
try:
conn.send(str.encode(' '))
conn.recv(20480)
except:
del all_connections[i]
del all_addresses[i]
continue
results += str(i) + ' ' + str(all_addresses[i][0]) + ' ' + str(all_addresses[i][1]) + '\n'
print('------ Clients -----' + '\n' + results)
def get_target(cmd):
try:
target = cmd.replace('select ', '')
target = int(target)
conn = all_connections[target]
print("You are now connected to " + str(all_addresses[target][0]))
print(str(all_addresses[target][0]) + "> ", end = "")
return conn
except:
print("Now a valid selection")
return None
def send_target_commands(conn):
while True:
try:
cmd = input()
if len(str.encode(cmd)) > 0:
conn.send(str.encode(cmd))
client_response = str(conn.recv(20480), "utf-8")
print(client_response, end="")
if cmd == 'quit':
break
except:
print("Connection was lost")
break
def create_workers():
for _ in range(NUMBER_OF_THREADS):
t = threading.Thread(target=work)
t.daemon = True
t.start()
def work():
while True:
x = queue.get()
if x == 1:
socket_create()
socket_bind()
accept_connections()
if x == 2:
start_turtle()
queue.task_done()
def create_jobs():
for x in JOB_NUMBER:
queue.put(x)
queue.join()
create_workers()
create_jobs()

Python script stuck at queue.join()

I am trying to implement a server for handling many clients (from thenewboston python reverse shell tutorials). I have the exact same code but when i run the script it gets stuck at queue.join(). How to make it work? I am unable to figure it out.
Here is the code
import socket
import sys
import threading
from queue import Queue
NUMBER_OF_THREADS = 2
JOB_NUMBER = [1, 2]
queue = Queue()
all_connections = []
all_addresses = []
# thread 1
# create socket (allows two computers to connect)
def socket_create():
try:
global host # ip address of the server
global port # port is to identify the kind of data
global s
host = ''
port = 9999
s = socket.socket()
except socket.error as msg:
print("Socket creation error: " + str(msg))
return
# bind socket to port and wait for connection from client
def socket_bind():
try:
global host
global port
global s
print("Binding socket to port: " + str(port))
s.bind((host, port))
s.listen(5)
# 5 is the no. of conections that can be made before server starts rejecting other requests
except socket.error as msg:
print("Socket binding error: " + str(msg) + "\n" + "Retrying...")
socket_bind()
return
# accept connections from multiple clients and save to list
def accept_connections():
for c in all_connections:
c.close()
del all_connections[:]
del all_addresses[:]
while 1:
try:
conn, address = s.accept()
conn.setblocking(1)
all_connections.append(conn)
all_addresses.append(address)
print("\nConnection has been establish: " + address[0])
except:
print("Error accepting connections")
return
# thread 2
# custom command promt for sending commands remotely
def start_turtle():
while True:
cmd = input('turtle> ')
if cmd == 'list':
list_connections()
elif 'select' in cmd:
conn = get_target(cmd)
if conn is not None:
send_target_commands(conn)
else:
print("Command not recognized")
return
# listing all the connections with indexing in the custom promt
def list_connections():
results = ''
for i, conn in enumerate(all_connections):
try:
conn.send(str.encode(' '))
conn.recv(20480)
except:
del all_connections[i]
del all_addresses[i]
continue
results += str(i) + ' ' + str(all_addresses[i][0]) + ' ' + str(all_addresses[i][1]) + '\n'
print('-----Clients-----' + '\n' + results)
return
# select a target client
def get_target(cmd):
try:
target = cmd.replace('select ', '')
target = int(target)
conn = all_connections[target]
print("You are now connected to " + str(all_addresses[target][0]))
print(str(all_addresses[target][0]) + '> ', end="")
return conn
except:
print("Not a valid selection")
return None
return
# connect with remote target client
def send_target_commands(conn):
while True:
try:
cmd = input()
if len(str.encode(cmd)) > 0:
conn.send(str.encode(cmd))
client_response = str(conn.recv(20480), "utf-8")
print(client_response, end="")
if cmd == "quit":
break
except:
print("Connection was lost")
break
return
# create worker threads
def create_workers():
for _ in range(NUMBER_OF_THREADS):
t = threading.Thread(target=work)
t.daemon = True
t.start
return
# do the next job in the queue (one handles connections, other sends commands)
def work():
while True:
x = queue.get()
if x == 1:
socket_create()
socket_bind()
accept_connections()
if x == 2:
start_turtle()
queue.task_done()
return
# create jobs for later extracting them and assigning them to the threads
def create_jobs():
for x in JOB_NUMBER:
queue.put(x)
queue.join()
return
def main():
create_workers()
create_jobs()
if __name__ == '__main__':
main()
Since you are using infinite loops (while True) at start_turtle and (while 1) at accept_connections they are not returning.
Since they don't return the func work never calls queue.task_done(), so the queue stuck joining.
I'm afraid you need to do one of the following:
start both start_turtle and accept_connections in parallel processes or threads.
Be sure they should call the queue.task_done().
For instance, you may include the queue as parameter and call it before starting the infinite loops (second option).
def work():
while True:
x = queue.get()
if x == 1:
socket_create()
socket_bind()
accept_connections(queue) # call queue.task_done() there
if x == 2:
start_turtle(queue) # call queue.task_done() in start_turtle
return
def start_turtle(queue):
queue.task_done() # Join one item from the queue
while True:
cmd = input('turtle> ')
if cmd == 'list':
list_connections()
elif 'select' in cmd:
conn = get_target(cmd)
if conn is not None:
send_target_commands(conn)
else:
print("Command not recognized")
return
On the other hand, in your create_workers you don't call the start method of the thread so your workers didn't really start.
Perhaps this is a typo.
def create_workers():
for _ in range(NUMBER_OF_THREADS):
t = threading.Thread(target=work)
t.daemon = True
# t.start # Not starting the Thread
t.start() # You need to call the start method
return

How python pymysql.cursors get INOUT return result from mysql stored procedure

I have mysql proc:
CREATE DEFINER=`user`#`localhost` PROCEDURE `mysproc`(INOUT par_a INT(10), IN par_b VARCHAR(255) , IN par_c VARCHAR(255), IN par_etc VARCHAR(255))
BEGIN
// bla... insert query here
SET par_a = LAST_INSERT_ID();
END$$
DELIMITER ;
to test that sp, if i run:
SET #par_a = -1;
SET #par_b = 'one';
SET #par_c = 'two';
SET #par_etc = 'three';
CALL mysproc(#par_a, #par_b, #par_c, #par_etc);
SELECT #par_a;
COMMIT;
it return #par_a as what i want - so i assume my db is fine...
then...
I have python as follow:
import pymysql.cursors
def someFunction(self, args):
# generate Query
query = "SET #par_a = %s; \
CALL mysproc(#par_a, %s, %s, %s); \
SELECT #par_a \
commit;"
try:
with self.connection.cursor() as cursor:
cursor.execute(query,(str(par_a), str(par_b), str(par_c), str(par_etc)))
self.connection.commit()
result = cursor.fetchone()
print(result) # <-- it print me 'none' how do i get my #par_a result from mysproc above?
return result
except:
raise
finally:
self.DestroyConnection()
result: the stored proc executed, as i can see record in.
problem: but i cant get my #par_a result in my python code from mysproc above?
and, if i change:
# generate Query
query = "SET #par_a = '" + str(-1) + "'; \
CALL mysproc(#par_a, %s, %s, %s); \
SELECT #par_a \
commit;"
to
# generate Query
query = "SELECT 'test' \
commit;"
and
cursor.execute(query)
strangely, it give me the correct result ('test',)
I used this class and I got response.
import pymysql.cursors
class connMySql:
def __init__(self, User, Pass, DB, Host='localhost', connShowErr=False, connAutoClose=True):
self.ShowErr = connShowErr
self.AutoClose = connAutoClose
self.DBName = DB
try:
self.connection = pymysql.connect(host=Host,
user=User,
password=Pass,
db=DB, #charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor)
except ValueError as ValErr:
if self.ShowErr == True: print(ValErr)
return False
def Fetch(self, Query):
try:
with self.connection.cursor() as cursor:
# Read a single record
cursor.execute(Query)
result = cursor.fetchall()
return result
except ValueError as ValErr:
if self.ShowErr == True: print(ValErr)
return False
finally:
if self.AutoClose == True: self.connection.close()
def Insert(self, Query):
try:
with self.connection.cursor() as cursor:
# Create a new record
cursor.execute(Query)
# connection is not autocommit by default. So you must commit to save
# your changes.
self.connection.commit()
except ValueError as ValErr:
if self.ShowErr == True: print(ValErr)
return False
finally:
if self.AutoClose == True: self.connection.close()
def ProcedureExist(self, ProcedureName):
try:
result = self.Fetch("SELECT * FROM mysql.proc WHERE db = \"" + str(self.DBName) + "\";")
Result = []
for item in result:
Result.append(item['name'])
if ProcedureName in Result:
return True
else:
return False
except ValueError as ValErr:
if self.ShowErr == True: print(ValErr)
return False
def CallProcedure(ProcedureName, Arguments=""):
try:
# Set arguments as a string value
result = self.Fetch('CALL ' + ProcedureName + '(' + Arguments + ')')
except ValueError as ValErr:
if self.ShowErr == True: print(ValErr)
return False
finally:
if self.AutoClose == True: self.connection.close()
def CloseConnection(self):
try:
self.connection.close()
return True
except ValueError as ValErr:
if self.ShowErr == True: print(ValErr)
return False
def main():
objMysqlConn = connMySql('user', '1234', 'myDB', connShowErr=True, connAutoClose=False)
ProcedureName= "mysproc"
if objMysqlConn.ProcedureExist(ProcedureName):
result = objMysqlConn.Fetch('CALL ' + ProcedureName + '()')
if result != False:
result = result[0]
print(result)
else:
print("The procecure does not exist!")
if __name__ == '__main__':
main()

Python threads didn't want to close

I have a problem with my program.
I managed to locate the source of problem. Problem is in the method "checkPort". Without it the standard textbook methods for closing/terminating threads works very well.
Am I missing something? Is in the checkPort method something that prevents to successfully join the threads? Its always stuck on thread.join().
Part of the main program:
try:
queue = Queue.Queue()
for i in range(MAX_THREAD_COUNT):
t = checkPort_IPv6_thread(queue)
t.daemon = True
threads.append(t)
t.start()
cur.execute("SELECT * FROM ipv6")
results = cur.fetchall()
for row in results:
queue.put((row[0], row[2]))
queue.join()
for thread in threads:
thread.stop()
thread.join()
except Exception as e:
sys.stderr.write("Error: " + str(e))
print
print "\nChecking ports for IPv6 - DONE"
Here is the thread class where I call checkPort method:
class checkPort_IPv6_thread(threading.Thread):
def __init__(self,queue):
threading.Thread.__init__(self)
self.queue = queue
self.keepRunning = True
def run(self):
while self.keepRunning:
args = self.queue.get()
id = args[0]
address = args[1]
port443 = 0
port21 = 0
port80 = 0
#---------------- Check ports for IPv6 ----------------
if str(address) != "N/A":
port443 = checkPort("TCP",str(address), 443)
port21 = checkPort("TCP",str(address), 21)
port80 = checkPort("TCP",str(address), 80)
lock.acquire()
try:
cur.execute("UPDATE ipv6 SET port_443=" + str(port443) + " WHERE id_ipv6 =" + str(id))
cur.execute("UPDATE ipv6 SET port_21=" + str(port21) + " WHERE id_ipv6 =" + str(id))
cur.execute("UPDATE ipv6 SET port_80=" + str(port80) + " WHERE id_ipv6 =" + str(id))
db.commit()
except Exception as e:
sys.stderr.write("Error: " + str(e))
except:
db.rollback()
lock.release()
self.queue.task_done()
def stop(self):
self.keepRunning = False
And the checkPort method:
def checkPort(typ, address, port):
if typ == "TCP":
s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
else:
s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
pom = 0 # 0/1 = True/False
try:
s.settimeout(2) # timeout 1.5 sekundy
s.connect((str(address), port))
s.settimeout(None)
#time.sleep(0.5)
pom = 1
print str(address) + " >> on port: " + str(port) + " >> Connection was successfull"
except socket.timeout:
print str(address) + " >> on port: " + str(port) + " >> * Error: Timed out *"
except socket.error as e:
if e.errno == 10061:
print str(address) + " >> on port: " + str(port) + " >> * No connection could be made - target machine refused it *"
except Exception as ex:
sys.stderr.write("Error: " + str(ex))
return pom
The following may help you along with your program. It is written for Python 3.x. I believe that the main problem is on the line args = self.queue.get() of your program. It should be fixed down below.
import multiprocessing
import queue
import threading
import sys
import socket
MAX_THREAD_COUNT = multiprocessing.cpu_count()
def main(cur):
cur.execute("""UPDATE ipv6
SET port_21 = 0,
port_80 = 0,
port_443 = 0
WHERE address = 'N/A'""")
q = queue.Queue()
for _ in range(MAX_THREAD_COUNT):
CheckPort(q).start()
cur.execute("""SELECT id_ipv6,
address
FROM ipv6
WHERE address != 'N/A'""")
for row in cur.fetchall():
q.put(row)
q.join()
for thread in threading.enumerate():
if isinstance(thread, CheckPort):
thread.stop()
thread.join()
class CheckPort(threading.Thread):
def __init__(self, q):
super().__init__()
self.__q = q
self.__run = True
def stop(self):
self.__run = False
def run(self):
while self.__run:
try:
id, address = self.__q.get(True, 1)
except queue.Empty:
continue
with lock:
try:
cur.execute('''UPDATE ipv6
SET port_21 = ?,
port_80 = ?,
port_443 = ?
WHERE id_ipv6 = ?''',
self.check_port(address, 21),
self.check_port(address, 80),
self.check_port(address, 443),
id)
db.commit()
except Exception as error:
print('Error:', error, file=sys.stdout)
self.__q.task_done()
#staticmethod
def check_port(address, port):
sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
sock.settimeout(2)
try:
sock.connect((address, port))
except socket.timeout:
return 0
else:
sock.shutdown(socket.SHUT_RDWR)
sock.close()
return 1
if __name__ == '__main__':
try:
main(cur)
except Exception as error:
print('Error:', error, file=sys.stdout)
From an OP's edit to his question:
Solution:
Thanks to Noctis Skytower the solution is to catch queue.empty exception:
try:
id, address = self.queue.get(True, 1)
except Queue.Empty:
continue

Categories