can't upload file using ftplib over ssh-tunnel - python

I'm trying to upload a file using ftplib over an sshtunnel. I can login successfully to the remote end ftp server over this tunnel, but the program times out when trying to send the file.
import paramiko
from sshtunnel import SSHTunnelForwarder
from ftplib import FTP
USER = ["userSSH","passSSH"]
SSHPORT = 22
SSHIP = "A.B.C.D"
ROUTER_FTP_PORT = 21
REMOTE_FTP = "W.X.Y.Z"
fserver = SSHTunnelForwarder( (SSHIP, SSHPORT),
ssh_username = USER[0],
ssh_password = USER[1],
remote_bind_address = (REMOTE_FTP, ROUTER_FTP_PORT), )
fserver.start()
fport = fserver.local_bind_port
ftp = FTP()
ftp.connect("127.0.0.1",fport)
ftp.login("ftpUser","ftpPass")
file = open('lucas.cfg','rb')
ftp.storbinary('STOR lucas.cfg',file)
file.close()
I can certanly connect and login:
In [8]: ftp.connect("127.0.0.1",fport)
Out[8]: '220 FTP server ready'
In [9]: ftp.login("ftpUser","ftpPass")
Out[9]: '230 User logged in'
... but a time out rises when trying to upload the file ...
In [19]: ftp.storbinary('STOR lucas.cfg',file)
---------------------------------------------------------------------------
TimeoutError Traceback (most recent call last)
<ipython-input-19-0af0cb3b5ebf> in <module>()
----> 1 ftp.storbinary('STOR lucas.cfg',file)
/usr/lib/python3.6/ftplib.py in storbinary(self, cmd, fp, blocksize, callback, rest)
502 """
503 self.voidcmd('TYPE I')
--> 504 with self.transfercmd(cmd, rest) as conn:
505 while 1:
506 buf = fp.read(blocksize)
/usr/lib/python3.6/ftplib.py in transfercmd(self, cmd, rest)
397 def transfercmd(self, cmd, rest=None):
398 """Like ntransfercmd() but returns only the socket."""
--> 399 return self.ntransfercmd(cmd, rest)[0]
400
401 def login(self, user = '', passwd = '', acct = ''):
/usr/lib/python3.6/ftplib.py in ntransfercmd(self, cmd, rest)
359 host, port = self.makepasv()
360 conn = socket.create_connection((host, port), self.timeout,
--> 361 source_address=self.source_address)
362 try:
363 if rest is not None:
/usr/lib/python3.6/socket.py in create_connection(address, timeout, source_address)
722
723 if err is not None:
--> 724 raise err
725 else:
726 raise error("getaddrinfo returns an empty list")
/usr/lib/python3.6/socket.py in create_connection(address, timeout, source_address)
711 if source_address:
712 sock.bind(source_address)
--> 713 sock.connect(sa)
714 # Break explicitly a reference cycle
715 err = None
TimeoutError: [Errno 110] Connection timed out
any hint?
thanks!

So the thing is I was missing tunneling the data port of FTP. In order to avoid creating a second tunnel, I just used sftp instead.
server = SSHTunnelForwarder( (SSHIP, SSHPORT),
ssh_username = USER[0],
ssh_password = USER[1],
remote_bind_address = (REMOTE_SFTP, ROUTER_SFTP_PORT), )
server.start()
sftpPort = server.local_bind_port
transport = paramiko.Transport(("127.0.0.1",sftpPort))
transport.connect(None,username,password)
sftp = paramiko.SFTPClient.from_transport(transport)
sftp.put(fileLocal,fileRemote)
With the previous I can upload a file to a remote SFTP server over an SSH tunnel. Yes, is not FTP, but it worked for me.
If FTP is the only possible way, then a second ssh tunnel for the data channel will be needed.

Related

Python - Spotipy: How do I grant access permissions to my script to stop getting this error?

I am trying to get my personal Spotify data for a personal project and am using the Spotipy api to attempt to do so. Mainly following this article/guide, I wrote this code:
import spotipy
from spotipy.oauth2 import SpotifyClientCredentials
import spotipy.util as util
cid ="********"
secret = "********"
redirecturi = 'http://localhost:8888'
username = "***"
client_credentials_manager = SpotifyClientCredentials(client_id=cid, client_secret=secret)
sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
scope = 'user-library-read playlist-read-private'
token = util.prompt_for_user_token(username, scope,client_id=cid,client_secret=secret,redirect_uri=redirecturi)
if token:
sp = spotipy.Spotify(auth=token)
else:
print("Can't get token for", username)
I get an error saying Couldn't read cache at: .cache-"my username" and the python error is this:
OSError Traceback (most recent call last)
<ipython-input-2-57cc37944df1> in <module>
16 sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
17 scope = 'user-library-read playlist-read-private'
---> 18 token = util.prompt_for_user_token(username, scope,client_id=cid,client_secret=secret,redirect_uri=redirecturi)
19 if token:
20 sp = spotipy.Spotify(auth=token)
~\anaconda3\lib\site-packages\spotipy\util.py in prompt_for_user_token(username, scope, client_id, client_secret, redirect_uri, cache_path, oauth_manager, show_dialog)
97
98 if not token_info:
---> 99 code = sp_oauth.get_auth_response()
100 token = sp_oauth.get_access_token(code, as_dict=False)
101 else:
~\anaconda3\lib\site-packages\spotipy\oauth2.py in get_auth_response(self, open_browser)
437 # Only start a local http server if a port is specified
438 if redirect_port:
--> 439 return self._get_auth_response_local_server(redirect_port)
440 else:
441 logger.warning('Using `%s` as redirect URI without a port. '
~\anaconda3\lib\site-packages\spotipy\oauth2.py in _get_auth_response_local_server(self, redirect_port)
403
404 def _get_auth_response_local_server(self, redirect_port):
--> 405 server = start_local_http_server(redirect_port)
406 self._open_auth_url()
407 server.handle_request()
~\anaconda3\lib\site-packages\spotipy\oauth2.py in start_local_http_server(port, handler)
1225
1226 def start_local_http_server(port, handler=RequestHandler):
-> 1227 server = HTTPServer(("127.0.0.1", port), handler)
1228 server.allow_reuse_address = True
1229 server.auth_code = None
~\anaconda3\lib\socketserver.py in __init__(self, server_address, RequestHandlerClass, bind_and_activate)
450 if bind_and_activate:
451 try:
--> 452 self.server_bind()
453 self.server_activate()
454 except:
~\anaconda3\lib\http\server.py in server_bind(self)
136 def server_bind(self):
137 """Override server_bind to store the server name."""
--> 138 socketserver.TCPServer.server_bind(self)
139 host, port = self.server_address[:2]
140 self.server_name = socket.getfqdn(host)
~\anaconda3\lib\socketserver.py in server_bind(self)
464 if self.allow_reuse_address:
465 self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
--> 466 self.socket.bind(self.server_address)
467 self.server_address = self.socket.getsockname()
468
OSError: [WinError 10013] An attempt was made to access a socket in a way forbidden by its access permissions
Can someone please let me know how I should go about granting access permissions or if there is something else that I am doing wrong? I'm using Jupyter Notebook for this if it makes any difference. Also if you are aware of an easier way to go about getting the data I am after, please let me know.
This is my first post so apologies for any bad practices I have used here.
Try running this in another environment/IDE. Line 310 of spotipy/oauth2.py illustrates that Spotipy throws this warning if a cache file for tokens has not yet been instantiated.

pymysql, Access Denied Error in connecting to SQL Server

I am trying to load an excel file into a database for which I have to first connect to my SQL server using python. MYSQL server is already running in the background. Now when I try to run this code:
import xlrd
import pymysql
xl_data = xlrd.open_workbook('C:/Users/xxx/Desktop/xyz.xlsx')
mydb = pymysql.connect( host = 'localhost' , user ="x" , passwd = "x" , db = "")
cursor = mydb.cursor()
I get the following error:
---------------------------------------------------------------------------
OperationalError Traceback (most recent call last)
<ipython-input-2-d43a74bc83ce> in <module>
3
4 xl_data = xlrd.open_workbook('C:/Users/Sankalp/Desktop/Problem_Sample Linkedin Data.xlsx')
----> 5 mydb = pymysql.connect( host = 'localhost' , user ="x" , passwd = "x" , db = "")
6 cursor = mydb.cursor()
D:\Softwares\Anaconda\lib\site-packages\pymysql\__init__.py in Connect(*args, **kwargs)
92 """
93 from .connections import Connection
---> 94 return Connection(*args, **kwargs)
95
96 from . import connections as _orig_conn
D:\Softwares\Anaconda\lib\site-packages\pymysql\connections.py in __init__(self, host, user, password, database, port, unix_socket, charset, sql_mode, read_default_file, conv, use_unicode, client_flag, cursorclass, init_command, connect_timeout, ssl, read_default_group, compress, named_pipe, autocommit, db, passwd, local_infile, max_allowed_packet, defer_connect, auth_plugin_map, read_timeout, write_timeout, bind_address, binary_prefix, program_name, server_public_key)
323 self._sock = None
324 else:
--> 325 self.connect()
326
327 def _create_ssl_ctx(self, sslp):
D:\Softwares\Anaconda\lib\site-packages\pymysql\connections.py in connect(self, sock)
597
598 self._get_server_information()
--> 599 self._request_authentication()
600
601 if self.sql_mode is not None:
D:\Softwares\Anaconda\lib\site-packages\pymysql\connections.py in _request_authentication(self)
869 plugin_name = auth_packet.read_string()
870 if self.server_capabilities & CLIENT.PLUGIN_AUTH and plugin_name is not None:
--> 871 auth_packet = self._process_auth(plugin_name, auth_packet)
872 else:
873 # send legacy handshake
D:\Softwares\Anaconda\lib\site-packages\pymysql\connections.py in _process_auth(self, plugin_name, auth_packet)
900 return _auth.caching_sha2_password_auth(self, auth_packet)
901 elif plugin_name == b"sha256_password":
--> 902 return _auth.sha256_password_auth(self, auth_packet)
903 elif plugin_name == b"mysql_native_password":
904 data = _auth.scramble_native_password(self.password, auth_packet.read_all())
D:\Softwares\Anaconda\lib\site-packages\pymysql\_auth.py in sha256_password_auth(conn, pkt)
181 data = b''
182
--> 183 return _roundtrip(conn, data)
184
185
D:\Softwares\Anaconda\lib\site-packages\pymysql\_auth.py in _roundtrip(conn, send_data)
120 def _roundtrip(conn, send_data):
121 conn.write_packet(send_data)
--> 122 pkt = conn._read_packet()
123 pkt.check_error()
124 return pkt
D:\Softwares\Anaconda\lib\site-packages\pymysql\connections.py in _read_packet(self, packet_type)
682
683 packet = packet_type(buff, self.encoding)
--> 684 packet.check_error()
685 return packet
686
D:\Softwares\Anaconda\lib\site-packages\pymysql\protocol.py in check_error(self)
218 errno = self.read_uint16()
219 if DEBUG: print("errno =", errno)
--> 220 err.raise_mysql_exception(self._data)
221
222 def dump(self):
D:\Softwares\Anaconda\lib\site-packages\pymysql\err.py in raise_mysql_exception(data)
107 errval = data[3:].decode('utf-8', 'replace')
108 errorclass = error_map.get(errno, InternalError)
--> 109 raise errorclass(errno, errval)
**OperationalError: (1045, "Access denied for user 'x'#'localhost' (using password: YES)")**
How to rectify this error? Can anyone help?
Is it the permissions problem? Or incorrect details?
I need a heads up.
Thanks!

smtplib/exchangelib connection to the email server error

I used to use auto discover to retrieve some emails from my inbox using exchangelib. However, last week they updated my email and auto discover is not working anymore. Now I am testing the connection with SMTPLIB using SMTP_SSL
server = smtplib.SMTP_SSL('xxxxxxxx.com',port=25)
but I get
ConnectionRefusedError: [WinError 10061]
c:\python37\lib\smtplib.py in __init__(self, host, port, local_hostname, keyfile, certfile, timeout, source_address, context)
1029 self.context = context
1030 SMTP.__init__(self, host, port, local_hostname, timeout,
-> 1031 source_address)
1032
1033 def _get_socket(self, host, port, timeout):
c:\python37\lib\smtplib.py in __init__(self, host, port, local_hostname, timeout, source_address)
249
250 if host:
--> 251 (code, msg) = self.connect(host, port)
252 if code != 220:
253 self.close()
c:\python37\lib\smtplib.py in connect(self, host, port, source_address)
334 if self.debuglevel > 0:
335 self._print_debug('connect:', (host, port))
--> 336 self.sock = self._get_socket(host, port, self.timeout)
337 self.file = None
338 (code, msg) = self.getreply()
c:\python37\lib\smtplib.py in _get_socket(self, host, port, timeout)
1035 self._print_debug('connect:', (host, port))
1036 new_socket = socket.create_connection((host, port), timeout,
-> 1037 self.source_address)
1038 new_socket = self.context.wrap_socket(new_socket,
1039 server_hostname=self._host)
c:\python37\lib\socket.py in create_connection(address, timeout, source_address)
725
726 if err is not None:
--> 727 raise err
728 else:
729 raise error("getaddrinfo returns an empty list")
c:\python37\lib\socket.py in create_connection(address, timeout, source_address)
714 if source_address:
715 sock.bind(source_address)
--> 716 sock.connect(sa)
717 # Break explicitly a reference cycle
718 err = None
ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it
When I used auto discover on exchangelib I got
AutoDiscoverFailed Traceback (most recent call last)
<ipython-input-48-c03f25ef8bb7> in <module>
5 autodiscover=True,
6 # config=self.config,
----> 7 access_type=DELEGATE
8 )
c:\python37\lib\site-packages\exchangelib\account.py in __init__(self, primary_smtp_address, fullname, access_type, autodiscover, credentials, config, locale, default_timezone)
78 raise AttributeError('config is ignored when autodiscover is active')
79 self.primary_smtp_address, self.protocol = discover(email=self.primary_smtp_address,
---> 80 credentials=credentials)
81 else:
82 if not config:
c:\python37\lib\site-packages\exchangelib\autodiscover.py in discover(email, credentials)
221 # We fell out of the with statement, so either cache was filled by someone else, or autodiscover redirected us to
222 # another email address. Start over after releasing the lock.
--> 223 return discover(email=email, credentials=credentials)
224
225
c:\python37\lib\site-packages\exchangelib\autodiscover.py in discover(email, credentials)
211 try:
212 # This eventually fills the cache in _autodiscover_hostname
--> 213 return _try_autodiscover(hostname=domain, credentials=credentials, email=email)
214 except AutoDiscoverRedirect as e:
215 if email.lower() == e.redirect_email.lower():
c:\python37\lib\site-packages\exchangelib\autodiscover.py in _try_autodiscover(hostname, credentials, email)
259 ), None)
260 log.info('autodiscover.%s redirected us to %s', hostname, e.server)
--> 261 return _try_autodiscover(e.server, credentials, email)
262 except AutoDiscoverFailed as e:
263 log.info('Autodiscover on autodiscover.%s (no TLS) failed (%s). Trying DNS records', hostname, e)
c:\python37\lib\site-packages\exchangelib\autodiscover.py in _try_autodiscover(hostname, credentials, email)
277 return _try_autodiscover(hostname=hostname_from_dns, credentials=credentials, email=email)
278 except AutoDiscoverFailed:
--> 279 raise_from(AutoDiscoverFailed('All steps in the autodiscover protocol failed'), None)
280
281
c:\python37\lib\site-packages\future\utils\__init__.py in raise_from(exc, cause)
398 myglobals['__python_future_raise_from_cause'] = cause
399 execstr = "raise __python_future_raise_from_exc from __python_future_raise_from_cause"
--> 400 exec(execstr, myglobals, mylocals)
401
402 def raise_(tp, value=None, tb=None):
c:\python37\lib\site-packages\exchangelib\autodiscover.py in <module>
AutoDiscoverFailed: All steps in the autodiscover protocol failed
I don't know how to deal with these exceptions

TimeoutError - Traceback (most recent call last), Django-app - sending e-mails. Python

I am trying to use 'mailgun' and gmail mail to send emails from my Django application, but each time I receive an error.
In my application I have the following code:
settings.py
EMAIL_HOST = 'smtp.mailgun.org'
EMAIL_PORT = 587
EMAIL_HOST_USER = 'aaa#mg.xxx.com'
EMAIL_HOST_PASSWORD = '#########'
EMAIL_USE_TLS = True
then I run the command from the command line:
manage.py shell
[1] from django.core.mail import send_mail
[2] send_mail('subject', 'body of the message', 'aaa#mg.xxx.com', ['
recipient#aaa.com'])
Do I use gmail, or with 'mailguna' always get the same error
Error:
TimeoutError Traceback (most recent call last)
<ipython-input-27-4c559962ca7f> in <module>()
----> 1 send_mail('subject', 'body of the message', '####mg.###.com', ['#######.com'])
~\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\core\mail\__init__.py in send_mail(subject, message, from_email, recipient_list, fail_silently, auth_user, auth_password, connection, html_message)
58 mail.attach_alternative(html_message, 'text/html')
59
---> 60 return mail.send()
61
62
~\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\core\mail\message.py in send(self, fail_silently)
289 # send to.
290 return 0
--> 291 return self.get_connection(fail_silently).send_messages([self])
292
293 def attach(self, filename=None, content=None, mimetype=None):
~\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\core\mail\backends\smtp.py in send_messages(self, email_messages)
101 return
102 with self._lock:
--> 103 new_conn_created = self.open()
104 if not self.connection or new_conn_created is None:
105 # We failed silently on open().
~\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\core\mail\backends\smtp.py in open(self)
61 })
62 try:
---> 63 self.connection = self.connection_class(self.host, self.port, **connection_params)
64
65 # TLS/SSL are mutually exclusive, so only attempt TLS over
~\AppData\Local\Programs\Python\Python37-32\lib\smtplib.py in __init__(self, host, port, local_hostname, timeout, source_address)
249
250 if host:
--> 251 (code, msg) = self.connect(host, port)
252 if code != 220:
253 self.close()
~\AppData\Local\Programs\Python\Python37-32\lib\smtplib.py in connect(self, host, port, source_address)
334 if self.debuglevel > 0:
335 self._print_debug('connect:', (host, port))
--> 336 self.sock = self._get_socket(host, port, self.timeout)
337 self.file = None
338 (code, msg) = self.getreply()
~\AppData\Local\Programs\Python\Python37-32\lib\smtplib.py in _get_socket(self, host, port, timeout)
305 self._print_debug('connect: to', (host, port), self.source_address)
306 return socket.create_connection((host, port), timeout,
--> 307 self.source_address)
308
309 def connect(self, host='localhost', port=0, source_address=None):
~\AppData\Local\Programs\Python\Python37-32\lib\socket.py in create_connection(address, timeout, source_address)
725
726 if err is not None:
--> 727 raise err
728 else:
729 raise error("getaddrinfo returns an empty list")
~\AppData\Local\Programs\Python\Python37-32\lib\socket.py in create_connection(address, timeout, source_address)
714 if source_address:
715 sock.bind(source_address)
--> 716 sock.connect(sa)
717 # Break explicitly a reference cycle
718 err = None
TimeoutError: [WinError 10060]
I tried to change the settings 'TLS', 'mail port' and 'SSL' but they always ended with the same error.
When the code runs outside the application everything works fine:
file_works_properly.py
import smtplib
from email.mime.text import MIMEText
msg = MIMEText('Title') #Tresc wiadomosci
msg['Subject'] = "Hello world"
msg['From'] = "XXX#mg.bbb.com"
msg['To'] = "ccc#ccc.com"
s = smtplib.SMTP('smtp.mailgun.org', 587)
s.login('####mg.bbb.com', '3###baa5e1f3###-26fa###0987')
s.sendmail(msg['From'], msg['To'], msg.as_string())
s.quit()
Every help will be appreciated.
The addition of three imports solved my problem (for 'python manage.py shell' or to the views.py file):
imports (in views.py/shell):
from django.contrib import messages
from django.core.mail import send_mail
from django.conf import settings
The rest of the activities are unchanged:
settings.py
[...]
EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_USER = 'myemail#gmail.com'
EMAIL_HOST_PASSWORD = 'mypassowrd'
EMAIL_PORT = 587
To send e-mail (in views.py/shell)
send_mail(subject, message, from_email, [to_list_email])
(*Important for gmail.com) - and often this option must be enabled.

How to replace a non routable IP address with server address on ftplib

I'm trying to use ftplib.FTP_TLS, but I can't list the directories.
Everything is OK with Filezilla, but when I'm on iPython, it fails.
import ftplib
from django.conf import settings # just a config file
client = ftplib.FTP_TLS(timeout=10)
client.connect(settings.HOST, 21)
client.auth()
client.prot_p()
client.login(settings.USER,settings.PWD)
client.set_debuglevel(2)
client.retrlines('LIST')
Here is the return of this last command :
*cmd* 'TYPE A'
*put* 'TYPE A\r\n'
*get* '200 Type set to A.\r\n'
*resp* '200 Type set to A.'
*cmd* 'PASV'
*put* 'PASV\r\n'
*get* '227 Entering Passive Mode (10,191,x,x,238,54).\r\n'
*resp* '227 Entering Passive Mode (10,191,x,x,238,54).'
---------------------------------------------------------------------------
timeout Traceback (most recent call last)
/usr/local/lib/python2.7/dist-packages/django/core/management/commands/shell.pyc in <module>()
----> 1 client.retrlines('LIST')
/usr/lib/python2.7/ftplib.pyc in retrlines(self, cmd, callback)
704 if callback is None: callback = print_line
705 resp = self.sendcmd('TYPE A')
--> 706 conn = self.transfercmd(cmd)
707 fp = conn.makefile('rb')
708 try:
/usr/lib/python2.7/ftplib.pyc in transfercmd(self, cmd, rest)
366 def transfercmd(self, cmd, rest=None):
367 """Like ntransfercmd() but returns only the socket."""
--> 368 return self.ntransfercmd(cmd, rest)[0]
369
370 def login(self, user = '', passwd = '', acct = ''):
/usr/lib/python2.7/ftplib.pyc in ntransfercmd(self, cmd, rest)
679
680 def ntransfercmd(self, cmd, rest=None):
--> 681 conn, size = FTP.ntransfercmd(self, cmd, rest)
682 if self._prot_p:
683 conn = ssl.wrap_socket(conn, self.keyfile, self.certfile,
/usr/lib/python2.7/ftplib.pyc in ntransfercmd(self, cmd, rest)
325 if self.passiveserver:
326 host, port = self.makepasv()
--> 327 conn = socket.create_connection((host, port), self.timeout)
328 try:
329 if rest is not None:
/usr/lib/python2.7/socket.pyc in create_connection(address, timeout, source_address)
569
570 if err is not None:
--> 571 raise err
572 else:
573 raise error("getaddrinfo returns an empty list")
timeout: timed out
Like I said, it works fine with Filezilla. But I can see something special :
Commande : PASV
Réponse : 227 Entering Passive Mode (10,191,x,x,236,94).
Statut : Le serveur a envoyé une réponse passive avec une adresse non routable. Adresse remplacée par celle du serveur.
The «Statut» lines means something like: «Server send a passive response with a non routable address. Address replaced by the server one».
It seem this is the way to make it work.
My question is: How can I do the same with ftplib? Or is there another option for me?
Thanks!
Suppose you know where to connect to. I think the key may be in this line 326:
325 if self.passiveserver:
326 host, port = self.makepasv()
--> 327 conn = socket.create_connection((host, port), self.timeout)
328 try:
329 if rest is not None:
You can subclass and replace the makepasv() method and return the right address.
Maybe you can use the output of filezilla or wireshark to get to know the right address.

Categories