Why botium-box HTTP(S)/JSON connector request is empty? - testing

This is my demo code:
from flask import Flask , jsonify, request, render_template
import json
app = Flask(__name__)
#app.route('/t',methods=['GET','POST'])
def t():
print(request.data)
print (request.headers)
return jsonify({"test":"test"})
if __name__ =='__main__':
app.run(debug=True,host="0.0.0.0",port=5000)
When I use the Generic HTTP(S)/JSON Connector and to Click CHECK CONNECTIVITY Button,
it response a "test" for text.
but I see the logs , the header is empty. The logs is below:
192.168.58.119 - - [17/Aug/2020 15:24:35] "[37mGET /t HTTP/1.1[0m" 200 -
b''
Host: 192.168.58.145:5000
Connection: close
The connectivity is successful.
How to get the botium box query text in the http headers?
thanks!

Related

How does Python Eventlet concurrently request?

The client uses eventlet with the following code.
import eventlet
import urllib.request
urls = [
"http://localhost:5000/",
"http://localhost:5000/",
"http://localhost:5000/",
]
def fetch(url: str) -> str:
return urllib.request.urlopen(url).read()
pool = eventlet.GreenPool(1000)
for body in pool.imap(fetch, urls):
print("got body", len(body), body)
The server side is built using fastapi, so why can we distinguish if the client is really concurrently requested, we add a delay
from fastapi import FastAPI
import uvicorn
import time
app = FastAPI()
#app.get('/')
def root():
time.sleep(3)
return {"message": "Hello World"}
if __name__ == '__main__':
uvicorn.run("api:app", host="0.0.0.0", port=5000)
Start the server first, then run the client code, using Linux's time command to see how long it takes.
got body 25 b'{"message": "Hello World"}'
got body 25 b'{"message": "Hello World"}'
got body 25 b'{"message": "Hello World"}'
python -u "013.py" 0.25s user 0.01s system 2% cpu 9.276 total
As you can see, it took 9 seconds instead of 3 seconds, so this ``eventlet` is not parallel, am I using it wrong? What is the correct way to open it?
Translated with www.DeepL.com/Translator (free version)

Cross Origin Problem with Flask Api (Access-Control-Allow-Origin)

Hello all good people.
I have tested everything that I can find on internet and nothing is working to fix this problem. I'm really hoping that someone here can help me solve this.
When i try to do "patch" request from backend to my flask API I get this error (GET, DELETE & PUT are working fine):
Access to fetch at 'https://MYAPI-NOTREALURL.com' from origin
'https://MYBACKEND-NOTREALURL.com' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check: The
'Access-Control-Allow-Origin' header contains multiple values
'https://MYBACKEND-NOTREALURL.com, *', but only one is allowed. Have
the server send the header with a valid value, or, if an opaque
response serves your needs, set the request's mode to 'no-cors' to
fetch the resource with CORS disabled.
This is how my code for API is written:
from flask_cors import CORS, cross_origin
from flask import render_template, redirect, flash, request, url_for, jsonify, session, make_response
from flask_restful import Api, Resource, reqparse
import requests
app = Flask(__name__)
cors = CORS(app, resources={r"/*": {"origins": "*"}})
api = Api(app)
class ordersByID(Resource):
def get(self,ID_ORDER):
****
return jsonify(data)
def patch(self,ID_ORDER):
req321 = request.form
result = updateOrder(req321,ID_ORDER)
return result
def delete(self,ID_ORDER):
****
return result
def put(self,ID_ORDER):
****
return result
api.add_resource(ordersByID, "/orders/id/<string:ID_ORDER>")
if __name__ == '__main__':
app.run(debug=True)
I have tested everything that I can find on internet and nothing is working when trying to do patch request. I'm doing patch request with fetch from popup window.
<form action="{{ **https://MYAPI-NOTREALURL.com** }}" id="popupForm" method="patch" onsubmit="formFetch(event,this,'patch')">
You can check javascript code under.
function formFetch(e,form,method) {
result = fetch(form.action, {method:method, body: new FormData(form)})
.then(response => response.json())
.then(data => document.getElementById('submitedFormConfirmationText').innerHTML = data['DB_Result']
);
e.preventDefault();
document.getElementById('submitedFormConfirmation').style.display = 'inline';
};
I really hope that someone can help me solve this problem without needing to redo whole code?
I managed to solve this.
For some strange reason "patch" with small letters was working on local but when deployed it did not work.
Changing method from "patch" to "PATCH" solved this problem.

flask_cors is registered but still getting CORS error

I have a Vue frontend that uses Axios to POST to my Flask API. I've registered flask_cors to my Flask instance but I'm still get a CORS error.
flask_cors registered in app/__init__.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from config import Config
from flask_marshmallow import Marshmallow
from flask_cors import CORS
app = Flask(__name__)
app.config.from_object(Config)
cors = CORS(app)
db = SQLAlchemy(app)
migrate = Migrate(app, db)
ma = Marshmallow(app)
from . import routes, models
app/routes.py
from flask import request, jsonify, current_app
from . import app, db
from .models import SetAnon
#app.route('/sets', methods=['POST'])
def sets():
data = request.get_json()
_set = SetAnon(
col1=data['somedata']
)
db.session.add(_set)
db.session.commit()
return "set saved", 201
Vue frontend is making POST request with axios:
import axios from 'axios'
const API_URL = 'http://127.0.0.1:5000'
export function saveSet(set) {
return axios.post(`${API_URL}/sets/`, set)
}
Getting this error in browser console
xhr.js?ec6c:172 OPTIONS http://127.0.0.1:5000/sets/ 404 (NOT FOUND)
Access to XMLHttpRequest at 'http://127.0.0.1:5000/sets/' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
Looks like an issue with trailing backslash. Your routes.py defines the route as '/sets' however the frontend is calling '/sets/'.
Change the routes.py to this and it should work -
from flask import request, jsonify, current_app
from . import app, db
from .models import SetAnon
#app.route('/sets/', methods=['POST']) # Added trailing backslash
def sets():
data = request.get_json()
_set = SetAnon(
col1=data['somedata']
)
db.session.add(_set)
db.session.commit()
return "set saved", 201

Setting secure cookie for python client connection

I am currently attempting to set a secure cookie for a connection that is incoming from a Python client using Tornado, however, although setting the cookie works fine for connecting incoming from browsers, the set_secure_cookie call does not seem to work in the case of a Python client.
Below are excerpts from my Tornado server code which serves both WebSocket and HTTP Requests:
class BaseHandler(tornado.web.RequestHandler):
def get_current_user(self):
return self.get_secure_cookie("user")
class LoginHandler(BaseHandler):
def get(self):
self.write('<html><body><form action="/login" method="post">'
'Name: <input type="text" name="name">'
'<input type="submit" value="Sign in">'
'</form></body></html>')
def post(self):
print("post received: ", self.get_argument("name"))
try:
print('trying to set cookie')
self.set_secure_cookie("user", self.get_argument("name"))
except Exception as e:
print(e)
print("cookie: ", self.get_current_user())
self.redirect("http://192.168.6.21/")
def main():
application = tornado.web.Application([
(r'/ws', EchoWebSocket),
(r'/login', LoginHandler)
], cookie_secret="nescafeh")
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(9000)
tornado.ioloop.IOLoop.instance().start()
And attempting to send a POST request to get the cookie set on a separate client:
s=requests.Session()
r = s.post("http://127.0.0.1:9000/login", data={'name': 'hello'})
sleep(2)
print(r.text)
No errors are returned when trying to set the cookie, removing the 'self.redirect' line to see the response from the POST request does not help (there is no text printed).
Thanks a lot!
r.text is empty because you're not writing anything to the response body in your handler.
Try self.write("something") in your handler's post method and r.text should print out the response.
You can also check r.cookies to see if your cookie is set or not.

create simple api with python to catch post request

I have developed a python plugin which is capable of sending log file in json format
in mm code i have used requests.post(url, data={})
what will be the api structure that catch this data and will be available for
send anywhere with GET request
If you are fairly new to web programming I would suggest using a lightweight framework like Flask. With it you can define custom paths that your server accepts requests on as follows:
from flask import Flask
from flask import request, jsonify
app = Flask(__name__)
log_file = None
#app.route("/api/logfile", methods=['GET', 'POST'])
def post_logfile():
if request.method == 'GET':
if log_file is not None:
return "Log file not instantiated yet", 404
else:
return jsonify(log_file)
elif request.method == 'POST':
log_file = request.form
if log_file is not None:
# log_file variable will have all the information
# from the JSON log file
return "Ok"
else:
return "No data provided", 400
if __name__ == "__main__":
app.run(port=9000)
As you can see, we have a global variable log_file which will be used to store the JSON logfile data, and a function that accepts both POST and GET requests and acts accordingly. If a GET request is sent, it checks if log_file variable is assigned. If so, it returns the log file as a JSON file else it return a 404 error. If a POST request is sent it checks if it has the log file and stores in the log_file variable, making it useful for all subsequent GET requests.
The URL used are:
localhost:9000/api/logfile
And you only need to change the method of the request(e.g. POST or GET)