I have a config file and i want to load the options dynamicaly by entering the section and the options name.
For instance this is the config file contents.
[templates]
path = /full/path/to/template
and the config.py file
class Config(object):
def __init__(self):
self.config = ConfigParser.ConfigParser()
self.config.read('config.ini')
for section in self.config.sections():
self.__dict__[section] = dict()
for k, v in self.config.items(section):
self.__dict__[section][k] = v
def from_options(self, section, option):
if section in self.__dict__:
if option in self.__dict__[section]:
return self.__dict__[section][option]
if __name__ == '__main__':
c = Config()
print c.from_options('templates', 'path')
EDIT:
The question is if this a pythonic == right way to do it.
config.py
;# if not applicable leave it blank
[templates]
path = /full/path/to/template
configparse.py
class Config(object):
def __init__(self):
self.config = ConfigParser.ConfigParser()
self.config.read('config.py')
def get_path(self):
return self.config.get('templates', 'path')
if __name__ == '__main__':
c = Config()
print c.get_path()
this should do the trick...
Related
Let's say I have following classes:
check.py:
class Build:
def __init__(self, url):
self.url = url
self.parameters = {}
class Job:
def __init__(self, builds):
self.builds = []
for build in builds:
self.builds.append(build)
def builds_filter(self, builds_filter_func):
self.builds = [build for build in self.builds if builds_filter_func(build)]
def build_filter_according_to_name(job, name):
job.builds_filter((lambda build: build.parameters.get("NAME", "") == name))
if __name__ == '__main__':
job = Job([Build(url="url1"), Build(url="url3"), Build(url="url3")])
build_filter_according_to_name(job, "FOO")
I'd like to test in a unittest file the method build_filter_according_to_name, with different sets of parameters in each build. How do I do it?
For example:
A Job object with 5 builds, 1 of them has "NAME" == "foo".
A Job object with 5 builds, 4 of them has "NAME" == "foo".
etc.
Do I have to loop over self.builds before each test, and assign the parameters for each build, like this?
test_check.py:
import unittest
from test.check import Job, Build, build_filter_according_to_name
NAME = "FOO"
class MyTestCase(unittest.TestCase):
def setUp(self):
self.job = Job([Build(url="url1"), Build(url="url3"), Build(url="url3")])
self.parameters = {
"NAME": "NAME",
"FOO": "BAR"
}
def init_params(self, number_of_foo_names=0):
for build in self.job.builds:
parameters = self.parameters.copy()
if number_of_foo_names > 0:
parameters["NAME"] = "FOO"
number_of_foo_names -= 1
build.parameters = parameters
def test_one_name_foo(self):
self.init_params(number_of_foo_names=1)
build_filter_according_to_name(self.job, name=NAME)
self.assertEqual(len(self.job.builds), 1)
def test_two_names_foo(self):
self.init_params(number_of_foo_names=2)
build_filter_according_to_name(self.job, name=NAME)
self.assertEqual(len(self.job.builds), 2)
if __name__ == '__main__':
unittest.main()
Or is there a better way to achieve it?
I have some python code and I want to coverage it with unittest.
My simple code is:
import os
import glob
class GitRepoParser:
def __init__(self, repo_dir: str):
self.repo_dir = repo_dir
def get_folder_path(self, service_name: str) -> str:
dir_path = '{path}/configuration/settings/{name}'.format(
path=self.repo_dir,
name=service_name
)
return dir_path
def create_new_service(self, service_name: str, service_version: str):
dir_path = self.get_folder_path(service_name)
if os.path.isdir(dir_path):
return
os.makedirs(dir_path)
property_file = '{folder}/{name}-deployment.properties'.format(
folder=dir_path,
name=service_name
)
current_path = os.path.dirname(__file__)
template_path = os.path.join(
current_path, '..', 'file_templates/deployment.properties'
)
if not os.path.isfile(template_path):
return
template_file = open(template_path, 'r')
with open(property_file, 'w') as properties:
for line in template_file:
# Create parser for this code part
value = line.strip().replace(
'%service_name%', service_name
)
properties.write(value + '\n')
template_file.close()
Help me to create some unittest for this lines of code. I create some class GitRepoParserTest in my python tests:
class GitRepoParserTest(unittest.TestCase):
def setUp(self):
self.app = create_app('testing')
self.app_context = self.app.app_context()
self.app_context.push()
self.parser = GitRepoParser('/path-to-download')
def test_get_folder_path(self):
folder_path = self.parser.get_folder_path(service_name='oleg-service')
self.assertIsInstance(folder_path, str)
def test_create_new_service(self):
pass
But I don't understand how I need to write tests for create_new_service function.
Please help me.
Thank you.
Here is the unit test solution for Python 3.7.5:
test_GitRepoParser.py:
import unittest
from unittest.mock import Mock, patch, mock_open, call
from GitRepoParser import GitRepoParser, os
class GitRepoParserTest(unittest.TestCase):
def setUp(self):
self.parser = GitRepoParser('/path-to-download')
self.mock_open = mock_open(read_data='some data')
def test_get_folder_path(self):
folder_path = self.parser.get_folder_path(service_name='oleg-service')
self.assertIsInstance(folder_path, str)
#patch('GitRepoParser.os')
def test_create_new_service_read_and_write_file_correctly(self, mock_os):
mock_path = Mock()
mock_path.dirname.return_value = '/Users/foo'
mock_path.isdir.return_value = False
mock_path.join.return_value = '/Users/whatever'
mock_path.isfile.return_value = True
mock_os.path = mock_path
mock_os.makedirs = Mock()
with patch('GitRepoParser.open', self.mock_open):
self.parser.create_new_service(service_name='oleg-service', service_version='1.0')
mock_path.isdir.assert_called_with('/path-to-download/configuration/settings/oleg-service')
mock_os.makedirs.assert_called_with('/path-to-download/configuration/settings/oleg-service')
expected = [call('/Users/whatever', 'r'),
call('/path-to-download/configuration/settings/oleg-service/oleg-service-deployment.properties', 'w')]
self.mock_open.assert_has_calls(expected)
handle = self.mock_open()
handle.write.assert_called()
handle.close.assert_called_once()
#patch('GitRepoParser.os')
def test_create_new_service_do_nothing_if_dir_path_is_dir(self, mock_os):
mock_path = Mock()
mock_path.isdir.return_value = True
mock_os.path = mock_path
mock_os.makedirs = Mock()
self.parser.create_new_service(service_name='oleg-service', service_version='1.0')
mock_path.isdir.assert_called_with('/path-to-download/configuration/settings/oleg-service')
mock_os.makedirs.assert_not_called()
if __name__ == '__main__':
unittest.main()
Unit test result with coverage report:
...
----------------------------------------------------------------------
Ran 3 tests in 0.023s
OK
Name Stmts Miss Cover Missing
--------------------------------------------------------------------------------
src/stackoverflow/58384586/GitRepoParser.py 24 1 96% 35
src/stackoverflow/58384586/test_GitRepoParser.py 37 0 100%
--------------------------------------------------------------------------------
TOTAL 61 1 98%
As you can see, there is still a if condition branch left. You can finish it by yourself.
Source code: https://github.com/mrdulin/python-codelab/tree/master/src/stackoverflow/58384586
I have created a singlton Here is the class description.
allsms.py
from DB.models import ApiKey,ServiceProvider
from DB.messagenet import MessageNet
class SMSMgr( object ):
_instance = None
_allsp = []
def __init__(self):
pass
def __new__(cls, *args, **kwargs):
if not cls._instance :
cls._instance = super(SMSMgr, cls).__new__(
cls, *args, **kwargs)
return cls._instance
def loadsettings(self):
get_all_sp = ServiceProvider.objects.filter(status = False)
for obj in get_all_sp:
cla = obj.class_Name
a=globals()[str(obj.class_Name)](obj.userName,obj.password,obj.sendingurl)
self._allsp.append(a)
#print self._allsp
def reload(self):
self._allsp = []
get_all_sp = ServiceProvider.objects.filter(status = False)
for obj in get_all_sp:
cla = obj.class_Name
a=globals()[str(obj.class_Name)](obj.userName,obj.password,obj.sendingurl)
self._allsp.append(a)
def send(self):
print "+++++++++++++++++++== Global send "
if __name__ == "__main__":
b = SMSMgr()
b.loadsettings()
Now in test.py file of the same directory I am trying to use the singleton object which stored in the _allsp variable like.
from SMShandler.allsms import SMSMgr
b = SMSMgr()
#b.loadsettings()
print b._allsp
This is printing empty list. But when I am doing like this:
b = SMSMgr()
b.loadsettings()
print b._allsp
it is printing the list of objects .
My question is, if the above design is singlton then why print b._allsp is printing empty list in test.py? I am already loading loadsettings in the allsms.py file .
You are running loadsettings() in an if __name__ == "__main__" block:
if __name__ == "__main__":
b = SMSMgr()
b.loadsettings()
The purpose of such a block is to happen only when the code is run directly (like python allsms.py). That means it won't happen when it is imported in the line:
from SMShandler.allsms import SMSMgr
If you put the line b.loadsettings() outside of the if block, you'll see that it will already be loaded.
I have a Solace JMS Messaging Box which I am automating the administration of, and the device uses lots of very small XML posts to configure. Since the device has so very many commands in its XML spec, I need a way to create arbitrary XML requests.
The XML looks like:
<rpc semp-version="soltr/5_5">
<create>
<message-vpn>
<vpn-name>developer.testvpn</vpn-name>
</message-vpn>
</create>
</rpc>
And a second call to change a setting might look like this:
<rpc semp-version="soltr/5_5">
<message-vpn>
<vpn-name>developer.testvpn</vpn-name>
<export-policy>
<no>
<export-subscriptions/>
</no>
</export-policy>
</message-vpn>
</rpc>
Since there are many commands in the XML spec, I'm looking for a way to create them freely from something like dot name space. eg:
mycall = SolaceXML()
mycall.create.message_vpn.vpn_name="developer.testvpn"
mycall.message_vpn.vpn_name='developer.testvpn'
mycall.message_vpn.export_policy.no.export_subscription
UPDATE
I have posted my solution below. Its not as small as I'd like it but it works for me.
K
I have found a solution in the mean time. Hopefully this helps someone else. This solution builds nested dictionary objects from dot name space calls, and then converts it to XML.
from xml.dom.minidom import Document
import copy
import re
from collections import OrderedDict
class d2x:
''' Converts Dictionary to XML '''
def __init__(self, structure):
self.doc = Document()
if len(structure) == 1:
rootName = str(structure.keys()[0])
self.root = self.doc.createElement(rootName)
self.doc.appendChild(self.root)
self.build(self.root, structure[rootName])
def build(self, father, structure):
if type(structure) == dict:
for k in structure:
tag = self.doc.createElement(k)
father.appendChild(tag)
self.build(tag, structure[k])
elif type(structure) == OrderedDict:
for k in structure:
tag = self.doc.createElement(k)
father.appendChild(tag)
self.build(tag, structure[k])
elif type(structure) == list:
grandFather = father.parentNode
tagName = father.tagName
grandFather.removeChild(father)
for l in structure:
tag = self.doc.createElement(tagName)
self.build(tag, l)
grandFather.appendChild(tag)
else:
data = str(structure)
tag = self.doc.createTextNode(data)
father.appendChild(tag)
def display(self):
# I render from the root instead of doc to get rid of the XML header
#return self.root.toprettyxml(indent=" ")
return self.root.toxml()
class SolaceNode:
''' a sub dictionary builder '''
def __init__(self):
self.__dict__ = OrderedDict()
def __getattr__(self, name):
name = re.sub("_", "-", name)
try:
return self.__dict__[name]
except:
self.__dict__[name] = SolaceNode()
return self.__dict__[name]
def __str__(self):
return str(self.__dict__)
def __repr__(self):
return str(self.__dict__)
def __call__(self, *args, **kwargs):
return self.__dict__
def __setattr__(self, name, value):
name = re.sub("_", "-", name)
self.__dict__[name] = value
class SolaceXMLBuilder(object):
''' main dictionary builder
Any dot-name-space like calling of a instance of SolaceXMLBuilder will create
nested dictionary keys. These are converted to XML whenever the instance
representation is called ( __repr__ )
Example
a=SolaceXMLBuilder()
a.foo.bar.baz=2
str(a)
'<rpc semp-version="soltr/5_5">\n<foo><bar><baz>2</baz></bar></foo></rpc>'
'''
def __init__(self):
self.__dict__ = OrderedDict()
self.__setattr__ = None
def __getattr__(self, name):
name = re.sub("_", "-", name)
try:
return self.__dict__[name]
except:
self.__dict__[name] = SolaceNode()
return self.__dict__[name]
def __repr__(self):
# Show XML
myxml = d2x(eval(str(self.__dict__)))
# I had to conjur up my own header cause solace doesnt like </rpc> to have attribs
#return str('<rpc semp-version="soltr/5_5">\n%s</rpc>' % myxml.display())
return str('<rpc semp-version="soltr/5_5">\n%s</rpc>' % myxml.display())
def __call__(self, *args, **kwargs):
return self.__dict__
# def __setattr__(self, name, value):
# raise Exception('no you cant create assignments here, only on sub-elements')
if __name__ == '__main__':
x = SolaceXMLBuilder()
x.create.message_vpn.vpn_name='NEWVPN'
print(x)
# <?xml version="1.0" ?>
# <rpc semp-version="soltr/5_5">
# <create>
# <message-vpn>
# <vpn-name>
# NEWVPN
# </vpn-name>
# </message-vpn>
# </create>
# </rpc semp-version="soltr/5_5">
x=SolaceXMLBuilder()
x.message_vpn.vpn_name='NEWVPN'
x.message_vpn.no.feature_X
print(x)
# <?xml version="1.0" ?>
# <rpc semp-version="soltr/5_5">
# <message-vpn>
# <vpn-name>
# NEWVPN
# </vpn-name>
# <no>
# <feature-X/>
# </no>
# </message-vpn>
# </rpc semp-version="soltr/5_5">
# >>> client = SolaceAPI('pt1')
# >>> xml = SolaceXMLBuilder()
# >>> xml.create.message_vpn.vpn_name='NEWVPN'
# >>> client.rpc(str(xml))
# {u'rpc-reply': {u'execute-result': {u'#code': u'ok'}, u'#semp-version': u'soltr/5_5'}}
I have a class that doesn't extend webapp.RequestHandler, and I can't use self.response.out.write(), I get:
AttributeError: Fetcher instance has no attribute 'response'
If I extend webapp.RequestHandler (I thought it would work), I get:
AttributeError: 'Fetcher' object has no attribute 'response'
How can I use that method properly? Sometimes print doesn't work either; I just get a blank screen.
EDIT:
app.yaml:
application: fbapp-lotsofquotes
version: 1
runtime: python
api_version: 1
handlers:
- url: .*
script: main.py
source (the problematic line is marked with #<- HERE):
import random
import os
from google.appengine.api import users, memcache
from google.appengine.ext import webapp, db
from google.appengine.ext.webapp import util, template
from google.appengine.ext.webapp.util import run_wsgi_app
import facebook
class Quote(db.Model):
author = db.StringProperty()
string = db.StringProperty()
categories = db.StringListProperty()
#rating = db.RatingProperty()
class Fetcher(webapp.RequestHandler):
'''
Memcache keys: all_quotes
'''
def is_cached(self, key):
self.fetched = memcache.get(key)
if self.fetched:
print 'ok'#return True
else:
print 'not ok'#return False
#TODO: Use filters!
def fetch_quotes(self):
quotes = memcache.get('all_quotes')
if not quotes:
#Fetch and cache it, since it's not in the memcache.
quotes = Quote.all()
memcache.set('all_quotes',quotes,3600)
return quotes
def fetch_quote_by_id(self, id):
self.response.out.write(id) #<---------- HERE
class MainHandler(webapp.RequestHandler):
def get(self):
quotes = Fetcher().fetch_quotes()
template_data = {'quotes':quotes}
template_path = 'many.html'
self.response.out.write(template.render(template_path, template_data))
class ViewQuoteHandler(webapp.RequestHandler):
def get(self, obj):
self.response.out.write('viewing quote<br/>\n')
if obj == 'all':
quotes = Fetcher().fetch_quotes()
self.render('view_many.html',quotes=quotes)
else:
quotes = Fetcher().fetch_quote_by_id(obj)
'''for quote in quotes:
print quote.author
print quote.'''
def render(self, type, **kwargs):
if type == 'single':
template_values = {'quote':kwargs['quote']}
template_path = 'single_quote.html'
elif type == 'many':
print 'many'
self.response.out.write(template.render(template_path, template_values))
'''
CREATORS
'''
class NewQuoteHandler(webapp.RequestHandler):
def get(self, action):
if action == 'compose':
self.composer()
elif action == 'do':
print 'hi'
def composer(self):
template_path = 'quote_composer.html'
template_values = ''
self.response.out.write(template.render(template_path,template_values))
def post(self, action):
author = self.request.get('quote_author')
string = self.request.get('quote_string')
print author, string
if not author or not string:
print 'REDIRECT'
quote = Quote()
quote.author = author
quote.string = string
quote.categories = []
quote.put()
def main():
application = webapp.WSGIApplication([('/', MainHandler),
(r'/view/quote/(.*)',ViewQuoteHandler),
(r'/new/quote/(.*)',NewQuoteHandler) ],
debug=True)
util.run_wsgi_app(application)
if __name__ == '__main__':
main()
You're not routing to Fetcher when you initialize a WSGIApplication. Rather, you create an instance manually in other handlers. Thus, App Engine will not initialize your request and response properties. You can manually do so in from the handlers you route to, such as MainHandler and ViewQuoteHandler. E.g.:
fetcher = Fetcher()
fetcher.initialize(self.request, self.response)
quotes = fetcher.fetch_quotes()
Note that fetcher really doesn't have to be a RequestHandler. It could be a separate class or function. Once you have request and response objects, you can pass them around as you choose.