This class provides the main way for defining resources. Below you can find a very simple example for defining new resources:
@Resource(name="app-setting", url="/app-settings")
class AppSetting(BASEMODEL):
id = Column("id", Integer, primary_key=True, autoincrement=True)
name = Column("name", String(50), unique=True, nullable=False)
value = Column("value", Text, nullable=False)
def __init__(self, name=None, value=None):
self.name = name
self.value = value
Starting from Fantastico version 0.6 ROA resources support OAuth2 authorization. Because of this, resources can now be user dependent or user independent. In order for authorization to work as expected for resources which are available only to certain users you can use the following code snippet:
@Resource(name="app-setting", url="/app-settings", user_dependent=True)
class AppSetting(BASEMODEL):
id = Column("id", Integer, primary_key=True, autoincrement=True)
name = Column("name", String(50), unique=True, nullable=False)
value = Column("value", Text, nullable=False)
user_id = Column("user_id", Integer, nullable=False)
def __init__(self, name=None, value=None, user_id=None):
self.name = name
self.value = value
self.user_id = user_id
If you do not define a user_id property for user dependent resources a runtime exception is raised. In order to find out more about OAuth2 authorization implemented into fantastico please read: OAUTH2.
This read only property holds the subresources of this resource. A resource can identify a subresource by one or multiple (composite uniquely identified resources) resource attributes.
@Resource(name="person", url="/persons", version=1.0,
subresources={"bill_address": ["bill_address_id"],
"mail_address": ["mail_address_id"],
"ship_address:" ["ship_address_id"])
class Person(BASEMODEL):
id = Column("id", Integer, primary_key=True, autoincrement=True)
first_name = Column("first_name", String(80))
last_name = Column("last_name", String(50))
bill_address_id = Column("bill_address_id", ForeignKey("addresses.id"))
bill_address = relationship(Address, primaryjoin=bill_address_id == Address.id)
ship_address_id = Column("ship_address_id", ForeignKey("addresses.id"))
ship_address = relationship(Address, primaryjoin=ship_address_id == Address.id)
mail_address_id = Column("ship_address_id", ForeignKey("addresses.id"))
ship_address = relationship(Address, primaryjoin=mail_address_id == Address.id)
This read only property returns True if user is owned only by one resource and False otherwise. It is really important to understand the impact of the property when set to True:
Every GET on resource root url will also receive a filter user_id from access_token == resource.model.user_id
Every GET on a specific resource id will be validated also on user_id field.
exception when the resource does not require create scopes.
Every PUT on a specific resource id will also check to ensure the user from the access_token owns the resource.
Every DELETE on a specific resource id will also check to ensure the user from the access_token owns the resource.
This property returns the validator type which must be used for this resource for creating / updating it. You can read more about it on fantastico.roa.resource_validator.ResourceValidator.
This class provide the methods for registering resources into Fantastico framework and locating them by url or name and version. As a Developer you will not usually need access to this class.
This method returns a list of all registered resources order by name and version. It is extremely useful for introspecting Fantastico ROA platform.
This method returns a registered resource under the given name and version.
Parameters: |
|
---|---|
Returns: | The resource found or None. |
Return type: |
This method returns a registered resource under the given url and version.
Parameters: |
|
---|---|
Returns: | The resource found or None. |
Return type: |
This method register a new resource into Fantastico framework. It first checks against name, url and version collision in order to detect as early as possible errors with the current defined resources.
Parameters: | resource (fantastico.roa.resource_decorator.Resource) – The resource instance we want to register into Fantastico ROA registry. |
---|---|
Raises fantastico.roa.roa_exceptions.FantasticoRoaDuplicateError: | |
This exception is raised when:
|
This method unregister a resource version. If the given resource is not found no exception is raised. Once a resource is unregistered latest version is recalculated. The resource is completely removed from AVAILABLE_RESOURCES and AVAILABLE_URLS dictionaries.
Parameters: |
|
---|
This class provides the algorithm for registering all defined resources. Resources discovered by this class are decorated by fantastico.roa.resource_decorator.Resource. In the constructor of this class you can define special naming convention for discovered resources (through regex). Default behavior is to scan only in models folder / subfolders in all available files.
In addition this class is also designed to be a route provider. This guarantees that at start time, all resources will be registered correctly.
This class provides the routes for introspecting Fantastico registered resources through ROA. It is extremely useful to surf using your browser and to not be required to hardcode links in your code. Typically, you will want to code your client side applications against resources name and you are going to use this controller to find the location of those records.
By default, all ROA resources are mapped on /api/ relative to current project root. You can easily change this behavior by modifying the settings of your application (fantastico.settings.BasicSettings - property roa_api_url)
This method handles all OPTIONS cors requests coming for resources registry listing.
This method list all registered resources as well as a link to their entry point.
// 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"}
}
// 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"}
}
This class provides ROA query parser functionality. It provides methods for transforming filter and sorting expressions (REST API standard) into mvc filters (Model View Controller).
This method transform the given filter expression into mvc filters.
Parameters: |
|
---|---|
Returns: | The newly created mvc query object. |
Return type: |
This method transform the given sort expression into mvc sort filter.
Parameters: |
|
---|---|
Returns: | The newly created mvc query object. |
Return type: |
This class defines the contract for a query parser operation.
This method builds the model filter (fantastico.mvc.models.model_filter.ModelFilter).
This method returns the rules required to interpret this operation.
return {
"(": [(self.TERM, "("), (self.RULE, self.REGEX_TEXT), (self.RULE, ","), (self.RULE, self.REGEX_TEXT),
(self.RULE, ")")],
}
Grammar rules simply describe the tokens which come after operator + symbol. For instance, eq( is followed by two comma separated arguments.
This method returns a dictionary describing the operator + symbol rule and action.
return {
"(": ("eq", "(", lambda: new_mixin(QueryParserOperationBinaryEq)),
")": None
}
Parameters: | new_mixin (function) – New mixin described a factory method required to correctly pass current operation to parser. |
---|---|
Returns: | A dictionary describing the grammar table for this operator. |
This method validates the given operation and argument in order to ensure a filter can be built.
Raises fantastico.roa.query_parser_exceptions.QueryParserOperationInvalidError: | |
---|---|
Whenever the current operation attributes are invalid. |
This class provides the validation / build logic for binary operations.
This class provides the eq operator which can compare two arguments for equality.
This class provides the gt operator which can compare two arguments for greater than relation.
This class provides the ge operator which can compare two arguments for greater or equal than relation.
This class provides the lt operator which can compare two arguments for less than relation.
This class provides the le operator which can compare two arguments for less or equal than relation.
This class provides the in operator which can compare a value with a possible list of values.
This class provides the like operator which can compare two arguments for similarity.
This class provides the parser for compound filter or. It will recursively parse each argument and in the end will return a compatible fantastico.mvc.model_filter_compound.ModelFilterCompound. Each concrete class must specify the compound filter type to use.
This class provides a query parser for or compound filtering.
This class provides a query parser for and compound filtering.
This class provides base support for sort operations: asc / desc.
This class provides asc sort operation.
This class provides desc sort operation.
This class provides the methods for serializing a given resource into a dictionary and deserializing a dictionary into a resource.
# serialize / deserialize a resource without subresources
json_serializer = ResourceJsonSerializer(AppSetting)
resource_json = json_serializer.serialize(AppSetting("simple-setting", "0.19"))
resource = json_serializer.deserialize(resource)
This method converts the given body into a concrete model (if possible).
Parameters: | body (dict) – A JSON object we want to convert to the model compatible with this serializer. |
---|---|
Returns: | A model instance initiated with attributes from the given dictionary. |
Raises fantastico.roa.resource_json_serializer_exceptions.ResourceJsonSerializerError: | |
Whenever given body contains entries which are not supported by resource underlining model. |
This method serialize the given model into a json object.
Parameters: |
|
---|---|
Returns: | A dictionary containing all required attributes. |
Return type: | dict |
Raises fantastico.roa.resource_json_serializer_exceptions.ResourceJsonSerializerError: | |
Whenever requested fields for serialization are not found in model attributes. |
This class provides the core error used within Fantastico ROA layer. Usually, more concrete exceptions are raised by ROA layers.
This concrete exception is used to notify user that multiple resources with same name and version or url and version can not be registered multiple times.
This class provides the base for all validators which can be used for resources.
class AppSettingValidator(ResourceValidator):
def validate(self, resource, request, existing_resource_id=None):
errors = []
if resource.name == "unsupported":
errors.append("Invalid setting name: %s" % resource.name)
if len(resource.value) == 0:
errors.append("Setting %s value can not be empty. %s" % resource.name)
if len(errors) == 0:
return
raise FantasticoRoaError(errors)
def format_collection(self, resources, request):
# we can safely retrieve the full collection of resources so nothing has to be done here.
def format_resource(self, resource, request):
# we can safely retrieve the resource so nothing has to be done here.
def on_post_create(self, resource, request):
# override this only if you want to trigger additional actions after a resource creation.
def on_post_update(self, resource, request):
# override this only if you want to trigger additional actions after a resource update.
def on_post_delete(self, resource, requesT):
# override this only if you want to trigger addition actions after a resource delete.
Every method from validator receives the current http request in order to give access to resource validators to security context and other contexts which might be necessary.
This method must be overriden by each subclass in order to provide custom logic which must be executed after a collection is fetched from database. By default, this method simply iterates over the list of available resources and invoke format_resource.
Usually you will want to override this method in order to suppress sensitive data to be sent to clients.
This method must be overriden by each subclass in order to provide custom logic which must be executed after a resource is fetched.
Usually you will want to override this method in order to suppress sensitive data to be sent to clients.
This method must be overriden by each subclass which wants to receive notifications after a resource has been successfully created.
This method must be overriden by each subclass which wants to receive notifications after a resource has been successfully deleted.
This method must be overriden by each subclass which wants to receive notifications after a resource has been successfully updated.
This method must be overriden by each subclass which wants to receive notifications about a pending create resource operation.
This method must be overriden by each subclass which wants to receive notifications about a pending delete resource operation.
This method must be overriden by each subclass which wants to receive notifications about a pending update resource operation.
This method must be overriden by each subclass in order to provide the validation logic required for the given resource. The resource received as an argument represents an instance of the model used to describe the resource. This method can raise unexpected exceptions. It is recommended to use fantastico.roa.roa_exceptions.FantasticoRoaError
Moreover, there are special cases when you need the existing resource id. The easiest way to achieve this is to look at existing_resource_id argument..
This class provides dynamic routes for ROA registered resources. All CRUD operations are supported out of the box. In addition error handling is automatically provided by this controller.
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:
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 REST Responses.
This method provides the route for deleting existing resources from an existing collection. The API is json only. Usually, when a resource is deleted successfully a similar answer is returned to the client:
204 No Content
Content-Type: application/json
Content-Length: 0
Below you can find all error response codes which might be returned when creating a new resource:
- 10000 - Whenever we try to delete a resource with unknown type. (Not registered to ROA).
- 10030 - Whenever we try to delete a resource and an unexpected database exception occurs.
- 10040 - Whenever we try to delete a resource which does not exist.
You can find more information about typical REST ROA APIs response on REST Responses.
This method provides the functionality for delete item latest version api route.
This method provides the route for accessing a resource collection. REST API standard for collections are enabled by this method. The typical response format is presented below:
var response = {"items": [
// resources represented as json objects.
],
"totalItems": 100}
If a resource is not found or the resource version does not exist the following response is returned:
{"error_code": 10000,
"error_description": "Resource %s version %s does not exist.",
"error_details": "http://rcosnita.github.io/fantastico/html/features/roa/errors/error_10000.html"}
This method retrieves a resource collection using the latest version of the api.
This method provides the API for retrieving a single item from a collection. The item is uniquely identified by resource_id. Below you can find a success response example:
GET - /api/1.0/simple-resources/1 HTTP/1.1
200 OK
Content-Type: application/json
Content-Length: ...
{
"id": 1,
"name": "Test resource",
"description": "Simple description"
}
Of course there are cases when exceptions might occur. Below, you can find a list of error response retrieved from get_item API:
- 10000 - Whenever we try to retrieve a resource with unknown type. (Not registered to ROA).
- 10030 - Whenever we try to retrieve a resource and an unexpected database exception occurs.
- 10040 - Whenever we try to retrieve a resource which does not exist.
This method provides the latest get_item route for ROA api.
This method enables support for http ajax CORS requests. This is mandatory if we want to host apis on different domains than project host.
This method handles OPTIONS http requests for ROA api latest versions.
This method provides the route for updating existing resources from an existing collection. The API is json only and invokes the validator as described in ROA spec. Usually, when a resource is update successfully a similar answer is returned to the client:
204 No Content
Content-Type: application/json
Content-Length: 0
Below you can find all error response codes which might be returned when creating a new resource:
- 10000 - Whenever we try to update a resource with unknown type. (Not registered to ROA).
- 10010 - Whenever we try to update a resource which fails validation.
- 10020 - Whenever we try to update a resource without passing a valid body.
- 10030 - Whenever we try to update a resource and an unexpected database exception occurs.
- 10040 - Whenever we try to update a resource which does not exist.
You can find more information about typical REST ROA APIs response on REST Responses.