in compiler/cpp/src/thrift/generate/t_py_generator.cc [1724:1921]
void t_py_generator::generate_service_remote(t_service* tservice) {
vector<t_function*> functions = tservice->get_functions();
// Get all function from parents
t_service* parent = tservice->get_extends();
while (parent != nullptr) {
vector<t_function*> p_functions = parent->get_functions();
functions.insert(functions.end(), p_functions.begin(), p_functions.end());
parent = parent->get_extends();
}
vector<t_function*>::iterator f_iter;
string f_remote_name = package_dir_ + "/" + service_name_ + "-remote";
ofstream_with_content_based_conditional_update f_remote;
f_remote.open(f_remote_name.c_str());
f_remote <<
"#!/usr/bin/env python" << '\n' <<
py_autogen_comment() << '\n' <<
"import sys" << '\n' <<
"import pprint" << '\n' <<
"if sys.version_info[0] > 2:" << '\n' <<
indent_str() << "from urllib.parse import urlparse" << '\n' <<
"else:" << '\n' <<
indent_str() << "from urlparse import urlparse" << '\n' <<
"from thrift.transport import TTransport, TSocket, TSSLSocket, THttpClient" << '\n' <<
"from thrift.protocol.TBinaryProtocol import TBinaryProtocol" << '\n' << '\n';
f_remote <<
"from " << module_ << " import " << service_name_ << '\n' <<
"from " << module_ << ".ttypes import *" << '\n' << '\n';
f_remote <<
"if len(sys.argv) <= 1 or sys.argv[1] == '--help':" << '\n' <<
indent_str() << "print('')" << '\n' <<
indent_str() << "print('Usage: ' + sys.argv[0] + ' [-h host[:port]] [-u url] [-f[ramed]] [-s[sl]] [-novalidate] [-ca_certs certs] [-keyfile keyfile] [-certfile certfile] function [arg1 [arg2...]]')" << '\n' <<
indent_str() << "print('')" << '\n' <<
indent_str() << "print('Functions:')" << '\n';
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
f_remote << indent_str() << "print(' " << (*f_iter)->get_returntype()->get_name() << " "
<< (*f_iter)->get_name() << "(";
t_struct* arg_struct = (*f_iter)->get_arglist();
const std::vector<t_field*>& args = arg_struct->get_members();
std::vector<t_field*>::size_type num_args = args.size();
bool first = true;
for (std::vector<t_field*>::size_type i = 0; i < num_args; ++i) {
if (first) {
first = false;
} else {
f_remote << ", ";
}
f_remote << args[i]->get_type()->get_name() << " " << args[i]->get_name();
}
f_remote << ")')" << '\n';
}
f_remote << indent_str() << "print('')" << '\n' << indent_str() << "sys.exit(0)" << '\n' << '\n';
f_remote << "pp = pprint.PrettyPrinter(indent=2)" << '\n'
<< "host = 'localhost'" << '\n'
<< "port = 9090" << '\n'
<< "uri = ''" << '\n'
<< "framed = False" << '\n'
<< "ssl = False" << '\n'
<< "validate = True" << '\n'
<< "ca_certs = None" << '\n'
<< "keyfile = None" << '\n'
<< "certfile = None" << '\n'
<< "http = False" << '\n'
<< "argi = 1" << '\n'
<< '\n'
<< "if sys.argv[argi] == '-h':" << '\n'
<< indent_str() << "parts = sys.argv[argi + 1].split(':')" << '\n'
<< indent_str() << "host = parts[0]" << '\n'
<< indent_str() << "if len(parts) > 1:" << '\n'
<< indent_str() << indent_str() << "port = int(parts[1])" << '\n'
<< indent_str() << "argi += 2" << '\n'
<< '\n'
<< "if sys.argv[argi] == '-u':" << '\n'
<< indent_str() << "url = urlparse(sys.argv[argi + 1])" << '\n'
<< indent_str() << "parts = url[1].split(':')" << '\n'
<< indent_str() << "host = parts[0]" << '\n'
<< indent_str() << "if len(parts) > 1:" << '\n'
<< indent_str() << indent_str() << "port = int(parts[1])" << '\n'
<< indent_str() << "else:" << '\n'
<< indent_str() << indent_str() << "port = 80" << '\n'
<< indent_str() << "uri = url[2]" << '\n'
<< indent_str() << "if url[4]:" << '\n'
<< indent_str() << indent_str() << "uri += '?%s' % url[4]" << '\n'
<< indent_str() << "http = True" << '\n'
<< indent_str() << "argi += 2" << '\n'
<< '\n'
<< "if sys.argv[argi] == '-f' or sys.argv[argi] == '-framed':" << '\n'
<< indent_str() << "framed = True" << '\n'
<< indent_str() << "argi += 1" << '\n'
<< '\n'
<< "if sys.argv[argi] == '-s' or sys.argv[argi] == '-ssl':" << '\n'
<< indent_str() << "ssl = True" << '\n'
<< indent_str() << "argi += 1" << '\n'
<< '\n'
<< "if sys.argv[argi] == '-novalidate':" << '\n'
<< indent_str() << "validate = False" << '\n'
<< indent_str() << "argi += 1" << '\n'
<< '\n'
<< "if sys.argv[argi] == '-ca_certs':" << '\n'
<< indent_str() << "ca_certs = sys.argv[argi+1]" << '\n'
<< indent_str() << "argi += 2" << '\n'
<< '\n'
<< "if sys.argv[argi] == '-keyfile':" << '\n'
<< indent_str() << "keyfile = sys.argv[argi+1]" << '\n'
<< indent_str() << "argi += 2" << '\n'
<< '\n'
<< "if sys.argv[argi] == '-certfile':" << '\n'
<< indent_str() << "certfile = sys.argv[argi+1]" << '\n'
<< indent_str() << "argi += 2" << '\n'
<< '\n'
<< "cmd = sys.argv[argi]" << '\n'
<< "args = sys.argv[argi + 1:]" << '\n'
<< '\n'
<< "if http:" << '\n'
<< indent_str() << "transport = THttpClient.THttpClient(host, port, uri)" << '\n'
<< "else:" << '\n'
<< indent_str() << "if ssl:" << '\n'
<< indent_str() << indent_str() << "socket = TSSLSocket.TSSLSocket(host, port, "
"validate=validate, ca_certs=ca_certs, keyfile=keyfile, certfile=certfile)"
<< '\n'
<< indent_str() << "else:" << '\n'
<< indent_str() << indent_str() << "socket = TSocket.TSocket(host, port)" << '\n'
<< indent_str() << "if framed:" << '\n'
<< indent_str() << indent_str() << "transport = TTransport.TFramedTransport(socket)" << '\n'
<< indent_str() << "else:" << '\n'
<< indent_str() << indent_str() << "transport = TTransport.TBufferedTransport(socket)" << '\n'
<< "protocol = TBinaryProtocol(transport)" << '\n'
<< "client = " << service_name_ << ".Client(protocol)" << '\n'
<< "transport.open()" << '\n'
<< '\n';
// Generate the dispatch methods
bool first = true;
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
if (first) {
first = false;
} else {
f_remote << "el";
}
t_struct* arg_struct = (*f_iter)->get_arglist();
const std::vector<t_field*>& args = arg_struct->get_members();
std::vector<t_field*>::size_type num_args = args.size();
f_remote << "if cmd == '" << (*f_iter)->get_name() << "':" << '\n';
indent_up();
f_remote << indent() << "if len(args) != " << num_args << ":" << '\n'
<< indent() << indent_str() << "print('" << (*f_iter)->get_name() << " requires " << num_args
<< " args')" << '\n'
<< indent() << indent_str() << "sys.exit(1)" << '\n'
<< indent() << "pp.pprint(client." << (*f_iter)->get_name() << "(";
indent_down();
bool first_arg = true;
for (std::vector<t_field*>::size_type i = 0; i < num_args; ++i) {
if (first_arg)
first_arg = false;
else
f_remote << " ";
if (args[i]->get_type()->is_string()) {
f_remote << "args[" << i << "],";
} else {
f_remote << "eval(args[" << i << "]),";
}
}
f_remote << "))" << '\n';
f_remote << '\n';
}
if (functions.size() > 0) {
f_remote << "else:" << '\n';
f_remote << indent_str() << "print('Unrecognized method %s' % cmd)" << '\n';
f_remote << indent_str() << "sys.exit(1)" << '\n';
f_remote << '\n';
}
f_remote << "transport.close()" << '\n';
// Close service file
f_remote.close();
#ifndef _MSC_VER
// Make file executable, love that bitwise OR action
chmod(f_remote_name.c_str(),
S_IRUSR | S_IWUSR | S_IXUSR
#ifndef _WIN32
| S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH
#endif
);
#endif // _MSC_VER
}