python telegram bot, "socket.error: [Errno 98] Address already in use" - nginx

Im developing a telegram bot with this api and I tried to use its webhook example to set up my own bot with webhook method.
I have an Ubuntu server and I have set up nginx on it.
now when trying to run my python bot, I get this error:
Traceback (most recent call last):
File "bot.py", line 106, in <module>
router.run(host=WEBHOOK_LISTEN, port=int(WEBHOOK_PORT), ssl_context= (WEBHOOK_SSL_CERT, WEBHOOK_PRIV_CERT), debug=True)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 841, in run
run_simple(host, port, self, **options)
File "/usr/local/lib/python2.7/dist-packages/werkzeug/serving.py", line 720, in run_simple
s.bind((hostname, port))
File "/usr/lib/python2.7/socket.py", line 228, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 98] Address already in use
so I checked what is using my port 443 and the process is nginx:
root 30734 1 0 Aug21 ? 00:00:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
I can't turn off nginx because my website is on it, and I need the port to set up telegram bot.
EDIT: I will put my code here for more clarification:
WEBHOOK_HOST = 'mywebsite.com'
WEBHOOK_PORT = '8443'
WEBHOOK_LISTEN = '0.0.0.0'
WEBHOOK_SSL_CERT = "/etc/letsencrypt/live/mywebsite.com/cert.pem"
WEBHOOK_PRIV_CERT = "/etc/letsencrypt/live/mywebsite.com/privkey.pem"
WEBHOOK_URL_BASE = "https://%s:%s" % (WEBHOOK_HOST, WEBHOOK_PORT)
WEBHOOK_URL_PATH = "/%s/" % (TOKEN.get_token())
router = flask.Flask(__name__)
#router.route('/', methods=['GET', 'HEAD'])
def index():
return 'OK'
#router.route(WEBHOOK_URL_PATH, methods=['POST'])
def webhook():
if flask.request.headers.get('content-type') == 'application/json':
json_string = flask.request.json
print json_string["message"]["text"] # here I get the text of message
return ''
else:
flask.abort(403)
bot.remove_webhook()
time.sleep(3)
bot.set_webhook(url=WEBHOOK_URL_BASE+WEBHOOK_URL_PATH,certificate=open(WEBHOOK_SSL_CERT, 'r'))
router.run(host=WEBHOOK_LISTEN, port=int(WEBHOOK_PORT), ssl_context=(WEBHOOK_SSL_CERT, WEBHOOK_PRIV_CERT), debug=True)

Related

How can I send a file using to a HTTP server and read it?

So, I created the following HTTP server tunneled via ngrok, and I am trying to send a file to the server, to then read it and display it on the web page of the server.
Here's the code for the server:
import os
from http.server import HTTPServer, BaseHTTPRequestHandler
from pyngrok import ngrok
import time
port = os.environ.get("PORT", 80)
server_address = ("127.0.0.1", port)
class MyServer(BaseHTTPRequestHandler):
def _set_headers(self):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
def do_GET(self):
self._set_headers()
self.wfile.write(bytes("<html><head><title>https://pythonbasics.org</title></head>", "utf-8"))
self.wfile.write(bytes("<p>Request: %s</p>" % self.path, "utf-8"))
self.wfile.write(bytes("<body>", "utf-8"))
self.wfile.write(bytes("<p>This is an example web server.</p>", "utf-8"))
self.wfile.write(bytes("</body></html>", "utf-8"))
def do_POST(self):
'''Reads post request body'''
self._set_headers()
content_len = int(self.headers.getheader('content-length', 0))
post_body = self.rfile.read(content_len)
self.wfile.write("received post request:<br>{}".format(post_body))
def do_PUT(self):
self.do_POST()
httpd = HTTPServer(server_address, MyServer)
public_url = ngrok.connect(port).public_url
print("ngrok tunnel \"{}\" -> \"http://127.0.0.1:{}\"".format(public_url, port))
try:
# Block until CTRL-C or some other terminating event
httpd.serve_forever()
except KeyboardInterrupt:
print(" Shutting down server.")
httpd.socket.close()
And I have been trying to send a file using POST as follow
>>> url = 'https://httpbin.org/post'
>>> files = {'file': open('report.xls', 'rb')}
>>> r = requests.post(url, files=files)
>>> r.text
I imported requests of course, and here's what I get
Exception occurred during processing of request from ('127.0.0.1', 60603)
Traceback (most recent call last):
File "C:\Program Files\Python39\lib\socketserver.py", line 316, in _handle_request_noblock
self.process_request(request, client_address)
File "C:\Program Files\Python39\lib\socketserver.py", line 347, in process_request
self.finish_request(request, client_address)
File "C:\Program Files\Python39\lib\socketserver.py", line 360, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "C:\Program Files\Python39\lib\socketserver.py", line 720, in __init__
self.handle()
File "C:\Program Files\Python39\lib\http\server.py", line 427, in handle
self.handle_one_request()
File "C:\Program Files\Python39\lib\http\server.py", line 415, in handle_one_request
method()
File "C:\Users\pierr\OneDrive\Desktop\SpyWare-20210104T124335Z-001\SpyWare\Ngrok_Test.py", line 28, in do_POST
content_len = int(self.headers.getheader('content-length', 0))
AttributeError: 'HTTPMessage' object has no attribute 'getheader'
Could someone please help me fix this error ? I don't get where it comes from.
Syntax has changed. You need to use
content_len = int(self.headers.get('Content-Length'))
Instead of
content_len = int(self.headers.getheader('content-length', 0))
The rest should be the same

airflow EmailOperator throws "smtplib.SMTPNotSupportedError: STARTTLS extension not supported by server"?

Trying to use airflow's EmailOperator to send an email on trigger_rule.ONE_FAILED and seeing error:
[2019-10-14 13:31:50,604] {configuration.py:206} WARNING - section/key [smtp/smtp_user] not found in config
Traceback (most recent call last):
File "/bin/airflow", line 27, in <module>
[ args.func(args)
File "/usr/lib/python2.7/site-packages/airflow/bin/cli.py", line 392, in run
pool=args.pool,
File "/usr/lib/python2.7/site-packages/airflow/utils/db.py", line 50, in wrapper
result = func(*args, **kwargs)
File "/usr/lib/python2.7/site-packages/airflow/models.py", line 1493, in _run_raw_task
result = task_copy.execute(context=context)
File "/usr/lib/python2.7/site-packages/airflow/operators/email_operator.py", line 64, in execute
send_email(self.to, self.subject, self.html_content, files=self.files, cc=self.cc, bcc=self.bcc, mime_subtype=self.mime_subtype)
File "/usr/lib/python2.7/site-packages/airflow/utils/email.py", line 44, in send_email
return backend(to, subject, html_content, files=files, dryrun=dryrun, cc=cc, bcc=bcc, mime_subtype=mime_subtype)
File "/usr/lib/python2.7/site-packages/airflow/utils/email.py", line 87, in send_email_smtp
send_MIME_email(SMTP_MAIL_FROM, recipients, msg, dryrun)
File "/usr/lib/python2.7/site-packages/airflow/utils/email.py", line 109, in send_MIME_email
s.starttls()
File "/usr/lib64/python2.7/smtplib.py", line 643, in starttls
raise SMTPException("STARTTLS extension not supported by server.")
smtplib.SMTPException: STARTTLS
Have not changed the default airflow.cfg (other than for basic password authentication to access the webserver) and the email portion looks like
[email]
email_backend = airflow.utils.email.send_email_smtp
[smtp]
# If you want airflow to send emails on retries, failure, and you want to use
# the airflow.utils.email.send_email_smtp function, you have to configure an
# smtp server here
smtp_host = localhost
smtp_starttls = True
smtp_ssl = False
# Uncomment and set the user/pass settings if you want to use SMTP AUTH
# smtp_user = airflow
# smtp_password = airflow
smtp_port = 25
smtp_mail_from = airflow#example.com
Checking the port in the cfg file, it seems to be open and listening...
[rvillanueva#mapr001 queensetl_airflow]$ netstat -plnt | grep ':25'
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN -
tcp6 0 0 ::1:25 :::* LISTEN -
... and I am able to use the linux sendmail bash command for other process that run on this same machine (CentOS 7).
Anyone know what could be going on here or any further debugging tips?
After help from the airflow users mailing list and from the error trace shown above, the thing that fixed this problem was just setting smtp_starttls = False.
Testing with a script like...
# Import smtplib for the actual sending function
import smtplib
from email.mime.text import MIMEText
send_to = 'myaddress#co.org'
msg = MIMEText('Hello World')
msg['Subject'] = 'Test Airflow Email'
msg['From'] = 'airflow#example.com'
msg['To'] = send_to
# SMTP Send
s = smtplib.SMTP('localhost')
s.starttls() # Try commenting out this line and see if you get a different error
s.sendmail(me, [send_to], msg.as_string())
s.quit()
saw the same error and was able to get rid of it by commenting out the s.starttls() line. So now my airflow.cfg file looks like...
[smtp]
# If you want airflow to send emails on retries, failure, and you want to use
# the airflow.utils.email.send_email_smtp function, you have to configure an
# smtp server here
smtp_host = localhost
#smtp_starttls = True
smtp_starttls = False
smtp_ssl = False
# Uncomment and set the user/pass settings if you want to use SMTP AUTH
# smtp_user = airflow
# smtp_password = airflow
smtp_port = 25
smtp_mail_from = airflow#example.com
and email alerts appear to be working fine.

Paramiko ssh to windows with ConnectionResetError: [WinError 10054]

My code below works fine with Linux servers but the script doesn't work with Windows 2008 Server with OpenSSH installed. I have also tested to ssh with teraterm with the same username, password, ipaddress and port22 it worked fine as well.
I am getting the below error.
C:\Users\>python auto-ssh_v1.py
Socket exception: An existing connection was forcibly closed by the remote host (10054)
Traceback (most recent call last):
File "auto-ssh_v1.py", line 71, in <module>
results = executer.execute()
File "auto-ssh_v1.py", line 53, in execute
stdin, stdout, stderr = ssh.exec_command(self.command)
File "C:\Anaconda3\lib\site-packages\paramiko\client.py", line 405, in exec_command
chan.exec_command(command)
File "C:\Anaconda3\lib\site-packages\paramiko\channel.py", line 60, in _check
return func(self, *args, **kwds)
File "C:\Anaconda3\lib\site-packages\paramiko\channel.py", line 229, in exec_command
self._wait_for_event()
File "C:\Anaconda3\lib\site-packages\paramiko\channel.py", line 1086, in _wait_for_event
raise e
File "C:\Anaconda3\lib\site-packages\paramiko\transport.py", line 1726, in run
ptype, m = self.packetizer.read_message()
File "C:\U\Anaconda3\lib\site-packages\paramiko\packet.py", line 386, in read_message
header = self.read_all(self.__block_size_in, check_rekey=True)
File "C:\Anaconda3\lib\site-packages\paramiko\packet.py", line 249, in read_all
x = self.__socket.recv(n)
ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host
The code is
#Modules
import paramiko
#Variables
USER = 'Administrator'
PSWD = 'Passw0rd'
#Classes and Functions
class InputReader:
def __init__(self, commands_path, hosts_path):
self.commands_path = commands_path
self.hosts_path = hosts_path
def read(self):
self.commands = self.__readlines(self.commands_path)
self.hosts = self.__readlines(self.hosts_path)
def __readlines(self, path):
with open(path) as f:
return [v.strip() for v in f.readlines()] #List comprehension
class CommandExecuter:
def __init__(self, host, command):
self.host = host
self.command = command
def execute(self):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(self.host, username=USER, password=PSWD)
stdin, stdout, stderr = ssh.exec_command(self.command)
errors = stderr.readlines()
if len(errors) != 0:
raise Exception(errors)
lines = [v.strip() for v in stdout.readlines()]
ssh.close()
return lines
#Main Procedure
if __name__ == '__main__':
reader = InputReader("commands.txt", "systems.txt")
reader.read()
for h in reader.hosts:
for c in reader.commands:
executer = CommandExecuter(h, c)
results = executer.execute()
print("{0}({1}):".format(h, c))
for i in results:
print(i)
print('\n')
You can try to run paramiko line by line to ssh to your windows server and see the trace.
Hope that will help,
Trinh

Trouble connecting Firefox WebDriver with Selenium in Python

i'm running into an error in trying to start up the selenium firefox driver. it seems like others have hit snags at this step, and there is no readily available solution online, so hopefully this question will be broadly helpful. it seems like firefox is failing to establish an http server interface when initiated through selenium's driver. it appears that i can run firefox from the command line with no errors.
i should specify that i am doing this via ssh login to a linux container. i'm running python2.7 on Ubuntu 14.04 LTS (GNU/Linux 3.16.3-elastic x86_64). i have the latest version of selenium (2.44) installed, and i'm using firefox 34.0. i'm using xvfb to spoof a display.
below is my code, the error logs, and some related source code.
from selenium import webdriver
d = webdriver.Firefox()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/firefox/webdriver.py", line 59, in __init__
self.binary, timeout),
File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/firefox/extension_connection.py", line 47, in __init__
self.binary.launch_browser(self.profile)
File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/firefox/firefox_binary.py", line 66, in launch_browser
self._wait_until_connectable()
File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/firefox/firefox_binary.py", line 105, in _wait_until_connectable
raise WebDriverException("Can't load the profile. Profile "
selenium.common.exceptions.WebDriverException: Message: Can't load the profile. Profile Dir: %s If you specified a log_file in the FirefoxBinary constructor, check it for details.
that error is raised here, due to a timeout:
def _wait_until_connectable(self):
"""Blocks until the extension is connectable in the firefox."""
count = 0
while not utils.is_connectable(self.profile.port):
if self.process.poll() is not None:
# Browser has exited
raise WebDriverException("The browser appears to have exited "
"before we could connect. If you specified a log_file in "
"the FirefoxBinary constructor, check it for details.")
if count == 30:
self.kill()
raise WebDriverException("Can't load the profile. Profile "
"Dir: %s If you specified a log_file in the "
"FirefoxBinary constructor, check it for details.")
count += 1
time.sleep(1)
return True
in the log_file:
tail -f logs/firefox_binary.log
1418661895753 addons.xpi DEBUG checkForChanges
1418661895847 addons.xpi DEBUG No changes found
1418661895853 addons.manager DEBUG Registering shutdown blocker for XPIProvider
1418661895854 addons.manager DEBUG Registering shutdown blocker for LightweightThemeManager
1418661895857 addons.manager DEBUG Registering shutdown blocker for OpenH264Provider
1418661895858 addons.manager DEBUG Registering shutdown blocker for PluginProvider
System JS : ERROR (null):0 - uncaught exception: 2147746065
JavaScript error: file:///tmp/tmplkLsLs/extensions/fxdriver#googlecode.com/components/driver-component.js, line 11507: NS_ERROR_NOT_AVAILABLE: Component is not available'Component is not available' when calling method: [nsIHttpServer::start]
*** Blocklist::_preloadBlocklistFile: blocklist is disabled
1418661908552 addons.manager DEBUG Registering shutdown blocker for <unnamed-provider>
one more point of information. early on, in the firefox driver initalization, socket.bind(('127.0.0.1',0)) was failing with a "can't assign requested address" error. i changed the location to (0.0.0.0,0) and edited the localhost entry in my /etc/hosts, and was able to bind that way. not sure if that could be causing the current failure though.
VV edits per louis's request VV . i specify the two lines where i change the localhost address.
def free_port():
"""
Determines a free port using sockets.
"""
free_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
free_socket.bind(('0.0.0.0', 0)) # changed from 127.0.0.1
free_socket.listen(5)
port = free_socket.getsockname()[1]
free_socket.close()
return port
def is_connectable(port):
"""
Tries to connect to the server at port to see if it is running.
:Args:
- port: The port to connect.
"""
try:
socket_ = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket_.settimeout(1)
socket_.connect(("0.0.0.0", port)) # changed again
socket_.close()
return True
except socket.error:
return False
here's the constructor from webdriver:
def __init__(self, firefox_profile=None, firefox_binary=None, timeout=30,
capabilities=None, proxy=None):
self.binary = firefox_binary
self.profile = firefox_profile
if self.profile is None:
self.profile = FirefoxProfile()
self.profile.native_events_enabled = (
self.NATIVE_EVENTS_ALLOWED and self.profile.native_events_enabled)
if self.binary is None:
self.binary = FirefoxBinary()
if capabilities is None:
capabilities = DesiredCapabilities.FIREFOX
if proxy is not None:
proxy.add_to_capabilities(capabilities)
RemoteWebDriver.__init__(self,
command_executor=ExtensionConnection("127.0.0.1", self.profile,
self.binary, timeout),
desired_capabilities=capabilities,
keep_alive=True)
self._is_remote = False
here's the constructor from extension_connector:
def __init__(self, host, firefox_profile, firefox_binary=None, timeout=30):
self.profile = firefox_profile
self.binary = firefox_binary
HOST = host
if self.binary is None:
self.binary = FirefoxBinary()
if HOST is None:
HOST = "127.0.0.1"
PORT = utils.free_port()
self.profile.port = PORT
self.profile.update_preferences()
self.profile.add_extension()
self.binary.launch_browser(self.profile)
_URL = "http://%s:%d/hub" % (HOST, PORT)
RemoteConnection.__init__(
self, _URL, keep_alive=True)
in posting my edits to louis's comment, i saw that my localhost issue turned up in other locations, as the host is hardcoded in twice more. i had my server master address the issue, changed everything in the source back to 127, and the problem was solved. thanks for prompting me, #louis, and i'm sorry my question wasn't more interesting. will accept my own answer after 2 days when SO allows me.

Determine difference in http request between Python2 and Python3

I am attempting to use Python3 to send metrics to Hosted Graphite. The examples given on the site are Python2, and I have successfully ported the TCP and UDP examples to Python3 (despite my inexperience, and have submitted the examples so the docs may be updated), however I have been unable to get the HTTP method to work.
The Python2 example looks like this:
import urllib2, base64
url = "https://hostedgraphite.com/api/v1/sink"
api_key = "YOUR-API-KEY"
request = urllib2.Request(url, "foo 1.2")
request.add_header("Authorization", "Basic %s" % base64.encodestring(api_key).strip())
result = urllib2.urlopen(request)
This works successfully, returning a HTTP 200.
So far I have ported this much to Python3, and while I was (finally) able to get it to make a valid HTTP request (i.e. no syntax errors), the request fails, returning HTTP 400
import urllib.request, base64
url = "https://hostedgraphite.com/api/v1/sink"
api_key = b'YOUR-API-KEY'
metric = "testing.python3.http 1".encode('utf-8')
request = urllib.request.Request(url, metric)
request.add_header("Authorization", "Basic %s" % base64.encodestring(api_key).strip())
result = urllib.request.urlopen(request)
The full result is:
>>> result = urllib.request.urlopen(request)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/Cellar/python3/3.3.1/Frameworks/Python.framework/Versions/3.3/lib/python3.3/urllib/request.py", line 160, in urlopen
return opener.open(url, data, timeout)
File "/usr/local/Cellar/python3/3.3.1/Frameworks/Python.framework/Versions/3.3/lib/python3.3/urllib/request.py", line 479, in open
response = meth(req, response)
File "/usr/local/Cellar/python3/3.3.1/Frameworks/Python.framework/Versions/3.3/lib/python3.3/urllib/request.py", line 591, in http_response
'http', request, response, code, msg, hdrs)
File "/usr/local/Cellar/python3/3.3.1/Frameworks/Python.framework/Versions/3.3/lib/python3.3/urllib/request.py", line 517, in error
return self._call_chain(*args)
File "/usr/local/Cellar/python3/3.3.1/Frameworks/Python.framework/Versions/3.3/lib/python3.3/urllib/request.py", line 451, in _call_chain
result = func(*args)
File "/usr/local/Cellar/python3/3.3.1/Frameworks/Python.framework/Versions/3.3/lib/python3.3/urllib/request.py", line 599, in http_error_default
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 400: Bad Request
Is it obvious what I am doing wrong? Are there any suggestions on how I might capture and compare what the successful (python2) and failing (python3) requests are actually sending?
Don't mix Unicode strings and bytes:
>>> "abc %s" % b"def"
"abc b'def'"
You could construct the header as follows:
from base64 import b64encode
headers = {'Authorization': b'Basic ' + b64encode(api_key)}
A quick way to see the request is to change the host in the url to localhost:8888 and run before making the request:
$ nc -l 8888
You could also use wireshark to see the requests.

Resources