api-hogs / bureaucrat Goto Github PK
View Code? Open in Web Editor NEWGenerate Phoenix API documentation from tests
Home Page: https://hexdocs.pm/bureaucrat/api-reference.html
License: The Unlicense
Generate Phoenix API documentation from tests
Home Page: https://hexdocs.pm/bureaucrat/api-reference.html
License: The Unlicense
Hello ๐
I updated the library to 0.2.1
and used the ApiBlueprintWriter
and everything went smoothly. I have the API documentation generated and it's working well with aglio.
I just wanted to report that I got this error after everything was finished:
10:58:40.116 [error] GenServer #PID<0.4398.0> terminating
** (stop) exited in: GenServer.call(Bureaucrat.Recorder, :get_records, 5000)
** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
(elixir) lib/gen_server.ex:820: GenServer.call/3
(bureaucrat) lib/bureaucrat/formatter.ex:20: Bureaucrat.Formatter.generate_docs/0
(bureaucrat) lib/bureaucrat/formatter.ex:10: Bureaucrat.Formatter.handle_cast/2
(stdlib) gen_server.erl:616: :gen_server.try_dispatch/4
(stdlib) gen_server.erl:686: :gen_server.handle_msg/6
(stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3
Last message: {:"$gen_cast", {:suite_finished, 178304628, nil}}
Finished in 178.3 seconds
585 tests, 0 failures
Randomized with seed 750804
If in a swagger file we have a parameter that references another schema (model) like this:
"paths": {
"/some_resource": {
"post": {
"description": "Create new new resource",
"operationId": "create_resource",
"parameters": [{
"description": "Resource object",
"in": "body",
"name": "resource",
"required": false,
"schema": {
"$ref": "#/definitions/Resource"
}
}],
...
}
}
}
then the resulting markdown won't contain the link to the schema:
...
#### Parameters
| Parameter | Description | In |Type | Required | Default | Example |
|-------------|-------------|----|----------|----------|---------|---------|
|resource|Resource object|body||false|||
...
Note that the Type
column is empty. Instead, it should equal to [Resource](#resource)
.
hi i am getting this error
my test-helper code
`Bureaucrat.start(
env_var: "DOC",
writer: Bureaucrat.SwaggerSlateMarkdownWriter,
default_path: "doc/source/index.html.md",
swagger: "priv/static/swagger.json"
|> File.read!()
|> Poison.decode!()
)
ExUnit.start(formatters: [ ExUnit.CLIFormatter,Bureaucrat.Formatter ])`
in conn case
import Bureaucrat.Helpers
** (FunctionClauseError) no function clause matching in Code.ensure_loaded?/1
The following arguments were given to Code.ensure_loaded?/1:
# 1
10
Attempted function clauses (showing 1 out of 1):
def ensure_loaded?(module) when is_atom(module)
(elixir) lib/code.ex:869: Code.ensure_loaded?/1
(ecto) lib/ecto/adapters/sql.ex:339: Ecto.Adapters.SQL.normalize_pool/1
(elixir) lib/keyword.ex:831: Keyword.update/4
(elixir) lib/keyword.ex:835: Keyword.update/4
(ecto) lib/ecto/adapters/sql.ex:324: Ecto.Adapters.SQL.ensure_all_started/3
(ecto) lib/mix/ecto.ex:99: Mix.Ecto.ensure_started/2
(ecto) lib/mix/tasks/ecto.migrate.ex:76: anonymous fn/4 in Mix.Tasks.Ecto.Migrate.run/2
(elixir) lib/enum.ex:737: Enum."-each/2-lists^foreach/1-0-"/2
Also this
test "GET /api/v1/products" do conn = conn() |> get("/api/v1/products") |> doc assert conn.status == 200 end
generates following error message after running "DOC=1 mix test":
== Compilation error in file test/backend_web/controllers/page_controller_test.exs ==
** (CompileError) test/backend_web/controllers/page_controller_test.exs:16: undefined function conn/0
(elixir 1.12.2) src/elixir_locals.erl:114: anonymous fn/3 in :elixir_locals.ensure_no_undefined_local/3
(stdlib 3.15.2) erl_eval.erl:685: :erl_eval.do_apply/6
(elixir 1.12.2) lib/kernel/parallel_compiler.ex:428: Kernel.ParallelCompiler.require_file/2
(elixir 1.12.2) lib/kernel/parallel_compiler.ex:321: anonymous fn/4 in Kernel.ParallelCompiler.spawn_workers/7
Iยดm using Elixir version "1.12.2" with Phoenix 1.5.12 and this version of bureaucrat:
{:bureaucrat, git: "https://github.com/api-hogs/bureaucrat.git", only: [:dev, :test]} (but it also doesnt work with version 0.2.7)
Hi,
After I upgraded my elixir to the newest version, I am getting this deprecation warning:
passing GenEvent handlers (Bureaucrat.Formatter in this case) in the :formatters option of ExUnit is deprecated, please pass a GenServer instead. Check the documentation for the ExUnit.Formatter module for more information
I saw it's fixed with this commit, but the new version of bureaucrat is not released. Can you tell me when it is going to be released?
Thanks!
I have swagger.json which looks like:
"api/v1/routes": {
"post": {
...
"parameters": [
{
"schema": "string",
"required": false,
"name": "name",
"in": "body",
"description": "Route name"
}
],
...
}
bureaucrat fails to write parameters when parameters is a list, which is how PhoenixSwagger generates parameters
OS: Ubuntu Linux (20.04 LTS)
Erlang/OTP 24 [erts-12.0.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [jit]
Elixir 1.12.2 (compiled with Erlang/OTP 22)
mix.exs
...
defp deps do
[
...
{:jason, "~> 1.0"},
{:bureaucrat, "~> 0.2.7"},
...
]
...
test_helper.exs
Bureaucrat.start(
default_path: "docs/api/README.md",
paths: [],
titles: [
{FooBarWeb.FooController, "/api/foo"},
{FooBarWeb.BarController, "/api/bar"}
],
env_var: "DOC",
json_library: Jason
)
ExUnit.start(formatters: [ExUnit.CLIFormatter, Bureaucrat.Formatter], exclude: [:skip])
Ecto.Adapters.SQL.Sandbox.mode(TransactionServer.Repo, :manual)
DOC=1 mix test
has no effect on the documentation generated prior to the upgrade to Elixir 1.12.2 and Erlang/OTP 24 from Elixir 1.11.2 & Erlang/OTP 23
On running DOC=1 mix test
, the documentation for the API calls should be updated where changes have been made.
I'm trying to use the integration with Swagger & Slate to generate API docs automatically.
I've followed to the letter the guidelines.
When I run DOC=1 mix test
, all the tests pass but I get the following error:
11:09:17.606 [error] GenServer #PID<0.519.0> terminating
** (Protocol.UndefinedError) protocol Enumerable not implemented for nil of type Atom. This protocol is implemented for the following type(s): DBConnection.PrepareStream, DBConnection.Stream, Date.Range, Ecto.Adapters.SQL.Stream, File.Stream, Function, GenEvent.Stream, HashDict, HashSet, IO.Stream, Jason.OrderedObject, List, Map, MapSet, Phoenix.LiveView.LiveStream, Postgrex.Stream, Range, Stream
(elixir 1.14.5) lib/enum.ex:1: Enumerable.impl_for!/1
(elixir 1.14.5) lib/enum.ex:166: Enumerable.reduce/3
(elixir 1.14.5) lib/enum.ex:1150: Enum.find/3
(bureaucrat 0.2.9) lib/bureaucrat/swagger_slate_markdown_writer.ex:236: Bureaucrat.SwaggerSlateMarkdownWriter.write_operations_for_tag/4
(elixir 1.14.5) lib/enum.ex:975: Enum."-each/2-lists^foreach/1-0-"/2
(elixir 1.14.5) lib/enum.ex:1662: anonymous fn/3 in Enum.map/2
(stdlib 5.0.2) maps.erl:416: :maps.fold_1/4
(elixir 1.14.5) lib/enum.ex:2480: Enum.map/2
(bureaucrat 0.2.9) lib/bureaucrat/formatter.ex:22: Bureaucrat.Formatter.suite_finished/0
(stdlib 5.0.2) gen_server.erl:1103: :gen_server.try_handle_cast/3
(stdlib 5.0.2) gen_server.erl:1165: :gen_server.handle_msg/6
(stdlib 5.0.2) proc_lib.erl:241: :proc_lib.init_p_do_apply/3
Last message: {:"$gen_cast", {:suite_finished, %{async: 163093, run: 509077, load: nil}}}
11:09:17.612 [error] Task #PID<0.501.0> started from #PID<0.101.0> terminating
** (stop) exited in: GenServer.stop(#PID<0.519.0>, :normal, :infinity)
** (EXIT) exited in: :sys.terminate(#PID<0.519.0>, :normal, :infinity)
** (EXIT) an exception was raised:
** (Protocol.UndefinedError) protocol Enumerable not implemented for nil of type Atom. This protocol is implemented for the following type(s): DBConnection.PrepareStream, DBConnection.Stream, Date.Range, Ecto.Adapters.SQL.Stream, File.Stream, Function, GenEvent.Stream, HashDict, HashSet, IO.Stream, Jason.OrderedObject, List, Map, MapSet, Phoenix.LiveView.LiveStream, Postgrex.Stream, Range, Stream
(elixir 1.14.5) lib/enum.ex:1: Enumerable.impl_for!/1
(elixir 1.14.5) lib/enum.ex:166: Enumerable.reduce/3
(elixir 1.14.5) lib/enum.ex:1150: Enum.find/3
(bureaucrat 0.2.9) lib/bureaucrat/swagger_slate_markdown_writer.ex:236: Bureaucrat.SwaggerSlateMarkdownWriter.write_operations_for_tag/4
(elixir 1.14.5) lib/enum.ex:975: Enum."-each/2-lists^foreach/1-0-"/2
(elixir 1.14.5) lib/enum.ex:1662: anonymous fn/3 in Enum.map/2
(stdlib 5.0.2) maps.erl:416: :maps.fold_1/4
(elixir 1.14.5) lib/enum.ex:2480: Enum.map/2
(bureaucrat 0.2.9) lib/bureaucrat/formatter.ex:22: Bureaucrat.Formatter.suite_finished/0
(stdlib 5.0.2) gen_server.erl:1103: :gen_server.try_handle_cast/3
(stdlib 5.0.2) gen_server.erl:1165: :gen_server.handle_msg/6
(stdlib 5.0.2) proc_lib.erl:241: :proc_lib.init_p_do_apply/3
(elixir 1.14.5) lib/gen_server.ex:995: GenServer.stop/3
(ex_unit 1.14.5) lib/ex_unit/event_manager.ex:22: anonymous fn/2 in ExUnit.EventManager.stop/1
(elixir 1.14.5) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3
(ex_unit 1.14.5) lib/ex_unit/event_manager.ex:21: ExUnit.EventManager.stop/1
(ex_unit 1.14.5) lib/ex_unit/runner.ex:62: ExUnit.Runner.run_with_trap/2
(ex_unit 1.14.5) lib/ex_unit/runner.ex:31: ExUnit.Runner.run/2
(elixir 1.14.5) lib/task/supervised.ex:89: Task.Supervised.invoke_mfa/2
(elixir 1.14.5) lib/task/supervised.ex:34: Task.Supervised.reply/4
(stdlib 5.0.2) proc_lib.erl:241: :proc_lib.init_p_do_apply/3
Function: #Function<0.96829595/0 in ExUnit.async_run/0>
Args: []
** (EXIT from #PID<0.101.0>) exited in: GenServer.stop(#PID<0.519.0>, :normal, :infinity)
** (EXIT) exited in: :sys.terminate(#PID<0.519.0>, :normal, :infinity)
** (EXIT) an exception was raised:
** (Protocol.UndefinedError) protocol Enumerable not implemented for nil of type Atom. This protocol is implemented for the following type(s): DBConnection.PrepareStream, DBConnection.Stream, Date.Range, Ecto.Adapters.SQL.Stream, File.Stream, Function, GenEvent.Stream, HashDict, HashSet, IO.Stream, Jason.OrderedObject, List, Map, MapSet, Phoenix.LiveView.LiveStream, Postgrex.Stream, Range, Stream
(elixir 1.14.5) lib/enum.ex:1: Enumerable.impl_for!/1
(elixir 1.14.5) lib/enum.ex:166: Enumerable.reduce/3
(elixir 1.14.5) lib/enum.ex:1150: Enum.find/3
(bureaucrat 0.2.9) lib/bureaucrat/swagger_slate_markdown_writer.ex:236: Bureaucrat.SwaggerSlateMarkdownWriter.write_operations_for_tag/4
(elixir 1.14.5) lib/enum.ex:975: Enum."-each/2-lists^foreach/1-0-"/2
(elixir 1.14.5) lib/enum.ex:1662: anonymous fn/3 in Enum.map/2
(stdlib 5.0.2) maps.erl:416: :maps.fold_1/4
(elixir 1.14.5) lib/enum.ex:2480: Enum.map/2
(bureaucrat 0.2.9) lib/bureaucrat/formatter.ex:22: Bureaucrat.Formatter.suite_finished/0
(stdlib 5.0.2) gen_server.erl:1103: :gen_server.try_handle_cast/3
(stdlib 5.0.2) gen_server.erl:1165: :gen_server.handle_msg/6
(stdlib 5.0.2) proc_lib.erl:241: :proc_lib.init_p_do_apply/3
operation_id(...)
to the operations in question.Am I missing something? The swagger.json file seems to be being generated fine, but both the markdown and the HTML generated from it don't include any operations.
Hi, great project! Wondering if it's possible to use this without Phoenix, on a Plug project.
I don't know what's required for Elixir 1.7 support, but seeing this warning:
warning: the dependency :bureaucrat requires Elixir "~> 1.6.1" but you are running on v1.7.3
Because I'm using put_req_header
in my test setup
and then passing the conn
into the test the body_params is empty.
Is there anyway around this at all?
I am using Bureaucrat to generate my API docs for one of my apps inside the umbrella project. So far so good. I decided to use it to generate API docs for another app inside the same umbrella with a separate Markdown output file. But after doing this, I got somehow mixed results. File for app2 is OK, but file for app1 contains records from app1 and app2 combined. I guess it's because of Bureaucrat.Recorder
is being used as a singleton basically.
Do you have any idea if there's a simple workaround available? It's not a requirement to have API docs in an output file per app, but I need to have a clear separation of which API docs are related to which app.
Thanks a lot. :-)
First and foremost, thank you for your work on this library! It has been crucial in my API development.
I am using custom mime-types in the Accept
header as the manner by which I version my API. For instance: application/vnd.my-app.v1+json
. A plug detects the custom mime-type and sets a value in the conn
to the mapped version number, something like: :v1
. Then the controller, views, etc can pattern match on the conn
version value to fork with different behaviors. For more info on this technique see this blog post.
Due to this API versioning implementation, it seems I am forced to document all API versions within the same file. Obviously, this makes the versions of the API harder to grok.
It would be nice if there was a way for me to generate my API version docs to different files even though the same module is implementing them.
Maybe you already know of a way to accomplish this with no changes to bureaucrat? If not, this could possibly be accomplished through:
What are your thoughts? Thanks again!
I suspect that commit changed the behaviour of the operation ID getter.
It would be nice to add support for Phoenix.Socket.Reply
.
Stacktrace:
** (FunctionClauseError) no function clause matching in Bureaucrat.Helpers.get_default_operation_id/1
The following arguments were given to Bureaucrat.Helpers.get_default_operation_id/1:
# 1
%Phoenix.Socket.Reply{join_ref: 77772, payload: %{final_decision: nil, id: "5b069f36-24c8-483c-9e1a-9aeed6def3ff", score: %{"manual" => 10}}, ref: #Reference<0.299170896.563085323.98609>, status: :ok, topic: "assessment_review:5b069f36-24c8-483c-9e1a-9aeed6def3ff"}
Attempted function clauses (showing 3 out of 3):
def get_default_operation_id(%Plug.Conn{private: private})
def get_default_operation_id(%Phoenix.Socket.Message{topic: topic, event: event})
def get_default_operation_id(%Phoenix.Socket.Broadcast{topic: topic, event: event})
code: assert_reply(ref, :ok, data) |> doc
stacktrace:
(bureaucrat 0.2.8) lib/bureaucrat/helpers.ex:122: Bureaucrat.Helpers.get_default_operation_id/1
test/hdo_assessor_web/acceptance/assessment_review_channel_test.exs:129: (test)
It looks like the readme mentions 0.2.5, which hasn't been released. Could you release a version?
Its unclear for the documentation on this repo how to create a nice API documentation in slate with custom intro pages and sections that are required of high quality docs. Is there a good reference for this? I don't see how the _intro pages work if you want to have your docs managed by multiple different source files for easier maintenance.
:)
We would love to use bureaucrat in https://github.com/blockscout/blockscout for API documentation generation. But we're currently depending on [email protected]. Would you mind adding support of [email protected]?
As part of a custom markdown writer for bureaucrat, I've extracted descriptions, parameters and response schemas from a swagger file.
It works similarly to the swagger2markup project.
Is this a feature worth integrating into the bureaucrat library?
My initial implementation is currently tied to my markdown writer module, but it feels like a cross-cutting feature that could benefit any output formatter.
Hello,
I am using bureaucrat to export postman json and all of the PUT and POST endpoint format the body in formdata mode and set the content-type to "multipart/mixed; boundary=plug_conn_test". I would expect the body to be raw JSON and not use multipart form by default. I'm not sure if this is expected behavior, but it does make the postman collection less useful since the body just shows [object Object]
for the data value.
Details about the project:
ja_serializer
to adhere to JSON:API formatThanks for any help!
Hello all,
First of all, thank you for this work!
I have a trouble currently setting up Bureaucrat with Slate & Swagger in an Phoenix API.
When I run DOC=1 mix test
, I get this error:
00:49:37.308 [error] GenServer #PID<0.3151.0> terminating ** (Protocol.UndefinedError) protocol Enumerable not implemented for nil. This protocol is implemented for: Ecto.Adapters.SQL.Stream, Postgrex.Stream, DBConnection.Stream, DBConnection.PrepareStream, HashDict, Map, MapSet, File.Stream, Date.Range, HashSet, List, Range, Stream, Function, GenEvent.Stream, IO.Stream (elixir) /builddir/build/BUILD/elixir-1.8.1/lib/elixir/lib/enum.ex:1: Enumerable.impl_for!/1 (elixir) /builddir/build/BUILD/elixir-1.8.1/lib/elixir/lib/enum.ex:141: Enumerable.reduce/3 (elixir) lib/enum.ex:3015: Enum.each/2 (elixir) lib/enum.ex:775: anonymous fn/3 in Enum.each/2 (stdlib) maps.erl:257: :maps.fold_1/3 (elixir) lib/enum.ex:1956: Enum.each/2 (bureaucrat) lib/bureaucrat/swagger_slate_markdown_writer.ex:287: Bureaucrat.SwaggerSlateMarkdownWriter.write_operations_for_tag/4 (elixir) lib/enum.ex:769: Enum."-each/2-lists^foreach/1-0-"/2 (elixir) lib/enum.ex:769: Enum.each/2 (elixir) lib/enum.ex:1331: anonymous fn/3 in Enum.map/2 (stdlib) maps.erl:257: :maps.fold_1/3 (elixir) lib/enum.ex:1956: Enum.map/2 (bureaucrat) lib/bureaucrat/formatter.ex:10: Bureaucrat.Formatter.handle_cast/2 (stdlib) gen_server.erl:637: :gen_server.try_dispatch/4 (stdlib) gen_server.erl:711: :gen_server.handle_msg/6 (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3 Last message: {:"$gen_cast", {:suite_finished, 326751, nil}} 00:49:37.310 [error] Task #PID<0.3130.0> started from #PID<0.93.0> terminating ** (stop) exited in: GenServer.stop(#PID<0.3151.0>, :normal, 30000) ** (EXIT) exited in: :sys.terminate(#PID<0.3151.0>, :normal, :infinity) ** (EXIT) an exception was raised: ** (Protocol.UndefinedError) protocol Enumerable not implemented for nil. This protocol is implemented for: Ecto.Adapters.SQL.Stream, Postgrex.Stream, DBConnection.Stream, DBConnection.PrepareStream, HashDict, Map, MapSet, File.Stream, Date.Range, HashSet, List, Range, Stream, Function, GenEvent.Stream, IO.Stream (elixir) /builddir/build/BUILD/elixir-1.8.1/lib/elixir/lib/enum.ex:1: Enumerable.impl_for!/1 (elixir) /builddir/build/BUILD/elixir-1.8.1/lib/elixir/lib/enum.ex:141: Enumerable.reduce/3 (elixir) lib/enum.ex:3015: Enum.each/2 (elixir) lib/enum.ex:775: anonymous fn/3 in Enum.each/2 (stdlib) maps.erl:257: :maps.fold_1/3 (elixir) lib/enum.ex:1956: Enum.each/2 (bureaucrat) lib/bureaucrat/swagger_slate_markdown_writer.ex:287: Bureaucrat.SwaggerSlateMarkdownWriter.write_operations_for_tag/4 (elixir) lib/enum.ex:769: Enum."-each/2-lists^foreach/1-0-"/2 (elixir) lib/enum.ex:769: Enum.each/2 (elixir) lib/enum.ex:1331: anonymous fn/3 in Enum.map/2 (stdlib) maps.erl:257: :maps.fold_1/3 (elixir) lib/enum.ex:1956: Enum.map/2 (bureaucrat) lib/bureaucrat/formatter.ex:10: Bureaucrat.Formatter.handle_cast/2 (stdlib) gen_server.erl:637: :gen_server.try_dispatch/4 (stdlib) gen_server.erl:711: :gen_server.handle_msg/6 (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3 (elixir) lib/gen_server.ex:948: GenServer.stop/3 (ex_unit) lib/ex_unit/event_manager.ex:24: anonymous fn/2 in ExUnit.EventManager.stop/1 (elixir) lib/enum.ex:1940: Enum."-reduce/3-lists^foldl/2-0-"/3 (ex_unit) lib/ex_unit/event_manager.ex:23: ExUnit.EventManager.stop/1 (ex_unit) lib/ex_unit/runner.ex:28: ExUnit.Runner.run/2 (elixir) lib/task/supervised.ex:90: Task.Supervised.invoke_mfa/2 (elixir) lib/task/supervised.ex:35: Task.Supervised.reply/5 (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3 Function: &ExUnit.run/0 Args: [] ** (EXIT from #PID<0.93.0>) exited in: GenServer.stop(#PID<0.3151.0>, :normal, 30000) ** (EXIT) exited in: :sys.terminate(#PID<0.3151.0>, :normal, :infinity) ** (EXIT) an exception was raised: ** (Protocol.UndefinedError) protocol Enumerable not implemented for nil. This protocol is implemented for: Ecto.Adapters.SQL.Stream, Postgrex.Stream, DBConnection.Stream, DBConnection.PrepareStream, HashDict, Map, MapSet, File.Stream, Date.Range, HashSet, List, Range, Stream, Function, GenEvent.Stream, IO.Stream (elixir) /builddir/build/BUILD/elixir-1.8.1/lib/elixir/lib/enum.ex:1: Enumerable.impl_for!/1 (elixir) /builddir/build/BUILD/elixir-1.8.1/lib/elixir/lib/enum.ex:141: Enumerable.reduce/3 (elixir) lib/enum.ex:3015: Enum.each/2 (elixir) lib/enum.ex:775: anonymous fn/3 in Enum.each/2 (stdlib) maps.erl:257: :maps.fold_1/3 (elixir) lib/enum.ex:1956: Enum.each/2 (bureaucrat) lib/bureaucrat/swagger_slate_markdown_writer.ex:287: Bureaucrat.SwaggerSlateMarkdownWriter.write_operations_for_tag/4 (elixir) lib/enum.ex:769: Enum."-each/2-lists^foreach/1-0-"/2 (elixir) lib/enum.ex:769: Enum.each/2 (elixir) lib/enum.ex:1331: anonymous fn/3 in Enum.map/2 (stdlib) maps.erl:257: :maps.fold_1/3 (elixir) lib/enum.ex:1956: Enum.map/2 (bureaucrat) lib/bureaucrat/formatter.ex:10: Bureaucrat.Formatter.handle_cast/2 (stdlib) gen_server.erl:637: :gen_server.try_dispatch/4 (stdlib) gen_server.erl:711: :gen_server.handle_msg/6 (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
I have some tags in my swagger.json though.
Can I borrow some help?
Hi and thanks for creating bureaucrat.
I've written a custom markdown writer that outputs in a format which can be used to create a slate (https://github.com/tripit/slate) static site.
Is this a feature worth submitting back to the bureaucrat library?
If so I can send a PR.
Now that Phoenix has moved to use Jason over Poison, it seems redundant to have multiple json libraries in one application.
Suggestion:
Make the json library configurable.
Something like
config :bureaucrat, :json_library, Jason # Or Poison / others
This has been done in other hex packages too, so I think it should be doable :)
I will happily try to make a PR if the suggestion is approved.
I am facing the following error when passing :operation_id
in doc()
.
[error] GenEvent handler Bureaucrat.Formatter installed in #PID<0.359.0> terminating
** (ArgumentError) cannot convert the given list to a string.To be converted to a string, a list must contain only:
- strings
- integers representing Unicode codepoints
- or a list containing one of these three elements
Please check the given list or call inspect/1 to get the list representation, got:
[operation_id: "create_user"]
(elixir) lib/list.ex:709: List.to_string/1 (bureaucrat) lib/bureaucrat/markdown_writer.ex:43: Bureaucrat.MarkdownWriter.write_example/2 (elixir) lib/enum.ex:645: Enum."-each/2-lists^foreach/1-0-"/2 (elixir) lib/enum.ex:645: Enum.each/2 (elixir) lib/enum.ex:651: anonymous fn/3 in Enum.each/2 (stdlib) lists.erl:1263: :lists.foldl/3 (elixir) lib/enum.ex:1772: Enum.each/2 (elixir) lib/enum.ex:645: Enum."-each/2-lists^foreach/1-0-"/2 (elixir) lib/enum.ex:645: Enum.each/2 (elixir) lib/enum.ex:1233: anonymous fn/3 in Enum.map/2 (stdlib) lists.erl:1263: :lists.foldl/3 (elixir) lib/enum.ex:1772: Enum.map/2 (bureaucrat) lib/bureaucrat/formatter.ex:10: Bureaucrat.Formatter.handle_event/2 (stdlib) gen_event.erl:570: :gen_event.server_update/4 (stdlib) gen_event.erl:552: :gen_event.server_notify/4 (stdlib) gen_event.erl:293: :gen_event.handle_msg/5 (stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3
Last message: {:suite_finished, 985361, nil}
State: nil
My Environment:
$ mix -v
Erlang/OTP 20 [erts-9.0] [source] [64-bit] [smp:1:1] [ds:1:1:10] [async-threads:10] [hipe] [kernel-poll:false]
Mix 1.4.4
Hello everyone!
I'm trying Bureaucrat right now and I'm facing an issue on a new Phoenix app.
I inserted bureaucrat as a dependency in my mix.exs file.
I added in the test helper the right lignes to make Bureaucrate start and find my already existing swagger file.
Finally as a test I added a doc
call to one of my test.
Unfortunately, when running them, this error occurs:
** (UndefinedFunctionError) function Bureaucrat.SwaggerSlateMarkdownWriter.write/2 is undefined (module Bureaucrat.SwaggerSlateMarkdownWriter is not available)
Do you have any ideas how I can fix this? It's like if this module was not included in the project...
Thanks!
2 Parts
Part 1:
It appears that Bureaucrat works as expected in the Elixir 1.7.x environment, however it throws a warning if above Elixir 1.6. Would you like a PR for adding Elixir 1.7 testing?
Part 2:
Is there a Roadmap to support Phoenix 1.4? It seems like Bureaucrat should still work with 1.4 as long as the default path is changed. Would you like a PR for adding Phoenix 1.4 testing and/or accept a new default path proposal?
Elixir Semantic Versioning
Phoenix Versioning
It may also be a good idea to switch the default JSON parser to Jason as Phoenix 1.4 now uses this as a default.
Running off the latest commit (necessary to bypass a parameters issue merged in #28)
UPDATE: using elixir 1.3 is causing the issue, master is incompatible
12:06:34.502 [error] GenEvent handler Bureaucrat.Formatter installed in #PID<0.689.0> terminating
** (UndefinedFunctionError) function Bureaucrat.Formatter.handle_event/2 is undefined or private. Did you mean one of:
* handle_cast/2
* handle_info/2
(bureaucrat) Bureaucrat.Formatter.handle_event({:suite_started, [seed: 424463, max_cases: 16, include: [], exclude: [], timeout: 60000, assert_receive_timeout: 100, refute_receive_timeout: 100, autorun: false, included_applications: [], trace: false, stacktrace_depth: 20, formatters: [ExUnit.CLIFormatter, Bureaucrat.Formatter], colors: [], capture_log: false]}, nil)
(stdlib) gen_event.erl:538: :gen_event.server_update/4
(stdlib) gen_event.erl:520: :gen_event.server_notify/4
(stdlib) gen_event.erl:261: :gen_event.handle_msg/5
(stdlib) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
I believe this is from the refactor to turn the formatter into a GenServer: 98af5c8#diff-0368a301ccafadcc320f87373218a0e4
Can someone confirm that this PR didn't break the formatter? I am using the swagger_slate_markdown_writer if that is relevant
Think about some params for this.
Hi
I set up my project as per the README and I'm getting this when I run my tests, piping through the doc() function (only with DOC=1 mix test
):
** (KeyError) key :phoenix_controller not found in: %{phoenix_recycled: true, plug_skip_csrf_protection: true}
(bureaucrat) lib/bureaucrat/markdown_writer.ex:138: anonymous fn/1 in Bureaucrat.MarkdownWriter.group_records/1
I tried debugging inside the lib but I'm none the wiser on how the 'private' values get set in this records collection.
Here's my env:
$ elixir -v
Erlang/OTP 19 [erts-8.0.2] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Elixir 1.3.3
$ mix deps | grep "*"
* connection 1.0.4 (Hex package) (mix)
* fs 0.9.1 (Hex package) (rebar)
* gettext 0.12.1 (Hex package) (mix)
* ranch 1.2.1 (Hex package) (rebar)
* poolboy 1.5.1 (Hex package) (rebar)
* decimal 1.2.0 (Hex package) (mix)
* poison 2.2.0 (Hex package) (mix)
* db_connection 1.0.0 (Hex package) (mix)
* cowlib 1.0.2 (Hex package) (rebar)
* cowboy 1.0.4 (Hex package) (rebar)
* mime 1.0.1 (Hex package) (mix)
* plug 1.2.2 (Hex package) (mix)
* bureaucrat 0.1.4 (Hex package) (mix)
* phoenix_html 2.6.2 (Hex package) (mix)
* phoenix 1.1.6 (Hex package) (mix)
* phoenix_live_reload 1.0.5 (Hex package) (mix)
* postgrex 0.11.2 (Hex package) (mix)
* ecto 1.1.9 (Hex package) (mix)
* phoenix_ecto 2.0.2 (Hex package) (mix)
Thanks
Currently the doc
macro must be invoked directly from the test. If it is invoked from a function, a compile-time exception is raised. As a result, we're facing a dilemma: either avoid wrappers, which can lead to excessively noisy code, or avoid generating documentation.
I think it's possible to do better, and allow devs to wrap the requests and still generate the docs. Here's the proposed approach:
nil
for the description if the immediate caller is not testnil
, try to deduce it from the runtime stack trace using Process.info(self(), :current_stacktrace)
._undocumented
), but emit a warning.In most cases this should work automagically. In exceptional cases, e.g. making a request from a setup block, it would still work while emitting a warning. The fix in such cases could be switching to _undocumented
or explicitly passing the description.
WDYT?
Every single doc/2
line in my test suite generates the following warning:
warning: this check/guard will always yield the same result
Example block:
build_conn()
|> get("/users")
|> doc(description: "List users")
|> json_response(:ok)
Having a swagger json with definitions like this:
{
"definitions": {
"Company": {
"description": "A long description with newlines \nand other stuff, so that model description is more informative.\n\nWith some edges cases ...",
"properties": {
"name": {
"description": "Company name",
"type": "string"
}
},
"title": "Company",
"type": "object"
},
"Owner": {
"description": "A user that owns a company.",
"properties": {
"company": {
"$ref": "#/definitions/Company",
"description": "The company object"
},
"firstName": {
"description": "First name",
"type": "string"
}
},
"title": "Owner",
"type": "object"
}
}
Will produce a markdown where the Owner.company.description will be overwritten by Company.description:
# Models
## Company
A long description with newlines
and other stuff, so that model description is more informative.
With some edges cases ...
|Property|Description|Type|Required|
|--------|-----------|----|--------|
|name|Company name|string|true|
## Owner
A user that owns a company.
|Property|Description|Type|Required|
|--------|-----------|----|--------|
|firstName|First name|string|true|
|company|A long description with newlines
and other stuff, so that model description is more informative.
With some edges cases ...
|[Company](#company)|false|
...
Note the description of company property in Owner model. Instead of it being The company object
from Owner.company.description, it's a long description from Company.description. This also breaks the generated Slate html formatting. I think a better approach would be to honor the original property description from swagger definitions.
I am not sure if this is actually a bug, because the SwaggerSlateMarkdownWriter.resolve_type/2
function was written specifically to do it that way. It seems intended behaviour, but I wonder if there could be an option setting or something similar to force preservation of original property descriptions.
Hello, thanks for the wonderful library, it's been super helpful!
I have run into a couple issues with the final json parsing of the response body failing when the response contains file data for download or when a basic string is returned, like when returning a plain token without a json wrapper. I'm wondering if there is an existing workaround, or if an MR to address these issues would be useful.
For the file download endpoints, I'm using Phoenix.Controller.send_download/3. There are {"content-type", "application/zip"}
and {"content-disposition", "attachment; filename=\"file_name.zip\""}
headers that could potentially be used to identify file payloads.
For the plain string, I was able to work around it by adding escaped quotes like so "\"token\""
, but it seems like the library should be able to handle basic strings in the body. We could use the JSON.encode
function without the exclamation and then if the error tuple is returned, skip the prettify step and let it be a regular binary, or something along those lines.
Thanks!
Currently in the default and swagger writers, the request and response bodies are just assumed to be JSON and passed through the Poison.encode/1
with the pretty: true
option.
In order to support other use cases (e.g., XML, other JSON libs) or just more control of the formatting, it would be great if it were possible to configure this without re-implementing the entire writer.
This could be done via options to the writer:
config :bureaucrat,
writer: {Bureaucrat.MarkdownWriter, payload_formatter: MyHelper}
Along with a default implementation based on the current strategy.
Also open to other suggestions. I can work on a PR if that's something you'd be willing to include.
The version of poison in this project is far behind the latest version. Due to some other dependencies I need bureaucrat
to support poison ~> 5.0
as well.
When trying to use doc_connect this error is thrown:
** (ArgumentError) errors were found at the given arguments:
* 1st argument: the device does not exist
(stdlib 4.3.1.4) io.erl:94: :io.put_chars(nil, ["* __Receive:__ ok", 10])
(bureaucrat 0.2.10) lib/bureaucrat/markdown_writer.ex:219: Bureaucrat.MarkdownWriter.puts/2
(elixir 1.16.3) lib/enum.ex:987: Enum."-each/2-lists^foreach/1-0-"/2
(elixir 1.16.3) lib/enum.ex:1708: anonymous fn/3 in Enum.map/2
(stdlib 4.3.1.4) maps.erl:411: :maps.fold_1/3
(elixir 1.16.3) lib/enum.ex:2540: Enum.map/2
(bureaucrat 0.2.10) lib/bureaucrat/formatter.ex:22: Bureaucrat.Formatter.suite_finished/0
(stdlib 4.3.1.4) gen_server.erl:1123: :gen_server.try_dispatch/4
(stdlib 4.3.1.4) gen_server.erl:1200: :gen_server.handle_msg/6
(stdlib 4.3.1.4) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
These are my settings:
Bureaucrat.start(
writer: Bureaucrat.MarkdownWriter,
default_path: "priv/static/doc/websockets.md",
paths: [],
titles: [],
env_var: "DOC",
json_library: Jason
)
The asserts piped into docs() work normally, and I tried using Jason and Poison
I think bureaucrat could be great for documenting phoenix channel messages and broadcasts, in addition to the API requests and responses it already supports. I'm not sure if it makes sense to support websockets without phoenix, but in any case phoenix could be an optional dependency.
The simplest and most common use cases for now, from my perspective, would be the ones described in the phoenix channel docs:
connect(UserSocket, %{"some" => "params"})
subscribe_and_join(RoomChannel, "room:lobby", %{"id" => 3})
push socket, "my_event", %{"some" => "data"}
broadcast_from socket, "my_event", %{"some" => "data"}
assert_push "my_event", %{"some" => "data"}
assert_broadcast "my_event", %{"some" => "data"}
I guess 1. - 4. are close to what bureaucrat records already.
For 5. - 6. it would be good to filter according to what's asserted, so you filter out the "noise" such as presence_diff broadcasts when you don't need them. Instead of going through assert, this could possibly be done with an alias function such as doc_assert
or so.
Would that be within the scope of bureaucrat for you?
Do you see any low-hanging fruits here?
I stumbled upon a few errors when I tried implementing Bureaucrat in an application I've been working on recently, so I decided to create a new phoenix application with one JSON resource and try creating docs for its automatically generated tests. This is the test app: https://github.com/NicolayD/bureaucrat_test
With {:bureaucrat, "~> 0.1.4"}
as a dependency I got the following error (you can see the doc(conn) call on line 23):
When I tried getting Bureaucrat directly from the github repo with {:bureaucrat, github: "api-hogs/bureaucrat", only: :test}
, I got the following message:
Could this be related to Elixir 1.4?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.