예제 #1
0
def test_duplicate_schema_names():
    from django.db import models

    from ninja import NinjaAPI, Schema
    from ninja.orm import create_schema

    class TestModelDuplicate(models.Model):
        field1 = models.CharField()
        field2 = models.CharField()

        class Meta:
            app_label = "tests"

    class TestSchema(Schema):
        data1: create_schema(TestModelDuplicate,
                             fields=["field1"])  # noqa: F821
        data2: create_schema(TestModelDuplicate,
                             fields=["field2"])  # noqa: F821

    api = NinjaAPI()

    @api.get("/test", response=TestSchema)
    def a_test_method(request):
        return []

    match = r"Looks like you may have created multiple orm schemas with the same name:"
    with pytest.raises(ConfigError, match=match):
        assert api.get_openapi_schema()
예제 #2
0
def test_examples():

    api = NinjaAPI()

    with patch("builtins.api", api, create=True):
        import docs.src.tutorial.path.code010

        client = NinjaClient(api)

        response = client.get("/events/2020/1/1")
        assert response.json() == {"date": "2020-01-01"}
        schema = api.get_openapi_schema("")
        events_params = schema["paths"]["/events/{year}/{month}/{day}"]["get"][
            "parameters"]
        assert events_params == [
            {
                "in": "path",
                "name": "year",
                "required": True
            },
            {
                "in": "path",
                "name": "month",
                "required": True
            },
            {
                "in": "path",
                "name": "day",
                "required": True
            },
        ]
예제 #3
0
def test_validates():
    api1 = NinjaAPI()
    try:
        os.environ["NINJA_SKIP_REGISTRY"] = ""
        with pytest.raises(ConfigError):
            api2 = NinjaAPI()
    finally:
        os.environ["NINJA_SKIP_REGISTRY"] = "yes"
예제 #4
0
def test_examples():

    api = NinjaAPI()

    with patch("builtins.api", api, create=True):
        import docs.src.tutorial.path.code01  # noqa: F401

        client = TestClient(api)

        response = client.get("/items/123")
        assert response.json() == {"item_id": "123"}

    api = NinjaAPI()

    with patch("builtins.api", api, create=True):
        import docs.src.tutorial.path.code02  # noqa: F401
        import docs.src.tutorial.path.code010  # noqa: F401

        client = TestClient(api)

        response = client.get("/items/123")
        assert response.json() == {"item_id": 123}

        response = client.get("/events/2020/1/1")
        assert response.json() == {"date": "2020-01-01"}
        schema = api.get_openapi_schema("")
        events_params = schema["paths"]["/events/{year}/{month}/{day}"]["get"][
            "parameters"]
        # print(events_params, "!!")
        assert events_params == [
            {
                "in": "path",
                "name": "year",
                "required": True,
                "schema": {
                    "title": "Year",
                    "type": "integer"
                },
            },
            {
                "in": "path",
                "name": "month",
                "required": True,
                "schema": {
                    "title": "Month",
                    "type": "integer"
                },
            },
            {
                "in": "path",
                "name": "day",
                "required": True,
                "schema": {
                    "title": "Day",
                    "type": "integer"
                },
            },
        ]
예제 #5
0
def test_no_handlers():
    api = NinjaAPI()
    api._exception_handlers = {}

    @api.get("/error")
    def thrower(request):
        raise RuntimeError("test")

    client = NinjaClient(api)

    with pytest.raises(RuntimeError):
        client.get("/error")
예제 #6
0
def test_unique_operation_ids():

    api = NinjaAPI()

    @api.get("/1")
    def same_name(request):
        pass

    @api.get("/2")
    def same_name(request):
        pass

    with pytest.warns(UserWarning):
        schema = api.get_openapi_schema()
예제 #7
0
def test_unique_operation_ids():

    api = NinjaAPI()

    @api.get("/1")
    def same_name(request):
        pass

    @api.get("/2")  # noqa: F811
    def same_name(request):  # noqa: F811
        pass

    match = 'operation_id "test_openapi_schema_same_name" is already used'
    with pytest.warns(UserWarning, match=match):
        api.get_openapi_schema()
예제 #8
0
def test_get_openapi_urls():

    api = NinjaAPI(openapi_url=None)
    paths = get_openapi_urls(api)
    assert len(paths) == 0

    api = NinjaAPI(docs_url=None)
    paths = get_openapi_urls(api)
    assert len(paths) == 1

    api = NinjaAPI(openapi_url="/path", docs_url="/path")
    with pytest.raises(
            AssertionError,
            match="Please use different urls for openapi_url and docs_url"):
        get_openapi_urls(api)
예제 #9
0
def test_raises_on_cookie_auth():
    "It should raise if user picked Cookie based auth and csrf=False"

    class Auth(APIKeyCookie):
        def authenticate(self, request, key):
            return request.COOKIES[key] == "foo"

    api = NinjaAPI(auth=Auth(), csrf=False)

    @api.get("/some")
    def some_method(request):
        pass

    with pytest.raises(ConfigError):
        api._validate()
예제 #10
0
 def __init__(self, router_or_app):
     if isinstance(router_or_app, NinjaAPI):
         self.urls = router_or_app.urls[0]
     else:
         api = NinjaAPI()
         router_or_app.set_api_instance(api)
         self.urls = list(router_or_app.urls_paths(""))
예제 #11
0
def test_manytomany():
    class SomeRelated(models.Model):
        f = models.CharField()

        class Meta:
            app_label = "tests"

    class ModelWithM2M(models.Model):
        m2m = models.ManyToManyField(SomeRelated, blank=True)

        class Meta:
            app_label = "tests"

    WithM2MSchema = create_schema(ModelWithM2M, exclude=["id"])

    api = NinjaAPI()

    @api.post("/bar")
    def post_with_m2m(request, payload: WithM2MSchema):
        return payload.dict()

    client = TestClient(api)

    response = client.post("/bar", json={"m2m": [1, 2]})
    assert response.status_code == 200, str(response.json())
    assert response.json() == {"m2m": [1, 2]}

    response = client.post("/bar", json={"m2m": []})
    assert response.status_code == 200, str(response.json())
    assert response.json() == {"m2m": []}
예제 #12
0
def test_examples():

    api = NinjaAPI()

    with patch("builtins.api", api, create=True):
        import docs.src.tutorial.form.code01  # noqa: F401
        import docs.src.tutorial.form.code02  # noqa: F401

        client = TestClient(api)

        assert client.post("/items",
                           data={
                               "name": "Katana",
                               "price": 299.00,
                               "quantity": 10
                           }).json() == {
                               "name": "Katana",
                               "description": None,
                               "price": 299.0,
                               "quantity": 10,
                           }

        assert client.post("/items/1?q=test",
                           data={
                               "name": "Katana",
                               "price": 299.00,
                               "quantity": 10
                           }).json() == {
                               "item_id": 1,
                               "q": "test",
                               "item": {
                                   "name": "Katana",
                                   "description": None,
                                   "price": 299.0,
                                   "quantity": 10,
                               },
                           }

    with patch("builtins.api", api, create=True):
        import docs.src.tutorial.form.code03  # noqa: F401

        client = TestClient(api)

        assert client.post(
            "/items-blank-default",
            data={
                "name": "Katana",
                "price": "",
                "quantity": "",
                "in_stock": ""
            },
        ).json() == {
            "name": "Katana",
            "description": None,
            "in_stock": True,
            "price": 0.0,
            "quantity": 0,
        }
예제 #13
0
 def urls(self) -> List:
     if not hasattr(self, "_urls_cache"):
         self._urls_cache: List
         if isinstance(self.router_or_app, NinjaAPI):
             self._urls_cache = self.router_or_app.urls[0]
         else:
             api = NinjaAPI()
             self.router_or_app.set_api_instance(api)
             self._urls_cache = list(self.router_or_app.urls_paths(""))
     return self._urls_cache
예제 #14
0
async def test_asyncio_exceptions():
    api = NinjaAPI()

    @api.get("/error")
    async def thrower(request):
        raise Http404("test")

    client = NinjaAsyncClient(api)
    response = await client.get("/error")
    assert response.status_code == 404
예제 #15
0
def test_examples():

    api = NinjaAPI()

    with patch("builtins.api", api, create=True):
        import docs.src.tutorial.body.code01
        import docs.src.tutorial.body.code02
        import docs.src.tutorial.body.code03

        client = NinjaClient(api)

        assert client.post("/items",
                           json={
                               "name": "Katana",
                               "price": 299.00,
                               "quantity": 10
                           }).json() == {
                               "name": "Katana",
                               "description": None,
                               "price": 299.0,
                               "quantity": 10,
                           }

        assert client.put("/items/1",
                          json={
                              "name": "Katana",
                              "price": 299.00,
                              "quantity": 10
                          }).json() == {
                              "item_id": 1,
                              "item": {
                                  "name": "Katana",
                                  "description": None,
                                  "price": 299.0,
                                  "quantity": 10,
                              },
                          }

        assert client.post("/items/1?q=test",
                           json={
                               "name": "Katana",
                               "price": 299.00,
                               "quantity": 10
                           }).json() == {
                               "item_id": 1,
                               "q": "test",
                               "item": {
                                   "name": "Katana",
                                   "description": None,
                                   "price": 299.0,
                                   "quantity": 10,
                               },
                           }
예제 #16
0
def test_kwargs():
    api = NinjaAPI()

    @api.get("/")
    def operation(request, a: str, *args, **kwargs):
        pass

    schema = api.get_openapi_schema()
    params = schema["paths"]["/api/"]["get"]["parameters"]
    print(params)
    assert params == [  # Only `a` should be here, not kwargs
        {
            "in": "query",
            "name": "a",
            "schema": {
                "title": "A",
                "type": "string"
            },
            "required": True,
        }
    ]
예제 #17
0
def test_docs_decorator():
    api = NinjaAPI(docs_decorator=staff_member_required)

    paths = get_openapi_urls(api)
    assert len(paths) == 2
    for ptrn in paths:
        request = Mock(user=Mock(is_staff=True))
        result = ptrn.callback(request)
        assert result.status_code == 200

        request = Mock(user=Mock(is_staff=False))
        request.build_absolute_uri = lambda: "http://example.com"
        result = ptrn.callback(request)
        assert result.status_code == 302
예제 #18
0
def test_raises_on_cookie_auth():
    "It should raise if user picked Cookie based auth and csrf=False"

    class Auth(APIKeyCookie):
        def authenticate(self, request, key):
            return request.COOKIES[key] == "foo"

    api = NinjaAPI(auth=Auth(), csrf=False)

    @api.get("/some")
    def some_method(request):
        pass

    with pytest.raises(ConfigError):
        api._validate()

    try:
        import os

        os.environ["NINJA_SKIP_REGISTRY"] = ""

        # Check for wrong error reported
        match = "Looks like you created multiple NinjaAPIs"
        with pytest.raises(ConfigError, match=match):
            api.urls

        # django debug server can attempt to import the urls twice when errors exist
        # verify we get the correct error reported
        match = "Cookie Authentication must be used with CSRF"
        with pytest.raises(ConfigError, match=match):
            with mock.patch(
                    "ninja.main._imported_while_running_in_debug_server",
                    True):
                api.urls

    finally:
        os.environ["NINJA_SKIP_REGISTRY"] = "yes"
예제 #19
0
def test_reuse_router_error():
    test_api = NinjaAPI()
    test_router = Router()
    test_api.add_router("/", test_router)

    # django debug server can attempt to import the urls twice when errors exist
    # verify we get the correct error reported
    match = "Router@'/another-path' has already been attached to API NinjaAPI:1.0.0"
    with pytest.raises(ConfigError, match=match):
        with mock.patch("ninja.main._imported_while_running_in_debug_server",
                        False):
            test_api.add_router("/another-path", test_router)

    # The error should be ignored under debug server to allow other errors to be reported
    with mock.patch("ninja.main._imported_while_running_in_debug_server",
                    True):
        test_api.add_router("/another-path", test_router)
예제 #20
0
async def test_asyncio_operations():
    api = NinjaAPI()

    class KeyQuery(APIKeyQuery):
        def authenticate(self, request, key):
            if key == "secret":
                return key

    @api.get("/async", auth=KeyQuery())
    async def async_view(request, payload: int):
        await asyncio.sleep(0)
        return {"async": True}

    @api.post("/async")
    def sync_post_to_async_view(request):
        return {"sync": True}

    client = NinjaAsyncClient(api)

    # Actual tests --------------------------------------------------

    # without auth:
    res = await client.get("/async?payload=1")
    assert res.status_code == 401

    # async successful
    res = await client.get("/async?payload=1&key=secret")
    assert res.json() == {"async": True}

    # async innvalid input
    res = await client.get("/async?payload=str&key=secret")
    assert res.status_code == 422

    # async call to sync method for path that hahve async operations
    res = await client.post("/async")
    assert res.json() == {"sync": True}

    # invalid method
    res = await client.put("/async")
    assert res.status_code == 405
예제 #21
0
from ninja import NinjaAPI, Router
import pytest
from ninja.testing import TestClient

api = NinjaAPI()


@api.get("/endpoint")
def global_op(request):
    return "global"


first_router = Router()


@first_router.get("/endpoint")
def router_op1(request):
    return "first"


second_router_one = Router()


@second_router_one.get("endpoint_1")
def router_op2(request):
    return "second 1"


second_router_two = Router()

예제 #22
0
from django.contrib import admin
from django.urls import path
from ninja import NinjaAPI
from someapp.api import router

api_v1 = NinjaAPI()
api_v1.add_router("events", router)
# TODO: check ^ for possible mistakes like `/events` `evetns/``

api_v2 = NinjaAPI(version="2.0.0")


@api_v2.get("events")
def newevents2(request):
    return "events are gone"


api_v3 = NinjaAPI(version="3.0.0")


@api_v3.get("events")
def newevents3(request):
    return "events are gone 3"


@api_v3.get("foobar")
def foobar(request):
    return "foobar"


urlpatterns = [
예제 #23
0
from client import NinjaClient


class RoomEnum(str, Enum):
    double = "double"
    twin = "twin"
    single = "single"


class Booking(BaseModel):
    start: date
    end: date
    room: RoomEnum = RoomEnum.double


api = NinjaAPI()


@api.post("/book")
def create_booking(request, booking: Booking):
    return booking


@api.get("/search")
def booking_search(request, room: RoomEnum):
    return {"room": room}


client = NinjaClient(api)

예제 #24
0
from emp_main.models import ValueMessage as ValueHistoryDb
from emp_main.models import LastValueMessage as ValueLatestDb
from emp_main.models import ScheduleMessage as ScheduleHistoryDb
from emp_main.models import LastScheduleMessage as ScheduleLatestDb
from emp_main.models import SetpointMessage as SetpointHistoryDb
from emp_main.models import LastSetpointMessage as SetpointLatestDb
from emp_main.models import ForecastMessage as ForecastMessageDb
from emp_main.models import Product as ProductDb
from emp_main.models import ProductRun as ProductRunDb
from emp_main.models import Plant as PlantDb

logger = logging.getLogger(__name__)

api = NinjaAPI(
    title="EMP API",
    version="v1",
    docs_url="/",
)


class GenericAPIView:
    """
    Some generic stuff that should be relevant for all API endpoints.

    Attributes:
    -----------
    PydanticModel: esg.models._BaseModel instance
        The Model that should be used to parse the input of `update_*` and
        serialize the output of `list_*` operations.
    DBModel: esg.django_models.DjangoBaseModel instance.
        The django model to interact with the DB.
예제 #25
0
from ninja import NinjaAPI
from django.conf import settings
from django.views.decorators.csrf import csrf_exempt
from client import NinjaClient

csrf_OFF = NinjaAPI(urls_namespace="csrf_OFF")
csrf_ON = NinjaAPI(urls_namespace="csrf_ON", csrf=True)


@csrf_OFF.post("/post")
def post_off(request):
    return {"success": True}


@csrf_ON.post("/post")
def post_on(request):
    return {"success": True}


@csrf_ON.post("/post/csrf_exempt")
@csrf_exempt
def post_on_with_exempt(request):
    return {"success": True}


TOKEN = "1bcdefghij2bcdefghij3bcdefghij4bcdefghij5bcdefghij6bcdefghijABCD"
COOKIES = {settings.CSRF_COOKIE_NAME: TOKEN}


def test_csrf_off():
    client = NinjaClient(csrf_OFF)
예제 #26
0
파일: views.py 프로젝트: jvsoe/decoupled
from django.http import HttpResponseServerError
from django.shortcuts import render, get_object_or_404

# Create your views here.
from typing import List, Dict
from ninja import NinjaAPI, Schema
from ninja.security import django_auth

from users.models import User
from .models import Entry

from ninja.orm import create_schema

# ninja_api = NinjaAPI(auth=django_auth, csrf=True)
ninja_api = NinjaAPI(title="Entry API")

EntryIn = create_schema(Entry, name='EntryIn', fields=['text', 'number'])

EntryOut = create_schema(Entry, name='EntryOut')


class Entries(Schema):
    # name: 'Entries'
    entries: List[EntryOut]
    columns: List[Dict]  # Dict
    entry_form_fields: Dict


UserOut = create_schema(User,
                        name='UserOut',
예제 #27
0
from django.urls import path
from ninja import NinjaAPI
from apps.article.api import router as article_router

api = NinjaAPI()
api.add_router('', article_router)

urlpatterns = [
     path('', api.urls),
]
예제 #28
0
from ninja import NinjaAPI
from server.middlewares.auth import JWTBearer
import server.routes.example

v1_route = NinjaAPI(auth=JWTBearer(), version="1.0.0")
v1_route.add_router('example', example.router)
예제 #29
0
from ninja import NinjaAPI, Router
import pytest
from client import NinjaClient

api = NinjaAPI()


@api.get("/endpoint")
def global_op(request):
    return "global"


first_router = Router()


@first_router.get("/endpoint")
def router_op(request):
    return "first"


second_router_one = Router()


@second_router_one.get("endpoint_1")
def router_op(request):
    return "second 1"


second_router_two = Router()

예제 #30
0
from ninja import NinjaAPI
from users.router import router as users_router
from properties.router import router as properties_router
from appointments.router import router as appointments_router
from communications.router import router as communications_router
from locations.router import router as locations_router
from .security import UserAuth

api = NinjaAPI(auth=UserAuth())
api.add_router("/users", users_router,
               tags=["users"])  # funciona igual con o sin slash
api.add_router("/properties", properties_router, tags=["properties"])
api.add_router("/appointments", appointments_router, tags=["appointments"])
api.add_router("/communications",
               communications_router,
               tags=["communications"])
api.add_router("/locations", locations_router, tags=["locations"])