responding to an HTTP POST requests - python

I need help responding to an HTTP POST request. I am trying to use slack slash and you need to respond in three seconds to their http post request. My code is like this
#app.route('/recover', methods = ['POST'])
def recover(data):
if verify_signature(slack_signing_signature):
send_message()
data = {"response_type":"in_channel"}
return jsonify(data)
My problem is that how can i return a response to slack first then do the actual stuff that I need?

You can use Thread;
from threading import Thread
def slack_it(sign):
if verify_signature(sign):
send_message()
#app.route('/recover', methods = ['POST'])
def recover(data):
Thread(target=slack_it, args=(slack_signing_signature,), daemon=False).start()
return jsonify({"response_type":"in_channel"})

Related

Make Bulk Requests API Client Programming Pattern / Design

I am writing an API client for a REST API that allows for requests the be batched together in and send as one request
I am struggling to figure out how to structure the client. I've come up with two designs so far (pseudo Python code):
Async Method
When calls to the api are made (make_api_request), the method waits for the bulk request to be made. Once the bulk request is made by calling the resolve coroutine, the request coroutine releases control back to he make_api_request method which processes the response for that specific request and returns it
import asyncio
class FakeAPIClient:
def __init__(self):
"""
"""
pass
async def make_api_request(self):
"""
returns response after request is made
"""
resp = await self.request()
#response processing
return resp
async def request(self):
"""
I block until the bulk request is made
Once it is make, I return the response from the single request
"""
return "RESPONSE AFTER DONE BLOCKING "
async def resolve(self):
"""
Make the bulk request and release the make_api_request calls and return the assocaited responses
"""
return None
async def example():
api = FakeAPIClient()
future1 = api.make_api_request()
future2 = api.make_api_request()
future3 = api.make_api_request()
#3 requests are sent in bulk
response1, response2, response3, _ = asyncio.gather(
future1,
future2,
future3,
api.resolve()
)
asyncio.run(example())
Lookup method
When calls to the api are made (make_api_request), a lookup ID is returned and the request is put into storage. When the resolve method is called, the bulk request is called, the requests in storage are sent as a bulk request and an object is returned that can be used to find the lookup id's corresponding response.
class FakeAPIClient:
def __init__(self):
pass
def make_api_request(self):
"""
adds request to a queue of requests that will be resolved when resolve method is called
also provide a callback for post request processing
returns a unique id of the request
"""
return "UNIQUE ID"
def resolve(self):
"""
makes the bulk request
takes the responses and associates them with the request id
calls the callback associated with the response for post request processing
returns an object with a method that returns the responses when provided the request id
"""
return "RESPONSE LOOKUP"
api = FakeAPIClient()
lookup_id1 = api.make_api_request()
lookup_id2 = api.make_api_request()
lookup_id3 = api.make_api_request()
lookup_object = api.resolve()
response1 = lookup_object.get(lookup_id1)
response2 = lookup_object.get(lookup_id2)
response3 = lookup_object.get(lookup_id3)
I don't really love either of these solutions, but I can't think of any alternatives. I'd assume there are known patterns for solving this problem, what are they?

aiohttp: How to update request headers according to request body?

I am trying to implement a type of custom authentication by using aiohttp something like the example in this link but I also need request body. Here is an example for requests:
class CustomAuth(AuthBase):
def __init__(self, secretkey):
self.secretkey = secretkey
def get_hash(self, request):
if request.body:
data = request.body.decode('utf-8')
else:
data = "{}"
signature = hmac.new(
str.encode(self.secretkey),
msg=str.encode(data),
digestmod=hashlib.sha256
).hexdigest().upper()
return signature
def __call__(self, request):
request.headers["CUSTOM-AUTH"] = self.get_hash(request)
return request
I've looked into tracing and BasicAuth but they are useless in my situation. On on_request_start request body is not ready, on on_request_chunk_sent headers have already been sent. A solution like BasicAuth don't have access the request data at all.
Do you have any idea?
Thanks in advance.

Flask Middleware with both Request and Response

I want to create a middleware function in Flask that logs details from the request and the response. The middleware should run after the Response is created, but before it is sent back. I want to log:
The request's HTTP method (GET, POST, or PUT)
The request endpoint
The response HTTP status code, including 500 responses. So, if an exception is raised in the view function, I want to record the resulting 500 Response before the Flask internals send it off.
Some options I've found (that don't quite work for me):
The before_request and after_request decorators. If I could access the request data in after_request, my problems still won't be solved, because according to the documentation
If a function raises an exception, any remaining after_request functions will not be called.
Deferred Request Callbacks - there is an after_this_request decorator described on this page, which decorates an arbitrary function (defined inside the current view function) and registers it to run after the current request. Since the arbitrary function can have info from both the request and response in it, it partially solves my problem. The catch is that I would have to add such a decorated function to every view function; a situation I would very much like to avoid.
#app.route('/')
def index():
#after_this_request
def add_header(response):
response.headers['X-Foo'] = 'Parachute'
return response
return 'Hello World!'
Any suggestions?
My first answer is very hacky. There's actually a much better way to achieve the same result by making use of the g object in Flask. It is useful for storing information globally during a single request. From the documentation:
The g name stands for “global”, but that is referring to the data being global within a context. The data on g is lost after the context ends, and it is not an appropriate place to store data between requests. Use the session or a database to store data across requests.
This is how you would use it:
#app.before_request
def gather_request_data():
g.method = request.method
g.url = request.url
#app.after_request
def log_details(response: Response):
g.status = response.status
logger.info(f'method: {g.method}\n url: {g.url}\n status: {g.status}')
return response
Gather whatever request information you want in the function decorated with #app.before_request and store it in the g object.
Access whatever you want from the response in the function decorated with #app.after_request. You can still refer to the information you stored in the g object from step 1. Note that you'll have to return the response at the end of this function.
you can use flask-http-middleware for it link
from flask import Flask
from flask_http_middleware import MiddlewareManager, BaseHTTPMiddleware
app = Flask(__name__)
class MetricsMiddleware(BaseHTTPMiddleware):
def __init__(self):
super().__init__()
def dispatch(self, request, call_next):
url = request.url
response = call_next(request)
response.headers.add("x-url", url)
return response
app.wsgi_app = MiddlewareManager(app)
app.wsgi_app.add_middleware(MetricsMiddleware)
#app.get("/health")
def health():
return {"message":"I'm healthy"}
if __name__ == "__main__":
app.run()
Every time you make request, it will pass the middleware
Okay, so the answer was staring me in the face the whole time, on the page on Deferred Request Callbacks.
The trick is to register a function to run after the current request using after_this_request from inside the before_request callback. This is the code snippet of what worked for me:
#app.before_request
def log_details():
method = request.method
url = request.url
#after_this_request
def log_details_callback(response: Response):
logger.info(f'method: {method}\n url: {url}\n status: {response.status}')
These are the steps:
Get the required details from the response in the before_request callback and store them in some variables.
Then access what you want of the response in the function you decorate with after_this_request, along with the variables you stored the request details in earlier.

Using web.py return a post request and do further processing after the response

I am using web.py to return a protocol buffer response from a post request and response time is critical. I have some writes to redis that I would like to do after the post response. rather than before.
r = redis.StrictRedis(host='localhost', port=6379, db=0)
class index:
def POST(self):
return pPbuffer
r.set('a','b')
So, how can I modify the code so I can I can return as quickly as possible but doing post cleanup (no pun intended).
Thanks
If you are using wsgi or something as server you could use yield to generate contents time after time and the browser will receive them in sort.
For your example:
class index:
def POST(self):
yield pPbuffer
r.set('a','b')
And this is a good example which is doing it this way.

Basic HTTP Parsing Using Twisted

I am a newcomer to the Python and Twisted game so excuse the ignorance I will likely be asking this question with. As a sort of first program, I am trying to write a basic HTTP server using twisted.web.sever which would simply print to screen the HTTP request, and then print to screen the HTTP response. I am trying to print the entire message. Here is what I have so far:
from twisted.internet import reactor
from twisted.web.server import Site
from twisted.web.resource import Resource
import time
class TestPage(Resource):
isLeaf = True
def render_GET(self, request):
response = "Success"
print "You're request was %s" % request
print "The sever's response was %s" % response
return response
resource = TestPage()
factory = Site(resource)
reactor.listenTCP(8000, factory)
reactor.run()
So far, I am having success printing the request. What I want to know is where I can access the raw response data, not just the textual message. Also, if I wanted to start parsing the request/response for information, what would be the best way to go about doing that?
Edit: I'm also new to stackoverflow, how do I get this code to display properly?
Take a look at the Request and IRequest API docs to get an idea of what that request parameter offers you. You should be able to find just about everything in the request there.
I'm not sure what you mean by raw response data though. The response is up to you to generate.

Categories