Gevent WSGI server doesn't handle request asynchronously even after monkey patch - asynchronous

My setup is simple. I load my server like this python gevent_wsgi_server.py.
When I execute the /block endpoint multiple times, request is rendered sequentially in my browser. 5 seconds each.
I am doing the monkey patch in the server before anything. I think it has to do something with the time module which I imported inside my app.py. But then again, wondering why patching didn't work.
This is my Application
# app.py
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello():
return 'Hello, World! I am a flask app'
#app.route('/block')
def blocking_view():
import time; time.sleep(5)
return 'BLOCKING !'
This is the gevent WSGI server
# gevent_wsgi_server.py
from gevent import monkey; monkey.patch_all()
from gevent.pywsgi import WSGIServer
from app import app
if __name__ == "__main__":
wsgi_server = WSGIServer(("0.0.0.0", 8000), app)
wsgi_server.serve_forever()

Related

Can't access the fastapi page using the public ipv4 address of the deployed aws ec2 instance with uvicorn running service

I was testing a simple fastapi backend by deploying it on aws ec2 instance. The service runs fine in the default port 8000 in the local machine. But as I ran the script on the ec2 instance with
uvicorn main:app --reload it ran just fine with following return
INFO: Will watch for changes in these directories: ['file/path']
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [4698] using StatReload
INFO: Started server process [4700]
INFO: Waiting for application startup.
INFO: Application startup complete.
Then in the ec2 security group configuration, the TCP for 8000 port was allowed as shown in the below image.
ec2 security group port detail
Then to test and access the service I opened the public ipv4 address with port address as https://ec2-public-ipv4-ip:8000/ in chrome.
But there is no response whatsoever.
The webpage is as below
result webpage
The error in the console is as below
VM697:6747 crbug/1173575, non-JS module files deprecated.
(anonymous) # VM697:6747
The fastapi main file contains :->
from fastapi import FastAPI, Form, Depends
from fastapi.middleware.cors import CORSMiddleware
from fastapi.encoders import jsonable_encoder
import joblib
import numpy as np
import os
from own.preprocess import Preprocess
import sklearn
col_data = joblib.load("col_bool_mod.z")
app = FastAPI()
#app.get("/predict")
async def test():
return jsonable_encoder(col_data)
#app.post("/predict")
async def provide(data: list):
print(data)
output = main(data)
return output
def predict_main(df):
num_folds = len(os.listdir("./models/"))
result_li = []
for fold in range(num_folds):
print(f"predicting for fold {fold} / {num_folds}")
model = joblib.load(f"./models/tabnet/{fold}_tabnet_reg_adam/{fold}_model.z")
result = model.predict(df)
print(result)
result_li.append(result)
return np.mean(result_li)
def main(data):
df = Preprocess(data)
res = predict_main(df)
print(res)
return {"value": f"{np.float64(res).item():.3f}" if res >=0 else f"{np.float64(0).item()}"}
The service runs fine with same steps in the react js frontend using port 3000 but the fastapi on 8000 is somehow not working.
Thank You for Your Patience
I wanted to retrieve the basic api reponses from the fastapi-uvicorn server deployed in an aws ec2 instance. But there is no response with 8000 port open and ec2 access on local ipv4 ip address.
One way the problem is fixed is by assigning public ipv4 address followed by port 3000 in the CORS origin. But the issue is to hide the get request data on the browser that is accessed by 8000 port.

Forcing a TLS 1.0 POST request with Requests

To start I know that TLSv1.0 is super old and should not be used, but I need to connect to some really old local hardware that isn't supporting anything else atm
#import ssl
from OpenSSL import SSL
try:
import urllib3.contrib.pyopenssl
urllib3.contrib.pyopenssl.inject_into_urllib3()
except ImportError:
pass
import requests sys, os, select, socket
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.poolmanager import PoolManager
from requests.packages.urllib3.util import ssl_
from requests.packages.urllib3.contrib import py
CIPHERS = (
'ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:
ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:AES256-SHA:'
)
class TlsAdapter(HTTPAdapter):
def __init__(self, ssl_options=0, **kwargs):
self.ssl_options = ssl_options
super(TlsAdapter, self).__init__(**kwargs)
def init_poolmanager(self, *pool_args, **pool_kwargs):
ctx = SSL.Context(SSL.TLSv1_METHOD)
self.poolmanager = PoolManager(*pool_args,
ssl_context=ctx,
**pool_kwargs)
session = requests.Session()
adapter = TlsAdapter(ssl.OP_NO_TLSv1_1 | ssl.OP_NO_TLSv1_2)
session.mount("https://", adapter)
data = { "key":"value"}
try:
r = session.post("https://192.168.1.1", data)
print(r)
except Exception as exception:
print(exception)
I've tried several ways. The above code is mostly ripped from similar issues posted here in the past but python3 ssl no longer supports TLSv1 so it throws an unsupported protocol error. I added the "import urllib3.contrib.pyopenssl" to try and force it to use pyOpenSSL instead per this urllib3 documentation. The current error with this code is
load_verify_locations() takes from 2 to 3 positional arguments but 4 were given
I know this is from the verify part of urllib3 context and I need to fix the context for pyOpenSSL but I've been stuck here trying to fix the context.
Analyzed the website in question in "https://www.ssllabs.com/" , the simulator doesn't use python for testing. I haven't been successful using python. However with jdk 1.8 , I was able to comment the line in the security file as mentioned in "https://www.youtube.com/watch?v=xSejtYOh4C0" and was able to work around the issue.
The server prefers these cipher suites. Is these supported ciphers in urllib3 ?
TLS_RSA_WITH_RC4_128_MD5 (0x4) INSECURE 128
TLS_RSA_WITH_RC4_128_SHA (0x5) INSECURE 128
TLS_RSA_WITH_3DES_EDE_CBC_SHA (0xa) WEAK
Right now I'm stuck with the below error:
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='{}', port={}): Max retries exceeded with url: /xxx.htm (Caused by ProtocolError('Connection aborted.', FileNotFoundError(2, 'No such file or directory')))

route defined in flask returns 404

I have a simple Flask script that has different routes defined with #app.route. The app is running through gunicorn on a nginx server.
The problem occurs when trying to access any route. Except for base url ( "/") , all url return an nginx 404 page. The app runs on venv and I have no idea on how to configure nginx so that they can be served.
I don't know whether to update nginx.conf, default site or something else.
I tried looking for nginx configuration for flask but found no appropriate resource.
The app looks like this
from flask import Flask
app = Flask(__name__)
#app.route("/")
def hello():
return "<h1 style='color:blue'>Hello There!</h1>"
#app.route("/test")
def test():
return "Test"
if __name__ == "__main__":
app.run(host='0.0.0.0')
I excpect /test to open, same way it opens on development server, but returns 404 on nginx.

Python Requests: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:547)

I'm trying to login and scrape an airline website with the python Request package. I am getting the belowe error just by trying to load the main website. This code use to work last year but I have not tried it until now with the new Requests 2.2.1. Any ideas what is going on?
[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:547)
I'm using Requests 2.2.1.
ssladapter.py
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.poolmanager import PoolManager
from ssl import PROTOCOL_TLSv1
class SSLAdapter(HTTPAdapter):
'''An HTTPS Transport Adapter that uses an arbitrary SSL version.'''
__attrs__ = ['max_retries', 'config', '_pool_connections', '_pool_maxsize', '_pool_block', 'ssl_version']
def __init__(self, ssl_version=None, **kwargs):
self.ssl_version = ssl_version
super(SSLAdapter, self).__init__(**kwargs)
def init_poolmanager(self, connections, maxsize, block=False):
self.poolmanager = PoolManager(num_pools=connections,
maxsize=maxsize, block = block,
ssl_version=self.ssl_version)
scrape.py
import requests
import ssladapter
from ssl import PROTOCOL_TLSv1
session = requests.Session()
session.mount('https://', ssladapter.SSLAdapter(ssl_version=PROTOCOL_TLSv1))
request = session.get("www.delta.com")
!!! SSLERROR raised here.
This Error is not a problem of the Requests library because it has been rigorously tested.
This is an indication of a 'Man-in-the-middle' attack.
May be you may be having a Network Sniffing tool like Fiddler or Wireshark running.
More Detailed Info on this a related Question
Here it is suggested that this is how SSL should work.

Will gevent speed up pymongo connection

I am using bottle with pymongo. My server is nginx and uwsgi.
Will gevent make my pymongo run async(What I mean multithread) by just using the code below?
from gevent import monkey; monkey.patch_socket()
My reference:
http://api.mongodb.org/python/current/examples/gevent.html
Update:
I have updated the uwsgi.ini:
[uwsgi]
plugins=python
socket=/tmp/uwsgi.myapp.socketpython
path=/var/www/myapp
gevent = 100
Am I doing it correctly?
You have to enable gevent mode in uWSGI too
http://uwsgi-docs.readthedocs.org/en/latest/Gevent.html
then use monkey.patch_all() instead of monkey.patch_socket() as uWSGI is a native gevent application and do not use its monkey patch features by default.

Resources