コード例 #1
0
    def list_registered_resources(self, request):
        '''This method list all registered resources as well as a link to their entry point.

        .. code-block:: javascript

            // ROA api is mapped on a subdomain: roa.fantasticoproject.com
            // listing is done by GET http://fantasticoproject.com/roa/resources HTTP/1.1

            {
                "Person": {1.0 : "http://roa.fantasticoproject.com/1.0/persons",
                           "latest": "http://roa.fantasticoproject.com/latest/persons"},
                "Address": {1.0 : "http://roa.fantasticoproject.com/1.0/addresses",
                            2.0 : "http://roa.fantasticoproject.com/2.0/addresses",
                            "latest": "http://roa.fantasticoproject.com/latest/addresses"}
            }

        .. code-block:: javascript

            // ROA api is mapped on a relative path of the project: http://fantasticoproject.com/api/
            // listing is done by GET http://fantasticoproject.com/roa/resources HTTP/1.1

            {
                "Person": {1.0 : "http://fantasticoproject.com/api/1.0/persons",
                           "latest": "http://roa.fantasticoproject.com/api/latest/persons"},
                "Address": {1.0 : "http://roa.fantasticoproject.com/api/1.0/addresses",
                            2.0 : "http://roa.fantasticoproject.com/api/2.0/addresses",
                            "latest": "http://roa.fantasticoproject.com/api/latest/addresses"}
            }'''

        body = {}
        resources = self._registry.all_resources()

        for resource in resources:
            if not body.get(resource.name):
                body[resource.name] = {}

            api_url = roa_helper.calculate_resource_url(
                self._roa_api, resource, resource.version)
            api_url_latest = roa_helper.calculate_resource_url(
                self._roa_api, resource, "latest")

            body[resource.name][resource.version] = api_url
            body[resource.name]["latest"] = api_url_latest

        body = json.dumps(body).encode()

        response = Response(body=body,
                            content_type="application/json",
                            charset="UTF-8")
        response.headers["Access-Control-Allow-Origin"] = "*"
        response.headers[
            "Access-Control-Allow-Methods"] = "OPTIONS,GET,POST,PUT,DELETE"

        return response
コード例 #2
0
    def list_registered_resources(self, request):
        """This method list all registered resources as well as a link to their entry point.

        .. code-block:: javascript

            // ROA api is mapped on a subdomain: roa.fantasticoproject.com
            // listing is done by GET http://fantasticoproject.com/roa/resources HTTP/1.1

            {
                "Person": {1.0 : "http://roa.fantasticoproject.com/1.0/persons",
                           "latest": "http://roa.fantasticoproject.com/latest/persons"},
                "Address": {1.0 : "http://roa.fantasticoproject.com/1.0/addresses",
                            2.0 : "http://roa.fantasticoproject.com/2.0/addresses",
                            "latest": "http://roa.fantasticoproject.com/latest/addresses"}
            }

        .. code-block:: javascript

            // ROA api is mapped on a relative path of the project: http://fantasticoproject.com/api/
            // listing is done by GET http://fantasticoproject.com/roa/resources HTTP/1.1

            {
                "Person": {1.0 : "http://fantasticoproject.com/api/1.0/persons",
                           "latest": "http://roa.fantasticoproject.com/api/latest/persons"},
                "Address": {1.0 : "http://roa.fantasticoproject.com/api/1.0/addresses",
                            2.0 : "http://roa.fantasticoproject.com/api/2.0/addresses",
                            "latest": "http://roa.fantasticoproject.com/api/latest/addresses"}
            }"""

        body = {}
        resources = self._registry.all_resources()

        for resource in resources:
            if not body.get(resource.name):
                body[resource.name] = {}

            api_url = roa_helper.calculate_resource_url(self._roa_api, resource, resource.version)
            api_url_latest = roa_helper.calculate_resource_url(self._roa_api, resource, "latest")

            body[resource.name][resource.version] = api_url
            body[resource.name]["latest"] = api_url_latest

        body = json.dumps(body).encode()

        response = Response(body=body, content_type="application/json", charset="UTF-8")
        response.headers["Access-Control-Allow-Origin"] = "*"
        response.headers["Access-Control-Allow-Methods"] = "OPTIONS,GET,POST,PUT,DELETE"

        return response
コード例 #3
0
ファイル: roa_controller.py プロジェクト: rcosnita/fantastico
    def create_item(self, request, version, resource_url):
        '''This method provides the route for adding new resources into an existing collection. The API is json only and invoke
        the validator as described in ROA spec. Usually, when a resource is created successfully a similar answer is returned to
        the client:

        .. code-block:: html

            201 Created
            Content-Type: application/json
            Content-Length: 0
            Location: /api/2.0/app-settings/123

        Below you can find all error response codes which might be returned when creating a new resource:

            * **10000** - Whenever we try to create a resource with unknown type. (Not registered to ROA).
            * **10010** - Whenever we try to create a resource which fails validation.
            * **10020** - Whenever we try to create a resource without passing a valid body.
            * **10030** - Whenever we try to create a resource and an unexpected database exception occurs.

        You can find more information about typical REST ROA APIs response on :doc:`/features/roa/rest_responses`.'''

        if version != "latest":
            version = float(version)

        resource = self._resources_registry.find_by_url(resource_url, version)

        if not resource:
            return self._handle_resource_notfound(version, resource_url)

        model = self._validate_resource(resource, request, request.body)
        access_token = request.context.security.access_token

        if isinstance(model, Response):
            return model

        try:
            if resource.user_dependent and access_token:
                model.user_id = access_token.user_id

            if resource.validator:
                resource.validator().on_pre_create(model, request)

            model_facade = self._model_facade_cls(resource.model, self._get_current_connection(request))
            model_id = model_facade.create(model)[0]
            
            if resource.validator:
                resource.validator().on_post_create(model, request)
        except FantasticoDbError as dbex:
            return self._handle_resource_dberror(resource.version, resource.url, dbex)

        model_location = roa_helper.calculate_resource_url(self._roa_api, resource, version)
        model_location += "/%s" % model_id

        response = Response(status_code=201, content_type="application/json")
        self._add_cors_headers(response)
        response.headers["Location"] = model_location

        return response
コード例 #4
0
    def test_calculate_resource_relative_api(self):
        '''This test case ensures an url is correctly built when roa_api is hosted on the same domain as the project.'''

        resource = Mock()
        resource.url = "/sample-resources"

        roa_api = "/api"

        self.assertEqual("/api/1.0%s" % resource.url, roa_helper.calculate_resource_url(roa_api, resource, 1.0))
コード例 #5
0
    def test_calculate_resource_abs_api(self):
        '''This test case ensures an url is correctly built when roa_api is hosted on a separate domain than the project.'''

        resource = Mock()
        resource.url = "/sample-resources"

        roa_api = "https://api.fantastico.com/roa/api"

        self.assertEqual("https://api.fantastico.com/roa/api/2.0%s" % resource.url,
                         roa_helper.calculate_resource_url(roa_api, resource, 2.0))
コード例 #6
0
    def test_calculate_resource_abs_api(self):
        '''This test case ensures an url is correctly built when roa_api is hosted on a separate domain than the project.'''

        resource = Mock()
        resource.url = "/sample-resources"

        roa_api = "https://api.fantastico.com/roa/api"

        self.assertEqual(
            "https://api.fantastico.com/roa/api/2.0%s" % resource.url,
            roa_helper.calculate_resource_url(roa_api, resource, 2.0))
コード例 #7
0
    def test_calculate_resource_relative_api(self):
        '''This test case ensures an url is correctly built when roa_api is hosted on the same domain as the project.'''

        resource = Mock()
        resource.url = "/sample-resources"

        roa_api = "/api"

        self.assertEqual(
            "/api/1.0%s" % resource.url,
            roa_helper.calculate_resource_url(roa_api, resource, 1.0))
コード例 #8
0
    def create_item(self, request, version, resource_url):
        '''This method provides the route for adding new resources into an existing collection. The API is json only and invoke
        the validator as described in ROA spec. Usually, when a resource is created successfully a similar answer is returned to
        the client:

        .. code-block:: html

            201 Created
            Content-Type: application/json
            Content-Length: 0
            Location: /api/2.0/app-settings/123

        Below you can find all error response codes which might be returned when creating a new resource:

            * **10000** - Whenever we try to create a resource with unknown type. (Not registered to ROA).
            * **10010** - Whenever we try to create a resource which fails validation.
            * **10020** - Whenever we try to create a resource without passing a valid body.
            * **10030** - Whenever we try to create a resource and an unexpected database exception occurs.

        You can find more information about typical REST ROA APIs response on :doc:`/features/roa/rest_responses`.'''

        if version != "latest":
            version = float(version)

        resource = self._resources_registry.find_by_url(resource_url, version)

        if not resource:
            return self._handle_resource_notfound(version, resource_url)

        model = self._validate_resource(resource, request, request.body)
        access_token = request.context.security.access_token

        if isinstance(model, Response):
            return model

        try:
            if resource.user_dependent and access_token:
                model.user_id = access_token.user_id

            if resource.validator:
                resource.validator().on_pre_create(model, request)

            model_facade = self._model_facade_cls(
                resource.model, self._get_current_connection(request))
            model_id = model_facade.create(model)[0]

            if resource.validator:
                resource.validator().on_post_create(model, request)
        except FantasticoDbError as dbex:
            return self._handle_resource_dberror(resource.version,
                                                 resource.url, dbex)

        model_location = roa_helper.calculate_resource_url(
            self._roa_api, resource, version)
        model_location += "/%s" % model_id

        response = Response(status_code=201, content_type="application/json")
        self._add_cors_headers(response)
        response.headers["Location"] = model_location

        return response