How to use safrs - 10 common examples

To help you get started, we’ve selected a few safrs examples, based on popular ways it is used in public projects.

Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.

github thomaxxl / safrs / tests / relationship / demo_relationship.py View on Github external
# Following method is exposed through the REST API
    # This means it can be invoked with a HTTP POST
    @classmethod
    @jsonapi_rpc(http_methods=["POST"])
    def send_mail(self, **args):
        """
        description : Send an email
        args:
            email:
                type : string
                example : test email
        """
        return {"result": args}


class Book(SAFRSBase, db.Model):
    """
        description: Book description
    """

    __tablename__ = "Books"
    id = db.Column(db.String, primary_key=True)
    name = db.Column(db.String, default="")
    user_id = db.Column(db.String, db.ForeignKey("Users.id"))
    user = db.relationship("User", back_populates="books")


def populate_db():
    """
        Add some items to the db
    """
    user0 = User(name="user0", email="em@il0")
github thomaxxl / safrs / tests / relationship / demo_relationship.py View on Github external
user1 = User(name="user2", email="em@il2", books=[book2])


if __name__ == "__main__":
    HOST = sys.argv[1] if len(sys.argv) > 1 else "0.0.0.0"
    PORT = 5000
    app = Flask("SAFRS Demo Application")
    app.config.update(SQLALCHEMY_DATABASE_URI="sqlite://", DEBUG=True)
    db.init_app(app)
    db.app = app
    # Create the database
    db.create_all()
    API_PREFIX = ""

    with app.app_context():
        api = SAFRSAPI(app, host="{}:{}".format(HOST, PORT), port=PORT, prefix=API_PREFIX)
        populate_db()
        # Expose the database objects as REST API endpoints
        api.expose_object(User)
        api.expose_object(Book)
        # Register the API at /api/docs
        print("Starting API: http://{}:{}{}".format(HOST, PORT, API_PREFIX))
        app.run(host=HOST, port=PORT)
github thomaxxl / safrs / tests / relationship / demo_relationship.py View on Github external
    @jsonapi_rpc(http_methods=["POST"])
    def send_mail(self, **args):
        """
        description : Send an email
        args:
            email:
                type : string
                example : test email
        """
        return {"result": args}
github thomaxxl / safrs / safrs / swagger_doc.py View on Github external
Parse the yaml description from the documented methods
    """
    api_doc = {}
    obj_doc = str(inspect.getdoc(object))
    raw_doc = obj_doc.split(DOC_DELIMITER)[0]
    yaml_doc = None

    try:
        yaml_doc = yaml.safe_load(raw_doc)
    except (SyntaxError, yaml.scanner.ScannerError) as exc:
        safrs.log.error("Failed to parse documentation {} ({})".format(raw_doc, exc))
        yaml_doc = {"description": raw_doc}

    except Exception as exc:

        raise ValidationError("Failed to parse api doc")

    if isinstance(yaml_doc, dict):
        api_doc.update(yaml_doc)

    return api_doc
github thomaxxl / safrs / safrs / jsonapi.py View on Github external
del links["last"]
    if first_args == self_args:
        del links["first"]
    if next_args == last_args:
        del links["next"]
    if prev_args == first_args:
        del links["prev"]

    if isinstance(object_query, (list, sqlalchemy.orm.collections.InstrumentedList)):
        instances = object_query[page_offset : page_offset + limit]
    else:
        try:
            res_query = object_query.offset(page_offset).limit(limit)
            instances = res_query.all()
        except OverflowError:
            raise ValidationError("Pagination Overflow Error")
        except Exception as exc:
            raise GenericError("Pagination Error {}".format(exc))

    return links, instances, count
github thomaxxl / safrs / safrs / jsonapi.py View on Github external
# the SAFRSObject should've implemented a filter method or
    # overwritten the _s_filter method to implement custom filtering
    filter_args = get_request_param("filter")
    if filter_args:
        safrs_object_filter = getattr(safrs_object, "filter", None)
        if callable(safrs_object_filter):
            result = safrs_object_filter(filter_args)
        else:
            result = safrs_object._s_filter(filter_args)
        return result

    expressions = []
    filters = get_request_param("filters", {})
    for attr_name, val in filters.items():
        if not attr_name in safrs_object._s_jsonapi_attrs + ["id"]:
            safrs.log.warning("Invalid filter {}".format(attr_name))
            continue
        attr = getattr(safrs_object, attr_name)
        expressions.append((attr, val))

    if isinstance(safrs_object, (list, sqlalchemy.orm.collections.InstrumentedList)):
        # todo: filter properly
        result = safrs_object
    elif expressions:
        expressions_ = [column.in_(val.split(",")) for column, val in expressions]
        result = safrs_object._s_query.filter(*expressions_)
    else:
        result = safrs_object._s_query

    return result
github thomaxxl / safrs / safrs / swagger_doc.py View on Github external
def parse_object_doc(object):
    """
        Parse the yaml description from the documented methods
    """
    api_doc = {}
    obj_doc = str(inspect.getdoc(object))
    raw_doc = obj_doc.split(DOC_DELIMITER)[0]
    yaml_doc = None

    try:
        yaml_doc = yaml.safe_load(raw_doc)
    except (SyntaxError, yaml.scanner.ScannerError) as exc:
        safrs.log.error("Failed to parse documentation {} ({})".format(raw_doc, exc))
        yaml_doc = {"description": raw_doc}

    except Exception as exc:

        raise ValidationError("Failed to parse api doc")

    if isinstance(yaml_doc, dict):
        api_doc.update(yaml_doc)

    return api_doc
github thomaxxl / safrs / safrs / base.py View on Github external
# Data is optional, it's also really slow for large sets!!!!!
                    rel_query = getattr(self, rel_name)
                    limit = request.page_limit
                    if not get_config("ENABLE_RELATIONSHIPS"):
                        meta["warning"] = "ENABLE_RELATIONSHIPS set to false in config.py"
                    elif rel_query:
                        # todo: chekc if lazy=dynamic
                        # In order to work with the relationship as with Query,
                        # you need to configure it with lazy='dynamic'
                        # "limit" may not be possible !
                        if getattr(rel_query, "limit", False):
                            count = rel_query.count()
                            rel_query = rel_query.limit(limit)
                            if rel_query.count() >= get_config("BIG_QUERY_THRESHOLD"):
                                warning = 'Truncated result for relationship "{}",consider paginating this request'.format(rel_name)
                                safrs.log.warning(warning)
                                meta["warning"] = warning
                            items = rel_query.all()
                        else:
                            items = list(rel_query)
                            count = len(items)
                        meta["count"] = count
                        meta["limit"] = limit
                        data = [{"id": i.jsonapi_id, "type": i._s_type} for i in items]
                else:  # shouldn't happen!!
                    safrs.log.error("Unknown relationship direction for relationship {}: {}".format(rel_name, relationship.direction))
                # add the relationship direction, for debugging purposes.
                if is_debug():
                    # meta["direction"] = relationship.direction.name
                    pass

            rel_link = urljoin(self_link, rel_name)
github thomaxxl / safrs / safrs / base.py View on Github external
data = {"id": rel_item.jsonapi_id, "type": rel_item._s_type}
                elif relationship.direction in (ONETOMANY, MANYTOMANY):
                    # Data is optional, it's also really slow for large sets!!!!!
                    rel_query = getattr(self, rel_name)
                    limit = request.page_limit
                    if not get_config("ENABLE_RELATIONSHIPS"):
                        meta["warning"] = "ENABLE_RELATIONSHIPS set to false in config.py"
                    elif rel_query:
                        # todo: chekc if lazy=dynamic
                        # In order to work with the relationship as with Query,
                        # you need to configure it with lazy='dynamic'
                        # "limit" may not be possible !
                        if getattr(rel_query, "limit", False):
                            count = rel_query.count()
                            rel_query = rel_query.limit(limit)
                            if rel_query.count() >= get_config("BIG_QUERY_THRESHOLD"):
                                warning = 'Truncated result for relationship "{}",consider paginating this request'.format(rel_name)
                                safrs.log.warning(warning)
                                meta["warning"] = warning
                            items = rel_query.all()
                        else:
                            items = list(rel_query)
                            count = len(items)
                        meta["count"] = count
                        meta["limit"] = limit
                        data = [{"id": i.jsonapi_id, "type": i._s_type} for i in items]
                else:  # shouldn't happen!!
                    safrs.log.error("Unknown relationship direction for relationship {}: {}".format(rel_name, relationship.direction))
                # add the relationship direction, for debugging purposes.
                if is_debug():
                    # meta["direction"] = relationship.direction.name
                    pass
github thomaxxl / safrs / safrs / _api.py View on Github external
safrs.DB.session.commit()
            return result

        except (ValidationError, GenericError, NotFoundError) as exc:
            safrs.log.exception(exc)
            status_code = getattr(exc, "status_code")
            message = exc.message

        except werkzeug.exceptions.NotFound:
            status_code = 404
            message = "Not Found"

        except Exception as exc:
            status_code = getattr(exc, "status_code", 500)
            traceback.print_exc()
            safrs.log.error(exc)
            if safrs.log.getEffectiveLevel() > logging.DEBUG:
                message = "Logging Disabled"
            else:
                message = str(exc)

        safrs.DB.session.rollback()
        safrs.log.error(message)
        errors = dict(detail=message)
        abort(status_code, errors=[errors])