Keep getting "Property object at 0x" when unpickling a class instance - python

I am trying to set up a multithreaded server and client, and am currently sending information wrapped in a TCP module class. I am sending the data using pickle, and have run in to a problem where attempting to access instance variables after unpickling the data leads to "Property object at 0x", instead of the instance variable.
Here is the relevant server code:
data = self.clientSocket.recv(2048)
print(data)
message = pickle.loads(data)
header = message.header
self.currUser = message.user
if header == 'user-login':
print("[recv] New login request")
self.userLogin()
client code:
username = input("Username: ")
password = input("Password: ")
message = TCPmodule().withSocket("user-login", password, self.clientSocket)
message.user = username
print(message.header)
data = pickle.dumps(message)
self.clientSocket.send(data)
Class (classmethod used and getters/setters):
def withSocket(self, header, content, socket):
self.header = header
self.content = content
self.socket = socket
self.user = ""
self.port = 0
return self
#property
def header(self):
return self._header
#header.setter
def header(self,value):
self._header = value
#property
def content(self):
return self._content
#content.setter
def content(self,content):
self._content = content
#property
def user(self):
return self._user
#user.setter
def user(self,user):
self._user = user
property object message when I print (message.header) server side
Am somewhat new to python, so I'm not sure if I'm missing something here.
Thanks

Related

How to get updated class variable value in Django

I'm having trouble getting the updated value of a class variable.
When ConnectTestAPI is called after the p_request function is executed, the class variables which are result and orderNo should updated in the post function.
Then I want to receive the updated value of class variables by looping while statement in the p_request function.
However, despite setting the values ​​of class variables with the post request, when the while statement is run, the corresponding values ​​are still empty and 0 value respectively,
So, the while statement cannot be terminated and results in a time out error.
Here is my source code. Thank you in advance!
class ConnectTestAPI(APIView):
result=""
orderNo=0
def post(self, request):
data = request.data
ConnectTestAPI.result = data['result']
ConnectTestAPI.orderNo = data['orderNo']
print(ConnectTestAPI.result) # I could successfully get data from POST request here!
print(ConnectTestAPI.orderNo) # I could successfully get data from POST request here!
return HttpResponse("ok")
def p_request():
data = {
"a" : 1234,
"b" : 5678
}
data = json.dumps(data,ensure_ascii=False).encode('utf-8')
con = redis.StrictRedis(outside_server['ip'],outside_server['port'])
con.set("data_dict", data)
while True:
if ConnectTestAPI.result != "" and ConnectTestAPI.orderNo != 0:
break
res_result = ConnectTestAPI.result
res_orderNo = ConnectTestAPI.orderNo
return res_result, res_orderNo
You need to access the class variables using self:
class ConnectTestAPI(APIView):
result=""
orderNo=0
def post(self, request):
data = request.data
self.result = data['result']
self.orderNo = data['orderNo']
print(self.result) # I could successfully get data from POST request here!
print(self.orderNo) # I could successfully get data from POST request here!
return HttpResponse("ok")
def p_request():
data = {
"a" : 1234,
"b" : 5678
}
data = json.dumps(data,ensure_ascii=False).encode('utf-8')
con = redis.StrictRedis(outside_server['ip'],outside_server['port'])
con.set("data_dict", data)
while True:
if self.result != "" and self.orderNo != 0:
break
res_result = self.result
res_orderNo = self.orderNo
return res_result, res_orderNo
NOTE: This usage of class attributes is not recommended. You are mutating a class attribute which has side effects on all instances of that class. In your case, an ordinary attribute initialized within __ init__() would be ok:
class ConnectTestAPI(APIView):
def __init__(self):
self.result=""
self.orderNo=0
def post(self, request):
data = request.data
self.result = data['result']
self.orderNo = data['orderNo']
print(self.result) # I could successfully get data from POST request here!
print(self.orderNo) # I could successfully get data from POST request here!
return HttpResponse("ok")
def p_request():
data = {
"a" : 1234,
"b" : 5678
}
data = json.dumps(data,ensure_ascii=False).encode('utf-8')
con = redis.StrictRedis(outside_server['ip'],outside_server['port'])
con.set("data_dict", data)
while True:
if self.result != "" and self.orderNo != 0:
break
res_result = self.result
res_orderNo = self.orderNo
return res_result, res_orderNo

How to call a variable from user input function inside _init_ function python?

I have an init function that holds some start up information.
I would like to
have the user input their email address,
save it to a variable called "user_id"
then use that variable within the init function.
It seems to be working using global variables, but I've read that using global variables is a bad idea.
How do I achieve this without using global variables?
user_id ="no email yet"
Class GetDatabase():
def user_email_input():
global user_id
user_id = input("what is your email")
return
def __init__(self,uri: Text = "localhost:2555", servername: Text = "schools") -> Text:
global user_id
self.uri = uri
self.servername= servername
self.me = user_id```
Bad way to do it but if you must:
class GetDatabase:
def __init__(self, uri="localhost:2555", servername="schools"):
self.uri = uri
self.servername = servername
self.user_email_input()
def user_email_input(self):
self.me = input("what is your email: ")
Passing arguments to the instantiation of the class seems like exactly what you need:
class GetDatabase:
def __init__(self, user_id, uri="localhost:2555", servername="schools"):
self.uri = uri
self.servername = servername
self.me = user_id
# then instantiated with
db = GetDatabase(my_user_id, my_uri, my_servername)

How do I use the functions within this Python script?

I have this Python script to control a PfSense router via FauxAPI. The problem is that when i call a function it gives an error. I think i'm calling the function wrong. Does anyone know how to call them?
Here is a link to the API i'm using: https://github.com/ndejong/pfsense_fauxapi
I have tried calling config_get(self, section=none) but that does not seem to work.
import os
import json
import base64
import urllib
import requests
import datetime
import hashlib
class PfsenseFauxapiException(Exception):
pass
class PfsenseFauxapi:
host = '172.16.1.1'
proto = None
debug = None
version = None
apikey = 'key'
apisecret = 'secret'
use_verified_https = None
def __init__(self, host, apikey, apisecret, use_verified_https=False, debug=False):
self.proto = 'https'
self.base_url = 'fauxapi/v1'
self.version = __version__
self.host = host
self.apikey = apikey
self.apisecret = apisecret
self.use_verified_https = use_verified_https
self.debug = debug
if self.use_verified_https is False:
requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning)
def config_get(self, section=None):
config = self._api_request('GET', 'config_get')
if section is None:
return config['data']['config']
elif section in config['data']['config']:
return config['data']['config'][section]
raise PfsenseFauxapiException('Unable to complete config_get request, section is unknown', section)
def config_set(self, config, section=None):
if section is None:
config_new = config
else:
config_new = self.config_get(section=None)
config_new[section] = config
return self._api_request('POST', 'config_set', data=config_new)
def config_patch(self, config):
return self._api_request('POST', 'config_patch', data=config)
def config_reload(self):
return self._api_request('GET', 'config_reload')
def config_backup(self):
return self._api_request('GET', 'config_backup')
def config_backup_list(self):
return self._api_request('GET', 'config_backup_list')
def config_restore(self, config_file):
return self._api_request('GET', 'config_restore', params={'config_file': config_file})
def send_event(self, command):
return self._api_request('POST', 'send_event', data=[command])
def system_reboot(self):
return self._api_request('GET', 'system_reboot')
def system_stats(self):
return self._api_request('GET', 'system_stats')
def interface_stats(self, interface):
return self._api_request('GET', 'interface_stats', params={'interface': interface})
def gateway_status(self):
return self._api_request('GET', 'gateway_status')
def rule_get(self, rule_number=None):
return self._api_request('GET', 'rule_get', params={'rule_number': rule_number})
def alias_update_urltables(self, table=None):
if table is not None:
return self._api_request('GET', 'alias_update_urltables', params={'table': table})
return self._api_request('GET', 'alias_update_urltables')
def function_call(self, data):
return self._api_request('POST', 'function_call', data=data)
def system_info(self):
return self._api_request('GET', 'system_info')
def _api_request(self, method, action, params=None, data=None):
if params is None:
params = {}
if self.debug:
params['__debug'] = 'true'
url = '{proto}://{host}/{base_url}/?action={action}&{params}'.format(
proto=self.proto, host=self.host, base_url=self.base_url, action=action, params=urllib.parse.urlencode(params))
if method.upper() == 'GET':
res = requests.get(
url,
headers={'fauxapi-auth': self._generate_auth()},
verify=self.use_verified_https
)
elif method.upper() == 'POST':
res = requests.post(
url,
headers={'fauxapi-auth': self._generate_auth()},
verify=self.use_verified_https,
data=json.dumps(data)
)
else:
raise PfsenseFauxapiException('Request method not supported!', method)
if res.status_code == 404:
raise PfsenseFauxapiException('Unable to find FauxAPI on target host, is it installed?')
elif res.status_code != 200:
raise PfsenseFauxapiException('Unable to complete {}() request'.format(action), json.loads(res.text))
return self._json_parse(res.text)
def _generate_auth(self):
# auth = apikey:timestamp:nonce:HASH(apisecret:timestamp:nonce)
nonce = base64.b64encode(os.urandom(40)).decode('utf-8').replace('=', '').replace('/', '').replace('+', '')[0:8]
timestamp = datetime.datetime.utcnow().strftime('%Y%m%dZ%H%M%S')
hash = hashlib.sha256('{}{}{}'.format(self.apisecret, timestamp, nonce).encode('utf-8')).hexdigest()
return '{}:{}:{}:{}'.format(self.apikey, timestamp, nonce, hash)
def _json_parse(self, data):
try:
return json.loads(data)
except json.JSONDecodeError:
pass
raise PfsenseFauxapiException('Unable to parse response data!', data)
Without having tested the above script myself, I can conclude that yes you are calling the function wrong. The above script is rather a class that must be instantiated before any function inside can be used.
For example you could first create an object with:
pfsense = PfsenseFauxapi(host='<host>', apikey='<API key>', apisecret='<API secret>')
replacing <host>, <API key> and <API secret> with the required values
Then call the function with:
pfsense.config_get() # self is not passed
where config_get can be replaced with any function
Also note
As soon as you call pfsense = PfsenseFauxapi(...), all the code in
the __init__ function is also run as it is the constructor (which
is used to initialize all the attributes of the class).
When a function has a parameter which is parameter=something, that something is the default value when nothing is passed for that parameter. Hence why use_verified_https, debug and section do not need to be passed (unless you want to change them of course)
Here is some more information on classes if you need.
You need to create an object of the class in order to call the functions of the class. For example
x = PfsenseFauxapi() (the init method is called during contructing the object)
and then go by x.'any function'. Maybe name the variable not x for a good naming quality.

How do I create multiple objects in a class, and assign each of them with variables in a cycle?

I'm building my 1st Python app, a car service where clients can request vehicles for transportation.
I have a "Clients.txt" file (in the same folder) with the Usernames and Passwords of each client, and I've successfully created the function "read_clients()" that opens the said file and stores each username in "client_username" and each password in "client_password".
What I want to do now is create an object in the Class "Client" for every client, and automatically make each object's self.username = client_username and each object's self.password = client_password.
I tried using a for loop.
I think I shouldn't call each object c1, as I think this would just keep overwriting the c1 variable, right? But what's the solution?
Should I implement some "counter" variable and increase it by 1 with each cycle and then create the variable c"counter"?
Should I use a dictionary for this instead? Maybe not, because I have a series of functions like create_account() and login() which I'll want to run on each object's variables. Right?
Thanks!
I tried defining the read_clients function both inside and outside of the "Clients" class and removing and applying the "self" attribute.
class Client:
def __init__(self, username, password):
self.username = username
self.password = password
def read_clients(self):
with open("Clients.txt", "r") as file:
client_list = file.readlines()
for pre_client in client_list:
client = pre_client.split(" ")
client_username = client[0]
pre_password = client[1]
client_password = pre_password.strip("\n")
c1 = Client(client_username, client_password)
Store your newly created clients in a list and return such list as result. Given you are not using self inside read_clients, you can define it as static using #staticmethod
Code
class Client:
def __init__(self, username, password):
self.username = username
self.password = password
#staticmethod
def read_clients():
with open("Clients.txt", "r") as file:
client_list = file.readlines()
# Store your clients here
clients = []
for pre_client in client_list:
client = pre_client.split(" ")
client_username = client[0]
pre_password = client[1]
client_password = pre_password.strip("\n")
# Save each new client
clients.append(Client(client_username, client_password))
# Return the created clients
return clients
clients = Client.read_clients()
If I understand correctly, I suggest you to use a list.
Example code (write it ourside the class):
def read_clients():
retuned_list=[]
with open("Clients.txt", "r") as file:
client_list = file.readlines()
for pre_client in client_list:
client = pre_client.split(" ")
client_username = client[0]
pre_password = client[1]
client_password = pre_password.strip("\n")
client = Client(client_username, client_password)
returned_list.append(client)
return returned_list

Inherited Methods How do I make super methods available?

I have a class (which works [or appears to]) to run an sql query. Code is below. If I inherit from object and do not use super, it works fine.
I am learning about inserting methods from super classes and so I thought that I would make my class header look like this
class database_connector(Connection)
and incorporate a super call in init like this
super().__init__()
However, I get
TypeError: function() argument 1 must be code, not str
I tried
super(database_connector, self).__init__()
after reading some other stuff in StackOverFlow but I now still get
TypeError: function() argument 1 must be code, not str
I am anticipating that this work will allow me to call more methods from pymysql.Connection.
Here is my class
from pymysql import Connection
# set up default values for database connector
class database_connector(Connection):
def __init__(self, host=None, db=None, user=None, passwd=None):
super(database_connector, self).__init__()
if host is None:
self.host = "mysql_host_ip"
else:
self.host = host
if db is None:
self.db = "fred_db"
else:
self.db = db
if user is None:
self.user = "fred"
else:
self.user = user
if passwd is None:
self.passwd = "fredspasswd"
else:
self.passwd = passwd
self.this_database = (Connection(host=self.host,
user=self.user,
passwd=self.passwd,
db=self.db))
self.cur = self.this_database.cursor()
def my_sql_run_this_sql(self, sql_to_run=None):
if sql_to_run is None:
data = self.cur.execute("SELECT * FROM person")
else:
data = self.cur.execute(sql_to_run)
data = []
for row in self.cur.fetchall():
data.append(row)
self.this_database.close()
return data

Categories

Resources