I have several Python scripts that are used from the CLI. Now I have been asked if I could provide a web API to perform some of the work normally done from the CLI. I would like to respond with JSON formatted data. I know little about JSON or API's.
How do I retrieve the query data from the http request?
How to a create the HTTP headers for the response from my script?
Given the following URL, how can I respond with a JSON reply of the name "Steve"?
http://myserver.com/api.py?query=who
I already have a functioning Apache web server running, and can serve up HTML and CGI scripts. It's simply coding the Python script that I need some help with. I would prefer not to use a framework, like Flask.
A simple code example would be appreciated.
The following is the Python code that I've come up with, but I know it's not the correct way to do this, and it doesn't use JSON:
#!/usr/local/bin/python3.7
import cgi # CGI module
# Set page headers and start page
print("Content-type: text/plain")
print("X-Content-Type-Options: nosniff\x0d\x0a\x0d\x0a")
# Form defaults
query_arg = None
# Get form values, if any
form = cgi.FieldStorage()
# Get the rest of the values if the form was submitted
if "query" in form.keys():
query_arg = form["query"].value
if query_arg == "who":
print("Steve", end="", flush=True)
You are trying to build a request handler with core python code. which is able to handle http request, In my opinion its not good idea as there are multiple securty scenarios attached with it, also in cross server request its bit difficult to handle all request and request scenarios . I will suggest to use Flask which is very lightweight and this will give an pre-setup of routing mechanism to handle all kind of request in very less code below is the snippet to generate http json response hope it helps
import sys
import flask
import random, string
from flask import jsonify
class Utils:
def make_response(self):
response = jsonify({
'message': 'success',
})
response.status_code = 200
return response
Related
guys I want to create a python API and request msg and get a response with JSON and send it to knime workflow and work with it
this is my script in python the fact is that he give me json.decoder.jsondecodeError
from importlib.metadata import files
import requests
url ='https://api.edination.com/v2/edifact/read'
headers = {'Ocp-Apim-Subscription-Key': '3ecf6b1c5cf34bd797a5f4c57951a1cf'}
files = {'file':open('C:\\Users\\hcharafeddine\\Desktop\\EDI\\Interchange_1654767219416.edi','rb')}
r = requests.post(url,files=files)
r.json()
We'll need more info to help further. I understand if you don't want to share the content of the EDI message, so here are a few things to try:
The EDINation website allows you to paste an EDI message in and it'll show you the JSON output that the API will return
It also has a sample EDIFACT document you can select and then save locally to run through your python script - you can then share the results here
You can also use HTTPToolkit to inspect the API request and response to troubleshoot further.
I'm updating some APIs that I have coded using Python and FastAPI. In the actual version I'm sending the info using Query Paramenters, but now I want to try to send the data by using Request Body, but the code doesn't seem to work.
Below you can see a sample of the code on the Server Side where FastAPI should return the text I'm sending (for this example only the "string_to_show" info, but in the real project there would be more fields). I know that is a base code, but this is just a sample.
from fastapi import FastAPI, Path, Query
from pydantic import BaseModel
import uvicorn
app = FastAPI()
class req_body(BaseModel):
string_to_show:str
#app.get("/test/")
def scraper_shield(payload:req_body):
request_feedback = str(payload.string_to_show)
return request_feedback
if __name__ == "__main__":
uvicorn.run(app)
On the Client Side I'm using this code, that simply sends the payload to the server.
import requests
payload = {'string_to_show':'Python is great!'}
r = requests.get('http://127.0.0.1:8000/test/', params=payload)
print(r.text)
When sending the request, I should get the string "Python is Great!" but instead I'm getting some errors, below the Client and Server messages:
CLIENT: {"detail":[{"loc":["body"],"msg":"field required","type":"value_error.missing"}]}
SERVER: "GET /test/?string_to_show=Python+is+great%21 HTTP/1.1" 422 Unprocessable Entity
GET methods are not suppose to have body.
https://dropbox.tech/developers/limitations-of-the-get-method-in-http
POST method is meant for that.
If you really need some robust parametrization with GET (but I really would reconsider that), think about putting them into custom header(s).
You are sending the parameters as query strings when using
r = requests.get('http://127.0.0.1:8000/test/', params=payload). You have to instead use
r = requests.get('http://127.0.0.1:8000/test/', json=payload) which will create a request body and send it correctly. This what you also see from the errors, which basically tell you that the required body is missing.
I am working on a url redirector application, in Python. The idea of this application is simple: when a user performs an http request to a certain domain (e.g. to https://google.com), the app stops the request and performs another http request (e.g. to https://github.com), thereby redirecting the user to the second page.
Unfortunately, I have looked through SO and I haven't found any question that addresses this issue directly:
Intercept and filter HTTP request doesn't redirect
Sending a HTTP request using python doesn't either
Admittedly, I only have some fabricated pseudocode to demonstrate what I wish to do, but it may prove useful:
import requests
original_site = "https://google.com"
redirect_site = "https://github.com"
def redirect_request():
if requests.get(original_site) == True:
requests.kill(request.original_site.id)
requests.get(redirect_site)
I greatly appreciate any suggestions.
EDIT - Here is a clarification of what I mean:
The user runs my python script, which I will call foobar.py, as follows:
python foobar.py
Then the user opens their web browser, and enters the url https://google.com, and as the script is running, the user will not actually visit https://google.com, but be redirected to https://github.com
One option is if you are trying to build a lightweight web app using python where you can mess with HTTP redirects, you can use Flask to accept a GET on a route and then simply do a redirect.
from flask import Flask, redirect
app = Flask(__name__)
#app.route('/')
def index():
return redirect("https://www.google.com")
But to answer your question more directly, you don't "stop" the initial request. You simply find a way to handle it and serve back a response that you specify.
I am working on a software that has a TCP Server that replies to requests done in a proprietary protocol.
Obviously the implementation relies on a socket listening on a fixed port and on analyzing and managing raw request and response.
I should add to this service the possibility to manage http requests.
I started using flask with the idea to let it manage templates rendering and responses creation, but I am a bit struck on the second part:
Righ now I managed to make this work with something like this:
with open(template_file) as f:
template = f.read()
app = flask.Flask('my app') # create a context to render Response
with app.app_context():
context = {'title': 'mytitle',
'other_info':'.....',}
rendered = flask.render_template_string(template, **context)
response = flask.make_response(rendered)
answer = f'''HTTP/1.0 200 OK\nContent-Type: text/html\n\n {rendered} \n\n'''
sock.sendall(answer.encode())
sock.close()
In this case make_response creates a Response instance where you can get the rendered html code but going from Response to the raw http is my problem.
To solve this i have added manually a header, but I think that there is a better way in flask to do this but can't figure out.
To make the question more general: how can coexist flask web application with others? Where is the point on which I have to take control of the process?
I decided to try to make an automated login script for Minecraft. However, the new authentication API is stumping me. I can't find any mentions of the new functionality of the API on here. This is my code as it stands:
import requests
import json
data = json.dumps({"agent":{"name":"Minecraft","version":1},"username":"abcdef","password":"abcdef","clientToken":""})
headers = {'Content-Type': 'application/json'}
r = requests.post('https://authserver.mojang.com', data=data, headers=headers)
print (r.text)
Unfortunately, this returns:
{"error":"Method Not Allowed","errorMessage":"The method specified in the request is not allowed for the resource identified by the request URI"}
According to this resource on request format, this error means that I didn't correctly send a post request. However, I clearly declared requests.post(), so my first question is how am I incorrect, and what is the correct way to go about this?
My second question is, since I'm relatively new to Python and JSON, how would I replace the username and password fields with my own data, inside a variable?
You haven't specified an endpoint in your POST request, for example:
https://authserver.mojang.com/authenticate
The root of the website probably does not accept POST requests
http://wiki.vg/Authentication#Authenticate