Code Monkey home page Code Monkey logo

Comments (4)

sugizo avatar sugizo commented on May 18, 2024 1
>>> q = {'key1': ['val1', 'val3'], 'key2': ['val2']}
>>> {k: v[0] for k, v in q.items()}
{'key1': 'val1', 'key2': 'val2'}
>>> {k: v[-1] for k, v in q.items()}
{'key1': 'val3', 'key2': 'val2'}

yes aware of that, thx
but will leave it as it be for a moment because in pydal there are case to store list data type

or perhaps you have any idea to simplified dict_values() with if condition and for loop are welcome

thanks

from blacksheep.

RobertoPrevato avatar RobertoPrevato commented on May 18, 2024

Hi @sugizo,
I took some time to answer because I needed time to think. When I implemented the code api for request.query I paused to think about how to handle values.

I finally opted for the current behavior because I thought it would be the "lesser evil":

  • query string keys can be repeated, so the same key can be associated to many values
  • most of times, APIs are designed to use a single value per key - so I took into consideration to use a dictionary like Dict[str, str]
  • but I didn't want, and still don't want, to handle cases when there is more than one value as joined strings
  • I considered to convert lists to a single string when the client specifies a single value, but this might be even more confusing for programmers

The recommended way to read query parameters is to use the FromQuery binder, which supports automatic binding to str, List[str], and other values. But this wouldn't work with the level of dynamism you want to achieve.

Would you take into consideration to use a JSON request payload instead of query string? This way, you might achieve what you desire this way:

from blacksheep.server.bindings import FromJson

@app.route('/api/post/{tablename}', methods = ['POST'] )
def post(tablename, values: FromJson[dict]):
    # TODO: validate values
    row = db[tablename].validate_and_insert(**values)
    db.commit()
    return response.json(row.as_dict())

I could add an API to read the query as a flat Dict[str, str], as additional method on the Request class (e.g. request.query_uniq()), but I am not convinced this is a good idea.

from blacksheep.

sugizo avatar sugizo commented on May 18, 2024
from blacksheep.server.bindings import FromJson

@app.route('/api/post/{tablename}', methods = ['POST'] )
def post(tablename, values: FromJson[dict]):
    # TODO: validate values
    row = db[tablename].validate_and_insert(**values)
    db.commit()
    return response.json(row.as_dict() )

solution you provide consider it documented on here
so it must be same like :

@post("/something")
async def create_something(request: Request):
    data = await request.json()

taken on same link above

so, the code provided on first issue is cutted down to make it focus on request.query, here is the full code for insert new data

@app.route('/api/post/{tablename}', methods = ['POST'] )
async def post(request, tablename):
    if request.query:
        values = dict_values(request.query)
    elif await request.form():
        values = await request.form()
    elif await request.json():
        values = await request.json()
    row = db[tablename].validate_and_insert(**values)
    db.commit()
    return responses.json(row.as_dict() )

so can insert new data via cli either using any of these command

request.query use this
curl -X POST -i "http://localhost:8000/api/post/instrument?name=name3&strings=3"

request.form() use this
curl -X POST -d "name=name4&strings=4" -i http://localhost:8000/api/post/instrument

request.json() use this
curl -X POST -d '{"name": "name5", "strings": 5}' -i http://localhost:8000/api/post/instrument

question
so how to achieve it using blacksheep way without calling dict_values() ?

thanks

from blacksheep.

RobertoPrevato avatar RobertoPrevato commented on May 18, 2024

For such scenario, currently you need something like your dict_values function. The API in the web framework always return a dictionary like Dict[str, List[str]].

Notes:

  1. your function can be simplified to a one liner dictionary comprehension:
def dict_values(raw_ori):
    return {k: v[-1] for k, v in raw_ori.items()}
  1. if you are going to do synchronous database operations, you will block the event loop of the application, removing the benefits of using async/await.

  2. the built-in parse_qs function in Python standard library behaves like BlackSheep:

from urllib.parse import parse_qs

parse_qs("a=20&b=10")

# {"a": ["20"], "b": ["10"]}
  1. if you are going to do this operation often, you might implement a custom binder to achieve the same, to handle an optional query string

I hope this helps. I will take consider implementing something like Flask does on this matter, to improve UX when handling queries with single values.

from blacksheep.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.