Giter Site home page Giter Site logo

vitalik / django-ninja Goto Github PK

View Code? Open in Web Editor NEW
6.2K 73.0 369.0 6.23 MB

πŸ’¨ Fast, Async-ready, Openapi, type hints based framework for building APIs

Home Page: https://django-ninja.dev

License: MIT License

Python 98.19% HTML 0.83% Shell 0.12% Dockerfile 0.36% Makefile 0.19% JavaScript 0.31%
python django rest-api openapi pydantic swagger swagger-ui django-ninja

django-ninja's Introduction

SCR-20230123-m1t

^ Please read ^

Fast to learn, fast to code, fast to run

Test Coverage PyPI version Downloads

Django Ninja - Fast Django REST Framework

v1.0 What's new

Read more details here - https://django-ninja.dev/whatsnew_v1/

Or Watch here:

SCR-20231116-qmoj

Django Ninja is a web framework for building APIs with Django and Python 3.6+ type hints.

Key features:

  • Easy: Designed to be easy to use and intuitive.
  • FAST execution: Very high performance thanks to Pydantic and async support.
  • Fast to code: Type hints and automatic docs lets you focus only on business logic.
  • Standards-based: Based on the open standards for APIs: OpenAPI (previously known as Swagger) and JSON Schema.
  • Django friendly: (obviously) has good integration with the Django core and ORM.
  • Production ready: Used by multiple companies on live projects (If you use django-ninja and would like to publish your feedback, please email [email protected]).

Django Ninja REST Framework

Documentation: https://django-ninja.dev


Installation

pip install django-ninja

Usage

In your django project next to urls.py create new api.py file:

from ninja import NinjaAPI

api = NinjaAPI()


@api.get("/add")
def add(request, a: int, b: int):
    return {"result": a + b}

Now go to urls.py and add the following:

...
from .api import api

urlpatterns = [
    path("admin/", admin.site.urls),
    path("api/", api.urls),  # <---------- !
]

That's it !

Now you've just created an API that:

  • receives an HTTP GET request at /api/add
  • takes, validates and type-casts GET parameters a and b
  • decodes the result to JSON
  • generates an OpenAPI schema for defined operation

Interactive API docs

Now go to http://127.0.0.1:8000/api/docs

You will see the automatic interactive API documentation (provided by Swagger UI or Redoc):

Swagger UI

What next?

django-ninja's People

Contributors

aasiffaizal avatar aliereno avatar antonrh avatar areski avatar barseghyanartur avatar baseplate-admin avatar c4ffein avatar chenatlas avatar chris-mcdo avatar dependabot[bot] avatar flaeppe avatar fojetin avatar gtbebbo avatar hbutau avatar hiaselhans avatar hyoungsooo avatar ivoire avatar jairhenrique avatar jkeyes avatar jlucas91 avatar jonklo avatar marksweb avatar nofalx avatar otherbarry avatar pawelngei avatar smileychris avatar stephane avatar stephenrauch avatar vitalik avatar wimolivier avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

django-ninja's Issues

How to upload images?

Thanks for this amazing tool. Quick question: how do you set up an API route that allows users to upload images?

Response schema from annotation

In this moment ninja use decorator param to find response schema.

@api.post('/login', response={200: Token, 401: Message, 402: Message})
@api.get("/tasks", response=List[TaskSchema])
@api.post("/users/", response=UserOut)

I think we should use python annotation like as request schemas
def login(request, payload: Auth) -> {200: Token, 401: Message, 402: Message}):
def tasks(request) -> List[TaskSchema]:
def create_user(request, data: UserIn) -> UserOut:

We can take this schema funcion.__annotations__.get('return')

@vitalik what you think about this enhancement? I want take on this task!

Authentication Support

This project is amazing work that you did, but do you have any plan for an Athentication system for generating tokens and resetting the user's password and etc?, I mean for now should I do all of it manually right?

CORS, adding headers to response

Dear @vitalik , this comment also not an issue, but more look like a question or proposal. But I really happy with using django-ninja, and faced to a problem, when it's required to add some key values to response header. Instead I've added middleware app to do that, but it breaks some logic for me.

Using form parameters in generated API documentation

Hi,
I'm pretty new to API programming so please bear with me.

I am trying to define login endpoint which will take username and password as form parameters, like this:

@router.post("/token")
def get_token(request, username: str = Form(...), password: str = Form(...)):
    return {username: password}

Generated API docs will display endpoint and form parameters correctly, however when I try using the endpoint through the docs it will generate curl like this:

curl -X POST "http://localhost:8000/api/token" -H  "accept: */*" -d ""

and the error I get is code 422 Undocumented | Error: Unprocessable Entity
with response:

{
  "detail": [
    {
      "loc": [
        "form",
        "username"
      ],
      "msg": "field required",
      "type": "value_error.missing"
    },
    {
      "loc": [
        "form",
        "password"
      ],
      "msg": "field required",
      "type": "value_error.missing"
    }
  ]

Looks like the parameters and their values are not passed to the generated API call.

If I do a manual curl call like this:

curl -X POST -F 'username=myusername' -F 'password=mypassword' http://localhost:8000/api/token

everything works as expected.
Thanks in advance!

Typing improvements

Hi! Thanks a lot for building this project. It looks really interesting.

I have seen that your docs says that

Type hints and automatic docs let's you focus only on business logic

But, there are some things to improve in this field:

  1. You are missing py.typed file in the root, example: https://github.com/dry-python/returns/blob/master/returns/py.typed Without this file mypy won't be able to know that sources are typed
  2. mypy support! This is very important for end users of typed libs. I was not able to find any mypy references in the CI
  3. django-stubs support. I have seen that you have troubles typing HttpRequest and HttpResponse. That's what django-stubs can solve! https://github.com/typeddjango/django-stubs

Cheers! πŸ‘

[proposal] Suggestion for improvements response schema

Hi, i have some humble ideas.

Function in multiple response dict

Now we have routes like @router.get("/check_model", response={200: UserModel, 202: UserModel}) It's case from tests.

And i'm really frustrated that we must duplicate Schema (UserModel) for many cases.
I suggest allow functions as key to multiple response.

we can do it cause functions is immutable

Examples of enhancement usage:

@router.get("/check_model", response={lambda x: x >= 200 and x < 300: UserModel})

or

def response_200(n):
    return n >= 200 and n < 300
from helpers import response_200


@router.get("/check_model", response={response_200: UserModel})

Default response schema

Also i want to set default response schema, for example for errors

We can use functions for this:

@router.get("/check_model", response={response_200: UserModel, lambda x: True: ErrorModel})

It will work because we check status_codes sequentially from left to right.

or we can add special status like 0 or 'default'

REST implementation of the Django authentication

Hi,

This is not an issue, but rather a proposal.

I came by Django-Ninja a few days ago while surfing the Internet. This is beyond great, I would love to contribute.

An essential feature IMHO is to develop a REST implementation of the Django authentication system with Ninja instead of DRF. I have used Djoser before, which exactly that but implemented with DRF.

Is that in your plans? What can I do to help?

response schema openapi

the docs state that the response schema gets documented but im unable to see it.

am i doing something wrong?

Composable query parameters

I really enjoy using Schemas as you've defined and configured them for this project. However, I'm running into some issues when using a Schema with a list of strings in my query parameters. I've documented an example below of this issue.

I've got my filters as such...

class Filters(Schema):
    tags: List[str] = []

    def __init__(self, **data):
        print(data)
        super().__init__(**data)

I've used the init method for debugging, which I'll address in a bit.

My view function as...

@api.get("")
def search_tagged_objects(request, filters: Filters = Query(...)):
    pass

The Swagger documentation is generated correctly, yay! But unfortunately, when I actually pass in a tag (or multiple tags) to the filter (either through the Swagger documentation or a request URL), I'm met with the error displayed below.

Screen Shot 2020-11-08 at 5 49 53 PM

When I print out the data passed to the Filters object, I'm met with the output...

{'tags': 'Tag A'}

... which is not the list of strings that I wanted to pass in.

The temporary fix that I've gotten working thus far is to NOT use a Schema model, and instead write the function definition as such...

def search_tagged_objects(request, tags: List[str] = Query(...)):

And while this totally works, it seems a bit messy. I've got 7 filters that I'd like to incorporate into a single function, and I've got pagination parameters (basically limit and offset) that I'd like to use for this function, as well as other functions. The issue seems to be solely with using a list inside an object in the query parameters.

I checked the tests and it doesn't look like this use case is covered (but correct me if I'm wrong). Let me know if this is something you'd like me to look at more, I'm happy to write some tests and submit a PR. I really do like how the documentation generated is correct (for both using the Filters and function-inline specifications), I'd like to add some small quality of life changes to this though.

[proposal] Class Based Operations

Read full proposal here - http://django-ninja.rest-framework.com/proposals/cbv/

To allow incapsulate common logic into class methods

from ninja import Router


router = Router()


@router.path('/project/{project_id}/tasks')
class Tasks:

    def __init__(self, request, project_id=int):
        user_projects = request.user.project_set
        self.project = get_object_or_404(user_projects, id=project_id))
        self.tasks = self.project.task_set.all()


    @router.get('/', response=List[TaskOut])
    def task_list(self, request):
        return self.tasks

    @router.get('/{task_id}/', response=TaskOut)
    def details(self, request, task_id: int):
        return get_object_or_404(self.tasks, id=task_id)

Spelling/Grammar Corrections

I've glanced over various pages of documentation, and I've noticed a few spelling/grammar mistakes. Would you like me to make a PR for fixes?

Reverse-able url names.

I'd like to be able to do something like:

@router.post('/foo/', name='bar')

Which would allow me to do reverse('api-1.0.0:bar') in order to dynamically get the URL without needing to hard code it. It looks like if this line is updated to pass in an optional name, then I think it could work.

If I'm reading the code correctly, all the METHODs (get/post/etc) would need to be updated to take an optional name (or url_name or something) argument. Additionally, api_operation and add_api_operation would need to be updated to take the same optional argument. Lastly, I think something like how self.operations is being updated in add_api_operation would need to be added to tell urls_paths what the names are.

I don't know how off base I am here. Let me know what you think.

Super slick library by the way. Big fan.

Edit:

Alternatively, some kind of auto-generated name based on the app the end point is in + the path would also work.

If we have @router.post('foo/bar/') in an app called baz, an auto-name of something like baz_foo_bar so we could reverse('api-1.0.0:baz_foo_bar') could be pretty slick. This solution has the by product of not needing to update nearly as much code.

Authentication is not working on router.

I was trying to add authentication on routers but it's not working. Below is the code snippet how I am implement the authentication.

api.py file

api = NinjaAPI(version="1.0.0", auth=TokenAuthentication())
api.add_router('/', account_router)

routers.py file

from ninja import Router
router = Router()


@router.post("/login")
def login(request):
    pass

@router.post("/register")
def register(request):
    pass

Empty body and Schema with all optional attributes

Hi, @vitalik. Is it a bug?

When i send request with empty body, i getting this error

    "detail": [
        {
            "loc": [
                "body",
                "data"
            ],
            "msg": "field required",
            "type": "value_error.missing"
        }
    ]
}

It happens because when we get None from cls.get_request_data(request, path_params)
this code always crash

        if data is None:
            return cls()

image

OperationID API schema attribute support

I'm a new user to your library β€” just discovered on Reddit a few days ago. Apologies if this was answered elsewhere.

OpenAPI supports a parameter called operationId, which provides an API-unique discriminator for an endpoint. There is annoyingly no hotlink to the relevant section; OpenAPI's docs could use improving:

https://swagger.io/docs/specification/paths-and-operations/

The ID isn't particularly useful for humans (it doesn't appear at all in the docs), but for a programmable client it is particularly useful as it avoids all the clutter of needing to deal with URL templates, method, and headers β€” you can just provide the operationId along with any arguments the endpoint requres.

If it's not too bold to point out, I use these today in FastAPI and would love to see β€” or bring β€” this support in/to django-ninja, if there's enough interest (and maybe a little help; I'm not a fantastic coder).

Http404 exception

Shortcuts are useful to follow the DRY philosophy. For that, I think we must create a shortcuts file to overwrite the commonly-used functions in Django as get_object_or_404.
Here I let my contribution :)

from django.http import Http404
from django.shortcuts import get_object_or_404 as dj_get_object_or_404

def get_object_or_404(klass, *args, **kwargs):
    try:
        return dj_get_object_or_404(klass, *args, **kwargs)
    except Http404:
        return Response({}, status=404)

Sync style code with non-blocking I/O?

I can't tell for sure from the docs whether this is as I think it is but here goes:

I love this project for the pydantic integration and not forcing me to choose between that and django.

For our new project at my company I'd prefer me and my team to write our new service with sync style code. gunicorn with gevent workers seems ideal for this. It monkey patches the most commonly used libraries for I/O such that even though we're not writing explicit async code, we have non-blocking I/O in the most important places. Sure, this is not the style to get every last drop of performance. It doesn't lend itself to sending a bunch of requests in parallel for instance. But for this project that's not a concern so I'd prefer not to add the overhead of forcing people think async and not risk a PR with a missing await that causes our event loop to block.

Have I described the above correctly? If so, is there a neat monkey patching solution for such that I can call a database in a sync method without worrying?

I'm new to python so I might be skipping over something that's obvious to anyone who knows its newer async abilities.

[proposal] router parameters

Hi vitalik,

This project is magical, I cannot imagine myself developing APIs using anything else from now on, I'm actually in the process of migrating two projects to Ninja already! πŸ™‚

I have an enhancement proposal for the router, I repetitively configure each route for auth, tags, response, etc. if it is possible to configure these generally in the router.

Examples:
instead of

staff_router = Router()


@staff.get('/orders',
           tags=['staff'],
           auth=IsAuthorized(staff_auth),
           response={200: List[InventoryOrderSchemaOut]}
           )

@staff.get ...

we do

staff = Router(
           tags=['staff'],
           auth=IsAuthorized('STAFF'),
)


@staff.get('/orders',
           response={200: List[InventoryOrderSchemaOut]}
           )

Authentication is never awaited in AsyncOperation

Example

from asgiref.sync import sync_to_async
from ninja import NinjaAPI, Schema
from ninja.security import APIKeyQuery
from .models import Client

api = NinjaAPI()


class ApiKey(APIKeyQuery):
    param_name = "key"

    async def authenticate(self, request, key):
        try:
            return await sync_to_async(Client.objects.get)(key=key)
        except Client.DoesNotExist:
            pass


class Test(Schema):
    msg: str


@api.get("", response=Test, auth=ApiKey())
async def test(request):
    return 200, {"msg": "hello!"}

Scenario

The API is called with a non-existing API key.
What should happen: Ninja should return a 401 response.
What actually happens: Returns 200.

Possible solution

Implement _run_checks and _run_authentication as async methods in AsyncOperation.

class AsyncOperation(Operation):
    def __init__(self, *args, **kwargs):
        if django.VERSION < (3, 1):  # pragma: no cover
            raise Exception("Async operations are supported only with Django 3.1+")
        super().__init__(*args, **kwargs)
        self.is_async = True

    async def _run_checks(self, request):
        "Runs security checks for each operation"
        # auth:
        if self.auth_callbacks:
            error = await self._run_authentication(request)
            if error:
                return error

        # csrf:
        if self.api.csrf:
            error = check_csrf(request, self.view_func)
            if error:
                return error

    async def _run_authentication(self, request):
        for callback in self.auth_callbacks:
            result = await callback(request)
            if result is not None:
                request.auth = result
                return
        return Response({"detail": "Unauthorized"}, status=401)

    async def run(self, request, **kw):
        error = await self._run_checks(request)
        if error:
            return error

        values, errors = self._get_values(request, kw)
        if errors:
            return Response({"detail": errors}, status=422)
        result = await self.view_func(request, **values)
        return self._create_response(result)

Above example will then return 401 on an invalid key as expected.

Not sure how to type some Django model fields (eg, ImageField)

Hey, I just found this project and wanted to say that it's exciting to have such a fast way to create an API in Django!

I'm trying it out on a small side project and ran into an issue with the types/casting for a Django ImageFieldFile. Calling str on the field gives the correct result (ie, it implements __str__), but setting the type for the field to str produces a ValidationError (response -> 0 -> photo str type expected (type=type_error.str)).

I'm not sure if this is something which hasn't been implemented or is a shortcoming in my understanding of pydantic or python type hinting (which are new to me), but I wasn't able to find anything relevant in the docs and my other attempts to understand the issue.

How to return instance or a message depending on condition in Ninja APIs

f```
rom 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


This Above example is taken from the Docs, as I  am stuck in a Case in which there is no chance of always passing the Instance to the return , As If we pass @api.post("/users/", response=UserOut)   Userout then it will always waiting for the user instance to return , But in my case its may be or may not be. 
Here Below is my Use Case which I want to achieve
class UserLogin(Schema):
	email: str
	password: str
    
class UserOut(Schema):
    id: int
    username: str
    email: str
    phone_number : int
    is_active: bool

@authapi.post("auth/login", response=UserOut)
def login(request, user_login: UserLogin):
if "@" in user_login.email:
user = User.objects.get(email__iexact=user_login.email)
if hasattr(user, 'teacher'):
if request.META.get('HTTP_CLIENT_NAME') == 'teacher':
if not user.is_active:
try:
message = "An email containing verification instructions was sent"
return {"message": message, "code": 401, "data": {'is_active': False}, "error_message": ""}
except:
pass
if user.teacher.is_verified == False:
message = "Admin verification is required, please wait."
return {"message": message, "code": 400, "data": {}, "error_message": message}

			return user

as In my Case there will be a chance of Coming error message also, But if we pass userout then Complusorily they want only User instance to be return , Showing me the error when we are using Userout and the string message comes:-

ydantic.error_wrappers.ValidationError: 5 validation errors for Response
response -> id
field required (type=value_error.missing)
response -> username
field required (type=value_error.missing)
response -> email
field required (type=value_error.missing)
response -> phone_number
field required (type=value_error.missing)
response -> is_active
field required (type=value_error.missing)

Please help me out

Class based views

Hi,
Great work, Pydantic with its standard lib type annotations is surely way forward for APIs!

Do you think class based views would be something easily implemented to Ninja?
I've seen couple of gh issues on this for Fastapi, however it hasn't arrived to the package yet.
But there's fastapi-utils extension that does the job:
https://fastapi-utils.davidmontague.xyz/user-guide/class-based-views/
Do you think something similar could be done here?

Purpose of the project?

Can you explain why one should use django-ninja and what cases of using it?

From the docs, it's unclear what benefits django-ninja offer. For example:

  • It based on django, but doesn't show how to work with core django features like DjangoORM, etc. Said that django-ninja is fast thanks to pydantic and async, but django didn't migrate all their stuff to async code, therefore they'll be issues with that.
  • Django-ninja looks basically the same as FastAPI, which is good from some perspective. But FastAPI built on asyncio code and has no limitations of half-async django. So, why not just FastAPI?

Testing

Is there a preferred workflow of writing endpoint tests with this library?

Camel case serialization/deserialization for Schema

I'm currently using DRF and a third-party package called djangorestframework-camel-case (DRFCC). DRFCC provides "Camel case JSON support for Django REST framework", which simply outputs snake case to camel case, and vice versa for input. This is really helpful for my counterpart on the front-end/React side of our application, so he doesn't need to camel case fields himself. DRFCC has 348 stars at this point, so I believe this is a fairly popular use case.

An implementation of this seems fairly straightforward using Pydantic's alias generators, and I see that you've already configured some specific Pydantic Config options for your Schema class.

Is this something you'd be interested in having included as an option to your Schema class? I'll be implementing this myself regardless, but I'm happy to discuss this in greater detail and submit a PR, I can also document this addition to the PR.

JSON:API

This one also not issue, but a proposal.
It will be very useful for response schema validation in jsonapi standards.

How to use django-ninja with class-based view of Django

I have found all the examples in the document are function-based view. As long as I am more accustomed to write code with class-based view rather than function-based view, how can I use class-based view with Django-Ninja?

Thank you!

how to change the default response when parameter is missing while calling the API?

first off, thanks for this great tool. I'm new into creating APis so please bear with me.

I'm building an API A from off another API B. I have to clone this API A for an academic activity.

so when API A is called :

/api/v1/login?email={email}&password={password}

it results in proper JSON but when you call it with something like:

/api/v1/login?email={email}

it results in specific JSON response that reads:

 {"response":{"status":202,"message":"Invalid email & credentials"}}

so far, I have setup API calls, and it is working fine for when I make correct call. However, when I make call with missing parameter like this:

http://127.0.0.1:8000/api/v1/login?email`

it always returns the default JSON response :

 {"detail": [{"loc": ["query", "email"], "msg": "field required", "type": "value_error.missing"}]}

so how do I change the above response to match with the error response of API A whenever it is called with a parameter missing?

thank you so much for your time.

BTW here is my code so far:

from django.contrib import admin
from django.urls import path
from ninja import NinjaAPI
from ninja import Schema
import requests

api = NinjaAPI()
version = "v1"


@api.get("/login") 
def login(request, email:str, password:str):
    response = requests.get(f'some_host_address/api/v1/login?email={email}&password={password}')
    mydata = response.json()
    
    return {"result": mydata}


urlpatterns = [
    path('admin/', admin.site.urls),
     path(f"api/{version}/", api.urls),
]

Tutorial - how to do a simple CRUD

Hello,
I am a beginner in Django Ninja, I would like to know if there are tutorials on how to do a simple CRUD in Django Ninja?
greetings,

auth token key issue

isAuthenticated token generation is by done by user manually by creating tables? is there any predefined method to get auth token or it is to be done manually

Type a message

quoting from docs :
from someapp.models import Client
"and find a Client in database that corresponds to this key. The Client instance will be set to request.auth attribu"

JWT authentication

Hi @vitalik ,
first of all congrats for your work in this project! I really like it. I've a simple question, sorry if this is a trivial one! ;)
In Django Rest Framework we can integrate JWT authentication quite easily using this https://github.com/SimpleJWT/django-rest-framework-simplejwt.

Is there something similar for django-ninja? I saw that in another issue (#9) you mentioned JWT, but I don't understand how it could be done in practice.

Thank you very much for your help and keep up the good work!

File Upload?

Hello @vitalik, I'm having lots of fun playing around with Django Ninja, congratulations it's great!
One thing I was wondering: is it currently impossible to accommodate file uploads within the framework?

There seems to me, to be no obvious way to define a file object in a request body's schema.
Apologies in advance, if I'm missing something obvious, and if anyone has a way of doing so, please let me know! πŸ‘

[proposal] Models to Schemas

Read full proposal here - http://django-ninja.rest-framework.com/proposals/models/

To make it possible to convert django models to ninja Schemas:

from ninja import ModelSchema

class UserOut(ModelSchema):
    class Meta:
        model = User
        fields = ['email', 'first_name', 'last_name']

This feature will definitely land soon to production code

But there is just one open question:

configuration class - should it be Meta (django way) or Config (pydantic way) ?

Hide validation errors in prodaction env

Hi! I need to hide {"detail": errors} on prod env. It's error after _get_values(request, kw)

I think, we should add some param to NinjaAPI, like hide_errors, to hide detail in error.
@vitalik do you approve this solution?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.