Using a file created in a keyword function as an argument - python

Confused on how to use a created file for a function in the robot framework. Normally I would do something along the lines of f = open("logFileTest.txt", "w") and then pass f into the function like so getAddresses(f)
This getAddresses function is written to use a passed argument for logging.
def getAddresses(logFile=None):
print("Entering getAddresses!", file=logFile)
So when translating this to the robot framework I attempt to create a file and set that created file into a variable and then call the function with that newly created variable.
${logFile}= Create File log.txt
${addresses}= Get Addresses ${logFile}
This however sets logFile equal to none rather than the newly created log.txt that I would like it to be set to.
Is there another way in the robot framework to open the file than Get File? Get file in this case doesn't work as it only returns the contents of the file.

Create File does not return path to the file (or anything according to documentation [1]). You could set path as variable and give that to Create File keyword as argument and then also to your Get Addresses keyword.
${path}= Set Variable log.txt
Create File ${path}
${addresses}= Get Addresses ${path}
Then in the keyword implementation you need to open it (as path is only passed):
def getAddresses(logFile):
with open(logFile, 'w') as f:
print('Entering getAddresses!', file=f)
[1] https://robotframework.org/robotframework/latest/libraries/OperatingSystem.html#Create%20File

Related

Transferring .MP3 file from FTP server to eventually use in discord bot [duplicate]

I have created a python script to connect to a remserver.
datfile = []
for dk in range(len(files)):
dfnt=files[dk]
dpst=dfnt.find('.dat')
if dpst == 15:
dlist = dfnt[:]
datfile.append(dlist)
assert datfile == ['a.dat','b.dat']
# True
Which as you can see creates a list. Now I am passing this list to
ftp.retrbinary('datfile')
but this lines returns an error:
typeerror: retrbinary() takes at least 3 arguments (2 given)
not sure what is looking for?
It's telling you that you aren't supplying enough arguments to the retrbinary method.
The documentation specifies that you must also supply a 'callback' function that gets called for every block of data received. You'll want to write a callback function and do something with the data it gives you (e.g. write it to a file, collect it in memory, etc.)
As a side note, you might ask why it says there are '3' required arguments instead of just '2'. This is because it's also counting the 'self' argument that Python requires on instance methods, but you are implicitly passing that with the ftp object reference.
EDIT - Looks like I may not have entirely answered your question.
For the command argument you are supposed to be passing a valid RETR command, not a list.
filenames = ['a.dat', 'b.dat']
# Iterate through all the filenames and retrieve them one at a time
for filename in filenames:
ftp.retrbinary('RETR %s' % filename, callback)
For the callback, you need to pass something that is callable (usually a function of some sort) that accepts a single argument. The argument is a chunk of data from the file being retrieved. I say a 'chunk' because when you're moving large files around, you rarely want to hold the entire file in memory. The library is designed to invoke your callback iteratively as it receives chunks of data. This allows you to write out chunks of the file so you only have to keep a relatively small amount of data in memory at any given time.
My example here is a bit advanced, but your callback can be a closure inside the for loop that writes to a file which has been opened:
import os
filenames = ['a.dat', 'b.dat']
# Iterate through all the filenames and retrieve them one at a time
for filename in filenames:
local_filename = os.path.join('/tmp', filename)
# Open a local file for writing (binary mode)...
# The 'with' statement ensures that the file will be closed
with open(local_filename, 'wb') as f:
# Define the callback as a closure so it can access the opened
# file in local scope
def callback(data):
f.write(data)
ftp.retrbinary('RETR %s' % filename, callback)
This can also be done more concisely with a lambda statement, but I find people new to Python and some of its functional-style concepts understand the first example more easily. Nevertheless, here's the ftp call with a lambda instead:
ftp.retrbinary('RETR %s' % filename, lambda data: f.write(data))
I suppose you could even do this, passing the write instance method of the file directly as your callback:
ftp.retrbinary('RETR %s' % filename, f.write)
All three of these examples should be analogous and hopefully tracing through them will help you to understand what's going on.
I've elided any sort of error handling for the sake of example.
Also, I didn't test any of the above code, so if it doesn't work let me know and I'll see if I can clarify it.

What is 'target' in 'target = open(...)'

I'm learning Python as someone more familiar with databases and ETL. I'm not sure where target comes from in the following code.
from sys import argv
script, filename = argv
target = open(filename, 'w')
I think argv is a class in the sys module, but I don't think target comes from argv.
If you run type(target), you will get this: <_io.TextIOWrapper name='dde-recommendation-engine/sample_data/synthetic-micro/ratings.txt' mode='r' encoding='UTF-8'>
What that means in simple terms is that it is an object accessing that particular file (with only write permission because you have a w mode).
You can use this object to add stuff into the file by target.write(.....)
Do remember to close the file however by doing target.close() at the end.
Another way to do the same and I prefer this most of the times is:
with open(filename, 'w') as target:
target.write(...)
This way the file is closed automatically once you are out of the with context.
argv is the list populated by the arguments provided by user while running the program from shell. Please see https://docs.python.org/3/library/sys.html#sys.argv for more info on that.
User supplied the filename from shell, program used the open call https://docs.python.org/3/library/functions.html#open to get a file handle on that filename
And that file handle is stored in variable called target (which could be named anything you like) so that you can process the file using other file methods.
You are using open() - a built-in function in python. This function returns an File object - which is assigned to target variable. Now you can interact with target to write data (since you are using the w mode)
.

Is there a way to access the name of the YAML variable file passed as an argument to robot framework?

I need to automate the calling of a Python script like this:
python3 sendStuff.py --yaml yamlVariableFile.yaml
To automate this, I am using RobotFramework. I plan to call the Robot script like this:
robot robotScript.robot --variablefile yamlVariableFile.yaml
I can now access the variables specified within yamlVariableFile.yaml, but I need a way to access the name of this file as well - yamlVariableFile.yaml - since I need to pass it as an argument to the Python script - sendStuff.py - within the robot script. Is there a way to do this?
I do not think you can do that. What you can do is pass the file name in a separate variable (not variable file):
--variable filename:yamlVariableFile.yaml
or add an additional variable to the yaml file that could have the name of the file itself.

How to invoke a Perl script that need args from Python

I'm writing my script in Python, and I want to invoke a Perl script from it.
This is the line I want to call:
perl conv_intel_hex_2_verilog.pl arg1 arg2
while arg1 is the input from the Python script and arg2 is a new file that I'm creating.
So far I have this:
def main(argv):
file = open("test.hex", "w")
input = argv[0];
subprocess.call(["perl", "conv_intel_hex_2_verilog.pl", input]);
file.close();
This runs and does nothing.
And when I'm changing the
subprocess.call(["perl", "conv_intel_hex_2_verilog.pl", input]);
to
subprocess.call(["perl", "conv_intel_hex_2_verilog.pl", input ,file]);
it doesn't compile...
As you've described it, the program you're running expects its second argument to be the name of a file, so that's what you need to give it. In your current code, you're giving it a Python file object, which is not the same as the string name of a file.
subprocess.call(["perl", "conv_intel_hex_2_verilog.pl", input, "test.hex"]);
There is no need to create the file object prior to running that code, either. The other program will surely create it for you, and might even balk if it finds that the file already exists.
You cannot just give it a filehandle (or whatever that is called in Python). You are constructing a call to another program, and that program expects a filename, so pass the filename as a string.
subprocess.call(["perl", "conv_intel_hex_2_verilog.pl", input ,"test.hex"]);
You also don't need to open the file first.

Opening file - Performing a function

I was wondering if someone could give me a direction on how to give functions to a file... This is a bit hard to explain, so I'll try my best.
Let's say I have an application (using wxPython) and let's say that I have a file. Now this file is assigned to open with the application. So, I double-click the file and it opens the application. Now my question is, what would have to be written on the file to, for example, open up a dialog? So we double-click the file and it opens a dialog on the application?
PS: I know that I have first to associate the program with a certain file type to double-click it, but thats not the question.
AFAIK most platforms just call the helper app with the file you clicked on as an argument, so your filepath will be in sys.argv[1]
I think what he wants to do is associate a file extension to his application so when he opens the file by double clicking it, it sends the contents of the file to his app; in this case, display the contents within a Dialog?
If this is the case, than the first thing you would need to do (provided you are on windows) is create the appropriate file association for your file extention. This can be done through the registry and when setup correctly will open your app with the the path/filename of the file that was executed as the first argument. Ideally it is the same as executing it from the command line like:
C:\your\application.exe "C:\The\Path\To\my.file"
Now as suggested above, you would then need to use sys.argv to to obtain the arguments passed to your application, in this case C:\Path\To\my.file would be the first argument. Simply put, sys.argv is a list of arguments passed to the application; in this case the first entry sys.argv[0] will always be the path to your application, and as mentioned above, sys.argv[1] would be the path to your custom file.
Example:
import sys
myFile = sys.argv[1]
f = file(myFile, "r")
contents = f.read()
f.close()
Then you will be able to pass the variable contents to your dialog to do whatever with.

Categories

Resources