[Risolto] [Python] inviare PEC

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
rai
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2848
Iscrizione: domenica 11 maggio 2008, 18:03
Desktop: plasma
Distribuzione: 22.04
Località: Palermo

[Risolto] [Python] inviare PEC

Messaggio da rai »

Devo scrivere qualche rigo di codice per inviare dei messaggi di posta certificata. Finora l'ho fatto senza problemi in bash, usando ssmtp + mail (ssmtp + mutt in caso di allegati)
Ora devo usare python. Ho un mio.account@pec.it presso Aruba e queste sono le informazioni di cui dispongo

questo è quello che ho provato e quello che ottengo con Py2.7 e Py3.2

Codice: Seleziona tutto

$ python
Python 2.7.3 (default, Jun 22 2015, 19:33:41) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import smtplib
>>> SERVER = "smtps.pec.aruba.it"
>>> FROM = "mio.account@pec.it"
>>> PASSWORD = "plainPassword"
>>> smtp = smtplib.SMTP_SSL(SERVER)
>>> smtp.ehlo()
(250, 'smtps.pec.aruba.it\nPIPELINING\nSIZE 157286400\nETRN\nAUTH LOGIN PLAIN\nENHANCEDSTATUSCODES\n8BITMIME')
>>> smtp.login(FROM, PASSWORD)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/smtplib.py", line 620, in login
    raise SMTPAuthenticationError(code, resp)
smtplib.SMTPAuthenticationError: (535, '5.7.8 Error: authentication failed:')
>>> 
$ python3
Python 3.2.3 (default, Jun 18 2015, 21:46:58) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import smtplib
>>> SERVER = "smtps.pec.aruba.it"
>>> smtp = smtplib.SMTP_SSL(SERVER)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.2/smtplib.py", line 853, in __init__
    SMTP.__init__(self, host, port, local_hostname, timeout)
  File "/usr/lib/python3.2/smtplib.py", line 260, in __init__
    (code, msg) = self.connect(host, port)
  File "/usr/lib/python3.2/smtplib.py", line 321, in connect
    (code, msg) = self.getreply()
  File "/usr/lib/python3.2/smtplib.py", line 367, in getreply
    line = self.file.readline(_MAXLINE + 1)
TypeError: readline() takes exactly 1 positional argument (2 given)
>>> 
Non so se è utile o confonde soltanto le idee: quando la connessione può iniziare senza crittografia (p.es. con gmail) riesco ad inviare normalmente con Py2 ma con lo stesso codice con Py3 ottengo:

Codice: Seleziona tutto

$ python3
Python 3.2.3 (default, Jun 18 2015, 21:46:58) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import smtplib
>>> SERVER = "smtp.gmail.com:587"
>>> FROM = "mio.account@gmail.com"
>>> PASSWORD = "plainPassword"
>>> smtp = smtplib.SMTP(SERVER)
>>> smtp.ehlo()
(250, b'smtp.gmail.com at your service, [5.92.95.224]\nSIZE 35882577\n8BITMIME\nSTARTTLS\nENHANCEDSTATUSCODES\nPIPELINING\nCHUNKING\nSMTPUTF8')
>>> smtp.starttls()
(220, b'2.0.0 Ready to start TLS')
>>> smtp.login(FROM, PASSWORD)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.2/smtplib.py", line 594, in login
    self.ehlo_or_helo_if_needed()
  File "/usr/lib/python3.2/smtplib.py", line 553, in ehlo_or_helo_if_needed
    if not (200 <= self.ehlo()[0] <= 299):
  File "/usr/lib/python3.2/smtplib.py", line 420, in ehlo
    (code, msg) = self.getreply()
  File "/usr/lib/python3.2/smtplib.py", line 367, in getreply
    line = self.file.readline(_MAXLINE + 1)
TypeError: readline() takes exactly 1 positional argument (2 given)
>>> 
Per ovvie ragioni di compatibilità col prossimo futuro preferirei risolvere usando Python3. So dei moduli socket e ssl ma non ho idea se servano in questo caso. Spero di non doverli usare perchè non saprei da dove incominciare a meno di una manina santa che mi indirizzi
Grazie
Ultima modifica di rai il venerdì 14 ottobre 2016, 19:41, modificato 1 volta in totale.
Avatar utente
crap0101
Rampante Reduce
Rampante Reduce
Messaggi: 8242
Iscrizione: martedì 30 ottobre 2007, 6:33
Desktop: LXDE
Distribuzione: Ubuntu 18.04.1 LTS
Sesso: Maschile
Località: TO
Contatti:

Re: [Python]inviare PEC

Messaggio da crap0101 »

riguardo all'errore, sembrerebbe essere causa di questo bug: http://bugs.python.org/issue25045
che dovrebbe essere stato risolto proprio in una minor version successiva a quella che utilizzi.
A fare le cose un po' "sporche" ma funzionanti almeno sulle tue macchine, potresti patchare manualmente il codice incriminato.

A parte questo, riguardo l'errore di autenticazione, non so se quello è codice "definitivo" che userai effettivamente o solo un esempio ma...
* quei protocolli, seppur non complicati, possono non essere immediatamente chiarissimi nell'uso (e soprattutto _quando_)
* quando vedo ehlo() solitari mi preoccupo

Dico questo perchè in passato avevo scritto un programma - anche piuttosto elaborato - per mandare mail con python (con gestione dei vari tipi di connessioni, firme, allegati, ecc) e ho dovuto "studiare" un po' bene la facenda per fare le cose correttamente (almeno spero). Una cosa che ho capito, imho, è che non conviene usare strumenti di basso livello come ehlo et similia quando sono disponibili un certo numero di oggetti che si smazzano tutti i passaggi e le comunicazioni "intermedie" e che funzionano bene nel 99% dei casi.

Al proposito ho riesumato sto vecchio programma (del 2011!) e ho provato a inviarmi una pec (la ho anch'io su aruba, per cui ho usato i dati del tuo link) e, con mia (im)modesta sorpresa, funziona sia con python 2.X che con python 3.X (si vede che ero stato lungimirante :-D ). Per cui - siccome non è malaccio - penso che lo ricaricherò su git, così se ti interessa puoi darci un'occhiata e cannibalizzare le parti che ti interessano.... anche perchè ora come ora non ho tanto tempo di vedere i dettagli del perchè e del percome di alcune scelte e nel frattempo mi son pure dimenticato alcune cosa (per dire che se dovesssi fare un esame sui protocolli di posta verrei bocciato ;-) ).

Giusto per farti un esempio operativo:

Codice: Seleziona tutto

$ python multimail.py -Sns OGGETTO_MAIL -m CORPO_MAIL -f XXX.YYY@pec.it -r destin@tar.io -l NOME_LOGIN -H smtps.pec.aruba.it -P 465
e la mail arriva a destinazione senza errori, le versioni di python utilizzate sono

Codice: Seleziona tutto

Python 3.5.2
Python 2.7.12
Dico tutto questo nel caso dovessi rifare da zero un lavoro (o parte di) che può non essere così immediato, almeno risparmi tempo.
Certo che se il bug è specifico di alcune sottoversioni, quello rimane, a meno di non applicare la prima "brutta" soluzione proposta.


EDIT:
qui
http://www.gnu.org/ http://boinc.berkeley.edu/ http://www.python-it.org/
- Ricorda le ultime parole di suo padre: «Sta' alla larga dalle chiese, figlio. La sola cosa per cui hanno la chiave è il merdaio. E giurami che non porterai mai un distintivo della legge» - W.S. Burroughs
rai
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2848
Iscrizione: domenica 11 maggio 2008, 18:03
Desktop: plasma
Distribuzione: 22.04
Località: Palermo

Re: [Python]inviare PEC

Messaggio da rai »

Grazie per la segnalazione del bug, al bug non ci avevo proprio pensato!
ho già scaricato la 3.5.2 e sto per compilarla

Grazie anche per il codice che condividi. Ora me lo studio e torno qui con le necessarie domandone
rai
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2848
Iscrizione: domenica 11 maggio 2008, 18:03
Desktop: plasma
Distribuzione: 22.04
Località: Palermo

Re: [Python]inviare PEC

Messaggio da rai »

Intanto confermo, se ce ne fosse bisogno, che aggiornando python alla 3.5.2 sono scomparsi tutti gli errori (sia con gmail che con aruba) e gli invii vanno a destinazione esattamente con quel codice che ho postato
Per la precisione, ehlo() non è necessario e funziona fare il login() direttamente dopo la connessione con SMTP_SSL()
Si trattava di una delle prove che avevo fatto per cercare di aggirare l'errore e poi l'ehlo() è rimasto lì
crap0101 ha scritto:* quando vedo ehlo() solitari mi preoccupo
In effetti quelle righe sono soltanto un esempio ma comunque il prodotto finale che mi serve sarà più simile a questo rispetto al corposo programma che hai scritto: io ho bisogno di uno scarno sistema non interattivo che recuperati oggetto, corpo, allegati e destinatari si sbrighi gli invii delle pec, verifichi l'arrivo delle ricevute di consegna, etc.

Quello che invece devo prevedere sono tutte le possibili eccezioni in caso di errori vari di rete, di connessione, login etc.
In questo mi sarà molto utile il tuo codice di multimail

Non metto ancora il Risolto prima di verificare come me la cavo con le mail multipart e gli allegati pdf e le buste crittografate

Bene: ho messo Risolto perché l'argomento "inviare PEC" è risolto coi suggerimenti di crap0101. Per tutti i dettagli che girano intorno a questo aprirò altre discussioni


Ultimo «riporta su» di rai il venerdì 14 ottobre 2016, 19:44.
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 12 ospiti