Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

datasette.urls.table(..., format="json") argument #1035

Closed
simonw opened this issue Oct 20, 2020 · 3 comments
Closed

datasette.urls.table(..., format="json") argument #1035

simonw opened this issue Oct 20, 2020 · 3 comments

Comments

@simonw
Copy link
Owner

simonw commented Oct 20, 2020

That datasette.urls.table("db", "table") + ".json" example is bad because if the table name contains a . it should be ?_format=json instead.

Maybe .table() should have a format="json" option that knows how to do this.

Originally posted by @simonw in #1026 (comment)

@simonw
Copy link
Owner Author

simonw commented Oct 20, 2020

Relevant code:

def path_with_format(request, format, extra_qs=None):
qs = extra_qs or {}
path = request.path
if "." in request.path:
qs["_format"] = format
else:
path = "{}.{}".format(path, format)
if qs:
extra = urllib.parse.urlencode(sorted(qs.items()))
if request.query_string:
path = "{}?{}&{}".format(path, request.query_string, extra)
else:
path = "{}?{}".format(path, extra)
elif request.query_string:
path = "{}?{}".format(path, request.query_string)
return path

Only used here:

it_can_render = await await_me_maybe(it_can_render)
if it_can_render:
renderers[key] = path_with_format(
request, key, {**url_labels_extra}
)

@simonw
Copy link
Owner Author

simonw commented Oct 20, 2020

That renderers[key] = path_with_format( is in a base class which can be used for both arbitrary queries, canned queries and the table view. I think that's OK, but it means that the format="json" argument on datasette.urls.table() won't be used by Datasette internally, it will just be available for plugins.

@simonw
Copy link
Owner Author

simonw commented Oct 20, 2020

Makes me question if datasette.urls should grow functionality equivalent to the other path and querystring manipulation methods in datasette.utils:

def append_querystring(url, querystring):
op = "&" if ("?" in url) else "?"
return "{}{}{}".format(url, op, querystring)
def path_with_added_args(request, args, path=None):
path = path or request.path
if isinstance(args, dict):
args = args.items()
args_to_remove = {k for k, v in args if v is None}
current = []
for key, value in urllib.parse.parse_qsl(request.query_string):
if key not in args_to_remove:
current.append((key, value))
current.extend([(key, value) for key, value in args if value is not None])
query_string = urllib.parse.urlencode(current)
if query_string:
query_string = "?{}".format(query_string)
return path + query_string
def path_with_removed_args(request, args, path=None):
query_string = request.query_string
if path is None:
path = request.path
else:
if "?" in path:
bits = path.split("?", 1)
path, query_string = bits
# args can be a dict or a set
current = []
if isinstance(args, set):
def should_remove(key, value):
return key in args
elif isinstance(args, dict):
# Must match key AND value
def should_remove(key, value):
return args.get(key) == value
for key, value in urllib.parse.parse_qsl(query_string):
if not should_remove(key, value):
current.append((key, value))
query_string = urllib.parse.urlencode(current)
if query_string:
query_string = "?{}".format(query_string)
return path + query_string
def path_with_replaced_args(request, args, path=None):
path = path or request.path
if isinstance(args, dict):
args = args.items()
keys_to_replace = {p[0] for p in args}
current = []
for key, value in urllib.parse.parse_qsl(request.query_string):
if key not in keys_to_replace:
current.append((key, value))
current.extend([p for p in args if p[1] is not None])
query_string = urllib.parse.urlencode(current)
if query_string:
query_string = "?{}".format(query_string)
return path + query_string

@simonw simonw added this to the 0.51 milestone Oct 23, 2020
@simonw simonw added the small label Oct 29, 2020
@simonw simonw closed this as completed in 11eb1e0 Oct 31, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant