def __init__(self): super().__init__() cls_name = self.__class__.__name__ class_meta = getattr(self, "Meta", None) if isinstance(class_meta, type): print( "resourse.Meta as class will be deprecated soon", file=sys.stderr, ) self.Meta = ResourceMeta.from_class(class_meta) if not isinstance(self.Meta, ResourceMeta): raise Exception( f"{cls_name}.Meta must inherit from ResourceMeta class" ) if not self.Meta.name or self.Meta.name in ( "base_resource", "_resource", ): raise Exception(f"{cls_name} must have Meta.name") resource_id_name = get_id_field(self, name_only=True, skip_exc=True) if resource_id_name: resource_id_field = self.fields.get(resource_id_name) resource_id_field = resource_id_field.metadata.get("model_field") if not resource_id_field: raise Exception( f"Resource's {cls_name} id field {resource_id_name}" f" must have model_field." )
class ForbiddenBookResource(BaseResource): Meta = ResourceMeta( model=m.Book, name="forbidden_book", methods=(CREATE, READ, UPDATE, BULK_UPDATE, DELETE), auth=BaseAuth, ) id = fields.Int(model_field=m.Book.id) title = fields.String(model_field=m.Book.title, required=True) description = fields.String(model_field=m.Book.description)
class StoreStatsResource(BaseResource): Meta = ResourceMeta( model=m.Store, name="store_stats", methods=(READ, ), select_from=sa.outerjoin(m.Store, m.Book, m.Store.id == m.Book.store_id), ) name = fields.String(model_field=m.Store.name) books_count = fields.Int(dump_only=True, model_field=sa.func.count(m.Book.id))
class HealthCheckResource(BaseResource): Meta = ResourceMeta(name="healthcheck", methods=(READ, CREATE)) def on_get( self, req: falcon.request.Request, resp: falcon.response.Response, resource_id: int = None, ): resp.body = "OK" def on_post(self, req: falcon.request.Request, resp: falcon.response.Response): raise Exception("Something Goes Wrong")
class AuthorResource(BaseResource): Meta = ResourceMeta( model=m.Author, name="author", methods=(CREATE, READ, UPDATE, BULK_UPDATE, DELETE), auth=AuthorAuth, select_from=sa.outerjoin(m.Author, m.Book, m.Author.id == m.Book.author_id), ) id = fields.Int(model_field=m.Author.id) books = custom_fields.ToMany( fields.Int(), resource="book", model_field=m.Book.id, description="Authors Books", ) books_count = fields.Int(dump_only=True, model_field=sa.func.count(m.Book.id)) name = fields.String( model_field=sa.func.concat(m.Author.first_name, " ", m.Author.last_name), dump_only=True, ) last_name = fields.String(model_field=m.Author.last_name, required=True, load_only=True) first_name = fields.String(model_field=m.Author.first_name, required=True, load_only=True) field_without_model_field = fields.String(load_only=True) def get_by_book_ids(self, session, ctx: ReadContext, field: sa.Column = None): books_count = self.fields.get("books_count").metadata["model_field"] q = (sa.select([ m.Author.id.label("id"), self.fields.name.metadata["model_field"].label("name"), books_count.label("books_count"), ]).select_from( sa.outerjoin(m.Author, m.Book, m.Author.id == m.Book.author_id)).where( m.Book.id.in_(ctx.obj_ids)).group_by(m.Author.id)) result = session.execute(q).fetchall() serialized_objs = self.dump(result, many=True) return serialized_objs
class TagStatsResource(BaseResource): Meta = ResourceMeta( model=m.Tag, name="tag_stats", methods=(READ,), disable_total=True, select_from=sa.outerjoin( m.Tag, m.M2M_Book_Tag, m.Tag.id == m.M2M_Book_Tag.c.tag_id ).outerjoin(m.Book, m.M2M_Book_Tag.c.book_id == m.Book.id), id_field="name", ) name = fields.String(model_field=m.Tag.name) books_count = fields.Int( dump_only=True, model_field=sa.func.count(m.Book.id) )
class TagResource(BaseResource): Meta = ResourceMeta( model=m.Tag, name="tag", methods=(CREATE, READ, UPDATE, BULK_UPDATE, DELETE), disable_total=True, select_from=sa.outerjoin( m.Tag, m.M2M_Book_Tag, m.Tag.id == m.M2M_Book_Tag.c.tag_id).outerjoin( m.Book, m.M2M_Book_Tag.c.book_id == m.Book.id), ) id = fields.Int(model_field=m.Tag.id) name = fields.String(model_field=m.Tag.name) books = custom_fields.ToMany(fields.Int(), resource="book", model_field=m.M2M_Book_Tag.c.book_id) book_titles = fields.List( fields.Str(), resource="author", model_field=sa.func.array_remove(sa.func.array_agg(m.Book.title), None), ) def get_by_book_ids(self, session, ctx: ReadContext, field: str = None): """ :param user_id: User id :return: serialized JSON response """ q = (sa.select( [m.Tag.id.label("id"), m.Tag.name.label("name")]).select_from( sa.join(m.M2M_Book_Tag, m.Tag, m.M2M_Book_Tag.c.tag_id == m.Tag.id)).where( m.M2M_Book_Tag.c.book_id.in_(ctx.obj_ids))) result = session.execute(q).fetchall() serialized_objs = self.dump(result, many=True) return serialized_objs
class StoreResource(BaseResource): Meta = ResourceMeta( model=m.Store, name="store", methods=(CREATE, BULK_CREATE, READ), select_from=sa.outerjoin(m.Store, m.Book, m.Store.id == m.Book.store_id), ) id = fields.Int(model_field=m.Store.id) book_ids = custom_fields.ToMany(fields.Int(), resource="book", model_field=m.Book.id) name = fields.String(model_field=m.Store.name, required=True) status = custom_fields.Choice( model_field=m.Store.status, allowed_values=[STORE_OPEN, STORE_CLOSED], allow_none=True, ) def get_by_book_ids(self, session, ctx: ReadContext, field: sa.Column = None): q = (sa.select([ m.Store.id.label("id"), m.Store.name.label("name"), sa.func.array_agg(m.Book.id).label("book_ids"), ]).select_from( sa.outerjoin(m.Store, m.Book, m.Store.id == m.Book.store_id)).where( m.Book.id.in_(ctx.obj_ids)).group_by(m.Store.id)) result = session.execute(q).fetchall() serialized_objs = self.dump(result, many=True) return serialized_objs
class BookResource(BaseResource): Meta = ResourceMeta( model=m.Book, name="book", methods=(CREATE, READ, UPDATE, BULK_UPDATE, DELETE), select_from=sa.outerjoin( m.Book, m.M2M_Book_Tag, m.Book.id == m.M2M_Book_Tag.c.book_id).outerjoin( m.Author, m.Book.author_id == m.Author.id), ) id = fields.Int(model_field=m.Book.id) title = fields.String(model_field=m.Book.title, required=True) description = fields.String(model_field=m.Book.description) author = custom_fields.ToOne(resource="author", model_field=m.Book.author_id) author_name = fields.Str(model_field=m.Author.first_name, dump_only=True) store = custom_fields.ToOne( resource="store", model_field=m.Book.store_id, description="Store selling book", ) tags = custom_fields.ToMany(fields.Int(), resource="tag", model_field=m.M2M_Book_Tag.c.tag_id) def get_by_author_ids(self, session, ctx: ReadContext, field: sa.Column = None): authors = sa.func.array_remove(sa.func.array_agg(m.Author.id), None).label("authors") q = (sa.select([ m.Book.id.label("id"), m.Book.title.label("title"), m.Book.description.label("description"), m.Book.store_id.label("store"), authors, ]).select_from( sa.outerjoin( m.Book, m.Author, m.Author.id == m.Book.author_id)).where( m.Book.author_id.in_(ctx.obj_ids)).group_by(m.Book.id)) result = session.execute(q).fetchall() serialized_objs = self.dump(result, many=True) return serialized_objs def get_by_tag_ids(self, session, ctx: ReadContext, field: sa.Column = None): q = (sa.select( [ m.Book.id.label("id"), m.Book.title.label("title"), m.Book.description.label("description"), m.Book.store_id.label("store"), ], distinct=True, ).select_from( sa.join( m.M2M_Book_Tag, m.Book, m.M2M_Book_Tag.c.book_id == m.Book.id, )).where(m.M2M_Book_Tag.c.tag_id.in_(ctx.obj_ids))) result = session.execute(q).fetchall() serialized_objs = self.dump(result, many=True) return serialized_objs