Package: yapi-ci
Description of yapiIt allows to use declarative language (yaml) to talk to APIs and to save the response for future ones.The main use case is to talk toHashiCorp Vault API.It is heavily based onTavern-ciInstalling itpip install yapi-ciHow to use itFor this example we will usehttp://httpbin.org/putasVAULT_ADDR, this service will echo everything we send plus extra information about our request.2019-11-2017:09:18,736[None][INFO]Startingyapi0.1.62019-11-2017:09:18,743[None][INFO]Loadingexamples/vault-init.yaml2019-11-2017:09:18,743[None][INFO]Stage:01-InitVault2019-11-2017:09:18,744[01-InitVault][INFO]->URL:http://httpbin.org/put2019-11-2017:09:18,744[01-InitVault][INFO]->Method:PUT2019-11-2017:09:18,745[01-InitVault][INFO]->Body:{"mykeys":["7f921414b13ad05eb844dc349423765d857e8175b48c5854ada0e24e96924ac2"],"secret_shares":1,"secret_threshold":1}2019-11-2017:09:18,934[01-InitVault][INFO]<-ReceivedstatuscodeOK200==2002019-11-2017:09:18,935[01-InitVault][INFO]<-Bodyofresponse:{..."headers":{"Accept-Encoding":"identity","Content-Length":"123","Content-Type":"application/json","Host":"httpbin.org"},"json":{"mykeys":["7f921414b13ad05eb844dc349423765d857e8175b48c5854ada0e24e96924ac2"],"secret_shares":1,"secret_threshold":1},...}2019-11-2017:09:18,936[01-InitVault][INFO]Writingtoexamples/data/primary/init.json2019-11-2017:09:18,937[None][INFO]Savedresponsevariables:{'headers':{'Accept-Encoding':'identity','Content-Length':'123','Content-Type':'application/json','Host':'httpbin.org'},'json_full':{'mykeys':['7f921414b13ad05eb844dc349423765d857e8175b48c5854ada0e24e96924ac2'],'secret_shares':1,'secret_threshold':1},'json_keys_list':['7f921414b13ad05eb844dc349423765d857e8175b48c5854ada0e24e96924ac2'],'json_secret_shares':1}2019-11-2017:09:18,938[None][INFO]Endofstage:01-InitVault2019-11-2017:09:18,938[None][INFO]Stage:02-UnsealVault2019-11-2017:09:18,942[02-UnsealVault][INFO]Readingexamples/data/primary/init.json,sub_vars:True2019-11-2017:09:18,945[02-UnsealVault][INFO]->URL:http://httpbin.org/put2019-11-2017:09:18,945[02-UnsealVault][INFO]->Method:PUT2019-11-2017:09:18,945[02-UnsealVault][INFO]->Body:{"json_full":{"mykeys":["7f921414b13ad05eb844dc349423765d857e8175b48c5854ada0e24e96924ac2"],"secret_shares":1,"secret_threshold":1},"json_keys_list":"7f921414b13ad05eb844dc349423765d857e8175b48c5854ada0e24e96924ac2","json_secret_shares":"test string 1","myheaders":{"Accept-Encoding":"identity","Content-Length":"123","Content-Type":"application/json","Host":"httpbin.org"},"mykeys":["7f921414b13ad05eb844dc349423765d857e8175b48c5854ada0e24e96924ac2"]}2019-11-2017:09:19,138[02-UnsealVault][INFO]<-ReceivedstatuscodeOK200==2002019-11-2017:09:19,139[02-UnsealVault][INFO]<-Bodyofresponse:{..."headers":{"Accept-Encoding":"identity","Content-Length":"473","Content-Type":"application/json","Host":"httpbin.org"},"json":{"json_full":{"mykeys":["7f921414b13ad05eb844dc349423765d857e8175b48c5854ada0e24e96924ac2"],"secret_shares":1,"secret_threshold":1},"json_keys_list":"7f921414b13ad05eb844dc349423765d857e8175b48c5854ada0e24e96924ac2","json_secret_shares":"test string 1","myheaders":{"Accept-Encoding":"identity","Content-Length":"123","Content-Type":"application/json","Host":"httpbin.org"},"mykeys":["7f921414b13ad05eb844dc349423765d857e8175b48c5854ada0e24e96924ac2"]},...}2019-11-2017:09:19,140[02-UnsealVault][INFO]Writingtoexamples/data/primary/unsealed_response.json2019-11-2017:09:19,141[None][INFO]Endofstage:02-UnsealVault2019-11-2017:09:19,141[None][INFO]Finishedexamples/vault-init.yamlExample file vault-init.yaml---stages:-name:01-Init Vaultrequest:url:"{env_vars.VAULT_ADDR}"method:PUTjson:secret_shares:1secret_threshold:1mykeys:-7f921414b13ad05eb844dc349423765d857e8175b48c5854ada0e24e96924ac2response:status_code:200save:$ext:function:extensions.save_responseextra_kwargs:path:"examples/data/{env_vars.VAULT_CLUSTER}/init.json"body:headers:headersjson_keys_list:json.mykeysjson_secret_shares:json.secret_sharesjson_full:json-name:02-Unseal Vaultrequest:url:"{env_vars.VAULT_ADDR}"method:PUTjson:mykeys:"ext.json.mykeys.to_list()"myheaders:"resp.headers.to_dict()"json_keys_list:"resp.json_keys_list.to_list()[0]"json_secret_shares:"teststring{resp.json_secret_shares}"json_full:"resp.json_full.to_dict()"$ext:function:extensions.read_jsonextra_kwargs:path:"examples/data/{env_vars.VAULT_CLUSTER}/init.json"sub_vars:Trueresponse:status_code:200save:$ext:function:extensions.save_responseextra_kwargs:path:"examples/data/{env_vars.VAULT_CLUSTER}/unsealed_response.json"The first stage called01-Init Vaultenv_vars.VAULT_ADDRwill be replaced by the enviromental variable$VAULT_ADDRas is the same with all variables starting withenv_vars.Do aGETcall tourlThe json sent to the API will be:{"mykeys":["7f921414b13ad05eb844dc349423765d857e8175b48c5854ada0e24e96924ac2"],"secret_shares":1,"secret_threshold":1}It expects a HTTP response of200or it will error out.It will save the output of the response as a json file underdata/{env_vars.VAULT_CLUSTER}/init.jsonIt will try to convert the response to json and save them in variables for the next stage:response:...body:headers:headersjson_keys_list:json.mykeysjson_secret_shares:json.secret_sharesjson_full:jsonThe second stage called02-Unseal VaultReplace replace variables that start with{env_vars.}with environmental variables.Insert the variables saved in previous stages fromresp.converting them to a python dictionary or list depending if we want a json object or array.Variables that have{}are used toformatthe string instead of replacing it with its value.json:mykeys:"ext.json.mykeys.to_list()"myheaders:"resp.headers.to_dict()"json_keys_list:"resp.json_keys_list.to_list()[0]"json_secret_shares:"teststring{resp.json_secret_shares}"json_full:"resp.json_full.to_dict()"Readdata/{env_vars.VAULT_CLUSTER}/init.jsonand replace variables that start withext.in the body with data from the json whensub_varsis set toTrue."json":{"mykeys":["7f921414b13ad05eb844dc349423765d857e8175b48c5854ada0e24e96924ac2"],Becomes:mykeys:"ext.json.mykeys.to_list()"Do aPUTcall tourlWith the json:{"json_full":{"mykeys":["7f921414b13ad05eb844dc349423765d857e8175b48c5854ada0e24e96924ac2"],"secret_shares":1,"secret_threshold":1},"json_keys_list":"7f921414b13ad05eb844dc349423765d857e8175b48c5854ada0e24e96924ac2","json_secret_shares":"test string 1","myheaders":{"Accept-Encoding":"identity","Content-Length":"123","Content-Type":"application/json","Host":"httpbin.org"},"mykeys":["7f921414b13ad05eb844dc349423765d857e8175b48c5854ada0e24e96924ac2"]}It will expect a200response code or error out.It will save the response todata/{env_vars.VAULT_CLUSTER}/unsealed_response.jsonTODOAdd Automated testingAdd version taggingAdd package automatic building from tags