### Example API Definition Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/testing.md Defines a simple API with a GET endpoint for '/hello'. ```python from ninja import NinjaAPI, Schema api = NinjaAPI() router = Router() class HelloResponse(Schema): msg: str @router.get("/hello", response=HelloResponse) def hello(request): return {"msg": "Hello World"} api.add_router("", router) ``` -------------------------------- ### Full CRUD Example Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/tutorial/other/crud.md A complete example demonstrating Create, Read, Update, and Delete operations for employees. ```python from datetime import date from typing import List from ninja import NinjaAPI, Schema from django.shortcuts import get_object_or_404 from employees.models import Employee api = NinjaAPI() class EmployeeIn(Schema): first_name: str last_name: str department_id: int = None birthdate: date = None class EmployeeOut(Schema): id: int first_name: str last_name: str department_id: int = None birthdate: date = None @api.post("/employees") def create_employee(request, payload: EmployeeIn): employee = Employee.objects.create(**payload.dict()) return {"id": employee.id} @api.get("/employees/{employee_id}", response=EmployeeOut) def get_employee(request, employee_id: int): employee = get_object_or_404(Employee, id=employee_id) return employee @api.get("/employees", response=List[EmployeeOut]) def list_employees(request): qs = Employee.objects.all() return qs @api.put("/employees/{employee_id}") def update_employee(request, employee_id: int, payload: EmployeeIn): employee = get_object_or_404(Employee, id=employee_id) for attr, value in payload.dict().items(): setattr(employee, attr, value) employee.save() return {"success": True} @api.delete("/employees/{employee_id}") def delete_employee(request, employee_id: int): employee = get_object_or_404(Employee, id=employee_id) employee.delete() return {"success": True} ``` -------------------------------- ### Installation Source: https://github.com/vitalik/django-ninja/blob/master/README.md Install django-ninja using pip. ```bash pip install django-ninja ``` -------------------------------- ### Install Uvicorn ASGI Server Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/async-support.md Install Uvicorn, a popular ASGI server, to run asynchronous Django applications. ```bash pip install uvicorn ``` -------------------------------- ### GET parameters type conversion Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/input/query-params.md Example showing type conversion for various GET parameter types. ```python @api.get("/example") def example(request, b: bool, d: date): return {"b": b, "d": d} ``` -------------------------------- ### Quick Example - urls.py Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/index.md Example of how to configure urls.py for a new Django project using Django Ninja. ```python from django.contrib import admin from django.urls import path from ninja import NinjaAPI api = NinjaAPI() @api.get("/add") def add(request, a: int, b: int): return {"result": a + b} urlpatterns = [ path("admin/", admin.site.urls), path("api/", api.urls), # <-- add this line ] ``` -------------------------------- ### Install Django and Django Ninja Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/async-support.md Install Django version 3.1 or higher and Django Ninja using pip. ```bash pip install Django>=3.1 django-ninja ``` -------------------------------- ### Create a Django project Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/tutorial/index.md Start a new Django project. ```bash django-admin startproject myproject ``` -------------------------------- ### Custom Throttle Example Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/throttling.md Example of creating a custom throttle that does not throttle GET requests. ```Python from ninja.throttling import AnonRateThrottle class NoReadsThrottle(AnonRateThrottle): """Do not throttle GET requests""" def allow_request(self, request): if request.method == "GET": return True return super().allow_request(request) ``` -------------------------------- ### FastAPI Example Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/motivation.md An example of how dependencies are handled in FastAPI, which can lead to verbose code when dealing with authentication and database sessions. ```python ... app = FastAPI() # Dependency def get_db(): db = SessionLocal() try: yield db finally: db.close() async def get_current_user(token: str = Depends(oauth2_scheme)): user = decode(token) if not user: raise HTTPException(...) return user @app.get("/task/{task_id}", response_model=Task) def read_user( task_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): ... use db with current_user .... ``` -------------------------------- ### API Key Authentication in Query Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/authentication.md This example demonstrates API key authentication where the key is provided in the query string (e.g., `GET /something?api_key=abcdef12345`). It retrieves the key from `GET['api_key']` and finds a corresponding `Client` in the database. ```python from ninja.security import APIKey class GlobalAuth(APIKey): param_name = "api_key" def authenticate(self, request, key): # ... logic to find client by key ... return Client.objects.get(key=key) api = NinjaAPI(auth=GlobalAuth()) ``` -------------------------------- ### Input Schema Example Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/response/index.md Example of defining an input schema for user creation. ```python from ninja import Schema class UserIn(Schema): username: str password: str @api.post("/users/") def create_user(request, data: UserIn): user = User(username=data.username) # User is django auth.User user.set_password(data.password) user.save() # ... return ? ``` -------------------------------- ### Basic Usage Source: https://github.com/vitalik/django-ninja/blob/master/README.md Example of creating a simple API endpoint with a GET method that adds two integers. ```python from ninja import NinjaAPI api = NinjaAPI() @api.get("/add") def add(request, a: int, b: int): return {"result": a + b} ``` -------------------------------- ### First operation - Hello World Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/tutorial/index.md Add a simple "hello world" GET endpoint. ```python from ninja import NinjaAPI api = NinjaAPI() @api.get("/hello") def hello(request): return "Hello world" ``` -------------------------------- ### Install Flit Source: https://github.com/vitalik/django-ninja/blob/master/CONTRIBUTING.md Installs Flit, the build and packaging tool used by Django Ninja. ```bash pip install flit ``` -------------------------------- ### Resolvers Example Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/response/index.md Example of creating calculated fields using resolve methods. ```python class TaskSchema(Schema): id: int title: str is_completed: bool owner: Optional[str] = None lower_title: str @staticmethod def resolve_owner(obj): if not obj.owner: return return f"{obj.owner.first_name} {obj.owner.last_name}" def resolve_lower_title(self, obj): return self.title.lower() ``` -------------------------------- ### Aliases Example 3 Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/response/index.md Example of using aliases to call methods on the object. ```python class TaskSchema(Schema): type: str = Field(None) type_display: str = Field(None, alias="get_type_display") # callable will be executed ``` -------------------------------- ### URL Configuration Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/versioning.md Example of configuring URLs to serve different API versions. ```python ... from api_v1 import api as api_v1 from api_v2 import api as api_v2 urlpatterns = [ ... path('api/v1/', api_v1.urls), path('api/v2/', api_v2.urls), ] ``` -------------------------------- ### ORJSON Parser Installation Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/input/request-parsers.md Command to install the orjson library. ```bash pip install orjson ``` -------------------------------- ### Install Development Dependencies Source: https://github.com/vitalik/django-ninja/blob/master/CONTRIBUTING.md Installs all dependencies required for development and testing using Flit. ```bash flit install --deps develop --symlink ``` -------------------------------- ### Switch to Redoc Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/api-docs.md Example of how to switch the documentation viewer to Redoc by initializing NinjaAPI with Redoc(). ```python from ninja import Redoc api = NinjaAPI(docs=Redoc()) ``` -------------------------------- ### Custom Pagination Class Example Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/response/pagination.md Example of creating a custom pagination class by subclassing `PaginationBase`. ```python from ninja.pagination import paginate, PaginationBase from ninja import Schema class CustomPagination(PaginationBase): # only `skip` param, defaults to 5 per page class Input(Schema): skip: int class Output(Schema): items: List[Any] # `items` is a default attribute total: int per_page: int def paginate_queryset(self, queryset, pagination: Input, **params): skip = pagination.skip return { 'items': queryset[skip : skip + 5], 'total': queryset.count(), 'per_page': 5, } @api.get('/users', response=List[UserSchema]) @paginate(CustomPagination) def list_users(request): return User.objects.all() ``` -------------------------------- ### Example YAML Request Body Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/input/request-parsers.md An example of a request body formatted in YAML. ```yaml ints: - 0 - 1 string: hello f: 3.14 ``` -------------------------------- ### Async Authenticator Example Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/whatsnew_v1.md Example of an asynchronous authenticator with an async authenticate method. ```Python class Auth(HttpBearer): async def authenticate(self, request, token): await asyncio.sleep(1) if token == "secret": return token ``` -------------------------------- ### Output Schema Example Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/response/index.md Example of defining an output schema and using it in a POST request. ```python from ninja import Schema class UserIn(Schema): username: str password: str class UserOut(Schema): id: int username: str @api.post("/users/", response=UserOut) def create_user(request, data: UserIn): user = User(username=data.username) user.set_password(data.password) user.save() return user ``` -------------------------------- ### API Version 1 Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/versioning.md Example of creating a NinjaAPI instance for version 1.0.0. ```python from ninja import NinjaAPI api = NinjaAPI(version='1.0.0') @api.get('/hello') def hello(request): return {'message': 'Hello from V1'} ``` -------------------------------- ### Project URL Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/help.md The URL to share on social media to promote the project. ```text https://django-ninja.dev ``` -------------------------------- ### Schema.Meta Example Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/whatsnew_v1.md Example showing the usage of the 'Meta' class for ModelSchema, similar to Django's ModelForms. ```Python class TxItem(ModelSchema): class Meta: model = Transaction fields = ["id", "account", "amount", "timestamp"] ``` -------------------------------- ### Using Schema for GET parameters Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/input/query-params.md Encapsulating GET parameters using a Schema. ```python from datetime import date from typing import List, Optional from fastapi import FastAPI from pydantic import BaseModel from ninja import NinjaAPI class QuerySchema(BaseModel): offset: int = 0 limit: int = 10 q: Optional[str] = None api = NinjaAPI() @api.get("/weapons", response=List[str]) def list_weapons(request, query_params: QuerySchema): return weapons[query_params.offset : query_params.offset + query_params.limit] ``` -------------------------------- ### API Version 2 Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/versioning.md Example of creating a NinjaAPI instance for version 2.0.0. ```python from ninja import NinjaAPI api = NinjaAPI(version='2.0.0') @api.get('/hello') def hello(request): return {'message': 'Hello from V2'} ``` -------------------------------- ### INSTALLED_APPS Setting Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/reference/management-commands.md Example of how to add 'ninja' to Django's INSTALLED_APPS setting. ```python INSTALLED_APPS = [ ... 'ninja', ] ``` -------------------------------- ### Install Django Ninja Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/whatsnew_v1.md Command to install the latest version of Django Ninja. ```bash pip install -U django-ninja ``` -------------------------------- ### HTTP Bearer Authentication Example Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/authentication.md This example demonstrates HTTP Bearer authentication, where a token is passed in the Authorization header. ```python from ninja import NinjaAPI from ninja.security import HttpBearer class GlobalAuth(HttpBearer): def authenticate(self, request, token): if token == "supersecret": return token api = NinjaAPI(auth=GlobalAuth()) ``` -------------------------------- ### Practical Example: Authentication Check (OPERATION mode) Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/decorators.md An example of a custom decorator to check for a feature flag before executing an operation, demonstrating OPERATION mode. ```python from functools import wraps def require_feature_flag(flag_name): def decorator(func): @wraps(func) def wrapper(request, *args, **kwargs): if not request.user.has_feature(flag_name): return {"error": f"Feature {flag_name} not enabled"} return func(request, *args, **kwargs) return wrapper return decorator router = Router() router.add_decorator(require_feature_flag("new_api")) @router.get("/new-feature") def new_feature(request): return {"feature": "enabled"} ``` -------------------------------- ### Employee Output Schema Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/tutorial/other/crud.md Output schema for an employee, including the ID and other details. ```python class EmployeeOut(Schema): id: int first_name: str last_name: str department_id: int = None birthdate: date = None ``` -------------------------------- ### Create Employee with File Upload Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/tutorial/other/crud.md API endpoint to create an employee, including handling a file upload for the CV. ```python from ninja import UploadedFile, File @api.post("/employees") def create_employee(request, payload: EmployeeIn, cv: File[UploadedFile]): payload_dict = payload.dict() employee = Employee(**payload_dict) employee.cv.save(cv.name, cv) # will save model instance as well return {"id": employee.id} ``` -------------------------------- ### Router with String Paths Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/whatsnew_v1.md Example demonstrating how to add routers using string paths. ```Python api = NinjaAPI() api.add_router('/app1', 'myproject.app1.router') api.add_router('/app2', 'myproject.app2.router') api.add_router('/app3', 'myproject.app3.router') api.add_router('/app4', 'myproject.app4.router') api.add_router('/app5', 'myproject.app5.router') ``` -------------------------------- ### Employee Input Schema Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/tutorial/other/crud.md Input schema for creating an employee, including first name, last name, department ID, and birthdate. ```python from datetime import date from ninja import Schema class EmployeeIn(Schema): first_name: str last_name: str department_id: int = None birthdate: date = None ``` -------------------------------- ### Example Project Structure Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/routers.md Illustrates a typical Django project structure with separate applications for events, news, and blogs. ```text ├── myproject │ └── settings.py ├── events/ │ ├── __init__.py │ └── models.py ├── news/ │ ├── __init__.py │ └── models.py ├── blogs/ │ ├── __init__.py │ └── models.py └── manage.py ``` -------------------------------- ### SessionAuthIsStaff Example Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/authentication.md This example uses `SessionAuthIsStaff` to authenticate users who are either superusers or staff members. A success message is returned if authentication is successful. ```python from ninja.security import SessionAuthIsStaff @api.get("/staff-area", auth=SessionAuthIsStaff()) def staff_view(request): return {"message": "Hello staff member!"} ``` -------------------------------- ### Practical Example: Request Timing Decorator Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/decorators.md An example of a custom decorator to time API requests and append the duration to the response. ```python import time from functools import wraps def timing_decorator(func): @wraps(func) def wrapper(request, *args, **kwargs): start = time.time() result = func(request, *args, **kwargs) duration = time.time() - start if isinstance(result, dict): result["_timing"] = f"{duration:.3f}s" return result return wrapper router = Router() router.add_decorator(timing_decorator) @router.get("/slow") def slow_endpoint(request): time.sleep(1) return {"message": "done"} # Returns: {"message": "done", "_timing": "1.001s"} ``` -------------------------------- ### File Upload Endpoint Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/tutorial/other/crud.md API endpoint for handling file uploads using FileSystemStorage. ```python from django.core.files.storage import FileSystemStorage from ninja import UploadedFile, File STORAGE = FileSystemStorage() @api.post("/upload") def create_upload(request, cv: File[UploadedFile]): filename = STORAGE.save(cv.name, cv) # Handle things further ``` -------------------------------- ### SessionAuthSuperUser Example Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/authentication.md This example uses `SessionAuthSuperUser` to authenticate only users with superuser privileges. A success message is returned if authentication is successful. ```python from ninja.security import SessionAuthSuperUser @api.get("/admin-only", auth=SessionAuthSuperUser()) def admin_view(request): return {"message": "Hello superuser!"} ``` -------------------------------- ### Synchronous API View Example Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/async-support.md A basic synchronous API view that simulates work by sleeping for a specified duration. ```python import time @api.get("/say-after") def say_after(request, delay: int, word: str): time.sleep(delay) return {"saying": word} ``` -------------------------------- ### Aliases Example 2 Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/response/index.md Example of using aliases to access nested attributes using dotted notation. ```python class TaskSchema(Schema): last_message: str = Field(None, alias="message_set.0.text") ``` -------------------------------- ### HTTP Basic Auth Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/authentication.md Example of implementing HTTP Basic Authentication in Django Ninja. ```python from django.http import HttpRequest from ninja.security import HttpBasicAuth @api.get("/users/me", auth=HttpBasicAuth()) def me(request: HttpRequest): return {"username": request.auth.get("username")} ``` -------------------------------- ### Create a custom renderer Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/response/response-renderers.md Example of creating a custom renderer by inheriting from `ninja.renderers.BaseRenderer` and overriding the `render` method. This example defines a plain text renderer. ```python from ninja import NinjaAPI from ninja.renderers import BaseRenderer class MyRenderer(BaseRenderer): media_type = "text/plain" def render(self, request, data, *, response_status): return ... # your serialization here api = NinjaAPI(renderer=MyRenderer()) ``` -------------------------------- ### Async Authentication Support Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/authentication.md Example of defining and using an asynchronous authentication callable. ```python async def async_auth(request): ... @api.get("/pets", auth=async_auth) def pets(request): ... ``` -------------------------------- ### SessionAuth Example Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/authentication.md This example uses Django's default session authentication, authenticating any logged-in user. The username of the authenticated user is returned. ```python from ninja.security import SessionAuth @api.get("/protected", auth=SessionAuth()) def protected_view(request): return {"user": request.auth.username} ``` -------------------------------- ### XML renderer example Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/response/response-renderers.md An example of a custom renderer that outputs all responses as XML. It uses `StringIO` and `SimplerXMLGenerator` for XML generation and sets the `media_type` to `text/xml`. ```python from io import StringIO from django.utils.encoding import force_str from django.utils.xmlutils import SimplerXMLGenerator from ninja import NinjaAPI from ninja.renderers import BaseRenderer class XMLRenderer(BaseRenderer): media_type = "text/xml" def render(self, request, data, *, response_status): stream = StringIO() xml = SimplerXMLGenerator(stream, "utf-8") xml.startDocument() xml.startElement("data", {}) self._to_xml(xml, data) xml.endElement("data") xml.endDocument() return stream.getvalue() def _to_xml(self, xml, data): if isinstance(data, (list, tuple)): for item in data: xml.startElement("item", {}) self._to_to_xml(xml, item) xml.endElement("item") elif isinstance(data, dict): for key, value in data.items(): xml.startElement(key, {}) self._to_xml(xml, value) xml.endElement(key) elif data is None: # Don't output any value pass else: xml.characters(force_str(data)) api = NinjaAPI(renderer=XMLRenderer()) ``` -------------------------------- ### Router Level Throttling Example (Router init) Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/throttling.md Applies throttling when initializing a Router instance. ```Python router = Router(..., throttle=[AnonRateThrottle('1000/h')]) ``` -------------------------------- ### Asynchronous API View Example Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/async-support.md Converts the synchronous view to an asynchronous one using `async` and `asyncio.sleep` for non-blocking I/O. ```python import asyncio @api.get("/say-after") async def say_after(request, delay: int, word: str): await asyncio.sleep(delay) return {"saying": word} ``` -------------------------------- ### Create Employee Endpoint Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/tutorial/other/crud.md API endpoint to create a new employee using the EmployeeIn schema. ```python @api.post("/employees") def create_employee(request, payload: EmployeeIn): employee = Employee.objects.create(**payload.dict()) return {"id": employee.id} ``` -------------------------------- ### Session Authentication Example Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/authentication.md This example demonstrates how to use Django session authentication, which is the default cookie-based method. An HTTP-401 error will be returned if the client does not use session authentication. ```python from ninja import NinjaAPI api = NinjaAPI() @api.get("/pets") def pets(request): return {"hello": "world"} ``` -------------------------------- ### Configurable Docs Viewers Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/whatsnew_v1.md Examples of how to configure different documentation viewers (Redoc, Swagger) for the API. ```Python from ninja import NinjaAPI, Redoc, Swagger # use redoc api = NinjaAPI(docs=Redoc())) # use swagger: api = NinjaAPI(docs=Swagger()) # set configuration for swagger: api = NinjaAPI(docs=Swagger({"persistAuthorization": True})) ``` -------------------------------- ### Configure URLs Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/tutorial/index.md Add the API to the project's urls.py. ```python from django.contrib import admin from django.urls import path from .api import api urlpatterns = [ path("admin/", admin.site.urls), path("api/", api.urls), ] ``` -------------------------------- ### Input from the path parameters Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/tutorial/step2.md This example shows how to declare path parameters using Python format-string syntax, which are then passed as arguments to the function. ```python @api.get("/math/{a}and{b}") def math(request, a: int, b: int): return {"add": a + b, "multiply": a * b} ``` -------------------------------- ### List of files with extra info Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/input/file-params.md Example for handling a list of files with extra info. ```python @api.post('/users') def create_user(request, details: Form[UserDetails], files: File[list[UploadedFile]]): return [details.dict(), [f.name for f in files]] ``` -------------------------------- ### Get Single Employee Endpoint Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/tutorial/other/crud.md API endpoint to retrieve a single employee by ID, using EmployeeOut as the response schema. ```python @api.get("/employees/{employee_id}", response=EmployeeOut) def get_employee(request, employee_id: int): employee = get_object_or_404(Employee, id=employee_id) return employee ``` -------------------------------- ### Handling different input types with type hints Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/tutorial/step2.md This code shows how to use Python type hints to specify input types for arguments. It includes a 'hello' function with a string argument and a 'math' function with integer arguments. ```python @api.get("/hello") def hello(request, name: str = "world"): return f"Hello {name}" @api.get("/math") def math(request, a: int, b: int): return {"add": a + b, "multiply": a * b} ``` -------------------------------- ### CursorPagination with Custom Parameters Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/response/pagination.md Example of setting custom parameters for CursorPagination directly in the view function. ```python @api.get("/events") @paginate(CursorPagination, ordering=("start_date", "end_date"), page_size=20, max_page_size=100) def list_events(request): return Event.objects.all() ``` -------------------------------- ### CursorPagination Usage Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/response/pagination.md Example of how to use CursorPagination with a Django Ninja API endpoint. ```python from ninja.pagination import paginate, CursorPagination @api.get('/events', response=List[EventSchema]) @paginate(CursorPagination) def list_events(request): return Event.objects.all() ``` -------------------------------- ### Employee and Department Models Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/tutorial/other/crud.md Django models for Department and Employee, including fields for name, department, birthdate, and CV. ```python from django.db import models class Department(models.Model): title = models.CharField(max_length=100) class Employee(models.Model): first_name = models.CharField(max_length=100) last_name = models.CharField(max_length=100) department = models.ForeignKey(Department, on_delete=models.CASCADE) birthdate = models.DateField(null=True, blank=True) cv = models.FileField(null=True, blank=True) ``` -------------------------------- ### Serve Documentation Locally Source: https://github.com/vitalik/django-ninja/blob/master/CONTRIBUTING.md Serves the project documentation locally using mkdocs for real-time preview. ```bash cd docs/ mkdocs serve ``` -------------------------------- ### Annotated Parameters Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/whatsnew_v1.md Example using typing.Annotated with Form parameters. ```Python @api.get("/annotated") def annotated(request, data: Annotated[SomeData, Form()]): return {"data": data.dict()} ``` -------------------------------- ### Run ASGI Server with Uvicorn Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/async-support.md Start the Uvicorn server for your Django project. Replace `your_project` with your actual project name. The `--reload` flag is useful for development. ```bash uvicorn your_project.asgi:application --reload ``` -------------------------------- ### API Key Authentication in Header Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/authentication.md This example shows API key authentication using a request header, specifically the `X-API-Key` header. ```python from ninja.security import APIKeyHeader api = NinjaAPI(auth=APIKeyHeader(name="X-API-Key")) ``` -------------------------------- ### Router Level Throttling Example (add_router) Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/throttling.md Applies throttling to all operations within a specific router. ```Python api = NinjaAPI() ... api.add_router('/sensitive', 'myapp.api.router', throttle=AnonRateThrottle('100/m')) ``` -------------------------------- ### Testing with Django Test Client Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/testing.md Demonstrates how to test the '/hello' API endpoint using Django's TestCase and Ninja's TestClient. ```python from django.test import TestCase from ninja.testing import TestClient class HelloTest(TestCase): def test_hello(self): # don't forget to import router from code above client = TestClient(router) response = client.get("/hello") self.assertEqual(response.status_code, 200) self.assertEqual(response.json(), {"msg": "Hello World"}) ``` -------------------------------- ### Specifying servers for OpenAPI Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/reference/operations-parameters.md Example of specifying single or multiple servers for OpenAPI specification using the servers parameter when initializing NinjaAPI. ```python from ninja import NinjaAPI api = NinjaAPI( servers=[ {"url": "https://stag.example.com", "description": "Staging env"}, {"url": "https://prod.example.com", "description": "Production env"}, ] ) # This will allow switching between environments when using interactive OpenAPI docs: # ![Servers](../img/servers.png) ``` -------------------------------- ### List Employees Endpoint Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/tutorial/other/crud.md API endpoint to retrieve a list of all employees, using a List of EmployeeOut as the response schema. ```python from typing import List @api.get("/employees", response=List[EmployeeOut]) def list_employees(request): qs = Employee.objects.all() return qs ``` -------------------------------- ### Input from the request body using a Schema Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/tutorial/step2.md This code demonstrates how to accept arguments from the request body by declaring a Schema. The 'hello' operation is changed to use HTTP POST and takes a 'name' from the request body. ```python from ninja import NinjaAPI, Schema api = NinjaAPI() class HelloSchema(Schema): name: str = "world" @api.post("/hello") def hello(request, data: HelloSchema): return f"Hello {data.name}" ``` -------------------------------- ### Specifying Headers Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/testing.md Demonstrates how to specify headers for the test client, both during instantiation and for individual requests. ```python client = TestClient(router, headers={"A": "a", "B": "b"}) # The request will be made with {"A": "na", "B": "b", "C": "nc"} headers response = client.get("/test-headers", headers={"A": "na", "C": "nc"}) ``` -------------------------------- ### Multiple Authenticators Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/authentication.md Demonstrates using multiple authentication methods, prioritizing API key from GET, then header. ```python from ninja.security import ApiKeyCookieAuth, HttpBearer api.add_router( "/users/", users_router, auth=(ApiKeyCookieAuth(cookie_name="session"), HttpBearer()), ) ``` -------------------------------- ### Aliases Example 1 Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/response/index.md Example of using aliases to rename fields and flatten nested responses. ```python from ninja import Field, Schema class TaskSchema(Schema): id: int title: str # The first Field param is the default, use ... for required fields. completed: bool = Field(..., alias="is_completed") owner_first_name: str = Field(None, alias="owner.first_name") ``` -------------------------------- ### Update Employee Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/tutorial/other/crud.md This code snippet shows how to update an existing employee record using the PUT method. ```python @api.put("/employees/{employee_id}") def update_employee(request, employee_id: int, payload: EmployeeIn): employee = get_object_or_404(Employee, id=employee_id) for attr, value in payload.dict().items(): setattr(employee, attr, value) employee.save() return {"success": True} ``` -------------------------------- ### Nested Objects Schema Example Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/response/index.md Example of defining a schema with nested objects for tasks and their owners. ```python from typing import List from ninja import Schema class UserSchema(Schema): id: int first_name: str last_name: str class TaskSchema(Schema): id: int title: str is_completed: bool owner: UserSchema = None # ! None - to mark it as optional @api.get("/tasks", response=List[TaskSchema]) def tasks(request): queryset = Task.objects.select_related("owner") return list(queryset) ``` -------------------------------- ### Bearer Token Authentication Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/authentication.md This example shows how a client can authenticate by passing a header with a Bearer token. The token format is 'Authorization: Bearer supersecret'. ```python from ninja import NinjaAPI from ninja.security import HttpBearer class GlobalAuth(HttpBearer): def authenticate(self, request, token): if token == "supersecret": return token api = NinjaAPI(auth=GlobalAuth()) @api.get("/pets") def pets(request): return {"hello": "world"} ``` -------------------------------- ### Different Business Logic APIs Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/versioning.md Example of defining separate NinjaAPI instances for different business logic or components, using different authentication and URL namespaces. ```python ... api = NinjaAPI(auth=token_auth, urls_namespace='public_api') ... api_private = NinjaAPI(auth=session_auth, urls_namespace='private_api') ... urlpatterns = [ ... path('api/', api.urls), path('internal-api/', api_private.urls), ] ``` -------------------------------- ### API Key Authentication in Cookie Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/authentication.md This example demonstrates API key authentication where the key is sent as a cookie, using the `X-API-KEY` cookie name. ```python from ninja.security import APIKeyCookie api = NinjaAPI(auth=APIKeyCookie(name="X-API-KEY")) ``` -------------------------------- ### Basic query parameters Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/input/query-params.md Demonstrates how to declare and use basic query parameters. ```python from typing import List from fastapi import FastAPI from ninja import NinjaAPI api = NinjaAPI() @api.get("/weapons") def list_weapons(request, offset: int, limit: int): return weapons[offset : offset + limit] ``` -------------------------------- ### Protecting docs with authentication Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/api-docs.md Example of protecting the API documentation with authentication using the 'docs_decorator' argument. ```python from django.contrib.admin.views.decorators import staff_member_required api = NinjaAPI(docs_decorator=staff_member_required) ``` -------------------------------- ### Using 'fields' argument Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/response/django-pydantic-create-schema.md Example demonstrating how to use the 'fields' argument to include only specific fields in the generated schema. ```python UserSchema = create_schema(User, fields=['id', 'username']) ``` -------------------------------- ### Nested schema example Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/response/django-pydantic-create-schema.md An example of a nested schema generated for a ManyToMany field when 'depth' is used. ```python class Group(Schema): id: int name: str permissions: List[int] ``` -------------------------------- ### Multiple response types Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/tutorial/step3.md This example demonstrates handling multiple response types by returning a different schema for authenticated and unauthenticated users. It uses a tuple to specify the HTTP response code and data, returning an error message for unauthenticated users. ```python class UserSchema(Schema): username: str email: str first_name: str last_name: str class Error(Schema): message: str @api.get("/me", response={200: UserSchema, 403: Error}) def me(request): if not request.user.is_authenticated: return 403, {"message": "Please sign in first"} return request.user ``` -------------------------------- ### Redoc Initialization Script Source: https://github.com/vitalik/django-ninja/blob/master/ninja/templates/ninja/redoc_cdn.html This script initializes Redoc using configuration from a JSON string embedded in the HTML and fetches the OpenAPI specification from a specified URL. ```html {{ api.title }}
``` -------------------------------- ### Redoc Initialization Source: https://github.com/vitalik/django-ninja/blob/master/ninja/templates/ninja/redoc.html Initializes the Redoc UI with OpenAPI JSON URL and configuration settings. ```javascript const configJson = document.getElementById("redoc-settings").textContent; const configObject = JSON.parse(configJson); const element = document.getElementById('redoc-ui'); Redoc.init('{{ openapi_json_url }}', configObject, element); ``` -------------------------------- ### Multiple response schemas example Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/response/index.md Example of defining multiple response schemas for different HTTP status codes. ```python from ninja import Status class Token(Schema): token: str expires: date class Message(Schema): message: str @api.post('/login', response={200: Token, 401: Message, 402: Message}) def login(request, payload: Auth): if auth_not_valid: return Status(401, {'message': 'Unauthorized'}) if negative_balance: return Status(402, {'message': 'Insufficient balance amount. Please proceed to a payment page.'}) return Status(200, {'token': xxx, ...}) ``` -------------------------------- ### Multiple API Versions with Django Ninja Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/motivation.md Demonstrates how to set up multiple API version instances within a single Django project using Django Ninja. ```python api_v1 = NinjaAPI(version='1.0', auth=token_auth) ... api_v2 = NinjaAPI(version='2.0', auth=token_auth) ... api_private = NinjaAPI(auth=session_auth, urls_namespace='private_api') ... urlpatterns = [ ... path('api/v1/', api_v1.urls), path('api/v2/', api_v2.urls), path('internal-api/', api_private.urls), ] ``` -------------------------------- ### Load Test API Endpoint with ApacheBench Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/async-support.md Use ApacheBench (ab) to send 100 concurrent requests to the API endpoint to measure performance under load. ```bash ab -c 100 -n 100 "http://127.0.0.1:8000/api/say-after?delay=3&word=hello" ``` -------------------------------- ### Accepting a name from the query string Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/tutorial/step2.md This code snippet shows how to add a 'name' argument to a function to accept input from the URL's query string. ```python from ninja import NinjaAPI api = NinjaAPI() @api.get("/hello") def hello(request, name): return f"Hello {name}" ``` -------------------------------- ### Decorator Example (Working with decorate_view) Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/whatsnew_v1.md Demonstrates the use of `decorate_view` to apply decorators that work with HTTP responses to Django Ninja API views. ```python from ninja.decorators import decorate_view @api.get("/test") @decorate_view(cache_page(5)) def test_view(request): return str(datetime.now()) ``` -------------------------------- ### Pydantic Context Example Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/whatsnew_v1.md Example demonstrating how to use Pydantic context to access the request object within a Schema. ```Python class Payload(Schema): id: int name: str request_path: str @staticmethod def resolve_request_path(data, context): request = context["request"] return request.get_full_path() ``` -------------------------------- ### Example - Integer type hint Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/index.md Declaring an integer parameter using standard Python type hints. ```python a: int ``` -------------------------------- ### ORJSON renderer example Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/response/response-renderers.md An example of a custom renderer that uses the `orjson` library for fast and accurate JSON serialization. It sets the `media_type` to `application/json`. ```python import orjson from ninja import NinjaAPI from ninja.renderers import BaseRenderer class ORJSONRenderer(BaseRenderer): media_type = "application/json" def render(self, request, data, *, response_status): return orjson.dumps(data) api = NinjaAPI(renderer=ORJSONRenderer()) ``` -------------------------------- ### Custom Exceptions for Authentication Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/authentication.md Illustrates how custom exceptions with handlers can manage authentication errors. ```python from ninja.errors import AuthenticationError class InvalidAuthError(AuthenticationError): def __init__(self, message="Invalid authentication credentials"): self.message = message @api.get("/items", auth=BearerAuth()) def items(request): return {"message": "You are authenticated"} ``` -------------------------------- ### Global Authentication with Override Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/authentication.md This example demonstrates setting a global authentication method for all API operations using `NinjaAPI(auth=GlobalAuth())`. It also shows how to override this for a specific operation, like disabling authentication for the `/token` operation. ```python from ninja import NinjaAPI, Form from ninja.security import HttpBearer class GlobalAuth(HttpBearer): def authenticate(self, request, token): if token == "supersecret": return token api = NinjaAPI(auth=GlobalAuth()) @api.get("/token") def token(request): return {"token": "this-is-a-token"} ``` -------------------------------- ### Async endpoint returning queryset Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/response/index.md Example of an async endpoint returning a queryset. Note: This specific example might not work as intended due to ORM call safety in async contexts. ```python @api.get("/tasks", response=List[TaskSchema]) async def tasks(request): return Task.objects.all() ``` -------------------------------- ### Custom exception handler example Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/errors.md This example demonstrates how to create a custom exception and register a handler for it using the `@api.exception_handler` decorator. The handler intercepts the custom exception and returns a specific HTTP response. ```python api = NinjaAPI() class ServiceUnavailableError(Exception): pass # initializing handler @api.exception_handler(ServiceUnavailableError) def service_unavailable(request, exc): return api.create_response( request, {"message": "Please retry later"}, status=503, ) # some logic that throws exception @api.get("/service") def some_operation(request): if random.choice([True, False]): raise ServiceUnavailableError() return {"message": "Hello"} ``` -------------------------------- ### Using LimitOffsetPagination Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/response/pagination.md Shows how to explicitly use the `LimitOffsetPagination` class with the `paginate` decorator. ```python from ninja.pagination import paginate, LimitOffsetPagination @api.get('/users', response=List[UserSchema]) @paginate(LimitOffsetPagination) def list_users(request): return User.objects.all() ``` -------------------------------- ### Applying paginate decorator Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/response/pagination.md Demonstrates how to apply the `paginate` decorator to a view function to enable pagination. ```python from ninja.pagination import paginate @api.get('/users', response=List[UserSchema]) @paginate def list_users(request): return User.objects.all() ``` -------------------------------- ### Async-Only Decorator Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/decorators.md An example of an asynchronous decorator for routers containing only async endpoints. ```python def async_timing_decorator(func): @wraps(func) async def wrapper(request, *args, **kwargs): start = time.time() result = await func(request, *args, **kwargs) duration = time.time() - start if isinstance(result, dict): result["_timing"] = f"{duration:.3f}s" return result return wrapper router = Router() router.add_decorator(async_timing_decorator) @router.get("/async") async def async_endpoint(request): await asyncio.sleep(1) return {"message": "async done"} ``` -------------------------------- ### Default API Configuration Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/input/request-parsers.md Example of configuring a custom parser for the NinjaAPI. ```python api = NinjaAPI(parser=MyYamlParser()) ``` -------------------------------- ### Providing a default value for a query string argument Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/tutorial/step2.md This snippet demonstrates how to specify a default value for the 'name' argument, which will be used if the argument is not provided in the query string. ```python @api.get("/hello") def hello(request, name="world"): return f"Hello {name}" ``` -------------------------------- ### Setting Cookies and Headers Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/response/temporal_response.md Example of how to set a cookie and a header on the response object. ```python from django.http import HttpRequest, HttpResponse @api.get("/cookie/") def feed_cookiemonster(request: HttpRequest, response: HttpResponse): # Set a cookie. response.set_cookie("cookie", "delicious") # Set a header. response["X-Cookiemonster"] = "blue" return {"cookiemonster_happy": True} ``` -------------------------------- ### Get Q-expression for custom filtering Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/input/filtering.md Retrieve the prepared Q-expression for custom queryset filtering. ```python @api.get("/books") def list_books(request, filters: Query[BookFilterSchema]): # Never serve books from inactive publishers and authors q = Q(author__is_active=True) | Q(publisher__is_active=True) # But allow filtering the rest of the books q &= filters.get_filter_expression() return Book.objects.filter(q) ``` -------------------------------- ### Applying Pagination to Main API Instance Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/response/pagination.md Shows how to apply pagination globally to the main API instance using the default_router argument. ```python api = NinjaAPI(default_router=RouterPaginated()) @api.get(...) ``` -------------------------------- ### Django HTTP Responses - Redirect Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/response/index.md Example of returning a Django redirect from an API endpoint. ```python from django.http import HttpResponse from django.shortcuts import redirect @api.get("/something") def some_redirect(request): return redirect("/some-path") # !!!! ``` -------------------------------- ### Self-referencing schemes Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/response/index.md Example of creating a schema that references itself, using quotes for the type and model_rebuild(). ```python class Organization(Schema): title: str part_of: 'Organization' = None #!! note the type in quotes here !! Organization.model_rebuild() # !!! this is important @api.get('/organizations', response=List[Organization]) def list_organizations(request): ... ``` -------------------------------- ### Returning querysets Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/response/index.md Example of an endpoint that returns a Django queryset, which will be automatically evaluated to a List. ```python @api.get("/tasks", response=List[TaskSchema]) def tasks(request): return Task.objects.all() ``` -------------------------------- ### Query parameters with default values Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/input/query-params.md Shows how to set default values for query parameters. ```python @api.get("/weapons") def list_weapons(request, limit: int = 10, offset: int = 0): return weapons[offset : offset + limit] ``` -------------------------------- ### CursorPagination with Page Size Override Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/response/pagination.md Example of overriding the default page size for CursorPagination in a request. ```http /api/events?cursor=eyJwIjoiMjAyNC0wMS0wMSIsInIiOmZhbHNlLCJvIjowfQ==&page_size=5 ``` -------------------------------- ### Overriding create_temporal_response Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/response/temporal_response.md Example of how to override the create_temporal_response method to alter the base response object. ```python def create_temporal_response(self, request: HttpRequest) -> HttpResponse: response = super().create_temporal_response(request) # Do your magic here... return response ``` -------------------------------- ### Example JSON Output Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/input/request-parsers.md The expected JSON output after parsing the YAML request body. ```json { "ints": [ 0, 1 ], "string": "hello", "f": 3.14 } ``` -------------------------------- ### Creating custom docs viewer Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/api-docs.md Example of creating a custom documentation viewer by inheriting from DocsBase and overwriting the render_page method. ```python from ninja.openapi.docs import DocsBase class MyDocsViewer(DocsBase): def render_page(self, request, api): ... # return http response ... api = NinjaAPI(docs=MyDocsViewer()) ``` -------------------------------- ### Django HTTP Responses - HttpResponse Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/guides/response/index.md Example of returning a regular Django HttpResponse from an API endpoint. ```python from django.http import HttpResponse from django.shortcuts import redirect @api.get("/http") def result_django(request): return HttpResponse('some data') # !!!! ``` -------------------------------- ### Delete Employee Source: https://github.com/vitalik/django-ninja/blob/master/docs/docs/tutorial/other/crud.md This code snippet shows how to delete an employee record using the DELETE method. ```python @api.delete("/employees/{employee_id}") def delete_employee(request, employee_id: int): employee = get_object_or_404(Employee, id=employee_id) employee.delete() return {"success": True} ```