Is POP3 thread safe? - python

I use poplib to retrieve new messages from my gmail.
I do it in the following way:
server = poplib.POP3_SSL('pop.gmail.com')
# ... login with credentials
#get info about new mails (1)
emails, total_bytes = server.stat()
for i in range(emails):
# get new mail (2)
response = server.retr(i+1)
I was wondering what may happen if between (1) and (2) gmail mailbox receive new emails?
I tried by myself and (2) works only with messages that were actual at the moment of retrieving information about them (1) and no new messages were fetched from the server.
Is this guaranteed by POP3 protocol or not?

Yes, POP3 locks the mailbox.
From RFC 1939:
Once the POP3 server has determined ... that the client should be given access to the
appropriate maildrop, the POP3 server then acquires an exclusive-
access lock on the maildrop, as necessary to prevent messages from
being modified or removed before the session enters the UPDATE state.

Related

Can receive but not send emails with aiosmtpd SMTP server

I have setup a local SMTP server with aiosmtpd where I received emails after setting the proper DNS records:
mail.mydomain.com A 1 minute 1.2.3.4
mydomain.com MX 1 minute 10 mail.mydomain.com.
Just running aiosmtpd in the command line is enough to receive emails:
python.exe -m smtpd -c DebuggingServer -n 0.0.0.0:25
The problem is now sending emails which for whatever reason seems not to work. I have set the SPF record this way:
mydomain.com TXT 1 minute "v=spf1 a mx include: mydomain.com ~all"
I have tried with this too:
mydomain.com TXT 1 minute "v=spf1 ip4:1.2.3.4 ~all"
I'm using this code to send the email while the SMTP server is running:
import smtplib
sender = 'from#mydomain.com'
receivers = ['to#mydomain.com']
message = """From: From Person <from#mydomain.com>
To: To Person <to#mydomain.com>
Subject: SMTP e-mail test
This is a test e-mail message.
"""
try:
smtpObj = smtplib.SMTP('127.0.0.1')
smtpObj.sendmail(sender, receivers, message)
print ("Successfully sent email")
except smtplib.SMTPException:
print ("Error: unable to send email")
I have tried to add as destination email my #gmail.com email address too but I don't get anything.
I can see that the email is sent to the SMTP server but I don't get the email back:
---------- MESSAGE FOLLOWS ----------
b'From: From Person <from#mydomain.com>'
b'To: To Person <to#mydomain.com>'
b'Subject: SMTP e-mail test'
b'X-Peer: 127.0.0.1'
b''
b'This is a test e-mail message.'
------------ END MESSAGE ------------
Any idea on what am I doing wrong?
Generally, email is sent on the internet from email clients connecting to mail transfer agents (MTAs) that relay emails to mail delivery agents (MDAs) that store the email for the recipient to read. That is, GMail operates both as an MTA for its users, relaying GMail users' emails to remote mail servers, and as an MDA that receives emails slated for delivery to its users' mailboxes. Emails are transferred between servers using the SMTP protocol, and aiosmtpd is an implementation of the server-end of the SMTP protocol, whereas the built-in smtplib module is an implementation of the client-end.
When you run aiosmtpd in its default configuration, it is simply a dumb SMTP server that receives emails and spits them out on the terminal without relaying them or storing them. That is to say, aiosmtpd by itself is not an MTA or an MDA, unless you write code that implements storage of email (e.g. using the 'mailbox' built-in module), or you write code that implements relaying of email.
When you use the SMTP client smtplib.SMTP() to connect to 127.0.0.1, you are simply connecting to aiosmtpd, which won't do anything interesting with the email that you give it (unless you add code that does something interesting).
If you want to send email to remote email providers, e.g. GMail, then you need to either submit the email to a fixed MTA, or you need to implement the relaying mechanism yourself using DNS lookups.
If all you need is a simple MTA to relay email to remote hosts, then you don't need aiosmtpd or any other kind of Python programming - postfix is an excellent choice. Further reading: aiosmtpd is not an MTA
If you want to implement the relaying mechanism yourself, then you need to look up the MX record for the recipient's address (e.g. gmail.com) and then instruct smtplib.SMTP to connect to the host specified in the MX record. However, I wouldn't recommend trying to do this, as there are many pitfalls and cases to consider. For example - what to do if there are multiple MX records or no MX records at all. Furthermore, the remote SMTP server might not respond, or it may respond with a 4xx or 5xx error code, in which case you need to take appropriate action and retry at a later time.

How to create a node js API for which users can subscribe to listen to events?

I am trying to create and node.js api to which users can subscribe to get event notifications?
I created the below API and was able to call the API using python ,however its not clear to me how can folks subscribe to it?
How can folks subscribe to this API to get notification of New root build released?what do I need to change?
node.js API
app.get("/api/root_event_notification", (req, res, next) => {
console.log(req.query.params)
var events = require('events');
var eventEmitter = new events.EventEmitter();
//Create an event handler:
var myEventHandler = function () {
console.log('new_root_announced!');
res.status(200).json({
message: "New root build released!",
posts: req.query.params
});
}
import requests
python call
input_json = {'BATS':'678910','root_version':'12A12'}
url = 'http://localhost:3000/api/root_event_notification?params=%s'%input_json
response = requests.get(url)
print response.text
OUTPUT:-
{"message":"New root build released!","posts":"{'root_version': '12A12', 'BATS': '678910'}"}
You can't just postpone sending an http response for an arbitrary amount of time. Both client and server (and sometimes the hosting provider's infrastructure) will timeout the http request after some number of minutes. There are various tricks to try to keep the http connection alive, but all have limitations.
Using web technologies, the usual options for get clients getting updated server data:
http polling (client regularly polls the server). There's also a long polling adaptation version of this that attempts to improve efficiency a bit.
Websocket. Clients makes a websocket connection to the server which is a lasting, persistent connection. Then either client or server can send data/events of this connection at any time, allowing the server to efficiently send notifications to the client at any time.
Server Sent Events (SSE). This is a newer http technology that allows one-way notification from server to client using some modified http technology.
Since a server cannot typically connect directly to a client due to firewall and public IP address issues, the usual mechanism for a server to notify a client is to use either a persistent webSocket connection from client to server over which either side can then send webSocket packets or use the newer SSE (server sent events) which allows some server events to be sent to a client over a long lasting connection.
The client can also "poll" the server repeatedly, but this is not really an event notification system (and not particularly efficient or timely) as much as it is some state that the client can check.

Unable to connect to gmail/Outlook using IMAP in python

I have tried to connect to the Gmail server using IMAP in Spyder(Python 3.6) using the Chilkat package.
I have enabled the IMAP for all Mail in the Settings>Forwarding and POP/IMAP and then I have also enabled the less secure apps tab here https://myaccount.google.com/lesssecureapps?pli=1 after signing in. But in this code
import sys
import chilkat
imap = chilkat.CkImap()
# Anything unlocks the component and begins a fully-functional 30-day trial.
success = imap.UnlockComponent("Anything for 30-day trial")
if (success != True):
print(imap.lastErrorText())
sys.exit()
# Connect to an IMAP server.
# Use TLS
imap.put_Ssl(True)
imap.put_Port(993)
success = imap.Connect("imap.gmail.com")
The success variable which is a boolean remains False. Please help me. My aim is to fetch all attachments from Outlook Server and dump them into a file.But I cannot even connect to the Gmail server. I tried to use "imap.mail.Outlook.com" but that also failed. I do not know the steps to enable IMAP in Outlook. But even if it is enabled in Gmail, why is it not working?
The 1st step is to examine the contents of the imap.LastErrorText property to see what happened. For example:
# Connect to an IMAP server.
# Use TLS
imap.put_Ssl(True)
imap.put_Port(993)
success = imap.Connect("imap.someMailServer.com")
if (success != True):
print(imap.lastErrorText())
sys.exit()
My guess is that a firewall (software or hardware) is blocking the outbound connection.
An alternative solution is to use the GMail REST API as shown in these examples: https://www.example-code.com/python/gmail.asp The HTTP ports (443) are unlikely to be blocked by a firewall. You would download into a Chilkat Email object and then save attachments in exactly the same way had you downloaded via IMAP.

Python's smtplib module violating Gmail's terms of use

How can I avoid violating Gmail's terms of use when using Python's smtplib?
I would like to send internal emails using Python. After 2 days of fighting with the Gmail API, I gave up. Then I found the smtplib module, which looked simple and promising.
Following the example here, I wrote this small block of Python code:
import smtplib
# Details of where to send FROM
emailUser = 'an.account.I.made.just.for this.test#gmail.com'
emailPassword = 'password123'
# Send the following message to an address...
message = '[ I am email content ]'
toAddress = 'test.victim#gmail.com'
# Define the HEADER (to, from, and subject)
header = """
To: %s
From: %s
Subject: Python SMTPLIB Test
"""
header = header % (toAddress, emailUser)
# [ Don't know what this does ]
smtpserver = smtplib.SMTP("smtp.gmail.com",587)
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.ehlo
# Use User/Password credentials to send email
smtpserver.login(emailUser, emailPassword)
smtpserver.sendmail(emailUser, toAddress, message)
smtpserver.close()
I executed this script. It looks like Google's algorithms must have interpreted this as having been sent with bad intentions, and promptly closed my account! Which is fair enough, as I'm sure smtplib can be abused quite readily. However, I have honest intentions, but I do not know how to get around this issue: how can I avoid violating Gmail's terms of use when using Python's smtplib?
It could be because you are indiscriminately making connections with EHLO, you should be using HELO.
If the server supports EHLO, the client can use EHLO instead of HELO as its first request.
On the other hand, if the server does not support EHLO, and the client sends EHLO, the server will reject EHLO. The client then has to fall back to HELO.
There are a few servers that disconnect when they see EHLO. If the client finds that neither EHLO nor HELO was accepted, for example because the connection was closed, then it has to make a new connection and start with HELO.

Sending an email, via python, from one outlook account to another

I'm writing a program to help the school's Biology Department and it involves sending an email. I've gathered all of the variables I need for the content of the message, it's just the actual sending of the email that's causing some issues.
I've looked around and realized that I was using code that sent to gmail, whereas the servers at school use Outlook 2010. Once I remembered that, I looked around for some python code that sent emails, but so far nothing has worked.
It all seems very complicated for just sending an email, but I need some help as to were to go from here.
gsal.org.uk is our school's web server address, which is an outlook server.
The current error that I am receiving is smtplib.SMTPException: STARTTLS extension not supported by server., but I keep receiving various errors with everything I try.
This is the code:
fromaddr = "test#gsal.org.uk"
toaddrs = "technicians#gsal.org.uk"
msg = "\r\n".join([
"From: user",
"To: user",
"Subject: Practical Request",
"",
"Test"
])
server = smtplib.SMTP_SSL('smtp.gmail.com:465')
server.ehlo()
server.starttls()
# server.login(username,password)
server.sendmail(fromaddr, toaddrs, msg)
server.quit()
messagebox.showinfo("Success!", "Your request has been sent successfully.")
All I want to do is send an email from an email account (specified within the program) to an email account that will soon be set up at school called technicians#gsal.org.uk. Any help appreciated.
EDIT
Thought I'd add the fact that if I remove the starttls() line, I get this:
smtplib.SMTPSenderRefused: (530, b'5.5.1 Authentication Required. Learn more at\n5.5.1 https://support.google.com/mail/answer/14257 hw1sm42144009wjb.6 - gsmtp', 'test#gsal.org.uk')
I've read that link, but it seems to be talking about gmail? I want to use outlook? I understand that I need to do authentication, but how?
In order to fight spam and protect resources, a normally configured SMTP server provides its services only to its owner (e.g. a company, organization or registered customers). Your school server probably accepts mail only if it is:
addressed to the school's own domain, or
coming from an authenticated person (e.g. a student, teacher), or
coming from a host with IP address belonging to the school's LAN (when allowed by the admin)
Further, a SMTP server communicates with other servers on TCP port 25 and with users submitting new mail (which is your case) on port 465 or 587. (Port 25 was used in the past for all mail, this is now deprecated)
Communication on port 465 is always encrypted (TLS). Communication on port 587 starts in plaintext, but with the STARTTLS command, the encryption is turned on. A successfull STARTTLS is usually required to allow authentication (login).
Why your progam does not work?
You are trying to start TLS on an TLS connection. It has been started. Either don't STARTTLS or change the port to 587.
You are using gmail's server to send a message not addressed to gmail. In this case you must login with a name and a password as a registered gmail user.
What should help? Contact the local admin for details about using the school's own server.

Categories

Resources