I am setting up a python project using RobotFramework and it is throwing No module named error even if I have added a Library entry in init.resource.
Also, I created an empty init.py in the folder in which the file exists so that the python file can be located.
My project structure is as below:
My Code is as below:
init.robot
*** Settings ***
Library MyLibrary.py
Test Setup Setup
Test Teardown Do Teardown
HelloVariable.robot
*** Settings ***
Resource init.resource
*** Test Cases ***
My First Robot Test
Say Hello From Library
Log To Console ${Data}
init.resource
*** Settings ***
Library test.py
Library MyLibrary.py
Library InitProject/ProtoFolder/ProtoService.py
MyLibrary.py
# mylibrary.py
from robot.api.deco import keyword
from robot.libraries.BuiltIn import BuiltIn
from robot.api import logger
import json
from InitProject.ProtoFolder.ProtoService import *
class MyLibrary:
def __init__(self):
self.data = None
#keyword("Setup")
def setup(self):
logger.console("Setting up test environment...")
self.data = {"key1": "value1", "key2": "value2"}
BuiltIn().set_test_variable("${Data}", self.data)
with open('/InitProject/ProtoFolder/RobotFramework/test.json') as f:
data = json.load(f)
logger.console(data)
#keyword("Do Teardown")
def teardown_test_environment(self):
logger.console("Tearing down test environment...")
self.data = None
ProtoService.proto_methods()
ProtoService.py
from robot.api import logger
from robot.api.deco import keyword
from robot.libraries.BuiltIn import BuiltIn
class ProtoService:
def proto_methods(self):
logger.console("Proto Method Called")
Actual Error:
er/RobotFramework/MyLibrary.py' failed: ModuleNotFoundError: No module named 'InitProject'
Traceback (most recent call last):
File "/Users/user/Python/pythonProject4/InitProject/ProtoFolder/RobotFramework/MyLibrary.py", line 7, in <module>
from InitProject.ProtoFolder.ProtoService import *
PYTHONPATH:
The code works after I add following however, I don't think it's a clean solution (or if there is a way to replace /Users/user/Python with an in-built variable).
import sys
sys.path.append('/Users/user/Python/pythonProject4/')
from InitProject.ProtoFolder.ProtoService import ProtoService
Related
I'm trying to use a third-party lib (docutils) on Google App Engine and have a problem with this code (in docutils):
try:
import pwd
do stuff
except ImportError:
do other stuff
I want the import to fail, as it will on the actual GAE server, but the problem is that it doesn't fail on my development box (ubuntu). How to make it fail, given that the import is not in my own code?
Even easier than messing with __import__ is just inserting None in the sys.modules dict:
>>> import sys
>>> sys.modules['pwd'] = None
>>> import pwd
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named pwd
In your testing framework, before you cause docutils to be imported, you can perform this setup task:
import __builtin__
self.savimport = __builtin__.__import__
def myimport(name, *a):
if name=='pwd': raise ImportError
return self.savimport(name, *a)
__builtin__.__import__ = myimport
and of course in teardown put things back to normal:
__builtin__.__import__ = self.savimport
Explanation: all import operations go through __builtin__.__import__, and you can reassign that name to have such operations use your own code (alternatives such as import hooks are better for such purposes as performing import from non-filesystem sources, but for purposes such as yours, overriding __builtin__.__import__, as you see above, affords truly simple code).
I have a folder structure similar to this (my example has all the necessary bits):
web-scraper/
scraper.py
modules/
__init__.py
config.py
website_one_scraper.py
Where config.py just stores some global variables. It looks a bit like:
global var1
var1 = "This is a test!"
Within website_one_scraper.py it looks like this:
import config
def test_function():
# Do some web stuff...
return = len(config.var1)
if __name__ == "__main__":
print(test_function)
And scraper.py looks like this:
from module import website_one_scraper
print(website_one_scraper.test_function())
website_scraper_one.py works fine when run by itself, and thus the code under if __name__ == "__main__" is run. However, when I run scraper.py, I get the error:
ModuleNotFoundError: No module named 'config'
And this is the full error and traceback (albeit with different names, as I've changed some names for the example above):
Traceback (most recent call last):
File "c:\Users\User\Documents\Programming\Work\intrack-web-scraper\satellite_scraper.py", line 3, in
<module>
from modules import planet4589
File "c:\Users\User\Documents\Programming\Work\intrack-web-scraper\modules\planet4589.py", line 5, in
<module>
import config
ModuleNotFoundError: No module named 'config'
Also note that In scraper.py I've tried replacing from modules import website_one_scraper with import website_one_scraper, from .modules import website_one_scraper, and from . import website_one_scraper, but they all don't work.
What could the cause of my error be? Could it be something to do with how I'm importing everything?
(I'm using Python 3.9.1)
In your website_scraper_one.py, instead of import config.py try to use from . import config
Explanation:
. is the current package or the current folder
config is the module to import
I have two files 'mod1.py' and 'mod2.py'.
mod1 requires request module to function. But I have not imported them in the mod1 instead I have imported both request and mod1 module in mod2.
But
I get an error 'name 'requests' is not defined'. I know it works if i Import 'request' module in mod1 directly it works fine. But I have other modules I want to use that requires 'request' module. So how do I import the module once and make in accessible to all the other modules ?.
mod1.py
class getUrl():
def __init__(self, url):
self.url = url
def grab_html(self):
html = requests.get(self.url).text
return html
mod2.py
import requests
import mod1
module1 = mod1.getUrl('https://www.wikipedia.org/')
HTML = module1.grab_html()
Edit: Complete error
Traceback (most recent call last):
File "C:\Users\camel\Desktop\test\mod2.py", line 5, in <module>
HTML = module1.grab_html()
File "C:\Users\camel\Desktop\test\mod1.py", line 6, in grab_html
html = requests.get(self.url).text
NameError: name 'requests' is not defined
[Finished in 0.5s with exit code 1]
[shell_cmd: python -u "C:\Users\guru\Desktop\test\mod2.py"]
When you import something, it becomes a named thing in the module that imported it. Requests is not being used driectly by mod2.py, but is by mod1.py so that's where you should import it.
You can do this, for example.
mod1.py
import requests
class getUrl():
def __init__(self, url):
self.url = url
def grab_html(self):
html = requests.get(self.url).text
return html
mod2.py
import mod1
module1 = mod1.getUrl('https://www.wikipedia.org/')
HTML = module1.grab_html()
# And also access requests via mod1
indirectly = mod1.requests.get('https://www.wikipedia.org/').text
import requests, should be in mod1.py, because it is used in the methods of the class defined in mod1.py. you could import it in both places if it was needed in mod2.py as well.
As you are not using requests in mod2.py, you could just do import requests in mod1.py
If you are worried about the memory, it will take the same amount as you are going to use it in just one script. But if you are using if you are planning to use it in mod2.py as well, then you have to include there also.
You need to create an __init__.py file (it can be empty) file so that the folder containing mod1 is recognized as a module.
Then you can do from mod1 import *, or from path.to.mod1 import * and it will carry over all the imports over to mod2. Check out this relative answer. In my opinion this is a sensible way of doing things, as you can keep all your dependencies in a centralized location.
As you're concerned about memory utilization, take a look at another conversation on the same matter.
Importing UTILS classes into Inventory - can it be done?
I have created a custom LDAP data importer as part of creating my inventory class. The LDAP schema we have wasn't similar enough to the LDAP plugin provided in samples.
My class is called ldapDataModule; the class is in:
/home/agt/ansible/agt_module_utils/ldapDataModule.py
My "$HOME/.ansible.cfg" file has the following:
module_utils = /home/agt/ansible/agt_module_utils
When running my Ansible inventory module, I get the following output:
ansible ecomtest37 -m ping
ERROR! Attempted to execute "/sites/utils/local/ansible/hosts" as
inventory script: Inventory script (/sites/utils/local/ansible/hosts) had
an execution error: Traceback (most recent call last):
File "/sites/utils/local/ansible/hosts", line 22, in
from ansible.module_utils import ldapDataModule
ImportError: No module named module.utils
The include statement inside hosts appears like this:
import copy
import ldap
import re
import sys
import operator
import os
import argparse
import datetime
import os.path
try:
import json
except:
import simplejson as json
from ansible.module_utils import ldapDataModule
class agtInventory(object):
RECOMENDATIONS?
I was able to do the following as a "work around". I'd still like to hear from Ansible guru's on proper use of "module_utils" variable from ansible.cfg
sys.path.insert(0, '/home/agt/ansible/agt_module_utils')
from ldapDataModule import ldapDataModule
I've been working on a python script that will require multiple libraries to be imported.
At the moment my directory structure is
program/
main.py
libs/
__init__.py
dbconnect.py
library01.py
library02.py
library03.py
My dbconnect.py which has the following contents
import psycopg2
class dbconnect:
def __init__(self):
self.var_parameters = "host='localhost' dbname='devdb' user='temp' password='temp'"
def pgsql(self):
try:
var_pgsqlConn = psycopg2.connect(self.var_parameters)
except:
print("connection failed")
return var_pgsqlConn
I am able to import and use this in my main.py using
from libs.dbconnect import dbconnect
class_dbconnect = dbconnect()
var_pgsqlConn = class_dbconnect.pgsql()
This works as expected however I am trying to import all of the library scripts each which have similar contents to bellow
def library01():
print("empty for now but this is library 01")
I have added to my __init__.py script
__all__ = ["library01", "library02"]
Then in my main.py I tried to import and use them as bellow
from libs import *
library01()
I am getting the following error
TypeError: 'module' object is not callable
I'll suppose content in your library0x.py are different (the functions/class have different names)
The best way is to import all your subfiles content in the __init__.py
# __init__.py
from .dbconnect import *
from .library01 import *
from .library02 import *
from .library03 import *
Then you can use the following :
from libs import library01, library02
If you want to restrict for some reasons importation with the wildcard (*) in your library0x.py files, you can define a __all__ variable containing all the names of the function you will import with the wildcard :
# library01.py
__all__ = ["library01"]
def a_local_function():
print "Local !"
def library01():
print "My library function"
Then, by doing from .library01 import *, only the function library01 will be import.
EDIT: Maybe i missunderstand the question : here are some ways to import the function library01 in the file library01.py :
# Example 1:
from libs.library01 import library01
library01()
# Example 2:
import libs.library01
libs.library01.library01()
# Example 3:
import libs.library01 as library01
library01.library01()
In your case library01 is a module which contains a function named library01. You import the library01 module and try to call it as a function. That's the problem. You should call the function like this:
library01.library01()