{"html_url": "https://github.com/simonw/datasette/issues/394#issuecomment-642522285", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/394", "id": 642522285, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MjUyMjI4NQ==", "user": {"value": 58298410, "label": "LVerneyPEReN"}, "created_at": "2020-06-11T09:15:19Z", "updated_at": "2020-06-11T09:15:19Z", "author_association": "NONE", "body": "Hi @wragge,\r\n\r\nThis looks great, thanks for the share! I refactored it into a self-contained function, binding on a random available TCP port (multi-user context). I am using subprocess API directly since the `%run` magic was leaving defunct process behind :/\r\n\r\n![image](https://user-images.githubusercontent.com/58298410/84367566-b5d0d500-abd4-11ea-96e2-f5c05a28e506.png)\r\n\r\n```python\r\nimport socket\r\n\r\nfrom signal import SIGINT\r\nfrom subprocess import Popen, PIPE\r\n\r\nfrom IPython.display import display, HTML\r\nfrom notebook.notebookapp import list_running_servers\r\n\r\n\r\ndef get_free_tcp_port():\r\n \"\"\"\r\n Get a free TCP port.\r\n \"\"\"\r\n tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\r\n tcp.bind(('', 0))\r\n _, port = tcp.getsockname()\r\n tcp.close()\r\n return port\r\n\r\n\r\ndef datasette(database):\r\n \"\"\"\r\n Run datasette on an SQLite database.\r\n \"\"\"\r\n # Get current running servers\r\n servers = list_running_servers()\r\n\r\n # Get the current base url\r\n base_url = next(servers)['base_url']\r\n\r\n # Get a free port\r\n port = get_free_tcp_port()\r\n\r\n # Create a base url for Datasette suing the proxy path\r\n proxy_url = f'{base_url}proxy/absolute/{port}/'\r\n\r\n # Display a link to Datasette\r\n display(HTML(f'
View Datasette (Click on the stop button to close the Datasette server)
'))\r\n\r\n # Launch Datasette\r\n with Popen(\r\n [\r\n 'python', '-m', 'datasette', '--',\r\n database,\r\n '--port', str(port),\r\n '--config', f'base_url:{proxy_url}'\r\n ],\r\n stdout=PIPE,\r\n stderr=PIPE,\r\n bufsize=1,\r\n universal_newlines=True\r\n ) as p:\r\n print(p.stdout.readline(), end='')\r\n while True:\r\n try:\r\n line = p.stderr.readline()\r\n if not line:\r\n break\r\n print(line, end='')\r\n exit_code = p.poll()\r\n except KeyboardInterrupt:\r\n p.send_signal(SIGINT)\r\n```\r\n\r\nIdeally, I'd like some extra magic to notify users when they are leaving the closing the notebook tab and make them terminate the running datasette processes. I'll be looking for it.", "reactions": "{\"total_count\": 1, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 1, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 396212021, "label": "base_url configuration setting"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/394#issuecomment-641908346", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/394", "id": 641908346, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTkwODM0Ng==", "user": {"value": 127565, "label": "wragge"}, "created_at": "2020-06-10T10:22:54Z", "updated_at": "2020-06-10T10:22:54Z", "author_association": "CONTRIBUTOR", "body": "There's a working demo here: https://github.com/wragge/datasette-test\r\n\r\nAnd if you want something that's more than just proof-of-concept, here's a notebook which does some harvesting from web archives and then displays the results using Datasette: https://nbviewer.jupyter.org/github/GLAM-Workbench/web-archives/blob/master/explore_presentations.ipynb", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 396212021, "label": "base_url configuration setting"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/394#issuecomment-641889565", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/394", "id": 641889565, "node_id": "MDEyOklzc3VlQ29tbWVudDY0MTg4OTU2NQ==", "user": {"value": 58298410, "label": "LVerneyPEReN"}, "created_at": "2020-06-10T09:49:34Z", "updated_at": "2020-06-10T09:49:34Z", "author_association": "NONE", "body": "Hi,\r\n\r\nI came across this issue while looking for a way to spawn Datasette as a SQLite files viewer in JupyterLab. I found https://github.com/simonw/jupyterserverproxy-datasette-demo which seems to be the most up to date proof of concept, but it seems to be failing to list the available db (at least in the Binder demo, https://hub.gke.mybinder.org/user/simonw-jupyters--datasette-demo-uw4dmlnn/datasette/, I only have `:memory`).\r\n\r\nDoes anyone tried to improve on this proof of concept to have a Datasette visualization for SQLite files?\r\n\r\nThanks!", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 396212021, "label": "base_url configuration setting"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/394#issuecomment-604166918", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/394", "id": 604166918, "node_id": "MDEyOklzc3VlQ29tbWVudDYwNDE2NjkxOA==", "user": {"value": 127565, "label": "wragge"}, "created_at": "2020-03-26T00:56:30Z", "updated_at": "2020-03-26T00:56:30Z", "author_association": "CONTRIBUTOR", "body": "Thanks! I'm trying to launch Datasette from *within* a notebook using the jupyter-server-proxy and the new `base_url` parameter. While the assets load ok, and the breadcrumb navigation works, the facet links don't seem to use the `base_url`. Or have I missed something?\r\n\r\nMy test repository is here: https://github.com/wragge/datasette-test", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 396212021, "label": "base_url configuration setting"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/394#issuecomment-603849245", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/394", "id": 603849245, "node_id": "MDEyOklzc3VlQ29tbWVudDYwMzg0OTI0NQ==", "user": {"value": 132978, "label": "terrycojones"}, "created_at": "2020-03-25T13:48:13Z", "updated_at": "2020-03-25T13:48:13Z", "author_association": "NONE", "body": "Great - thanks again.\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 396212021, "label": "base_url configuration setting"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/394#issuecomment-603631640", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/394", "id": 603631640, "node_id": "MDEyOklzc3VlQ29tbWVudDYwMzYzMTY0MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-03-25T04:19:08Z", "updated_at": "2020-03-25T04:19:08Z", "author_association": "OWNER", "body": "Shipped in 0.39: https://datasette.readthedocs.io/en/latest/changelog.html#v0-39", "reactions": "{\"total_count\": 1, \"+1\": 1, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 396212021, "label": "base_url configuration setting"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/394#issuecomment-603570972", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/394", "id": 603570972, "node_id": "MDEyOklzc3VlQ29tbWVudDYwMzU3MDk3Mg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-03-25T00:17:24Z", "updated_at": "2020-03-25T00:17:24Z", "author_association": "OWNER", "body": "I got this working as a proxied instance inside Binder, building on @psychemedia's work: https://github.com/simonw/jupyterserverproxy-datasette-demo/issues/1\r\n\r\nNow that I've seen it working there I'm going to land the pull request.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 396212021, "label": "base_url configuration setting"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/394#issuecomment-603539349", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/394", "id": 603539349, "node_id": "MDEyOklzc3VlQ29tbWVudDYwMzUzOTM0OQ==", "user": {"value": 132978, "label": "terrycojones"}, "created_at": "2020-03-24T22:33:23Z", "updated_at": "2020-03-24T22:33:23Z", "author_association": "NONE", "body": "Hi Simon - I'm just (trying, at least) to follow along in the above. I can't try it out now, but I will if no one else gets to it. Sorry I didn't write any tests in the original bit of code I pushed - I was just trying to see if it could work & whether you'd want to maybe head in that direction. Anyway, thank you, I will certainly use this. Comment back here if no one tried it out & I'll make time.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 396212021, "label": "base_url configuration setting"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/394#issuecomment-603525339", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/394", "id": 603525339, "node_id": "MDEyOklzc3VlQ29tbWVudDYwMzUyNTMzOQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-03-24T21:55:46Z", "updated_at": "2020-03-24T22:07:40Z", "author_association": "OWNER", "body": "OK, I have an implementation of this over in the `base-url` branch (see pull request #708) which is passing all of the unit tests.\r\n\r\nAnyone willing to give it a quick test and see if it works for your particular use-case? You can install it with:\r\n\r\n pip install https://github.com/simonw/datasette/archive/base-url.zip\r\n\r\nThen you can run Datasette like this:\r\n\r\n datasette fixtures.db --config base_url:/new-base/path/here/", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 396212021, "label": "base_url configuration setting"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/394#issuecomment-603509266", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/394", "id": 603509266, "node_id": "MDEyOklzc3VlQ29tbWVudDYwMzUwOTI2Ng==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-03-24T21:16:34Z", "updated_at": "2020-03-24T21:16:34Z", "author_association": "OWNER", "body": "Actually I'll teach `DatasetteRouter` since that subclasses `AsgiRouter` but has access to a `datasette` instance (which it can read configuration values from):\r\nhttps://github.com/simonw/datasette/blob/298a899e792ebd0cd82a5f01b613c31f19082e51/datasette/app.py#L750-L753", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 396212021, "label": "base_url configuration setting"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/394#issuecomment-603508785", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/394", "id": 603508785, "node_id": "MDEyOklzc3VlQ29tbWVudDYwMzUwODc4NQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-03-24T21:15:28Z", "updated_at": "2020-03-24T21:15:28Z", "author_association": "OWNER", "body": "That means I should teach `AsgiRouter` how to handle an optional prefix:\r\nhttps://github.com/simonw/datasette/blob/298a899e792ebd0cd82a5f01b613c31f19082e51/datasette/utils/asgi.py#L81-L93", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 396212021, "label": "base_url configuration setting"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/394#issuecomment-603508356", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/394", "id": 603508356, "node_id": "MDEyOklzc3VlQ29tbWVudDYwMzUwODM1Ng==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-03-24T21:14:31Z", "updated_at": "2020-03-24T21:14:31Z", "author_association": "OWNER", "body": "I'm going to assume that whatever is proxying to Datasette leaves the full incoming URL path intact, so I'm going to need to teach the URL routing code to strip off the prefix before processing the incoming request.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 396212021, "label": "base_url configuration setting"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/394#issuecomment-603501719", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/394", "id": 603501719, "node_id": "MDEyOklzc3VlQ29tbWVudDYwMzUwMTcxOQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-03-24T20:59:28Z", "updated_at": "2020-03-24T20:59:28Z", "author_association": "OWNER", "body": "Here's the line I'm stuck on now:\r\n\r\nhttps://github.com/simonw/datasette/blob/298a899e792ebd0cd82a5f01b613c31f19082e51/datasette/views/base.py#L417\r\n\r\nTricky question: do I continue to rebuild URLs based on the incoming `request` (on the assumption that it has been modified to the new thing) or do I expect that I may still see un-prefixed incoming requests and need to change them?\r\n\r\nIf the incoming URL paths contain the prefix, at what point do I drop that so I can run the regular URL matching code?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 396212021, "label": "base_url configuration setting"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/394#issuecomment-602955699", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/394", "id": 602955699, "node_id": "MDEyOklzc3VlQ29tbWVudDYwMjk1NTY5OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2020-03-24T01:34:06Z", "updated_at": "2020-03-24T01:34:15Z", "author_association": "OWNER", "body": "I don't think I'll go with the `