24
loading...
This website collects cookies to deliver better user experience
loafang
as a way to kill my time and is still in development.{
"GET:get-user": {
"user --name ad": ["username", "email"],
"posts --user-id ad34": ["latest"]
}
}
"GET:get-user": {
"user --name ad": ["username", "email"],
"posts --user-id ad34": ["latest"]
}
GET:get-user
GET
(The schema is case sensitive), METHOD:id:property-key
"user --name ad": ["username", "email"]
--name
)["username", "email"]
GET
and DELETE
queries.POST
, PUT
, and PATCH
, as these three methods require you to update or add things.ADD
, UPDATE
, and GET
data from the DB.pip3 install loafang fastapi uvicorn tinydb
# app.py
from __future__ import annotations
from typing import Any, Union
from argparse import Namespace # type hinting purposes only
from fastapi import FastAPI, HTTPException
from loafang import parse, Methods, MethodsError, QueryBuilder
from tinydb import TinyDB, Query
# what our query looks like
query = QueryBuilder("database")
query.add_argument("uname", type=str)
class RequestMethods(Methods):
# class to handle/create a response for queries in a block
def __init__(self) -> None:
# you can have different query parser for different request methods
self.get_query_parser = query
self.post_query_parser = query
self.put_query_parser = query
def get(self, args: Namespace, contents: list[str]) -> Any:
# our database only has fields for name, username and email.
if not all(i in ["name", "email"] for i in contents):
raise MethodsError(400, "Bad contents arguments")
User = Query()
db = TinyDB(args.database)
db_ret = db.search(User.username == args.uname)
if not db_ret:
raise MethodsError(404, "User does not exists")
else:
user = db_ret[0]
return {i: user[i] for i in contents}
def post(self, args: Namespace, contents: dict[str, Any]) -> Any:
if not all(i in contents for i in ["name", "email"]):
raise MethodsError(400, "Bad contents arguments")
User = Query()
db = TinyDB(args.database)
if db.search(User.username == args.uname):
raise MethodsError(403, "User already exists")
else:
db.insert({"username": args.uname, **contents})
return {"msg": f"user {args.uname} added."}
def put(self, args: Namespace, contents: dict[str, Any]) -> Any:
if not all(i in contents for i in ["name", "email"]):
raise MethodsError(400, "Bad contents arguments")
User = Query()
db = TinyDB(args.database)
user = db.search(User.username == args.uname)
if not user:
raise MethodsError(404, "User already exists")
db.update(contents, User.username == args.uname)
return {"msg": f"User updated successfully. {args.uname}"}
request_methods = RequestMethods()
# a vague representation of the loafang query
QueryType = Union[dict[str, Any], list[str]]
# initialize the server
app = FastAPI()
@app.get("/")
def read_root():
return {"ping": "pong"}
@app.post("/loaf")
def loaf(data: QueryType):
# the parsers gives you three things
# The parsed data with all the output (None, if something goes wrong)
# err code (only if something goes wrong, else None)
# err message (only if something goes wrong else None)
parsed_data, err, msg = parse(request_methods, data)
return parsed_data if parsed_data else HTTPException(status_code=err, detail=msg)
uvicorn app:app
loaf
endpoint and see what happens.{
"GET:get-user:pe": {
"db.json --uname adwaith": ["name", "email"]
},
"POST:add-user": {
"db.json --uname adwaith": {
"name": "ad",
"email": "[email protected]"
}
},
"PUT:update-user": {
"db.json --uname adwaith | update-ad": {
"name": "ad2",
"email": "[email protected]"
},
"after": "get-user"
}
}
{
"add-user": {
"db.json --uname adwaith": {
"msg": "user adwaith added."
}
},
"update-user": {
"update-ad": {
"msg": "User updated successfully. adwaith"
},
"after": {
"db.json --uname adwaith": {
"name": "ad2",
"email": "[email protected]"
}
}
}
}
pe
property key (currently that is the only one). It tells the parser to skip the block or "prevents the execution" of the block, the block can now be called from other blocks.POST
block and has one query in it that adds a user with the name adwaith to the DB 'db.json'.PUT
block that has one query that updates a user with the name adwaith. But there is something special with that block. It has an after
key. It tells the parser that after it executes the current block it needs to execute the block specified in the after
.The after
key can only point to a block that has pe
as its property key.
A block with pe
as its property cannot have an after
key
|
in between the query. It specifies that anything after the pipe is an alias to the query. As you can see in the result, the key to a query's values is the query itself. So it might be hard at times to retrieve data using the query as the key.loafang
, feel free to ask questions, use the package and if you have any errors, pls report it or ask me on discord.