Giter Club home page Giter Club logo

micropython-ftplib's Introduction

micropython-ftplib

An FTP client library for MicroPython.

This is an adaption of the ftplib module from the CPython standard library to MicroPython. Apart from making it compatible with the socket module implementation of MicroPython and removing the use of the re library, some parts of the original library have been removed and the code and docstrings have been cleaned up somewhat.

The FTP_TLS class has been moved to a separate module file (ftplibtls.py) and the all_errors module global variable has been removed. The test code has been moved to a separate script and reworked too. The ftpcp function has been moved to the ftpcp.py module file.

The code has been tested under the following MicroPython ports against the FTP server from the pyftpdlib package.

  • unix
  • stm32 (using W5500 ethernet module)
  • esp8266
  • esp32
  • rp2 (Raspberry Pi Pico W)

For the esp8266 port the code needed to be slighty altered to make it work with the ssl module there and to reduce the memory usage. This version can be found in the esp directory (this version also works with the esp32 port, but there you should be able to use the normal version too).

FTP over TLS

FTP-over-TLS support is available in a separate ftplibtls module:

>>> from ftplibtls import FTP_TLS
>>> ftp = FTP_TLS('example.com')  # default port 21
>>> ftp.login('username', 'password')
>>> ftp.prot_p()
>>> ftp.retrlines('LIST')

Note that you must call the prot_b method after connecting and authentication to actually establish secure communication for data transfers.

If you require server certificate validation (recommended):

>>> from ftplib import FTP_TLS, ssl
>>> ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
>>> ctx.verify_mode = ssl.CERT_REQUIRED
>>> ctx.load_verify_locations(cafile="cert.der")  # Certificate file must be in DER format
>>> ftp = FTP_TLS(ssl_context=ctx, server_hostname="example.com")
>>> ftp.connect('example.com')
>>> ftp.prot_p()
>>> ftp.retrlines('LIST')

Use the server_hostname constructor argument if the common name in the server's certificate differs from the host name used for connecting.

Note: the version of ftplibtls in the esp directory does not support the ssl_context and server_hostname constructor arguments, since the ssl module of the esp2866 port unfortunately does not support server certificate validation.

Testing FTP over TLS

The tests directory contains the pyftplib-server.py script to start an FTP server, which is based on the pyftpdlib library for CPython and which supports FTP over TLS.

To run this script with TLS support enabled, you first need to create a server certificate. For testing, a self-signed certificate can be used and created with:

openssl req -new -x509 -nodes -out cert.pem -keyout tests/key.pem

Specify the country, code, location, organization and common name, when prompted. (Note: the test scripts in the tests directory assume that the common name you choose is example.com. If you choose a different common name, these scripts will fail with an error due to certificate verification failure.)

Combine the server certificate and the key into one file:

cat tests/key.pem tests/cert.pem > tests/keycert.pem

The ftplibtls module needs the server certificate in DER format, so convert it with:

openssl x509 -in tests/cert.pem -out tests/cert.der -outform DER

Now you can start the test FTP server:

mkdir -p tests/ftproot
python3 tests/pyftpdlib-server.py -w -s -p 2121 -c tests/keycert.pem tests/ftproot

The FTP server will listen on port 2121, support TLS using the certificate in the file tests/keycert.pem and allow clients to read files from the directory tests/ftproot and also upload files there.

To upload a file to the test FTP server using the ftplibtls module, run the tests/test_upload.py script:

MICROPYPATH=`pwd` micropython tests/test_upload.py ftps://localhost:2121 <filename>

This should upload the file <filename> to the FTP server using FTP over TLS and the file should appear in the tests/ftproot directory.

micropython-ftplib's People

Contributors

spotlightkid avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

micropython-ftplib's Issues

unable to connect to ftp server

# FTP server details
ftp_server = '44.241.66.173'
ftp_port = 21
ftp_user = 'dlpuser'
ftp_password = 'XXXXXX'

try:
    ftp.connect(ftp_server, ftp_port, timeout=30)
    ftp.set_pasv(True)  # Enable passive mode
    ftp.login(ftp_user, ftp_password)
    print("Connected to FTP server")
except ftplib.error_perm as e_perm:
    print(f"FTP Permission Error: {e_perm}")
except ftplib.error_temp as e_temp:
    print(f"FTP Temporary Error: {e_temp}")
except Exception as e:
    print(f"An error occurred: {e}")
finally:
    ftp.close()
Started webrepl in normal mode
An error occurred: Could not connect to ('44.241.66.173', 21)

I got this error while trying to establish an ftp connection between esp32 and the server

test_ftplib_cmdline.py confuses : of password for port #

It seems that the parsing in test_ftplib_cmdline.py uses the same split character for password and port.
This causes specifying a user:pass to fail.

Suggest using another delimiter perhaps + between user and password

Thank you

ESP32 can't connect to any server

Hi,

I've got the same problem as previous person... (#2)
I can't connect to any server, debugging gives the same answer. I've tried pinging the server from my ESP32 and it works fine.

FTP_TLS error "extra keyword arguments given" on Pico W (RP2) port

Hello
Here is my code :

import network
from ftplibtls import FTP_TLS

status_reseau = connect_wifi_local("NETWORK", "123456789")[1]

if status_reseau == 3:

    try:
        
        ftp_tls = FTP_TLS()
        print("1")
        ftp_tls.connect(adresse_serveur, port)
        print("2")
        ftp_tls.login(utilisateur_1, mot_de_passe_1)
        print("3")
        ftp_tls.prot_p()
        print("4")
        files = ftp_tls.nlst()
        print(files)
        
    except Exception as e:
        erreur = str(e)
        print("Erreur FTPS : " + str(e))

But I have the following error on the login line :

Erreur FTPS : extra keyword arguments given

Someone can help me?

Thx

Error when trying to download a file from a server AttributeError: 'SSLSocket' object has no attribute 'recv'

Hello! I'm using the libraries inside the folder esp.
I want to download a file from a server with the following code:

fileToWrite = open("comoEstan.txt", "wb")
def handleDownload(block):
    fileToWrite.write(block)

result = ftp.retrbinary('RETR comoEstan.txt', handleDownload)
print('ftp download comoEstan.txt return code=', result)

But I'm getting the following error:

Traceback (most recent call last):
File "", line 53, in
File "ftplib.py", line 553, in retrbinary
File "ftplib.py", line 89, in getattr
AttributeError: 'SSLSocket' object has no attribute 'recv'

Trouble installing this on rpi pico 2 w

When I run setup.py on a new pico 2 W it gives an "ImportError: no module names 'setuptools'". I get stuck here. I am unable to find setuptools for micropython. Any assistance is appreciated.

Problem with ftp.example.py test

Hy!

I'll try to test " ftplib.py" in my Rasp Pico W using Thonny IDE.

When I run "ftp_example.py" as is, the follow error msn appears

Testing
Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
  File "ftplib.py", line 160, in __init__
  File "ftplib.py", line 217, in connect
  File "ftplib.py", line 180, in _create_connection
  File "ftplib.py", line 71, in _resolve_addr
OSError: -6

Usage on ESP32 / Error: Could not connect to...

Can I use it on ESP32 directly? I succesfully imported it on my board, but couldn't connect to FTP server.
>> ftp = FTP(host='192.168.0.14',port=21,user='esp32',passwd='1234')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "ftplib.py", line 206, in __init__
File "ftplib.py", line 264, in connect
File "ftplib.py", line 242, in _create_connection
Error: Could not connect to ('192.168.0.14', 21)
I can access to the storage via Chrome, with same settings (user, passwd, etc.)

error when get file sizes

thank for your project, I can download files , but I can not get file sizes, can your help me.

Traceback (most recent call last):
File "main.py", line 37, in
File "ftplib.py", line 635, in size
File "ftplib.py", line 292, in sendcmd
File "ftplib.py", line 262, in getresp
Error: 550 SIZE not allowed in ASCII mode.

code:

from ftpadvanced import AdvancedFTP

PORT = 21
ftp = AdvancedFTP('192.168.2.232', PORT)
ftp.login()
files = ftp.nlst()
print(files)
print('sizes=', ftp.size('aaaaaa.dxf'))#error

ESP32 - Could not connect to ('host', port)

Hi there,

I'm getting the error mentioned in #2 and #4

This is my code:

from ftplib import FTP
ftp = FTP()
ftp.set_debuglevel(2)
ftp.connect('ftp1.at.proftpd.org')

I also added print('addrinfos: ', addrinfos) before line 227 in ftplib.py as suggested in #2 (comment)

This is what I'm getting:

addrinfos:  [(2, 1, 0, '', ('86.59.114.198', 21))]
requested length 2 but object has length 1

Traceback (most recent call last):
  File "<stdin>", line 44, in <module>
  File "ftplib.py", line 265, in connect
  File "ftplib.py", line 243, in _create_connection
Error: Could not connect to ('86.59.114.198', 21)

I was able to create a raw socket connection with this code #4 (comment), it works just fine

import usocket

IP_ADDRESS = 'ftp1.at.proftpd.org'

sock = usocket.socket()
sockaddr = usocket.getaddrinfo(IP_ADDRESS, 21)[0][-1]
sock.connect(sockaddr)

This is what I get with the code above (there's no error):

MicroPython v0.5.0-88-gb7f0c13 on 2020-05-27; Sipeed_M1 with kendryte-k210
Type "help()" for more information.
>>> 

Also, I've sent messages over TCP and made HTTP requests succesfully.

FTPS

Are you going to implement the FTPS or SFTP protocols?

OSError: [Errno 12] ENOMEM

Hello!
I'm trying to execute the example code:

>>> from ftplibtls import FTP_TLS
>>> ftp = FTP_TLS('servername')  # default port 21
>>> ftp.login('username', 'password')
>>> ftp.prot_p()
>>> ftp.retrlines('LIST')

But I'm getting this error:

Traceback (most recent call last):
File "boot.py", line 71, in
File "modules/ftplib.py", line 510, in retrlines
File "modules/ftplibtls.py", line 110, in ntransfercmd
File "modules/ftplibtls.py", line 126, in _wrap_socket
OSError: [Errno 12] ENOMEM
MicroPython v1.22.1 on 2024-01-05; Generic ESP32 module with ESP32

The connection is successful, I don't have problems with the other functions, only with dir(), in addition to this one.

issues on RPi Pico W

I ran into 2 issues which i "fixed?" I'm new to Python so these fixes are not authoritative.
In ftplib in "def connect(self, addr):"
the code reads: self._sock.connect(_resolve_addr(addr))
but this gives an error deep in \micropython-1.19.1\py\obj.c "requested length 2 but object has length 1"
_resolve_addr(addr) returns an array with 1 element, but connect wants 2 - IP and port
the addr is already resolved.
I "fixed" by changing to: self._sock.connect(addr)

Then i encountered a python error in getmultiline at "line = line + (b'\n' + nextline)"
but line and nextline are both str, Python moans about concat a byte with a string
I "fixed" by: line = line + "\n" + nextline)

With those two changes i was able to log onto a server, list files, change dir, upload a file, quit, and close.

What is your opinion of my fixes?

ftp download success, but I dont known where is the file

I test the download and upload function, upload func works,but the download func have same problem, can not find the download file.

code:

result = ftp.retrbinary('RETR aaaaaa.dxf', progress)
print('ftp download aaaaaa.dxf return code=', result)

with open('README.pdf', 'rb') as fp:
    result = ftp.storbinary('STOR README.pdf', fp)
    print('ftp upload README.pdf return code=', result)`

serial print:

ftp download aaaaaa.dxf return code= 226 Transfer complete.
ftp upload README.pdf return code= 226 Transfer complete.
MicroPython v1.13 on 2020-09-02; ESP32 module with ESP32
Type "help()" for more information.

>>> import os
>>> os.listdir()
['README.pdf', 'esp', 'ftp.py', 'ftp_pycom.py', 'ftp_thread.py', 'ftpadvanced.py', 'ftplib.py', 'ftplibtls.py', 'main.py', 'uftpd.py']

where is the download file aaaaaa.dxf?

Cannot import on esp8266

Thanks for making this port of ftplib available. I am having issues importing it on esp8266 though.

If I import the esp8266 port compiled to mpy, I get the error:

>>> import ftplib                                                               
Traceback (most recent call last):                                              
  File "<stdin>", line 1, in <module>                                           
ValueError: incompatible .mpy file

If I import the esp8266 port as a py file, I get the error:

>>> import ftplib                                                               
Traceback (most recent call last):                                              
  File "<stdin>", line 1, in <module>                                           
MemoryError: memory allocation failed, allocating %u bytes 

Is there any simple fix you can think of?

I can't connect to the ftp server (ESP32-WROOM-32).

Hi , I don't know if I am doing something wrong .
I have an esp-32 :
https://www.az-delivery.de/it/products/esp32-developmentboard
With micropython installed , and I am using Thonny .
I loaded on the esp32 , theftplib.pyfile .
And then in the boot.py file I added the line :

from ftplib import FTP

In main.py , after I connect to the wifi network , I try to access an ftp server local on the ip 192.168.1.1

the part of code dedicated to ftp in main.py is :

ftp= FTP('192.168.1.1',21,'user','password')
print('done')

When I try to run the code an error message comes up :

Could not connect to('192.168.1.1',21)
I confirm that the server is working ( i login in it with my computer) , and that the esp32 is able to ping the ip 192.168.1.1

EDIT:
Maybe i was wrong , i realized thay maybe i was using the wrong library , i have to use the library inside the esp folder right?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.