I'm trying to upload an image to my uploads folder on my remote server. The folder structure is always uploads/year/month/
and I can't get paramiko to check if the folders exist and if not make them.
SSH connection is working, uploading a file is working too, but creating the subfolders in the uploads directory isn't working.
I came across what looked like the solution here. It's the same question I have, but I'm on iOS and use Pythonista. Option A: my code is plain wrong or Option B it's an iOS/Pythonista specific issue.
So, the code from the other thread (linked above) set a definition and runs a try/error loop to tests if the folders passed through it already exists and if not creates them. In my script below it's # Set Definition for "mkdir -p"
.
Calling it with the remoteFilePath
…
datePath
exists, since the remotePath
definitely existsfileName
is no path and will be put there by the next command.I tried adjusting the script, but somehow I can't make it work.
TypeError: mkdir_p() takes exactly 2 arguments (1 given)"
AttributeError: 'tulpe' object has no attribute 'rfind'
Exception: unknown type for (/home/userZ/Dropbox/uploads/year/month', 'test.png') type <type 'tuple'>
Here's a snippet of the relevant parts of the script (or a gist if you prefer the look of it):
# Set Variables
fileName = "temp.png"
remotePath = "/home/userZ/Dropbox/uploads/"
datePath = "year/month/"
remoteFilePath = remotePath + datePath + fileName #
# Set Definition for "mkdir -p"
def mkdir_p(sftp,remote_directory):
remote_dirname, basename = os.path.split(remote_directory)
mkdir_p(os.path.dirname(remote_directory))
try:
sftp.chdir(name)
except IOError:
sftp.mkdir(name)
sftp.chdir(name)
try:
transport.connect(username = username, password = password)
sftp = paramiko.SFTPClient.from_transport(transport) # Start SFTP client
# Try to make remote path - 3 Versions and all fail
mkdir_p(sftp,remoteFilePath) # Version 1
#mkdir_p(sftp, os.path.split(remoteFilePath)) # Version 2
#sftp.mkdir(os.path.split(remoteFilePath)) # Version 3
# Put file to remote
sftp.put('temp.png', remoteFilePath)
# Close connection
finally:
transport.close()
sftp.close()
Any help is appreciated. (Careful: OP = Python noob). I rely on Paramiko because my shared host only supports SFTP. Otherwise I'd have gone with FTPlib.
CClauss got the answer and put it in the comment section of the gist linked above. I take no credit.
This was his answer - in cause anyone else tries to emulate mkdir -p
with paramiko, then here you go:
My sense is that you need to: Try to mkdir on :/home/ Try to mkdir on :/home/userZ/ Try to mkdir on :/home/userZ/Dropbox/ Try to mkdir on :/home/userZ/Dropbox/uploads/ Try to mkdir on :/home/userZ/Dropbox/uploads/year/ Try to mkdir on :/home/userZ/Dropbox/uploads/year/month/ Then cd to /home/userZ/Dropbox/uploads/year/month/ Then copy your file
Try this...
# Slash '/' is hardcoded because ftp always uses slash
def mk_each_dir(sftp, inRemoteDir):
currentDir = '/'
for dirElement in inRemoteDir.split('/'):
if dirElement:
currentDir += dirElement + '/'
print('Try to mkdir on :' + currentDir)
try:
sftp.mkdir(currentDir)
except:
pass # fail silently if remote directory already exists
# Set Variables
fileName = "temp.png"
remotePath = "/home/userZ/Dropbox/uploads/"
datePath = "year/month/"
remoteDirPath = remotePath + datePath
mk_each_dir(sftp, remoteDirPath)
sftp.chdir(remoteDirPath)
remoteFilePath = remoteDirPath + fileName