I have a problem with mongo. When I ended my automation tests, I need trash all data and object which I created. I create a script. In this script I delete a rows from a few table. But when I start this, This class doesn't start, where is my problem?
In consol I haven't any message, zero value.
from pymongo import MongoClient
class deleteMongo():
def deleteFirst(self):
client = MongoClient('databaseaddress')
db = client.TableData
db.Employe.delete_one({"name": "EmployeOne"})
def deleteSecond(self):
client = MongoClient('databaseaddress')
db = client.PersonData
db.Person.delete_one({"name": "PersonOne"})
def deleteThird(self):
client = MongoClient('databaseaddress')
db = client.AutoData
db.Auto.delete_one({"name": "AutoThird"})
If I am understanding your question correctly, you are trying to run the script above and it's not doing anything?
If this is your complete module, you are not calling the class at all, but defining the class object.
also the parenthesis in class deleteMongo(): are redundant in a class, since it always inherits the object. On the current setup of this class object, you should use def instead, or setup your class to initialize shared objects of the class.
Based on your current code, try this:
from pymongo import MongoClient
class deleteMongo:
def __init__(self, databaseAddress):
# if the databseAddress is always the same, you can remove it from the arguments
# and hardcode it here
self.client = MongoClient(databaseAddress)
def deleteFirst(self):
db = self.client.TableData
db.Employe.delete_one({"name": "EmployeOne"})
def deleteSecond(self):
db = self.client.PersonData
db.Person.delete_one({"name": "PersonOne"})
def deleteThird(self):
db = self.client.AutoData
db.Auto.delete_one({"name": "AutoThird"})
and then when you need to call one of the class functions, call it like this:
deleteMongo(databaseAddress='someaddress').deleteFirst()
Related
Suppose I have a module data_provider.py that keeps some code responsible for connecting to external API. In order to establish a connection, an API token needs to be retrieved from the database.
API_TOKEN = get_token_from_database()
class DataProvider:
def __init__(self):
self.api_token = API_TOKEN
def make_query(self):
'''make some request using self.api_token'''
Assuming the code needs to stay in such shape more or less (API_TOKEN being a global variable), what would be a good pattern for retrieving the API_TOKEN from the database?
Obiously now it is not ideal because the module cannot be imported without the database being turned on. Also, I would like to retrieve it only once, not per DataProvider creation.
Should I for example make API_TOKEN load lazily or turn it into a function?
If you have one single DataProvider object in your application, you could simply remove the global variable and load the token in the __init__ method:
class DataProvider:
def __init__(self):
self.api_token = get_token_from_database()
Another possible lazy loading would be to initialize the global token to None and then set it at first instanciation of a DataProvider object
API_TOKEN = None
class DataProvider:
def __init__(self):
global API_TOKEN
if API_TOKEN is None:
API_TOKEN = get_token_from_database()
self.api_token = API_TOKEN
Error processing still omitted for brievety...
I'd probably go with a simple singleton pattern
class DataProvider:
def __init__(self):
self.__api_token = None
def get_token(self):
if self.__api_token is None:
self.__api_token = .....
return self.__api_token
You might want to make get_token(self) into a property token instead. That's a matter of taste.
I'm new to testing and testing in python. I have a python class that looks like this :
File name : my_hive.py
from pyhive import hive
class Hive:
def __init__(self, hive_ip):
self.cursor = hive.connect(hive_ip).cursor()
def execute(self, command):
self.cursor.execute(command)
I want to mock these functions : pyhive.hive.connect, pyhive.Connection.cursor(used by my class as hive.connect(hive_ip).cursor()) and pyhive.Cursor.execute (used by my class as self.cursor.execute(command) in execute method).
I'm able to mock function call hive.connect and also I have been able to assert that it has been called with hive_ip given by me as follows.
import unittest
import mock
from my_hive import Hive
class TestHive(unittest.TestCase):
#mock.patch('pyhive.hive.connect')
def test_workflow(self, mock_connect):
hive_ip = "localhost"
processor = Hive(hive_ip)
mock_connect.assert_called_with(hive_ip)
But how do I make sure that subsequent function calls like .cursor() and self.cursor.execute() have also been called? hive.connect(hive_ip) returns an instance of pyhive.hive.Connection, which has method called cursor
I have tried to add mocks like this :
import unittest
import mock
from hive_schema_processor import HiveSchemaProcessor
class TestHive(unittest.TestCase):
#mock.patch('pyhive.hive.connect')
#mock.patch('pyhive.hive.Connection.cursor')
def test_workflow(self, mock_connect, mock_cursor):
hive_ip = "localhost"
processor = Hive(hive_ip)
mock_connect.assert_called_with(hive_ip)
mock_cursor.assert_called()
But the tests are failed with complain :
AssertionError: expected call not found.
Expected: cursor('localhost')
Actual: not called.
Your problem is that you have already mocked connect, so the subsequent calls on the result of connect will be made on the mock, not on the real object.
To check that call, you have to make the check on the returned mock object instead:
class TestHive(unittest.TestCase):
#mock.patch('pyhive.hive.connect')
def test_workflow(self, mock_connect):
hive_ip = "localhost"
processor = Hive(hive_ip)
mock_connect.assert_called_with(hive_ip)
mock_cursor = mock_connect.return_value.cursor
mock_cursor.assert_called()
Each call on a mock produces another mock object.
mock_connect.return_value gives you the mock that is returned by calling mock_connect, and mock_connect.return_value.cursor contains another mock that will actually be called.
entry_point.py
from other_file import UserBehaviour
class ApiUser(HttpUser):
tasks = [UserBehaviour]
def on_start(self):
# log in and return session id and cookie
# example: self.foo = "foo"
other_file.py
from entry_point import ApiUser
class UserBehaviour(TaskSet):
#task
def do_something(self, session_id, session_cookie)
# use session id and session cookie from user instance running the taskset
# example: print(self.ApiUser.foo)
NOTE: Going through the documentation, I did find that "the User instance can be accessed from within a TaskSet instance through the TaskSet.user", however all my attempts to import the user into the taskset file led to a "cannot import name 'ApiUser' from 'entry_point'" error. If instead of from entry_point import ApiUser I do from entry_point import *, then I get a name 'ApiUser' is not defined error.
Thank you very much #Cyberwiz for putting me on the right track. I've finally managed to figure out what I was doing wrong... which, as it turns out, was a couple of things.
Firstly, importing ApiUser in other_file.py was incorrect for two reasons: 1) it creates a cyclical dependency, and 2) even if it would eventually work it would import the ApiUser class, not the instance of the ApiUser class.
Secondly, I was previously getting a module locust.user has no attribute {name} error, and that was because my code looked like this:
class UserBehaviour(TaskSet):
# do something with user.foo
Having figured this out, I honestly have no idea why I thought the above would work. I've changed my code to reflect the example below and everything now works like a charm:
class UserBehaviour(TaskSet):
#task
def do_something(self):
# do something with self.user.foo
I'm new to Python and tried similar suggestions from here and failed.
I'm writing a script that consists of few functions, the first function will create some of the variables that will be used in other functions (it can't global variables).
When I've tried my script I kept getting NameError for undefined vars.
import boto3
import json
from awsretry import AWSRetry
from botocore.exceptions import ClientError
#AWSRetry.backoff(tries=5)
def instance_details(event, context):
client = boto3.client('ec2')]
ec2_resource = boto3.resource('ec2')`
alert = event['Records'][0]['Sns']['Message']
instance_id = alert['Trigger']['Dimensions'][0]['value']
instance = ec2_resource.Instance(instance_id)
return client
#AWSRetry.backoff(tries=5)
def tagging():
instance_type = instance['Reservations'][0]['Instances'][0]['InstanceType']
Why I can't pass the values of instance and client to other functions?
Thanks in advance and sorry for duplicates.
intance_details i believe is lambda handler method. Since you are returing client I believe you should be able to see client value in the variable in which you will be capturing return of this method.
Apart from that, you can try to use Class here and declare these variables in __init__ method. Then create instance of that class in the lambda handler and access these variables. Then you would be able to use these variables in the whole class.
import boto3
class Answer:
def __init__(self):
self.instance = None
self.client = boto3.client('ec2')]
self.ec2_resource = boto3.resource('ec2')
def meth1(self):
# suppose here we want to use the value of instance
# using self.instance you can use the value of instance here
# you can pass the alert from lambda_handler to this method
# as well and do all the computation here too.
print(self.client) # example how to use class variables.
def lambda_handler(event, context):
ans = Answer()
alert = event['Records'][0]['Sns']['Message']
instance_id = alert['Trigger']['Dimensions'][0]['value']
ans.instance = ans.ec2_resource.Instance(instance_id)
# if you want to pass instance id, you can pass in the arguments and
# change the definition of meth1 accordingly.
# Apart form that you can pass the alert in the meth1 too and do all the computation there.
ans.meth1()
if __name__ == "__main__":
lambda_handler(event, "")
I come from Java background and most of my thinking comes from there. Recently started learning Python. I have a case where I want to just create one connection to Redis and use it everywhere in the project. Here is how my structure and code looks.
module: state.domain_objects.py
class MyRedis():
global redis_instance
def __init__(self):
redis_instance = redis.Redis(host='localhost', port=6379, db=0)
print("Redus instance created", redis_instance)
#staticmethod
def get_instance():
return redis_instance
def save_to_redis(self, key, object_to_cache):
pickleObj = pickle.dumps(object_to_cache)
redis_instance.set(key, pickleObj)
def get_from_redis(self, key):
pickled_obj = redis_instance.get(key)
return pickle.loads(pickled_obj)
class ABC():
....
Now I want to use this from other modules.
module service.some_module.py
from state.domain_objects import MyRedis
from flask import Flask, request
#app.route('/chat/v1/', methods=['GET'])
def chat_service():
userid = request.args.get('id')
message_string = request.args.get('message')
message = Message(message_string, datetime.datetime.now())
r = MyRedis.get_instance()
user = r.get(userid)
if __name__ == '__main__':
global redis_instance
MyRedis()
app.run()
When I start the server, MyRedis() __init__ method gets called and the instance gets created which I have declared as global. Still when the service tries to access it when the service is called, it says NameError: name 'redis_instance' is not defined I am sure this is because I am trying to java-fy the approach but not sure how exactly to achieve it. I read about globals and my understanding of it is, it acts like single variable to the module and thus the way I have tried doing it. Please help me clear my confusion. Thanks!