I have built an API with Flask and keep getting an error when testing it with postman.
I only started getting this error when I added threading so that I could continue running my scraper after returning data to postman, now I'm not sure how to get past this issue
My code looks something like this:
from threading import Thread
from flask import Flask
application = Flask(__name__)
class Compute(Thread):
def __init__(self, request):
print("init")
Thread.__init__(self)
self.request = request
def run(self):
print("RUN")
command = './webscraper.py -us "{user}" -p "{password}" -url "{url}"'.format(**self.request.json)
output = subprocess.call(['bash','-c', command])
print("done")
#application.route('/scraper/run', methods=['POST'])
def init_scrape():
thread_a = Compute(request.__copy__())
thread_a.start()
return jsonify({'Scraping this site: ': request.json["url"]}), 201
if __name__ == '__main__':
application.run(host="0.0.0.0", port="8080")
My POST data is just a site url and details to login to it, looks something like this
data = {
{
"user":"username",
"password":"password",
"url":"www.mysite.com/"
}
If I make a POST request to localhost:8080/scraper/run with postman I get this error:
init
RUN
Exception in thread Thread-2:
Traceback (most recent call last):
File "/usr/lib/python3.6/threading.py", line 916, in _bootstrap_inner
self.run()
File "api_app.py", line 19, in run
command = './portal_scrape.py -us "{user}" -p "{password}" -start {start} -end {end} -fav "{favourite}" -url "{url}"'.format(**self.request.json)
File "/home/connor/Desktop/portal_dl/venv36/lib/python3.6/site-packages/flask/wrappers.py", line 47, in json
return self.get_json()
File "/home/connor/Desktop/portal_dl/venv36/lib/python3.6/site-packages/flask/wrappers.py", line 71, in get_json
data = self._get_data_for_json(cache=cache)
File "/home/connor/Desktop/portal_dl/venv36/lib/python3.6/site-packages/flask/wrappers.py", line 50, in _get_data_for_json
return self.get_data(cache=cache)
File "/home/connor/Desktop/portal_dl/venv36/lib/python3.6/site-packages/werkzeug/wrappers.py", line 514, in get_data
rv = self.stream.read()
File "/home/connor/Desktop/portal_dl/venv36/lib/python3.6/site-packages/werkzeug/wsgi.py", line 1307, in read
return self.on_disconnect()
File "/home/connor/Desktop/portal_dl/venv36/lib/python3.6/site-packages/werkzeug/wsgi.py", line 1275, in on_disconnect
raise ClientDisconnected()
werkzeug.exceptions.ClientDisconnected: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.
I am sending the same POST request I had used when it was working without threading
Related
So I have very strange problem. I am working on this application that is using GitLab instance (version: 15.5.1) on my server in background with CentOS. I am using API, python-gitlab library and my Flask app. I was was making little change to my function which was adding bas64 decoder before this everything worked just fine. So after this change I send one request with Postman to see if it works.
And this is where the problem starts functions works it decodes base64 and sends it to server where it is saved in repo. BUT serevr response with 500 INTERNAL SERVER ERROR in Postman.
ERROR FROM TERMINAL:
[2023-02-17 10:07:45,597] ERROR in app: Exception on /data [POST]
Traceback (most recent call last):
File "exceptions.py", line 337, in wrapped_f
return f(*args, **kwargs)
File "mixins.py", line 246, in list
obj = self.gitlab.http_list(path, **data)
File "client.py", line 939, in http_list
return list(GitlabList(self, url, query_data, **kwargs))
File "client.py", line 1231, in __next__
return self.next()
File "client.py", line 1242, in next
self._query(self._next_url, **self._kwargs)
File "/client.py", line 1154, in _query
result = self._gl.http_request("get", url, query_data=query_data, **kwargs)
File "client.py", line 798, in http_request
raise gitlab.exceptions.GitlabHttpError(
gitlab.exceptions.GitlabHttpError: 404: HERE STARTS LONG HTML FILE
MY FUNCTION: type and text are JSON parameter JSON file is below this code
def pushFile(type, text):
decoded_text = base64.b64decode(text)
project_id = config.REPO_ID
project = gl.projects.get(project_id)
#RANDOM ID
uni_id = uuid.uuid1()
f = project.files.create({'file_path': f'{compared_type}'+'_RULES/'+f'{type}'+'_'+f'{uni_id}'+'.txt',
'branch': 'main',
'content': f'{decoded_text}',
'author_email': 'test#example.com',
'author_name': 'yourname',
'commit_message': 'Create testfile'})
JSON:
{
"type" :"radar",
"text" : "dGVzdHRlc3R0ZXN0dGVzdHRlc3R0ZXN0dGVzdHRlc3R0ZXN0dGVzdHRlc3R0ZXN0dGVzdHRlc3R0ZXN0dGVzdHRlc3R0ZXN0dGVzdHRlc3R0ZXN0dGVzdA=="
}
So I tried to:
Restart GitLab instance
Delete bas64 decoder
But nothing helped and I still get 500 error but files are still uploaded. Does someone have any idea what might be wrong?
I'm trying to serve a Flask (v1.1.2) wsgi application using cheroot server of CherryPy (v18.6.0) and after each request executed via Postman or browser I'm getting the following exception in my console. I'm running python v3.8.5
Error in HTTPServer.tick
Traceback (most recent call last):
File "C:\myproject\venv\lib\site-packages\cheroot\server.py", line 1795, in serve
self.tick()
File "C:\myproject\venv\lib\site-packages\cheroot\server.py", line 2030, in tick
self.connections.expire()
File "C:\myproject\venv\lib\site-packages\cheroot\connections.py", line 107, in expire
for sock_fd, conn in timed_out_connections:
File "C:\myproject\venv\lib\site-packages\cheroot\connections.py", line 103, in <genexpr>
(sock_fd, conn)
File "C:\python\lib\_collections_abc.py", line 743, in __iter__
for key in self._mapping:
RuntimeError: dictionary changed size during iteration
Code as follows:
from cheroot.wsgi import Server
from flask import Flask
app = Flask(__name__)
#app.route("/", methods=["GET"])
def index():
return "Hello"
if __name__ == "__main__":
server = Server(bind_addr=("0.0.0.0", 3000), wsgi_app=app)
try:
server.start()
finally:
server.stop()
Any idea causing that exception and how we can resolve it?
This is a recent and acknowledged issue with cheroot, take a look to the cheroot GitHub Issue 312.
I am trying to communicate with Flask websocket from a python script. But I am getting the following exception.
Traceback (most recent call last):
File "client.py", line 5, in <module>
socket = create_connection("ws://127.0.0.1:5000")
File "C:\Users\anyms\AppData\Local\Programs\Python\Python37-32\lib\site-packages\websocket\_core.py", line 514, in create_connection
websock.connect(url, **options)
File "C:\Users\anyms\AppData\Local\Programs\Python\Python37-32\lib\site-packages\websocket\_core.py", line 226, in connect
self.handshake_response = handshake(self.sock, *addrs, **options)
File "C:\Users\anyms\AppData\Local\Programs\Python\Python37-32\lib\site-packages\websocket\_handshake.py", line 79, in handshake
status, resp = _get_resp_headers(sock)
File "C:\Users\anyms\AppData\Local\Programs\Python\Python37-32\lib\site-packages\websocket\_handshake.py", line 160, in _get_resp_headers
raise WebSocketBadStatusException("Handshake status %d %s", status, status_message, resp_headers)
websocket._exceptions.WebSocketBadStatusException: Handshake status 404 NOT FOUND
app.py
from flask import Flask
from flask_socketio import SocketIO, send
app = Flask(__name__)
app.config["SECRET_KEY"] = "uhjsbajksHGhksajjf^&*8*()"
socketio = SocketIO(app)
#socketio.on("message")
def message(msg):
print("Message received: {}".format(msg))
send(msg, broadcast=True)
#socketio.on("connect")
def connect():
print("Connected!")
if __name__ == "__main__":
socketio.run(app)
client.py
#!/usr/bin/python
from websocket import create_connection
socket = create_connection("ws://127.0.0.1:5000")
socket.send("hello, world")
result = socket.recv()
print("Received: {}".format(result))
socket.close()
If I write an HTML page as a client it works fine, but I could not connect from my python script.
When I use ws://echo.websocket.org it works fine, I am confused, I am new to websocket programming.
1 year old now, but basically websockets and socket.io are two different methods of creating a socket. They are not compatible. You have a socket.io server but a websocket client. Change either one to match the other and it should work.
I'm trying to send emails periodically with flask mail, but I'm stuck with this error: Flask object has no attribute app_context
def mail_periodic():
print "sending mail at " +time.ctime()
app = current_app._get_current_object()
msg = Message("no-reply: Avantgarde.Rentals",
sender="avantgarde.rentals.noreply#gmail.com",
)
msg.add_recipient('aladinne.k#gmail.com')
msg.body = 'Email periodic '
mail2 = Mail(app)
with app.app_context():
mail2.send(msg)
print"email sent "
threading.Timer(5, mail_periodic).start()
#app.route('/startcronemailing')
def startcronemailing():
try:
mail_periodic()
except Exception, exception:
return exception.message
return "crone mailing started"
the exception that i got :
Exception in thread Thread-3:
Traceback (most recent call last):
File "C:\Python27\lib\threading.py", line 801, in __bootstrap_inner
self.run()
File "C:\Python27\lib\threading.py", line 1073, in run
self.function(*self.args, **self.kwargs)
File "app.py", line 113, in mail_periodic
host_link='http://' + request.host,
File "C:\Python27\lib\site-packages\werkzeug\local.py", line 336, in __getattr__
return getattr(self._get_current_object(), name)
File "C:\Python27\lib\site-packages\werkzeug\local.py", line 295, in _get_current_object
return self.__local()
File "C:\Python27\lib\site-packages\flask\globals.py", line 19, in _lookup_object
raise RuntimeError('working outside of request context')
RuntimeError: working outside of request context
please note that even if i use another mailing service like sendgrid i got the same error
You have to pass app instance as args. If you use current_app._get_current_object() to get app instance inside target function, you will not get the right app in another thread. For example:
from threading import Thread
from flask import current_app
from flask_mail import Message
from bluelog.extensions import mail
def _send_async_mail(app, message): # target function
with app.app_context():
mail.send(message)
def send_async_mail(subject, to, html):
app = current_app._get_current_object() # get the real app instance
message = Message(subject, recipients=[to], html=html)
thr = Thread(target=_send_async_mail, args=[app, message]) # pass app
thr.start()
return thr
I am developing a web app using Python + Flask. In the simplest sense, a request from the client to a specific URL will trigger the app to login into a remote machine on the server side, perform a series of shell commands, and parse and send the output (formatted in JSON) to the client as part of the response. These commands are fairly simple. To log in to the remote machine, the only method available to me is rlogin, so I used the pexpect module since I couldn't find any standard Python modules for rlogin.
Now the problem is that while I am able to get the correct output from pexpect/rlogin, sending that output (a string) as a response results in an error:
----------------------------------------
Exception happened during processing of request from ('171.71.55.54', 62736)
Traceback (most recent call last):
File "/isan/python/python2.7/SocketServer.py", line 295, in _handle_request_noblock
self.process_request(request, client_address)
File "/isan/python/python2.7/SocketServer.py", line 321, in process_request
self.finish_request(request, client_address)
File "/isan/python/python2.7/SocketServer.py", line 334, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/isan/python/python2.7/SocketServer.py", line 651, in __init__
self.finish()
File "/isan/python/python2.7/SocketServer.py", line 710, in finish
self.wfile.close()
File "/isan/python/python2.7/socket.py", line 279, in close
self.flush()
File "/isan/python/python2.7/socket.py", line 303, in flush
self._sock.sendall(view[write_offset:write_offset+buffer_size])
error: [Errno 9] Bad file descriptor
----------------------------------------
I've stripped the code down to the bare minimum required to reproduce the error. An HTTP request to this app results in the "Bad file descriptor" error. Sorry for the varying indentation, I was using two different editors to modify the code!
import os
import subprocess
import pexpect
from flask import Flask
app = Flask(__name__)
class rlogin:
def __init__(self, host, prompt):
self.child = pexpect.spawn("rlogin " + host)
self.prompt = prompt
self.child.expect_exact(self.prompt)
def command(self, command):
self.child.sendline(command)
self.child.expect_exact(self.prompt)
response = self.child.before
return response
def close(self):
self.child.close()
#app.route('/')
def index():
rl = rlogin("myserver", "root#myserver:~# ")
output = rl.command("pwd")
rl.close()
# The output of the next line is just as I expect:
print output
# This is probably where it fails:
return output
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
Removing the calls to rlogin(), rl.command() and rl.close(), and returning a simple string like "A" resolves the error. I've been stuck on this issue for a while now, and would hugely appreciate any help. Thanks!
You will have to make sure that the return type is str, unicode, response class or WSGI function. It looks like your output doesn't belong to any of the accepted Flask route return types.
#app.route('/')
def index():
rl = rlogin("myserver", "...")
output = rl.command("pwd")
rl.close()
print type(output)
# Convert output into something that flask can understand
value = str(output)
resp = make_response(value)
resp.headers['Content-Type'] = 'text/plain'
return resp
You can read more about this at http://flask.pocoo.org/docs/0.10/api/#flask.Flask.make_response