redoc icon indicating copy to clipboard operation
redoc copied to clipboard

Can't use relative URL to spec.yaml file

Open sn4kebite opened this issue 6 years ago • 4 comments

I'm trying to use a relative URL to the spec.yaml file, which fails because it's interpreted as a file path:

Traceback (most recent call last):
  File "/usr/lib/python3.6/site-packages/sphinx/cmdline.py", line 304, in main
    app.build(args.force_all, filenames)
  File "/usr/lib/python3.6/site-packages/sphinx/application.py", line 331, in build
    self.builder.build_update()
  File "/usr/lib/python3.6/site-packages/sphinx/builders/__init__.py", line 338, in build_update
    'out of date' % len(to_build))
  File "/usr/lib/python3.6/site-packages/sphinx/builders/__init__.py", line 402, in build
    self.finish()
  File "/usr/lib/python3.6/site-packages/sphinx/builders/html.py", line 621, in finish
    self.finish_tasks.add_task(self.gen_additional_pages)
  File "/usr/lib/python3.6/site-packages/sphinx/util/parallel.py", line 50, in add_task
    res = task_func()
  File "/usr/lib/python3.6/site-packages/sphinx/builders/html.py", line 648, in gen_additional_pages
    for pagename, context, template in pagelist:
  File "/usr/lib/python3.6/site-packages/sphinxcontrib/redoc.py", line 47, in render
    os.path.join(specpath, specname))
  File "/usr/lib/python3.6/site-packages/sphinx/util/osutil.py", line 165, in copyfile
    if not path.exists(dest) or not filecmp.cmp(source, dest):
  File "/usr/lib/python3.6/filecmp.py", line 51, in cmp
    s1 = _sig(os.stat(f1))
FileNotFoundError: [Errno 2] No such file or directory: '/api/rest/spec.yaml'

I need to use a relative path because the generated docs will be deployed on multiple hosts, and I don't want to bind the spec to a specific host. As a workaround I'm using the full URL in the config, then edit the generated html file manually before deployment.

sn4kebite avatar Apr 27 '18 08:04 sn4kebite

@sn4kebite sorry for the late reply, I've been busy lately. :(

I'm not quite sure I understand your use case correctly. Could you please elaborate? For what purpose exactly you want to use relative HTTP URL? I mean, if you specify a path on filesystem, the spec would be copied to output directory and relative URL would be used automatically.

ikalnytskyi avatar May 24 '18 14:05 ikalnytskyi

Alternatively, in some cases (when only domain is changed), you may use something like:

    'spec': 'http:///api/rest/spec.yaml',

which will try to download the spec from /api/rest/spec.yaml from the same domain.

Please respond whether it worked for you or not.

ikalnytskyi avatar May 24 '18 14:05 ikalnytskyi

I am building a docker image containing both API and documentation. The spec.yaml file is not available when the documentation is being built, as it is generated by the API on demand.

From what I understand this is when you want to use an HTTP URL to the spec, however I don't know the URL in advance. The spec can however be found relative to the docs, so using a relative URL in this case solves this problem.

Using the HTTP URL without hostname is a neat trick (I didn't know you could do that), but I'm concerned how well supported it is (no results on google that I could find), and it only works with either http or https.

sn4kebite avatar May 24 '18 14:05 sn4kebite

Using the HTTP URL without hostname is a neat trick (I didn't know you could do that), but I'm concerned how well supported it is (no results on google that I could find),

Well, honestly, I don't know; this is behaviour I observe in Python when you do urljoin.

and it only works with either http or https.

A doubt Redoc.js support any other protocol except for HTTP(s). It's a limitation of JS machines in browsers.

Still I do understand your use case now. I'm thinking about fallbacking to HTTP relative URI if the corresponding file wasn't found. I.e.

  • You would still have something like

     'spec': '/api/rest/spec.yaml',
    
  • The extension will try to find a file of filesystem first.

  • If found, it will be copied over to output directory.

  • If not found, the extension would pass /api/rest/spec.yaml "As Is" to Redoc.js.

ikalnytskyi avatar May 25 '18 08:05 ikalnytskyi