tfranzel / drf-spectacular

Sane and flexible OpenAPI 3 schema generation for Django REST framework.
https://drf-spectacular.readthedocs.io
BSD 3-Clause "New" or "Revised" License
2.38k stars 264 forks source link

SWAGGER_UI_SETTINGS JavaScript String Not Treated as JS Function/Object #695

Closed joeleonjr closed 2 years ago

joeleonjr commented 2 years ago

Describe the bug I'm attempting to add some additional logic to the Swagger-UI schema via the SWAGGER_UI_SETTINGS option. Specifically, I'm setting the 'requestInterceptor' configuration option and assigning a function to process the request. I read the docs and understand that we're supposed to place the JS in a string. I placed my JS in a string, but it's definitely still being treated like a string and not a JavaScript function (or object).

It's entirely possible I don't understand how to implement what's written in the docs, but I've tried various things (different functions, wrapping the function in single quotes vs. double quotes, etc.) and nothing has worked.

To Reproduce

Add the following to your project's settings.py file:

SPECTACULAR_SETTINGS = {
    'SWAGGER_UI_SETTINGS':{
        'requestInterceptor':'function(request){console.log(request.url);return request;}',
    },
}

When refreshing the Swagger-UI page, you'll see something like this:

image

Expected behavior When adding a JS string to a configuration variable that requires a JavaScript function, the JS string should be available as a JavaScript object and not processed as a string.

Thank you in advance for reviewing!

tfranzel commented 2 years ago

Hi @joeleonjr

the documentation is not super specific in that regard. The value of SWAGGER_UI_SETTINGS needs to be a string in that case. Your equivalent would be:

SPECTACULAR_SETTINGS = {
    'SWAGGER_UI_SETTINGS': """{
        requestInterceptor: function(request){console.log(request.url);return request;},
    }"""
}

Doesn't need to be triple quotes but its easier to format like that. The content of that string needs to be a valid JS map, because it gets unpacked and added to the other settings. The template loads that string here:

https://github.com/tfranzel/drf-spectacular/blob/6f5bd1688182829204bb61db6a9d7903fdaf0bbe/drf_spectacular/templates/drf_spectacular/swagger_ui.js#L3 and that JS map called swaggerSettings is unpacked here:

https://github.com/tfranzel/drf-spectacular/blob/6f5bd1688182829204bb61db6a9d7903fdaf0bbe/drf_spectacular/templates/drf_spectacular/swagger_ui.js#L115

The default template does a couple of things including reloading the schema on auth changes. You might break that functionality with a custom requestInterceptor. Depending on the case, it might make sense adapting the swagger_ui.js to your needs, not just through our setting. But it would be certainly possible to call that existing inteceptor in your interceptor in addition to your custom logic. That will work purely with the quoted settings string.

joeleonjr commented 2 years ago

Just got it working by copying in what you posted. Thank you very much @tfranzel! Hopefully this issue helps someone else who can't get their JS function to execute in SWAGGER_UI_SETTINGS.

Sincerely appreciate all of the work you all have done to create and maintain this!