cic-stack/apps/cic-eth/cic_eth/callbacks/http.py

65 lines
1.7 KiB
Python

# standard imports
import json
import ssl
import os
import urllib
from urllib import request
from urllib.request import urlopen
# third-party imports
from . import Callback
import celery
celery_app = celery.current_app
logg = celery_app.log.get_default_logger()
@celery_app.task(base=Callback, bind=True)
def http(self, result, url, status_code):
"""A generic web callback implementation for task results.
Input parameters depend on whether the callback is used as an error callback, or as a part of a celery chain.
The callback receives:
{
'root_id': the uuid of the topmost task in the chain, which is known to the API caller.
'status': <status_code>,
'result': <result>,
}
:param result: Task context object (on error) or return value of previous task (on success)
:type result: Varies
:param url: Url to HTTP POST results to
:type url: str
:param status_code: 0 on success, any other value is error
:type status_code: int
"""
req = request.Request(url)
data = {
'root_id': self.request.root_id,
'status': status_code,
'result': result,
}
data_str = json.dumps(data)
data_bytes = data_str.encode('utf-8')
req.add_header('Content-Type', 'application/json')
req.data = data_bytes
ctx = None
if self.ssl:
ctx = ssl.SSLContext()
ctx.load_cert_chain(
self.ssl_cert_file,
self.ssl_key_file,
self.ssl_password,
)
response = urlopen(
req,
context=ctx,
)
if response.status != 200:
raise RuntimeError('Expected status 200 from remote server, but got {} {}'.format(response.status, response.msg))