Package: thrift-explorer
Thrift ExplorerApache Thriftis a language agnostic framework that enables typed communication between services.Thrift explorer is intended to be a tool aimed at developers who use thrift services. Enabling the user to explore their services without having to write or maintain any code.This project is alphaI am still finding fundemental issues with the implementation and am working though them. Slowly but surelyHow does this workYou place your service thrifts in a directory and configure Thrift Explorer to pull from it. Then make http calls to Thrift Explorer providing information such as host/port and
it will forward your request to it and return the response.Example UsageExample calls are provided as part of aPostman Collection. However, Lets walk though a basic session.If you are working on a todo thrift service that you have running on your machine you can use thrift explorer to make calls to it. With the todo server running you
add the todo thrifts to thrift explorer and start the server. (I will be usingcurlto make requests andjqto pretty print the responses)You can see what services are loadedcurl-Sslocalhost:5000|jq'.'{"thrifts":[{"thrift":"Batman.thrift","service":"BatPuter","methods":["ping","getVillain","addVillain","saveCase"]},{"thrift":"todo.thrift","service":"TodoService","methods":["ping","listTasks","numTasks","getTask","createTask","completeTask","fancyNewMethod"]}]}List the methods of a particular servicecurl-Sslocalhost:5000/todo/TodoService/|jq'.'{"thrift":"todo.thrift","service":"TodoService","methods":["ping","listTasks","numTasks","getTask","createTask","completeTask","fancyNewMethod"]}Make a call to one of the methods of that service (the response is in the "data" field of the response body)curl-Ss-XPOST\http://localhost:5000/todo/TodoService/createTask/ \-H'Content-Type:application/json'\-d'{"host":"localhost","port":6000,"protocol":"tbinaryprotocol","transport":"tbufferedtransport","request_body":{"description":"task 1","dueDate":"12-12-2012"}}'|jq"."{"status":"Success","request":{"thrift_file":"todo.thrift","service_name":"TodoService","endpoint_name":"createTask","host":"localhost","port":6000,"protocol":"tbinaryprotocol","transport":"tbufferedtransport","request_body":{"description":"task 1","dueDate":"12-12-2012"}},"data":{"__thrift_struct_class__":"Task","taskId":"1","description":"task 1","dueDate":"12-12-2012"},"time_to_make_request":"0:00:00.008794","time_to_connect":"0:00:00.001502"}and just for fun we will make another callcurl-Ss-XPOST\http://localhost:5000/todo/TodoService/getTask/ \-H'Content-Type:application/json'\-d'{"host":"localhost","port":6000,"protocol":"tbinaryprotocol","transport":"tbufferedtransport","request_body":{"taskId":"1"}}'|jq"."{"status":"Success","request":{"thrift_file":"todo.thrift","service_name":"TodoService","endpoint_name":"getTask","host":"localhost","port":6000,"protocol":"tbinaryprotocol","transport":"tbufferedtransport","request_body":{"taskId":"1"}},"data":{"__thrift_struct_class__":"Task","taskId":"1","description":"task 1","dueDate":"12-12-2012"},"time_to_make_request":"0:00:00.001283","time_to_connect":"0:00:00.000554"}If you make a mistake making a request thrift explorer tries to be helpful telling you the mistake you madecurl-sS-XPOST\http://localhost:5000/todo/TodoService/completeTask/ \-d'{"host":"localhost","port":6000,"protocol":"tbinaryprotocol","transport":"tbufferedtransport","request_body":{"description":"task 1"}}'|jq'.'{"errors":[{"code":"ErrorCode.REQUIRED_FIELD_MISSING","message":"Required Field 'taskId' not found","arg_spec":{"name":"taskId","required":true,"type_info":{"ttype":"string"},},}]}and if you just want to get the thrift itself you can do that tocurl-Sslocalhost:5000/todo/include"basethrifts/Exceptions.thrift"structTask{1:optionalstringtaskId;2:optionalstringdescription;3:optionalstringdueDate;}serviceTodoService{voidping();list<Task>listTasks();i64numTasks();TaskgetTask(1:stringtaskId)throws(1:Exceptions.NotFoundnotfound);TaskcreateTask(1:stringdescription,2:stringdueDate);voidcompleteTask(1:requiredstringtaskId)throws(1:Exceptions.NotFoundnotfound);voidfancyNewMethod();// Not implemented by the server to simulate that kind of error}Installation and Running the serverInstallation with pipIf you are comfortable with python environments and python packaging you can install this with pip. I suggest using a virtual environment.pip install thrift-explorerThen you may either use the flask development server or you can install a wsgi server. I am going to use gunicornpip install gunicornThen you set the environment variables you will use to configure the server. SeeConfiguring the serverfor details. At a minimum you must set THRIFT_DIRECTORYexport THRIFT_DIRECTORY=$(pwd)/example-thrifts/Then start it!gunicorn -b 127.0.0.1:5000 thrift_explorer.wsgi
[2018-10-07 12:01:30 -0400] [7864] [INFO] Starting gunicorn 19.9.0
[2018-10-07 12:01:30 -0400] [7864] [INFO] Listening at: http://127.0.0.1:5000 (7864)
[2018-10-07 12:01:30 -0400] [7864] [INFO] Using worker: sync
[2018-10-07 12:01:30 -0400] [7867] [INFO] Booting worker with pid: 7867Installation with dockerIf you would rather not work with the python directly you can pull down a docker containerdocker pull bachmann1234/thrift-explorerWhen running the docker container you are going to need to pass in a directory containing the thrifts the server will load in.
This will be provided via the source parameter. In the example below I pass in the example-thrifts directory in this very repodocker run --mount type=bind,source=$(pwd)/example-thrifts,target=/thrifts -p 5000:80 bachmann1234/thrift-explorerIn english this command is saying "run the thrift-explorer server with example-thrifts as its thrift directory. Make it so that server is accessible to me at port 8000". You can also
pass in other environment variables in this command to configure the server. SeeConfiguring the serverfor details.For a more detailed explanation of the docker commandconsult the docker documentationOne gotcha: When using the docker container you need to be mindful of how networking works with docker. For example. If you are running thrift-explorer with the docker container
and you need it to access a service running on your localhost you would use the hostname "host.docker.internal" (at least on docker-for-mac). For examplecurl-Ss-XPOST\http://localhost:4000/todo/TodoService/createTask/ \-H'Content-Type:application/json'\-d'{"host":"host.docker.internal","port":6000,"protocol":"tbinaryprotocol","transport":"tbufferedtransport","request_body":{"description":"task 1","dueDate":"12-12-2012"}}'|jq"."{"status":"Success","request":{"thrift_file":"todo.thrift","service_name":"TodoService","endpoint_name":"createTask","host":"host.docker.internal","port":6000,"protocol":"tbinaryprotocol","transport":"tbufferedtransport","request_body":{"description":"task 1","dueDate":"12-12-2012"}},"data":{"__thrift_struct_class__":"Task","taskId":"2","description":"task 1","dueDate":"12-12-2012"},"time_to_make_request":"0:00:00.012562","time_to_connect":"0:00:00.001214"}Configuring the serverThe service is configured via environment variablesVariableDescriptionDefaultRequiredTHRIFT_DIRECTORYThe directory where the thrifts you want the server to be aware of are storedYesDEFAULT_THRIFT_PROTOCOLWhat thrift protocol should the server assume if one is not providedTBinaryProtocolNoDEFAULT_THRIFT_TRANSPORTWhat thrift transport should the server assume if one is not providedTBufferedTransportNoRunning the example thrift serverThis repo contains some example thrifts and one example thrift service. SeeTodo Thriftfor a service definition.To run it just set your pythonpath appropriately (seeMy environmentfor how I setup my environment (I use fish shell)). Then runpython tests/todoserver/service.pyThis service is intended as a development/testing aid. It is not required for using thrift explorer