From 55d25c660086d9ab6e1a7750d784febe4e301252 Mon Sep 17 00:00:00 2001 From: Vincent Botbol Date: Wed, 7 Mar 2018 10:44:24 +0100 Subject: [PATCH] Docs: add rpc documentation generation --- .gitignore | 1 + docs/Makefile | 7 +- docs/conf.py | 2 +- docs/doc_gen/rpcs/jbuild | 24 ++ docs/doc_gen/rpcs/rpc_doc.ml | 633 +++++++++++++++++++++++++++++++ docs/doc_gen/rpcs/run_rpc_doc.sh | 56 +++ docs/doc_gen/rpcs/sandbox.json | 14 + docs/doc_gen/rpcs/usage.rst | 21 + docs/index.rst | 1 + 9 files changed, 757 insertions(+), 2 deletions(-) create mode 100644 docs/doc_gen/rpcs/jbuild create mode 100644 docs/doc_gen/rpcs/rpc_doc.ml create mode 100755 docs/doc_gen/rpcs/run_rpc_doc.sh create mode 100644 docs/doc_gen/rpcs/sandbox.json create mode 100644 docs/doc_gen/rpcs/usage.rst diff --git a/.gitignore b/.gitignore index 9a9c7fd37..e0f990a2c 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ __pycache__ /docs/introduction/readme.rst /docs/api/errors.rst +/docs/api/rpc.rst /docs/_extensions/*.pyc *.install diff --git a/docs/Makefile b/docs/Makefile index 1eaa81055..377089a70 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -7,6 +7,7 @@ BUILDDIR = _build DOCGENDIR = doc_gen DOCERRORDIR = $(DOCGENDIR)/errors +DOCRPCDIR = $(DOCGENDIR)/rpcs all: html linkcheck @@ -17,11 +18,15 @@ api/errors.rst: $(DOCERRORDIR)/error_doc.ml @jbuilder build $(DOCERRORDIR)/error_doc.exe ../_build/default/docs/$(DOCERRORDIR)/error_doc.exe > api/errors.rst +api/rpc.rst: $(DOCRPCDIR)/rpc_doc.ml $(DOCRPCDIR)/usage.rst $(DOCRPCDIR)/run_rpc_doc.sh + @jbuilder build $(DOCRPCDIR)/rpc_doc.exe + ./$(DOCRPCDIR)/run_rpc_doc.sh > api/rpc.rst + .PHONY: help Makefile # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -html: Makefile api/errors.rst +html: Makefile api/errors.rst api/rpc.rst @$(SPHINXBUILD) -b html "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) clean: diff --git a/docs/conf.py b/docs/conf.py index f7ab824a2..8979dcb80 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -70,7 +70,7 @@ language = None # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This patterns also effect to html_static_path and html_extra_path -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', 'usage.rst'] # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' diff --git a/docs/doc_gen/rpcs/jbuild b/docs/doc_gen/rpcs/jbuild new file mode 100644 index 000000000..bcf63758f --- /dev/null +++ b/docs/doc_gen/rpcs/jbuild @@ -0,0 +1,24 @@ +(jbuild_version 1) + +(executable + ((name rpc_doc) + (libraries + (tezos-base + tezos-rpc-http + tezos-client-base + tezos-client-commands + tezos-client-base-unix)) + (flags (:standard -w -9+27-30-32-40@8 + -safe-string + -open Tezos_base__TzPervasives + -open Tezos_rpc_http + -open Tezos_client_base + -open Tezos_client_commands + -open Tezos_client_base_unix + -linkall)) +)) + +(alias + ((name runtest_indent) + (deps ((glob_files *.ml*))) + (action (run bash ${libexec:tezos-stdlib:test-ocp-indent.sh} ${^})))) diff --git a/docs/doc_gen/rpcs/rpc_doc.ml b/docs/doc_gen/rpcs/rpc_doc.ml new file mode 100644 index 000000000..c5f504825 --- /dev/null +++ b/docs/doc_gen/rpcs/rpc_doc.ml @@ -0,0 +1,633 @@ +(**************************************************************************) +(* *) +(* Copyright (c) 2014 - 2018. *) +(* Dynamic Ledger Solutions, Inc. *) +(* *) +(* All rights reserved. No warranty, explicit or implicit, provided. *) +(* *) +(**************************************************************************) + +(* Utility functions *) + +exception Unsupported_construct + +type input = { + int : int -> int -> string option -> string list -> int ; + float : string option -> string list -> float ; + string : string option -> string list -> string ; + bool : string option -> string list -> bool ; + continue : string option -> string list -> bool ; + display : string -> unit ; +} + +open Json_schema + +(* generic JSON generation from a schema with callback for random or + interactive filling *) +let fill_in ?(show_optionals=true) input schema : ([> `A of 'a list | `Null | `O of (string * 'a) list | `String of string ] + as 'a) = + let rec element path { title ; kind }= + match kind with + | Integer { minimum ; maximum } -> + let minimum = + match minimum with + | None -> min_int + | Some (m, `Inclusive) -> int_of_float m + | Some (m, `Exclusive) -> int_of_float m + 1 in + let maximum = + match maximum with + | None -> max_int + | Some (m, `Inclusive) -> int_of_float m + | Some (m, `Exclusive) -> int_of_float m - 1 in + let i = input.int minimum maximum title path in + `Float (float i) + | Number _ -> + let f = input.float title path in + `Float f + | Boolean -> + let f = input.bool title path in + `Bool f + | String _ -> + let f = input.string title path in + `String f + | Combine ((One_of | Any_of), elts) -> + let nb = List.length elts in + let n = input.int 0 (nb - 1) (Some "Select the schema to follow") path in + element path (List.nth elts n) + | Combine ((All_of | Not), _) -> raise Unsupported_construct + | Def_ref name -> + (`String (Json_query.json_pointer_of_path name)) + | Id_ref _ | Ext_ref _ -> + raise Unsupported_construct + | Array (elts, _) -> + let rec fill_loop acc n ls = + match ls with + | [] -> acc + | elt :: elts -> + let json = element (string_of_int n :: path) elt in + fill_loop (json :: acc) (succ n) elts + in + let acc = fill_loop [] 0 elts in + (`A (List.rev acc)) + | Object { properties } -> + let properties = + if show_optionals + then properties + else (List.filter (fun (_, _, b, _) -> b) properties) in + let rec fill_loop acc ls = + match ls with + | [] -> acc + | (n, elt, _, _) :: elts -> + let json = element (n :: path) elt in + fill_loop ((n, json) :: acc) elts + in + let acc = fill_loop [] properties in + (`O (List.rev acc)) + | Monomorphic_array (elt, specs) -> + let rec fill_loop acc min n max = + if n > max then + acc + else + let json = element (string_of_int n :: path) elt in + if n < min || input.continue title path then + fill_loop (json :: acc) min (succ n) max + else (json :: acc) + in + let max = match specs.max_items with None -> max_int | Some m -> m in + let acc = fill_loop [] specs.min_items 0 max in + `A (List.rev acc) + | Any -> raise Unsupported_construct + | Dummy -> raise Unsupported_construct + | Null -> `Null + in + element [] (Json_schema.root schema) + +let random_fill_in ?(show_optionals=true) schema = + let display _ = () in + let int min max _ _ = + let max = Int64.of_int max + and min = Int64.of_int min in + let range = Int64.sub max min in + let random_int64 = Int64.add (Random.int64 range) min in + Int64.to_int random_int64 in + let string _title _ = "" in + let float _ _ = Random.float infinity in + let bool _ _ = (Random.int 2 = 0) in + let continue _ _ = (Random.int 4 = 0) in + fill_in ~show_optionals + { int ; float ; string ; bool ; display ; continue } + schema + +type service_repr = + { path : string list ; + meth : Resto.meth ; + description : string ; + input : Json_schema.schema option; + output : Json_schema.schema ; + example : string option; + error : Json_schema.schema option + } + +type service_tree = + | Root of service_tree list + | Node of service_repr * service_tree list + | SymbNode of string list * service_tree list + +let make_descr = function + | None | Some "" -> "No description" + | Some s -> s + +let repr_of_service path + RPC_description.{ description ; error ; + meth ; input ; output ; _ } : service_repr= + (* TODO? : check that json schema are not empty *) + + (* let escape_html_string str = + * let open Stringext in + * let str = replace_all str "<" "<" in + * replace_all str ">" ">" + * in + * + * let example = begin + * match input with + * | None -> None + * | Some input when input = Json_schema.any -> None + * | Some input -> begin + * let json = random_fill_in ~show_optionals:true input in + * (\* curl -X METH -H "Content-type: application/json" http://
: -d '' *\) + * + * let tezos_client_cmd_example = + * Format.asprintf "tezos-client rpc call /%s with '%s'" + * (String.concat "/" path |> escape_html_string) + * (Data_encoding.Json.to_string ~minify:true json) + * in + * let curl_cmd_example = + * Format.asprintf "curl -X %s -H \"Content-type: application/json\" http://<address>:<port>/%s -d '%s'" + * (RPC_service.string_of_meth meth) + * (String.concat "/" path |> escape_html_string) + * (Data_encoding.Json.to_string ~minify:true json) + * in + * let open Format in + * + * Some ( + * List.fold_left (fun acc s -> + * (Format.sprintf "
%s
" s) :: acc) + * [] [tezos_client_cmd_example ; curl_cmd_example] + * |> List.rev |> String.concat "or" + * ) + * + * end + * end in *) + + { path ; meth ; + description = make_descr description ; + input ; output ; + example=None ; error = Some error } + +open Format + +let pp_print_service fmt + { path ; meth } + = + fprintf fmt "%s %s" (Resto.string_of_meth meth) (String.concat "/" path) + +let rec pp_print_service_tree fmt = function + | Root l -> + fprintf fmt "@[/"; + List.iter + (fun tree -> + fprintf fmt "@ "; + fprintf fmt "%a" pp_print_service_tree tree + ) l; + fprintf fmt "@]" + | Node (repr, l) -> + fprintf fmt "@[%a" pp_print_service repr; + List.iter + (fun tree -> + fprintf fmt "@ "; + fprintf fmt "%a" pp_print_service_tree tree + ) l; + fprintf fmt "@]" + | SymbNode (sl, l) -> + fprintf fmt "@[%s" (String.concat "/" sl); + List.iter + (fun tree -> + fprintf fmt "@ "; + fprintf fmt "%a" pp_print_service_tree tree + ) l; + fprintf fmt "@]" + +let collected_args = ref [] + +let make_tree cctxt path = + (* TODO : discuss about automatic example generation *) + let collect arg = + if not (arg.RPC_arg.descr <> None && List.mem arg !collected_args) then + collected_args := arg :: !collected_args + in + let open RPC_description in + describe cctxt ~recurse:true path >>=? fun dir -> + let rec loop path : _ directory -> service_tree list = function + | Dynamic descr -> + [ Node ({ path ; meth=`POST ; + description=make_descr descr ; + input = None ; output = Json_schema.any ; + example = None ; error = None }, []) ] + + | Empty -> [] + + | Static { services ; subdirs = None } -> + let l = RPC_service.MethMap.bindings services in + let l = List.map snd l in + List.map + (fun service -> Node (repr_of_service path service, [])) + l + + | Static { services ; subdirs = Some (Suffixes subdirs) } -> + let subdirs = Resto.StringMap.bindings subdirs in + + let l = List.map (fun (name, subdir) -> + loop (path @ [ name ]) subdir + ) subdirs |> List.concat + in + + let services = RPC_service.MethMap.bindings services in + let services = List.map snd services in + + begin + match services with + | [] -> [ SymbNode (path, l) ] + | service::[] -> [ Node (repr_of_service path service, l) ] + | _ -> assert false (* ? *) + end + + | Static { services ; subdirs = Some (Arg (arg, solo)) } -> + collect arg; + let name = Printf.sprintf "<%s>" arg.RPC_arg.name in + + let services = RPC_service.MethMap.bindings services in + let services = List.map snd services in + + let l = loop (path @ [ name ]) solo in + + begin + match services with + | [] -> [ SymbNode (path, l) ] + | service::[] -> [ Node (repr_of_service path service, l) ] + | _ -> assert false (* ? *) + end + in + return (Root (loop path dir)) + +let rec pp_print_hierarchy fmt = + let open Format in + function + | Root l -> + List.iter + (fun tree -> + fprintf fmt "@ "; + fprintf fmt "%a" pp_print_hierarchy tree + ) l; + fprintf fmt "@]" + + | SymbNode (path, l) + | Node ( { path } , l) -> + if List.length path = 0 then begin + List.iter + (fun tree -> + fprintf fmt "@ "; + fprintf fmt "%a" pp_print_hierarchy tree + ) l; + fprintf fmt "@]" + end + else + begin + let name = "/" ^ List.hd (List.rev path) in + let offset = max 2 (String.length name / 2) in + + if List.length l = 0 then + pp_open_vbox fmt 0 + else + pp_open_vbox fmt offset; + + fprintf fmt "%s" name; + List.iter + (fun tree -> + fprintf fmt "@ "; + fprintf fmt "%a" pp_print_hierarchy tree) + l; + pp_close_box fmt () + end + +(**************** RST PRINTING ****************) + +let pp_print_rst_title ~char ppf title = + let sub = String.map (fun _ -> char) title in + Format.fprintf ppf "@[%s@ %s@ @]" title sub + +let pp_print_rst_h1 = pp_print_rst_title ~char:'#' +let pp_print_rst_h2 = pp_print_rst_title ~char:'*' +let pp_print_rst_h3 = pp_print_rst_title ~char:'=' +let pp_print_rst_h4 = pp_print_rst_title ~char:'`' + +let pp_print_rst_raw_html fmt str = + (* let ic = open_in file in *) + fprintf fmt "@[.. raw:: html@ @ %s@ @ @]" str + +let label_table = Hashtbl.create 17 + +let make_counter () = + let i = ref 1 in + fun () -> incr i; !i + +let count = make_counter () + +let rst_label_of_path path = + let label = Printf.sprintf "ref%d" (count ()) in + Hashtbl.add label_table path label; + "<" ^ label ^ "_>" + +let ref_of_path path = + Hashtbl.find label_table path + +let rec pp_print_rst_hierarchy fmt ~title node = + fprintf fmt "%a@ " pp_print_rst_h2 title; + let rst_name = + String.lowercase_ascii title + |> String.map (function ' ' -> '-' | x -> x) + in + let rst_name = + let rec loop str = + let open Stringext in + if find_from str ~pattern:"--" <> None then + loop (Stringext.replace_all_assoc str [("--","-")]) + else + str + in loop rst_name + in + + fprintf fmt "%a@." pp_print_rst_raw_html + (sprintf "" rst_name rst_name rst_name); + + let rec loop fmt tree = + match tree with + | Root l -> + (* fprintf fmt "@[/"; *) + fprintf fmt "@["; + List.iter + (fun tree -> + fprintf fmt "@ "; + fprintf fmt "%a" loop tree + ) l; + fprintf fmt "@]" + | Node ( { path }, l) -> + let name = "/" ^ String.concat "/" path in + fprintf fmt "@["; + fprintf fmt "`%s %s`_" name (rst_label_of_path path); + fprintf fmt "@ "; + + List.iter + (fun tree -> + fprintf fmt "@ "; + fprintf fmt "%a" loop tree + ) l; + fprintf fmt "@]" + | SymbNode (path, l) -> + if List.length path > 0 then begin + let name = "\\/" ^ String.concat "/" path in + + fprintf fmt "@[%s" name; + (* fprintf fmt "%s" name; *) + + fprintf fmt "@ "; + + List.iter + (fun tree -> + fprintf fmt "@ "; + fprintf fmt "%a" loop tree + ) l; + fprintf fmt "@]" + + end else + List.iter + (fun tree -> + fprintf fmt "@ "; + fprintf fmt "%a" loop tree + ) l + in + loop fmt node + +let pp_print_html_tab_button fmt ?(default=false) ~shortlabel ~content path = + let target_ref = ref_of_path path in + fprintf fmt "@ " + (if default then " defaultOpen" else "") + (target_ref ^ shortlabel) + target_ref + content + +let pp_print_html_tab_content fmt ~tag ~shortlabel ~pp_content ~content path = + let target_ref = ref_of_path path in + fprintf fmt "@[
@ " + (target_ref ^ shortlabel) target_ref; + fprintf fmt "<%s>@ %a@ " tag pp_content content tag; + fprintf fmt "
@]" + +let pp_print_html_tab_content_example fmt ~shortlabel ~pp_content ~content path = + let target_ref = ref_of_path path in + fprintf fmt "@[
@ %a
@]" + (target_ref ^ shortlabel) target_ref pp_content content + +let pp_print_html_tabs fmt { path ; description ; input ; output ; example ; error } = + fprintf fmt "@[.. raw:: html@ @ "; + fprintf fmt "@[
@ "; + + fprintf fmt "%a" (pp_print_html_tab_button ~default:true ~shortlabel:"descr" ~content:"Description") path; + (match input with + | Some _ -> + fprintf fmt "%a" (pp_print_html_tab_button ~default:false ~shortlabel:"input" ~content:"Input") path; + | None -> ()); + fprintf fmt "%a" (pp_print_html_tab_button ~default:false ~shortlabel:"output" ~content:"Output") path; + (match example with + | Some _ -> + fprintf fmt "%a" (pp_print_html_tab_button ~default:false ~shortlabel:"example" ~content:"Example") path; + | None -> ()); + (match error with + | Some _ -> + fprintf fmt "%a" (pp_print_html_tab_button ~default:false ~shortlabel:"error" ~content:"Errors") path; + | None -> ()); + fprintf fmt "
@]@ "; + + fprintf fmt "%a@ " (pp_print_html_tab_content ~tag:"p" ~shortlabel:"descr" + ~pp_content:pp_print_string ~content:description) path; + (match input with + | Some x -> fprintf fmt "%a@ " (pp_print_html_tab_content ~tag:"pre" ~shortlabel:"input" + ~pp_content:Json_schema.pp ~content:x) path; + | None -> ()); + fprintf fmt "%a@ " (pp_print_html_tab_content ~tag:"pre" ~shortlabel:"output" + ~pp_content:Json_schema.pp ~content:output) path; + (match example with + | Some x -> fprintf fmt "%a@ " (pp_print_html_tab_content_example ~shortlabel:"example" + ~pp_content:pp_print_string ~content:x) path; + | None -> ()); + (match error with + | Some x -> fprintf fmt "%a@ " (pp_print_html_tab_content ~tag:"pre" ~shortlabel:"error" + ~pp_content:Json_schema.pp ~content:x) path; + | None -> ()); + fprintf fmt "@]" + +let pp_print_rst_full_service fmt ({ path ; meth } as repr) = + fprintf fmt ".. _%s :@\n@\n**%s %s**@\n@\n" + (ref_of_path path) + (Resto.string_of_meth meth) + ("/" ^ String.concat "/" path); + fprintf fmt "%a" pp_print_html_tabs repr + +let rec pp_print_rst_service_tree fmt node = + let open Format in + match node with + | Root l -> (pp_print_list ~pp_sep:pp_print_cut pp_print_rst_service_tree) fmt l + | SymbNode (_, l) -> (pp_print_list ~pp_sep:pp_print_cut pp_print_rst_service_tree) fmt l + | Node ( repr , l) -> + (* Generates services details and ref for links *) + fprintf fmt "%a@\n@\n" pp_print_rst_full_service repr; + fprintf fmt "%a" (pp_print_list ~pp_sep:pp_print_newline pp_print_rst_service_tree) l + +let style = + "" + +let script = + "" + +let ppf = Format.std_formatter +let err_ppf = Format.err_formatter + +let run ?(rpc_port=18731) () = + (* Client context *) + let rpc_config = { RPC_client.default_config with port=rpc_port } in + let open Client_config in + let {block; _} = default_cli_args in + let (cctxt : #Tezos_client_base.Client_context.full) = + new Client_context_unix.unix_full ~block ~base_dir: "/" ~rpc_config + in + + let print_header () = + (* Style : hack *) + fprintf ppf "%a@." pp_print_rst_raw_html style; + (* Script : hack *) + fprintf ppf "%a@." pp_print_rst_raw_html script; + (* Page title *) + fprintf ppf "%a" pp_print_rst_h1 "Tezos RPCs"; + (* include/copy usage.rst from input *) + let rec loop () = + let s = read_line () in + fprintf ppf "%s@\n" s; + loop () + in begin try loop () with End_of_file -> () end + in + + (make_tree cctxt [] >>= function + | Ok service_tree -> + (* Print header!! *) + fprintf ppf "@\n"; + print_header (); + fprintf ppf "@\n"; + + (* Shell RPCs tree *) + fprintf ppf "%a@." (pp_print_rst_hierarchy ~title:"Client RPCs - Index") service_tree; + fprintf ppf "%a" pp_print_rst_h2 "Client RPCs - Full description"; + fprintf ppf "%a@." pp_print_rst_service_tree service_tree; + + Lwt.return 0 + + | Error _ -> + Format.eprintf "[RPC Doc Generation] Client : Couldn't reach node\n"; + Lwt.return 1) >>= function + | 0 -> + (* Alpha Protocol RPCs *) + let path_proto_alpha = String.split '/' "/blocks/head/proto" in + begin + make_tree cctxt path_proto_alpha >>= function + | Ok service_tree -> + (* TODO : replace head by ? *) + (* Proto alpha RPCs tree *) + fprintf ppf "%a@." (pp_print_rst_hierarchy ~title:"Protocol Alpha RPCs - Index") service_tree; + fprintf ppf "%a" pp_print_rst_h2 "Protocol Alpha RPCs - Full description"; + fprintf ppf "%a@." pp_print_rst_service_tree service_tree; + Lwt.return 0 + (* TODO : add dynamic parameter description *) + + | Error _ -> + Format.fprintf err_ppf "[RPC Doc Generation] Proto alpha : Couldn't reach node\n"; + Lwt.return 1 + end + | _ -> Lwt.return 1 + +let () = + Pervasives.exit + (Lwt_main.run + begin try + if Array.length Sys.argv > 1 then + let rpc_port = int_of_string Sys.argv.(1) in + run ~rpc_port () + else + run () + with _ -> + run () + end) diff --git a/docs/doc_gen/rpcs/run_rpc_doc.sh b/docs/doc_gen/rpcs/run_rpc_doc.sh new file mode 100755 index 000000000..e3ccee91f --- /dev/null +++ b/docs/doc_gen/rpcs/run_rpc_doc.sh @@ -0,0 +1,56 @@ +#!/bin/bash + +set -e +set -o pipefail + +#**************************************************************************# +#* *# +#* Copyright (c) 2014 - 2018. *# +#* Dynamic Ledger Solutions, Inc. *# +#* *# +#* All rights reserved. No warranty, explicit or implicit, provided. *# +#* *# +#**************************************************************************# + +docgen_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && echo "$(pwd -P)")" + +rpc_doc="../_build/default/docs/doc_gen/rpcs/rpc_doc.exe" + +tezos_sandboxed_node="${1:-$docgen_dir/../../../src/bin_node/tezos-sandboxed-node.sh}" +tezos_init_sandboxed_client="${3:-$docgen_dir/../../../src/bin_client/tezos-init-sandboxed-client.sh}" + +local_node="${2:-$docgen_dir/../../../_build/default/src/bin_node/main.exe}" +local_client="${2:-$docgen_dir/../../../_build/default/src/bin_client/main_client.exe}" + +sandbox_file="$docgen_dir/sandbox.json" +usage="$docgen_dir/usage.rst" + +source $tezos_sandboxed_node +source $tezos_init_sandboxed_client + +start_node() { + local id=${1:-1} + start_sandboxed_node $id + init_sandboxed_client $id + wait_for_the_node_to_be_ready + add_sandboxed_bootstrap_identities + client_instances+=("$client") + export "client$id=$client" +} + +cleanup() { + set -e + cleanup_nodes + cleanup_clients +} +trap cleanup EXIT INT + +# Default to 7 to avoid potentially running nodes +# TODO : get first available port +start_node 7 >&2 + +activate_alpha >&2 + +sleep 2 + +$rpc_doc $rpc < $usage | sed 's|/blocks/head/|/blocks//|g' diff --git a/docs/doc_gen/rpcs/sandbox.json b/docs/doc_gen/rpcs/sandbox.json new file mode 100644 index 000000000..be91a4281 --- /dev/null +++ b/docs/doc_gen/rpcs/sandbox.json @@ -0,0 +1,14 @@ +{ + "genesis_pubkey": + "edpkuSLWfVU1Vq7Jg9FucPyKmma6otcMHac9zG4oU1KMHSTBpJuGQ2", + "bootstrap_keys": [ + "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav", + "edpktzNbDAUjUk697W7gYg2CRuBQjyPxbEg8dLccYYwKSKvkPvjtV9", + "edpkuTXkJDGcFd5nh6VvMz8phXxU3Bi7h6hqgywNFi1vZTfQNnS1RV", + "edpkuFrRoDSEbJYgxRtLx2ps82UdaYc1WwfS9sE11yhauZt5DgCHbU", + "edpkv8EUUH68jmo3f7Um5PezmfGrRF24gnfLpH3sVNwJnV5bVCxL2n" + ], + "slot_durations" : [ 1, 0 ], + "cycle_length" : 128, + "first_free_baking_slot" : 4 +} diff --git a/docs/doc_gen/rpcs/usage.rst b/docs/doc_gen/rpcs/usage.rst new file mode 100644 index 000000000..27f219b63 --- /dev/null +++ b/docs/doc_gen/rpcs/usage.rst @@ -0,0 +1,21 @@ +Usage +***** + +In order to interact with a Tezos node, you may use RPC calls through the +client using this command ``tezos-client rpc call ``. + +For instance, if you wish to request the current balance of a given +block and contract, you can call the associated RPC via the command : +``$ tezos-client rpc call +/blocks//proto/context/contracts//balance``. + +A RPC may takes an *input* and generates an *output* both in JSON +format. For example, the previous RPC call, that does not require an +input, would display on the standard output : ``{ "balance": +"4000000000000" }``. When calling a RPC that requires an input +through command-line, you will be prompted to provide the JSON input +in your default configured text editor. + +In the following sections, you may find the complete list of RPCs +available for the client and for the protocol Alpha. You may also find +input, output and errors JSON schema. diff --git a/docs/index.rst b/docs/index.rst index 626a408bf..e113e5100 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -84,6 +84,7 @@ license when the main network lunches. api/api-inline api/cli-commands api/errors + api/rpc Indices and tables ==================