Passed
Pull Request — master (#1269)
by
unknown
03:10
created

ClientCallbackHandler.do_POST()   A

Complexity

Conditions 1

Size

Total Lines 11
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 10
dl 0
loc 11
rs 9.9
c 0
b 0
f 0
cc 1
nop 1
1
import click
2
from http.server import BaseHTTPRequestHandler, HTTPServer
3
from typing import Optional
4
5
from ocrd.decorators import parameter_option
6
from ocrd_network import Client
7
from ocrd_utils import DEFAULT_METS_BASENAME
8
9
10
STOP_WAITING_CALLBACK = False
11
12
13
class ClientCallbackHandler(BaseHTTPRequestHandler):
14
    """
15
    A simple callback handler for the network client to be invoked when the Processing Worker
16
    sends requests to the `callback_url` set in the processing request submitted to the Processing Server.
17
    """
18
19
    def do_POST(self):
20
        self.send_response(200)
21
        self.send_header("Content-Type", "text/plain")
22
        self.end_headers()
23
        self.wfile.write("finished".encode("utf-8"))
24
        len = int(self.headers.get("Content-Length", 0))
25
        data = self.rfile.read(len).decode("utf-8")
26
        # TODO: how should the callback-content be handled/printed
27
        print(f"Processor finished: {data}")
28
        global STOP_WAITING_CALLBACK
29
        STOP_WAITING_CALLBACK = True
30
31
32
class ClientCallbackServer(HTTPServer):
33
    """
34
    A simple http-server that listens for callbacks from the Processing Server/Worker.
35
    """
36
    def __init__(self):
37
        super().__init__(server_address=("0.0.0.0", 0), RequestHandlerClass=ClientCallbackHandler)
38
        self.callback_url = f"http://172.17.0.1:{self.server_address[1]}"
39
40
41
@click.group('client')
42
def client_cli():
43
    """
44
    A client for interacting with the network modules.
45
    The client CLI mimics the WebAPI endpoints
46
    """
47
    pass
48
49
50
@client_cli.group('discovery')
51
def discovery_cli():
52
    """
53
    The discovery endpoint of the WebAPI
54
    """
55
    pass
56
57
58
@client_cli.group('processing')
59
def processing_cli():
60
    """
61
    The processing endpoint of the WebAPI
62
    """
63
    pass
64
65
66
@processing_cli.command('processor')
67
@click.argument('processor_name', required=True, type=click.STRING)
68
@click.option('--address')
69
@click.option('-m', '--mets', required=True, default=DEFAULT_METS_BASENAME)
70
@click.option('-I', '--input-file-grp', default='OCR-D-INPUT')
71
@click.option('-O', '--output-file-grp', default='OCR-D-OUTPUT')
72
@click.option('-g', '--page-id')
73
@parameter_option
74
@click.option('--result-queue-name')
75
@click.option('--callback-url')
76
@click.option('--agent-type', default='worker')
77
def send_processing_request(
78
    address: Optional[str],
79
    processor_name: str,
80
    mets: str,
81
    input_file_grp: str,
82
    output_file_grp: Optional[str],
83
    page_id: Optional[str],
84
    parameter: Optional[dict],
85
    result_queue_name: Optional[str],
86
    callback_url: Optional[str],
87
    # TODO: This is temporally available to toggle
88
    #  between the ProcessingWorker/ProcessorServer
89
    agent_type: Optional[str]
90
):
91
    callback_server = ClientCallbackServer()
92
    req_params = {
93
        "path_to_mets": mets,
94
        "description": "OCR-D Network client request",
95
        "input_file_grps": input_file_grp.split(','),
96
        "parameters": parameter if parameter else {},
97
        "agent_type": agent_type,
98
        "callback_url": callback_server.callback_url
99
    }
100
    if output_file_grp:
101
        req_params["output_file_grps"] = output_file_grp.split(',')
102
    if page_id:
103
        req_params["page_id"] = page_id
104
    if result_queue_name:
105
        req_params["result_queue_name"] = result_queue_name
106
    if callback_url:
107
        req_params["callback_url"] = callback_url
108
109
    client = Client(server_addr_processing=address)
110
    response = client.send_processing_request(processor_name=processor_name, req_params=req_params)
111
    processing_job_id = response.get('job_id', None)
112
    print(f"Processing job id: {processing_job_id}")
113
    while not STOP_WAITING_CALLBACK:
114
        callback_server.handle_request()
115
116
117
@client_cli.group('workflow')
118
def workflow_cli():
119
    """
120
    The workflow endpoint of the WebAPI
121
    """
122
    pass
123
124
125
@client_cli.group('workspace')
126
def workspace_cli():
127
    """
128
    The workspace endpoint of the WebAPI
129
    """
130
    pass
131