How to Export a Schema File with export_openapi_schema After Customizing the Top-Level API Path
The default top-level route in ninja is 'api'. Suppose you change it to 'coast/api' and then run
python manage.py export_openapi_schema, it will raise an error.
python manage.py export_openapi_schema
System check identified some issues:
WARNINGS:
?: (ckeditor.W001) django-ckeditor bundles CKEditor 4.22.1 which isn't supported anmyore and which does have unfixed security issues, see for example https://ckeditor.com/cke4/release/CKEditor-4.24.0-LTS . You should consider strongly switching to a different editor (maybe CKEditor 5 respectively django-ckeditor-5 after checking whether the CKEditor 5 license terms work for you) or switch to the non-free CKEditor 4 LTS package. See https://ckeditor.com/ckeditor-4-support/ for more on this. (Note! This notice has been added by the django-ckeditor developers and we are not affiliated with CKSource and were not involved in the licensing change, so please refrain from complaining to us. Thanks.)
Traceback (most recent call last):
File "/Users/baoge/WebstormProjects/coast_be/manage.py", line 27, in <module>
main()
File "/Users/baoge/WebstormProjects/coast_be/manage.py", line 23, in main
execute_from_command_line(sys.argv)
File "/opt/anaconda3/envs/coast_be/lib/python3.10/site-packages/django/core/management/__init__.py", line 419, in execute_from_command_line
utility.execute()
File "/opt/anaconda3/envs/coast_be/lib/python3.10/site-packages/django/core/management/__init__.py", line 413, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/opt/anaconda3/envs/coast_be/lib/python3.10/site-packages/django/core/management/base.py", line 354, in run_from_argv
self.execute(*args, **cmd_options)
File "/opt/anaconda3/envs/coast_be/lib/python3.10/site-packages/django/core/management/base.py", line 398, in execute
output = self.handle(*args, **options)
File "/opt/anaconda3/envs/coast_be/lib/python3.10/site-packages/ninja/management/commands/export_openapi_schema.py", line 79, in handle
api = self._get_api_instance(options["api"])
File "/opt/anaconda3/envs/coast_be/lib/python3.10/site-packages/ninja/management/commands/export_openapi_schema.py", line 34, in _get_api_instance
return resolve("/api/").func.keywords["api"] # type: ignore
File "/opt/anaconda3/envs/coast_be/lib/python3.10/site-packages/django/urls/base.py", line 24, in resolve
return get_resolver(urlconf).resolve(path)
File "/opt/anaconda3/envs/coast_be/lib/python3.10/site-packages/django/urls/resolvers.py", line 589, in resolve
raise Resolver404({'tried': tried, 'path': new_path})
django.urls.exceptions.Resolver404: {'tried': [[<URLResolver <URLResolver list> (None:None) 'coast/'>]], 'path': 'api/'}
api = resolve("/api/").func.keywords["api"].
If your top-level route is not /api/, you must specify it via the --api parameter. This parameter is loaded through import_string(api_path), so it needs to be the import path of the NinjaAPI instance.
For example, in my project it is 'website.utils.tools.api.ninja_api'. If you cannot find it, look in urls.py for the variable in front of add_router or urls — that is what you want.
Additional knowledge:
Me
In this code, if the --api parameter is passed via the command line, what should its format be?
AI Assistant
In this code, the --api parameter is used to specify an API instance module. According to the comments and docstring in the code, the format of the --api parameter should be a module path — specifically, a Python module path that can be resolved by Django's import_string function.
Format
```shell script
--api ### Example
Assume your project structure is as follows:
If the `NinjaAPI` instance is defined in the `project/api.py` file and the instance is named `api`, you can pass the parameter like this:
```shell script
python manage.py export_openapi_schema --api project.api.api
Notes
<module_path>is a Python module path pointing to the module that contains theNinjaAPIinstance.- The last part of the path is the variable name of the
NinjaAPIinstance in the module (for example,api). - If the
--apiparameter is not provided, the code attempts to fetch theNinjaAPIinstance dynamically viaresolve("/api/"). If that fails, it raises an error prompting the user to specify it explicitly via the--apiparameter.
Caveats
- Make sure the provided module path is valid and that a
NinjaAPIinstance actually exists in the module. Otherwise, the code will raise aCommandErrorindicating that the module or attribute was not found. - If you are unsure of the path to the
NinjaAPIinstance, refer to your project'surls.pyor other related files to find where theNinjaAPIis instantiated.
Method 1: Inspect the project URL configuration
Typically, the URL routes for a Django project are configured in the urls.py file. Open the project's urls.py and find the part related to /api/. For example:
# project/urls.py
from django.urls import path
from .api import api # Assume the NinjaAPI instance is named `api`
urlpatterns = [
path("coast/api/", api.urls), # Mount `api`'s routes under `/coast/api/`
]
In this example:
- api is a NinjaAPI instance.
- It is defined in the module project.api (assuming the project root directory is project).
Therefore, the equivalent --api parameter should be:
```shell script
--api project.api.api
### Summary
To replicate the behavior of `resolve("/coast/api/")`, you need to know the module path of the `NinjaAPI` instance that the `/coast/api/` path maps to, and pass it as the value of the `--api` parameter. For example:
```shell script
python manage.py export_openapi_schema --api project.api.api
If you are not sure where the instance is located, inspect the project's urls.py file or confirm by debugging.
本文总阅读量次