From 2f271bd3c051dd3626916b4ed6b573dfa94c450d Mon Sep 17 00:00:00 2001 From: vbot Date: Fri, 1 Jul 2022 17:14:19 +0200 Subject: [PATCH 1/3] Docs: add notes in rpc doc headers --- docs/include/rpc_introduction.rst.inc | 10 +++++++++- docs/shell/rpc_introduction.rst.inc | 12 ++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/docs/include/rpc_introduction.rst.inc b/docs/include/rpc_introduction.rst.inc index 39a5b023dd20..0e566a2fb4d8 100644 --- a/docs/include/rpc_introduction.rst.inc +++ b/docs/include/rpc_introduction.rst.inc @@ -7,7 +7,10 @@ This page describes the RPCs specific to a particular version of the Tezos proto .. warning:: - Some dynamic or plugin RPCs are not listed here due to a current limitation in the documentation generator. They are listed in the :doc:`../api/openapi` (search the ``.json`` files that are linked from that page). + This list could be missing RPC endpoints. The :doc:`OpenAPI + specification <../api/openapi>` may be used to retrieve the + complete list of protocol RPCs and their associated schemas + (search the ``.json`` files that are linked from that page). RPCs - Index ************ @@ -16,6 +19,11 @@ Note that the RPCs served under a given prefix can also be listed using the clie tezos-client rpc list /chains/main/blocks/head/context/constants +Any RPC endpoint may also be described, using the ``describe`` RPC to +retrieve all JSON and binary schemas, e.g.:: + + tezos-client rpc get /describe/chains/main/blocks/head/context/constants + Shell ===== diff --git a/docs/shell/rpc_introduction.rst.inc b/docs/shell/rpc_introduction.rst.inc index 028da9384517..acb6d7d76bf0 100644 --- a/docs/shell/rpc_introduction.rst.inc +++ b/docs/shell/rpc_introduction.rst.inc @@ -1,5 +1,12 @@ This page describes the RPCs built into the Octez shell, which are independent from a particular version of the Tezos protocol. +.. warning:: + + This list could be missing RPC endpoints. The :doc:`OpenAPI + specification <../api/openapi>` can be used to retrieve the + complete list of protocol RPCs and their associated schemas + (search the ``.json`` files that are linked from that page). + RPCs - Index ************ @@ -7,6 +14,11 @@ Note that the RPCs served under a given prefix can also be listed using the clie tezos-client rpc list /chains/main/levels +Any RPC endpoint may also be described, using the ``describe`` RPC to +retrieve all JSON and binary schemas, e.g.:: + + tezos-client rpc get /describe/chains/main/chain_id + Protocol ======== -- GitLab From d57bc8d55797788e1fa7c21009f6fdec90d9f297 Mon Sep 17 00:00:00 2001 From: vbot Date: Fri, 1 Jul 2022 17:14:44 +0200 Subject: [PATCH 2/3] Docs: fix typo in Makefile --- docs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Makefile b/docs/Makefile index 54841d6719eb..a108cbea7dd1 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -31,7 +31,7 @@ CHECKXREFS = $(SCRIPTSDIR)/check_proto_xrefs.py # Build all documentation (with CLI manuals and odoc) but without old PROTOCOLS all: odoc-lite - # Html needs the API pages for Ocaml modules, generated by odoc, because of + # Html needs the API pages for OCaml modules, generated by odoc, because of # the :package: custom roles in RST files; so run html *after* odoc ${MAKE} html -- GitLab From 5f743d6f935ec9346db835bdba927cd94f40258d Mon Sep 17 00:00:00 2001 From: vbot Date: Fri, 1 Jul 2022 18:24:28 +0200 Subject: [PATCH 3/3] Docs: refactor RPCs doc and remove costly schemas computation --- docs/doc_gen/p2p_doc.ml | 2 - docs/doc_gen/rpc_doc.ml | 287 +++++++++++++++------------------------- docs/doc_gen/rst.ml | 106 +++++++-------- 3 files changed, 155 insertions(+), 240 deletions(-) diff --git a/docs/doc_gen/p2p_doc.ml b/docs/doc_gen/p2p_doc.ml index dbe39a52365f..8229a263beaa 100644 --- a/docs/doc_gen/p2p_doc.ml +++ b/docs/doc_gen/p2p_doc.ml @@ -29,8 +29,6 @@ let protocols = let main () = (* Style : hack *) Format.printf "%a@." Rst.pp_raw_html Rst.style ; - (* Script : hack *) - Format.printf "%a@." Rst.pp_raw_html Rst.script ; (* Page title *) Format.printf "%a" Rst.pp_h1 "P2P message format" ; (* include/copy usage.rst from input *) diff --git a/docs/doc_gen/rpc_doc.ml b/docs/doc_gen/rpc_doc.ml index 5f0ac078a76d..fec3076302a1 100644 --- a/docs/doc_gen/rpc_doc.ml +++ b/docs/doc_gen/rpc_doc.ml @@ -2,6 +2,7 @@ (* *) (* Open Source License *) (* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2018-2022 Nomadic Labs, *) (* *) (* Permission is hereby granted, free of charge, to any person obtaining a *) (* copy of this software and associated documentation files (the "Software"),*) @@ -75,35 +76,25 @@ module Index = struct | Empty -> Format.fprintf ppf "Empty" | Static {services; subdirs = None} -> pp_services prefix ppf services | Static {services; subdirs = Some (Suffixes map)} -> - Format.fprintf - ppf - "@[%a@ @ %a@]" - (pp_services prefix) - services - (Format.pp_print_list - ~pp_sep:(fun ppf () -> Format.fprintf ppf "@ @ ") - (pp_suffixes prefix)) - (Resto.StringMap.bindings map) + pp_services prefix ppf services ; + pp_suffixes prefix ppf (Resto.StringMap.bindings map) | Static {services; subdirs = Some (Arg (arg, dir))} -> + pp_services prefix ppf services ; let name = Format.asprintf "<%s>" arg.name in - Format.fprintf - ppf - "@[%a@ @ %a@]" - (pp_services prefix) - services - (pp_suffixes prefix) - (name, dir) - | Dynamic _ -> Format.fprintf ppf "* %a ()" pp_name prefix + pp_suffixes prefix ppf [(name, dir)] + | Dynamic _ -> + Format.fprintf ppf "@[* %a ()@]@\n" pp_name prefix - and pp_suffixes prefix ppf (name, dir) = pp (prefix @ [name]) ppf dir + and pp_suffixes prefix ppf l = + List.iter (fun (name, dir) -> pp (prefix @ [name]) ppf dir) l - and pp_services prefix ppf services = - match Resto.MethMap.bindings services with - | [] -> Format.fprintf ppf "* %a" pp_name prefix - | _ :: _ as services -> + and pp_services prefix ppf service = + match Resto.MethMap.bindings service with + | [] -> () + | services -> Format.fprintf ppf - "* %a (@[%a@])" + "@[* %a (%a)@]@\n" pp_name prefix (Format.pp_print_list @@ -120,6 +111,10 @@ module Index = struct end module Description = struct + let pp_h ppf n content = Format.fprintf ppf "%s" n content n + + let pp_p ppf content = Format.fprintf ppf "

%s

" content + module Query = struct let pp_arg fmt = let open RPC_arg in @@ -133,7 +128,7 @@ module Description = struct | Single arg | Optional arg -> Format.fprintf ppf "[%s=%a]" name pp_arg arg | Flag -> Format.fprintf ppf "[%s]" name - | Multi arg -> Format.fprintf ppf "(%s=%a)\\*" name pp_arg arg) + | Multi arg -> Format.fprintf ppf "(%s=%a)*" name pp_arg arg) let pp_title ppf query = Format.fprintf @@ -170,9 +165,10 @@ module Description = struct match query with | [] -> () | _ :: _ as query -> + pp_h ppf 6 "Optional query arguments:" ; Format.fprintf ppf - "

Optional query arguments :

  • %a
" + "
  • %a
" (Format.pp_print_list ~pp_sep:(fun ppf () -> Format.fprintf ppf "
  • ") pp_item) @@ -180,137 +176,75 @@ module Description = struct end module Tabs = struct - let pp_tab_div ppf f = - Format.fprintf - ppf - "@[
    %a
    @]" - (fun ppf () -> f ppf) - () - - let pp_tabcontent_div ~id ~class_ ppf f = + let pp_div ?id ?classes ppf f = Format.fprintf ppf - "@[
    @ %a@ @]
    @ " + "%a" + (fun fmt -> function + | None -> () + | Some c -> Format.fprintf fmt " id=\"%s\"" c) id - class_ + (fun fmt -> function + | None -> () + | Some cl -> Format.fprintf fmt " class=\"%s\"" (String.concat " " cl)) + classes (fun ppf () -> f ppf) () - let pp_button ppf ?(default = false) ~shortlabel ~content target_ref = - Format.fprintf - ppf - "@ " - (if default then " defaultOpen" else "") - (target_ref ^ shortlabel) - target_ref - content - - let pp_content ppf ~tag ~shortlabel target_ref pp_content content = - pp_tabcontent_div - ~id:(target_ref ^ shortlabel) - ~class_:target_ref - ppf - (fun ppf -> - Format.fprintf ppf "<%s>@ %a" tag pp_content content tag) + let pp_main_description ppf content = + pp_h ppf 6 "Description" ; + let content = html_encode content in + let contents_l = Stdlib.String.trim content |> String.split '\n' in + List.iter (pp_p ppf) (List.map (Format.sprintf "%s") contents_l) let pp_description ppf (service : _ RPC_description.service) = - let open RPC_description in - (* TODO collect and display arg description (in path and in query) *) - Format.fprintf - ppf - "@[%a@]%a" - Format.(pp_print_option pp_print_text) - (Option.map html_encode service.description) - Query.pp + pp_div ~classes:["tabcontent"] ppf (fun ppf -> + (* let open RPC_description in *) + (* TODO collect and display arg description (in path and in query) *) + Format.fprintf + ppf + "@[%a%a@]" + Format.(pp_print_option pp_main_description) + service.description + Query.pp + service.query) + + let pp_dynamic_tail fmt service = + List.last_opt service.Resto.Description.path + |> Option.iter (function + | Resto.Description.PDynamicTail {name; _} -> + Format.fprintf fmt "(/<%s>)*" name + | _ -> ()) + + let pp_service_title ppf prefix service = + Format.kasprintf + html_encode + "%a%a%a" + pp_name + prefix + pp_dynamic_tail + service + Query.pp_title service.query + |> Format.fprintf ppf "%s" - let pp ppf prefix service = - let open RPC_description in - let target_ref = ref_of_service (prefix, service.meth) in + let class_of_method meth = + String.lowercase_ascii (Resto.string_of_meth meth) ^ "-meth" + + let pp ppf prefix (meth, service) = Rst.pp_html ppf (fun ppf -> - pp_tab_div ppf (fun ppf -> - pp_button - ppf - ~default:true - ~shortlabel:"descr" - ~content:"Description" - target_ref ; - Option.iter - (fun _ -> - pp_button - ppf - ~default:false - ~shortlabel:"input.json" - ~content:"Json input" - target_ref ; - pp_button + pp_div ppf (fun ppf -> + pp_div ~classes:["tab"] ppf (fun ppf -> + pp_div + ~classes:["meth"; class_of_method meth] ppf - ~default:false - ~shortlabel:"input.bin" - ~content:"Binary input" - target_ref) - service.input ; - pp_button - ppf - ~default:false - ~shortlabel:"output.json" - ~content:"Json output" - target_ref ; - pp_button - ppf - ~default:false - ~shortlabel:"output.bin" - ~content:"Binary output" - target_ref) ; - pp_content - ppf - ~tag:"p" - ~shortlabel:"descr" - target_ref - pp_description - service ; - Option.iter - (fun input -> - let schema, bin_schema = Lazy.force input in - pp_content - ppf - ~tag:"pre" - ~shortlabel:"input.json" - target_ref - Json_schema.pp - schema ; - pp_content - ppf - ~tag:"pre" - ~shortlabel:"input.bin" - target_ref - Data_encoding.Binary_schema.pp - bin_schema) - service.input ; - pp_content - ppf - ~tag:"pre" - ~shortlabel:"output.json" - target_ref - Json_schema.pp - (fst (Lazy.force service.output)) ; - pp_content - ppf - ~tag:"pre" - ~shortlabel:"output.bin" - target_ref - Data_encoding.Binary_schema.pp - (snd (Lazy.force service.output))) + (fun ppf -> + Format.pp_print_string ppf (Resto.string_of_meth meth)) ; + pp_div ~classes:["rpc-path"] ppf (fun ppf -> + pp_service_title ppf prefix service)) ; + pp_description ppf service)) end - let pp_dynamic_tail fmt service = - List.last_opt service.Resto.Description.path - |> Option.iter (function - | Resto.Description.PDynamicTail {name; _} -> - Format.fprintf fmt "(/<%s>)*" name - | _ -> ()) - let rec pp prefix ppf dir = let open Resto.Description in match dir with @@ -335,24 +269,13 @@ module Description = struct and pp_service prefix ppf (meth, service) = Rst.pp_ref ppf (ref_of_service (prefix, meth)) ; - Format.fprintf - ppf - "**%s %a%a%a**@\n@\n" - (Resto.string_of_meth meth) - pp_name - prefix - pp_dynamic_tail - service - Query.pp_title - service.query ; - Tabs.pp ppf prefix service + Format.fprintf ppf "------------@\n@\n" ; + Tabs.pp ppf prefix (meth, service) end let pp_document ppf descriptions version = (* Style : hack *) - Format.fprintf ppf "%a@." Rst.pp_raw_html Rst.style ; - (* Script : hack *) - Format.fprintf ppf "%a@." Rst.pp_raw_html Rst.script ; + Format.fprintf ppf "%a@\n" Rst.pp_raw_html Rst.style ; (* Index *) Format.pp_set_margin ppf 10000 ; Format.pp_set_max_indent ppf 9000 ; @@ -364,7 +287,7 @@ let pp_document ppf descriptions version = (* If provided, insert the introductory include *) Option.iter (Format.fprintf ppf ".. include:: %s@\n@\n") intro ; Rst.pp_h3 ppf name ; - Format.fprintf ppf "%a@\n@\n" (Index.pp prefix) rpc_dir) + Format.fprintf ppf "%a@\n" (Index.pp prefix) rpc_dir) descriptions ; (* Full description *) Rst.pp_h2 ppf "RPCs - Full description" ; @@ -379,46 +302,48 @@ let pp_document ppf descriptions version = let make_index node required_version = let open Lwt_syntax in - let shell_dir = Node.build_rpc_directory node in - let protocol_dirs = - List.map - (fun (version, name, intro, hash) -> + let dir = + if required_version = "shell" then + let shell_dir = Node.build_rpc_directory node in + ("shell", "Shell", Some "/shell/rpc_introduction.rst.inc", [""], shell_dir) + else + let make_protocol_index (version, name, intro, hash) = let hash = Protocol_hash.of_b58check_exn hash in let (module Proto) = match Registered_protocol.get hash with + | Some proto -> proto | None -> (* This is probably an indication that a line for the requested protocol is missing in the dune file of this repository *) - Format.eprintf "Hash not found: %a" Protocol_hash.pp hash ; - assert false - | Some proto -> proto + Format.kasprintf + Stdlib.failwith + "Hash not found: %a" + Protocol_hash.pp + hash + in + let open RPC_directory in + let proto_rpc_directory = + Block_directory.build_raw_rpc_directory (module Proto) (module Proto) + |> map (fun () -> assert false) in ( version, "Protocol " ^ name, intro, [".."; ""], - RPC_directory.map (fun () -> assert false) - @@ Block_directory.build_raw_rpc_directory - (module Proto) - (module Proto) )) - protocols - in - let dirs = - ("shell", "Shell", Some "/shell/rpc_introduction.rst.inc", [""], shell_dir) - :: protocol_dirs - in - let _version, name, intro, path, dir = - WithExceptions.Option.get ~loc:__LOC__ - @@ List.find - (fun (version, _name, _intro, _path, _dir) -> - version = required_version) - dirs + proto_rpc_directory ) + in + WithExceptions.Option.get ~loc:__LOC__ + @@ List.find + (fun (version, _name, _intro, _hash) -> version = required_version) + protocols + |> make_protocol_index in + let _version, name, intro, path, dir = dir in let* dir = RPC_directory.describe_directory ~recurse:true ~arg:() dir in let ppf = Format.std_formatter in pp_document ppf [(name, intro, path, dir)] required_version ; - return_ok () + return_ok_unit let make_default_acl _node = let addr_of_string addr = P2p_point.Id.{addr; port = None; peer_id = None} in diff --git a/docs/doc_gen/rst.ml b/docs/doc_gen/rst.ml index 045d2a8b157a..a4a79521a1b4 100644 --- a/docs/doc_gen/rst.ml +++ b/docs/doc_gen/rst.ml @@ -25,7 +25,7 @@ let pp_title ~char ppf title = let sub = String.map (fun _ -> char) title in - Format.fprintf ppf "@[%s@ %s@ @ @]" title sub + Format.fprintf ppf "%s@\n%s@\n@\n" title sub let pp_h1 = pp_title ~char:'#' @@ -38,13 +38,13 @@ let pp_h4 = pp_title ~char:'`' let pp_raw_html ppf str = Format.fprintf ppf - "@[.. raw:: html@ @ %s@ @ @]" + "@[.. raw:: html@\n %s@]@\n" (Re.Str.global_replace (Re.Str.regexp "\n") "\n " str) let pp_html ppf f = Format.fprintf ppf - "@[.. raw:: html@ @ %a@]@\n@\n" + "@[.. raw:: html@ @ @[%a@]@]@\n@\n" (fun ppf () -> f ppf) () @@ -53,75 +53,67 @@ let pp_ref ppf name = Format.fprintf ppf ".. _%s :@\n@\n" name let style = {css| -|css} - -let script = - {script| - -|script} +|css} -- GitLab