Python equivalent of this Curl command - python

I am trying to download a file using python, imitating the same behavior as this curl command:
curl ftp://username:password#example.com \
--retry 999 \
--retry-max-time 0
-o 'target.txt' -C -
How would this look in python ?
Things I have looked into:
Requests : no ftp support
Python-wget: no download resume support
requests-ftp : no download resume support
fileDownloader : broken(?)
I am guessing one would need to build this from scratch and go low level with pycurl or urllib2 or something similar.
I am trying to create this script in python and I feel lost.. Should I just call curl from python subprocess ?
Any point to the write direction would be much appreciated

you can use python's inbuilt ftplib
Here is the code:
from ftplib import FTP
ftp = FTP('example.com', 'username', 'password') #logs in
ftp.retrlines() # to see the list of files and directories ftp.cwd('to change to any directory')
ftp.retrbinary('RETR filename', open('Desktop\filename', 'wb').write) # start downloading
ftp.close() # close the connection
Auto resume is supported. I even tried turning off my wifi and checked if the download is resuming.
You can refer to /Python27/Lib/ftplib.py for default GLOBAL_TIME_OUT settings.

there is this library for downloading files from ftp server
fileDownloader.py
to download the file
downloader = fileDownloader.DownloadFile(‘http://example.com/file.zip’, “C:UsersusernameDownloadsnewfilename.zip”, (‘username’,’password’))
downloader.download()
to resume download
downloader = fileDownloader.DownloadFile(‘http://example.com/file.zip’, “C:UsersusernameDownloadsnewfilename.zip”, (‘username’,’password’))
downloader.resume()

Related

FileNotFoundError: [Errno2]: No Such file or directory:

I am trying to make a server hardening script for my work, part of it is to install wazuh-agent on the servers that will be connected to a SIEM manager.
The script has 2 parts, one where it adds the repo entry - that works fine.
The second part installs the wazuh agent (code below). When I run the commands on the shell, they work fine but with the script it gives me the following error.
import os
import subprocess
wazuhrepofile = "/etc/yum.repos.d/wazuh.repo"
wazuh = "wazuh-agent"
wazuhmanager = 'WAZUHMANAGER="10.0.0.2"'
def install_wazuh(wazuh, wazuhmanager, wazuhrepofile):
subprocess.run([wazuhmgr ,'yum', 'install', '-y', wazuh], check=True)
print("Wazuh Agent Installed")
subprocess.run(['systemctl', 'daemon-reload'], check=True)
print("Daemon Reloaded")
subprocess.run(['systemctl', 'enable', wazuh])
print("Wazuh Agent Enabled")
subprocess.run(['systemctl', 'start', wazuh], check=True)
print("Wazuh-Agent Service Started!")
subprocess.run(['sed', '-i', '"s/^enabled=1/enabled=0/"', wazuhrepofile])
install_wazuh(wazuh, wazuhmgr, wazuhrepofile)
and the following is the error
[run error]
hj.
Thanks for choosing Wazuh.
As it was stated, subprocess.run accepts a series of parameters, but it seems that the first one needs to be an actual command instead of a variable assignment.
What you are doing is passing the Manager IP to have the Agent auto-enroll to the Manager. Another possible way, would be to install the Agent and then use the agent-auth located on the /var/ossec/bin/ folder. This commands also allows the Agent to pass an Agent Name to the Manager, so it will show with on the alerts and the UI, for easier identification.
the command is: /var/ossec/bin/agent-auth -m MANAGER-IP -A AGENT-NAME
For more information on agent registration visit here and for info on agent-auth tool, here
In case you have any further questions, don't hesitate to ask.
Cheers

CURL request to Python as command line

Currently, I'm trying to convert CURL request to Python script.
curl $(curl -u username:password -s https://api.example.com/v1.1/reports/11111?fields=download | jq ".report.download" -r) > "C:\sample.zip"
I have tried pycurl, with no success, due to knowledge limitation.
As a solution, I have found, that it is possible to run commands through python.
https://www.raspberrypi.org/forums/viewtopic.php?t=112351
import os
os.system("curl -K.........")
And other solution ( based on the search more common) using subprocess
import subprocess
subprocess.call(['command', 'argument'])
Currently, I'm not sure where to move and how to adapt this solution to my sitionation.
import os
os.system("curl $(curl -u username:password -s https://api.example.com/v1.1/reports/11111?fields=download | jq '.report.download' -r) > 'C:\sample.zip'")
'curl' is not recognized as an internal or external command,
operable program or batch file.
255
P.S. - Update v1
Any suggestion?
import requests
response = requests.get('https://api.example.com/v1.1/reports/11111?fields=download | jq ".report.download" -r', auth=('username', 'password'))
This work without "| jq ".report.download" this part, but this is the main part which gives at the end only link to download the file.
ANy way around it?
The error 'curl' is not recognized as an internal or external command means that python couldn't find the location where curl is installed. If you have already installed curl, try giving the full path to where curl is installed. For example, if curl.exe is located in C:\System32, the try
import os
os.system("C:\System32\curl $(curl -u username:password -s https://api.example.com/v1.1/reports/11111?fields=download | jq '.report.download' -r) > 'C:\sample.zip'")
But thats definitely not pythonic way of doing things. I would instead suggest to use requests module.
You need to invoke requests module twice for this, first to download the json content from https://api.example.com/v1.1/reports/11111?fields=download, get a new url pointed byreport.download and then invoke requests again to download data from the new url.
Something along these lines should get you going
import requests
url = 'https://api.example.com/v1.1/reports/11111'
response = requests.get(url, params=(('fields', 'download'),),
auth=('username', 'password'))
report_url = response.json()['report']['download']
data = requests.get(report_url).content
with open('C:\sample.zip', 'w') as f:
f.write(data)
You can use this site to convert the actual curl part of your command to something that works with requests: https://curl.trillworks.com/
From there, just use the .json() method of the request object to do whatever processing you need to be doing.
Finally, can save like so:
import json
with open('C:\sample.zip', 'r') as f:
json.dump(data, f)

youtube-dl not accepting playlist url

With this code
import os
with open('urls.txt') as f:
for line in f:
os.system("youtube-dl "+"--write-thumbnail "+"--skip-download "+"--yes-playlist " +line)
The first image in the playlist downloads, then I get an error message saying 'list' is not recognized as an internal or ex ternal command, operable program or batch file. In 'urls.txt' I have just one url of a Youtube playlist. The url is this:
https://www.youtube.com/watch?v=GA3St3Rf9Gs&list=PL-uc0GihCvU9s24BT_mvTzt3zm7e2uDGm
It's cutting off input after the & symbol. If I replace 'list' in the url with 'foo' I get the same message. What do I do to make youtube-dl accept playlist URL?
Your program has a major command injection security vulnerability. You have triggered this (with harmless code) by accident. You are executing
youtube-dl --write-thumbnail --skip-download --yes-playlist \
https://www.youtube.com/watch?v=GA3St3Rf9Gs&list=PL-uc0GihCvU9s24BT_mvTzt3zm7e2uDGm
Since the ampersand is a command character in shell scripts, you're running two commands
youtube-dl --write-thumbnail --skip-download --yes-playlist \
https://www.youtube.com/watch?v=GA3St3Rf9Gs
and
list=PL-uc0GihCvU9s24BT_mvTzt3zm7e2uDGm
Since there is no program with that name, the second command will likely fail.
To fix this, use proper subprocess invocations with subprocess:
import subprocess
with open('urls.txt') as f:
for line in f:
subprocess.check_call([
"youtube-dl",
"--write-thumbnail", "--skip-download", "--yes-playlist",
line])
All you have to do to fix this, quote the YouTube URL, as in:
yt-dlp --yes-playlist "https://www.youtube.com/watch?v=XArZ74galOE&list=PLDrswW4_QtejDZdLE4EOVXunQvqU18sPK"
Solved the problem.
Thanks to nav3916872
You can use the youtube_dl library directly in your script and pass the urls to download from.
import os
import youtube_dl
ydl_opts = {
'writethumbnail': True,
'skip_download': True,
'noplaylist': False
}
with open('urls.txt') as f:
sources = f.readlines()
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
ydl.download(sources)
in commandprompt , you just need to quote the url(with ampersand). You can try to escape the url(with ampersand) in the same way in python. Refer youtube-dl FAQ

Remote Directory Listing Python WSGI

I'm currently an Intern in a IT service and I've been asked to build a web based app using Python that will run on a Linux environment. This web app has to be WSGI-compliant and I cannot use any framework.
My issue currently is that I want to have a variable set as a list of files in the said directory. Therefore I can then proceed to list those files by printing a table having each row being a file.
I am aware of os.listdir() but can't find a way to use it on a remote server (which is supposed not to be the case considering what google searches showed me...).
I tried an os.system(ssh root#someip:/path/to/dir/) but as python doc states, I cant get the output I want as it returns some integers...
Below is a piece of my script.
#ip is = to the ip of the server I want to list.
ip = 192..............
directory = "/var/lib/libvirt/images/"
command = "ssh root#"+ip+" ls "+directory
dirs = os.system(command)
files = ""
table_open = "<table>"
table_close = "</table>"
table_title_open = "<th>Server: "
table_title_close = "</th>"
tr_open = "<tr>"
tr_close = "</tr>"
td_open = "<td>"
td_close = "</td>"
input_open = "<input type='checkbox' name='choice' value='"
input_close = "'>"
#If i don't put dirs in brackets it raises an error (dirs not being iterable)
for file in [dirs]:
files = files + tr_open+td_open+file+td_close+td_open+input_open+file+input_close+td_close+tr_close
table = table_open+table_title_open+str(num_server)+table_title_close+files+table_close
I've tried this with a local directory (with os.listdir) and it works perfectly. I am having troubles only with remote directory listing...
I do hope that my question is crystal clear, if not I'll do my best to be more accurate.
Thanks in advance,
-Karink.
You can use subprocess module, here is an example:
import subprocess
ls = subprocess.Popen(['ssh','user#xx.xx.xx.xx', 'ls'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = ls.communicate()
print out
print err
You may also use pysftp
first install it using pip install pysftp then the below code can list the files on remote linux machine from windows as well
import pysftp
cnopts = pysftp.CnOpts()
cnopts.hostkeys = None
with pysftp.Connection('ipLinuxmachine', username='username', password='passwd',cnopts=cnopts) as sftp:
out=sftp.execute('cd path of directory ; ls')
print out

How to check results of wget/urllib2 in Python?

I am brand new to Python and am trying to write a monitor to determine whether a Java web app (WAR file) running on localhost (hosted by Apache Tomcat) is running or not. I had earlier devised a script that ran:
ps -aef | grep myWebApp
And inspected the results of the grep to see if any process IDs came back in those results.
But it turns out that the host OS only sees the Tomcat process, not any web apps Tomcat is hosting. I next tried to see if Tomcat came with any kind of CLI that I could hit from the terminal, and it looks like the answer is no.
Now, I'm thinking of using wget or maybe even urllib2 to determine if my web app is running by having them hit http://localhost:8080/myWebApp and checking the results. Here is my best attempt with wget:
wgetCmd = "wget http://localhost:8080/myWebApp"
wgetResults = subprocess.check_output([wgetCmd], shell=True, stderr=subprocess.STDOUT)
for line in wgetResults.strip().split('\n'):
if 'failed' in line:
print "\nError: myWebApp is not running."
sys.exit()
My thinking here is that, if the web app isn't running, wget's output should always contain the word "failed" inside of it (at least, from my experience). Unfortunately, when I run this, I get the following error:
Traceback (most recent call last):
File "/home/myUser/mywebapp-mon.py", line 52, in <module>
main()
File "/home/myUser/mywebapp-mon.py", line 21, in main
wgetResults = subprocess.check_output([wgetCmd], shell=True, stderr=subprocess.STDOUT)
File "/usr/lib/python2.7/subprocess.py", line 544, in check_output
raise CalledProcessError(retcode, cmd, output=output)
subprocess.CalledProcessError: Command '['wget http://localhost:8080/myWebApp']' returned non-zero exit status 4
Any thoughts as to what's going on here (what the error is)? Also, and more importantly, am I going about this the wrong way? Thanks in advance!
I suggest you try the Requests module. It is much more user-friendly then wget or urllib. Try something like this:
import requests
r = requests.get('http://localhost:8080/myWebApp')
>>> r.status_code
200
>>> r.text
Some text of your webapp
*EDIT * installation instructions http://docs.python-requests.org/en/latest/user/install/
To check url:
import urllib2
def check(url):
try:
urllib2.urlopen(url).read()
except EnvironmentError:
return False
else:
return True
To investigate what kind of an error occurred you could look at the exception instance.
You can also build on using urllib2/requests and interact with Tomcat's manager service if it's installed. My using the list method you can receive the following information:
OK - Listed applications for virtual host localhost
/webdav:running:0
/examples:running:0
/manager:running:0
/:running:0

Categories

Resources