Comments (16)
Not sure if this helps, but.. try adding an await statement
@api.get("", response=Test, auth=ApiKey())
async def test(request):
await request.auth <<<
return 200, {"msg": "hello!"}
from django-ninja.
@vitalik I'd like to help with this. I don't understand what's wrong with #202 though. It seems that it's very similar to the code above plus taking care of async auth on not-async operation and vice versa. If I understand what needs to be changed compared to #202, I'd be happy to prepare PR with code, tests and docs changes.
One of the main reasons I chose django-ninja
was it's support for async views and I'd like to broaden the async experience even further. Right now, I can't use built-in auth
at all and I'm doomed to calling my async auth function in each view, which is repetitive and prone to errors.
from django-ninja.
For the full copypasta
@api.get("", response=Test, auth=ApiKey())
async def test(request):
api_key = await request.auth
if not api_key:
raise AuthenticationError()
return 200, {"msg": "hello!"}
from django-ninja.
Thanks @changhyun-an and @maxmorlocke!
I build a decorator from your code :) This should reduce some boilerplate in case of many endpoints
def await_auth(f):
@functools.wraps(f)
async def decorator(*args, **kwargs):
auth = await args[0].auth # args[0] is always the request instance injected from ninja
if not auth :
raise AuthenticationError()
args[0].auth = auth
return await f(*args, **kwargs)
return decorator
Usage:
api = NinjaAPI(auth=ApiKey(), ...)
@api.post(...)
@await_auth
async def create(request, data: Input):
....
from django-ninja.
Yes, in nutshell this is the code I'm targeting for...
but there are few things to deal with - like if you have async auth, but not-async operation or vice-versa
from django-ninja.
Is there any chance for this issue to be resolved soon? I'm quite fond of django-ninja, it's just this issue that I find a bit unsettling.
from django-ninja.
I tried async-auth with v1.0 beta2 but it didn't work, and I finally came across this issue...
could you provide your example code ?
from django-ninja.
@skokado please check with latest version
pip install django-ninja==1.0rc0
from django-ninja.
any news on this ?
from django-ninja.
Not sure if this helps, but.. try adding an await statement
@api.get("", response=Test, auth=ApiKey()) async def test(request): await request.auth <<< return 200, {"msg": "hello!"}
ah, that's the magic of the event loop. Thank you, it really works.
from django-ninja.
While @changhyun-an 's answer works with a single authentication mechanism, I am having issues with multiple authentication classes.
I have a JWTAuth
and an APITokenAuth
. Using the await request.auth
technqiue, if the first auth class returns None
, the second is not tried and auth fails.
I could combine both authentication classes in one, but I prefer to keep them separate.
Does anyone have an idea about this ?
from django-ninja.
I tried async-auth with v1.0 beta2 but it didn't work, and I finally came across this issue...
I saw "async authentication fully supported on all layers" in the Release Note, but is the async-auth roadmap still in progress?
https://github.com/vitalik/django-ninja/releases/tag/v1.0b2
If so, I'd be very happy to mention that in the documentation, also link to this PR :)
Thank you
from django-ninja.
@vitalik Sorry 🙇 I was using 0.22.2, I broke my local environment without realizing.
It works as I expected with 1.0b2.
But one more, when failed Authentication caused by no token provided, then occurs 500 error
Here's my example code.
from ninja import NinjaAPI
from ninja.security import HttpBearer
api = NinjaAPI()
class MyAuth(HttpBearer):
async def authenticate(self, request, token):
if token == "secret":
request.user = MyUser(id=1, name="Foo")
return token
return None
@api.get("/me", auth=MyAuth())
async def me_view(request):
return {"hello": "world"}
curl -X 'GET' \
'http://localhost:8000/me' \
-H 'accept: */*'
Traceback:
Traceback (most recent call last):
File "/home/skokado/workspace/django-ninja-tutorial/venv/lib/python3.11/site-packages/ninja/operation.py", line 304, in _run_authentication
result = await callback(request)
^^^^^^^^^^^^^^^^^^^^^^^
TypeError: object NoneType can't be used in 'await' expression
It does not solve by registering @api.exception_handler
By incorrect token then can get 401 response
curl -X 'GET' \
'http://localhost:8000/api/me' \
-H 'accept: */*' \
-H 'Authorization: Bearer dummy'
# => {"detail": "Unauthorized"}
That does not occur when using sync-auth
from django-ninja.
@vitalik Works as expected, thank you for fixing.
from django-ninja.
@vitalik Sorry for repetitive, but I found new Warning in case non-empty token request at only first time.
It does not matter the authenticate attempt would be succeede or not.
Sample code is same as above #44 (comment)
$ curl -X 'GET' \
'http://localhost:8000/api/me' \
-H 'accept: */*' \
-H 'Authorization: Bearer secret'
/home/skokado/workspace/django-ninja/ninja/operation.py:311: RuntimeWarning: coroutine 'MyAuth.authenticate' was never awaited
result = await callback(request)
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
{"hello": "world"}
At here, callback
is called twice
django-ninja/ninja/operation.py
Lines 308 to 310 in cd66ac8
from django-ninja.
Created a PR for this #44 (comment)
from django-ninja.
Related Issues (20)
- Overriding JSON schema title and summary without using `Field` HOT 1
- [BUG] CSRF Fails with Django Auth HOT 15
- [BUG] Order of operations affect response and request schemas HOT 1
- Documentation - link the schema article to the error article
- Add description to tags HOT 2
- Field order issue in JSON response HOT 1
- [BUG] Allow specifying field types for custom fields
- [BUG] The other API URLs work, but the openapi docs don't appear. HOT 5
- [BUG] Can't use parameter `keys`
- how to add a description for query params that shows in the generated docs?
- Field with list factory causes API docs to not load with non-serializable. HOT 2
- Annotate Decimal field does not supported "Unable to serialize unknown type: <class 'ellipsis'"
- Traversing the data structures to create an HTTP API client HOT 3
- how to use token ? HOT 1
- Path parameters, order matters HOT 3
- [BUG] Combining JWTAuth with django_auth only works in that order
- [BUG] Pydantic 2.7.0 incompatibily HOT 4
- [BUG] ModelSchema with ManyToManyField won't work under async views HOT 5
- How do you use aliases with nested objects
- [BUG] HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from django-ninja.