datasette-edit-schema 0.8a2__tar.gz → 0.8a5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (20) hide show
  1. {datasette_edit_schema-0.8a2 → datasette_edit_schema-0.8a5}/PKG-INFO +12 -18
  2. {datasette_edit_schema-0.8a2 → datasette_edit_schema-0.8a5}/README.md +7 -13
  3. {datasette_edit_schema-0.8a2 → datasette_edit_schema-0.8a5}/datasette_edit_schema/__init__.py +47 -24
  4. {datasette_edit_schema-0.8a2 → datasette_edit_schema-0.8a5}/datasette_edit_schema/templates/edit_schema_table.html +13 -12
  5. {datasette_edit_schema-0.8a2 → datasette_edit_schema-0.8a5}/datasette_edit_schema.egg-info/PKG-INFO +12 -18
  6. {datasette_edit_schema-0.8a2 → datasette_edit_schema-0.8a5}/datasette_edit_schema.egg-info/requires.txt +1 -1
  7. {datasette_edit_schema-0.8a2 → datasette_edit_schema-0.8a5}/pyproject.toml +5 -6
  8. {datasette_edit_schema-0.8a2 → datasette_edit_schema-0.8a5}/tests/test_edit_schema.py +23 -17
  9. {datasette_edit_schema-0.8a2 → datasette_edit_schema-0.8a5}/LICENSE +0 -0
  10. {datasette_edit_schema-0.8a2 → datasette_edit_schema-0.8a5}/datasette_edit_schema/static/draggable.1.0.0-beta.11.bundle.js +0 -0
  11. {datasette_edit_schema-0.8a2 → datasette_edit_schema-0.8a5}/datasette_edit_schema/static/draggable.1.0.0-beta.11.bundle.min.js +0 -0
  12. {datasette_edit_schema-0.8a2 → datasette_edit_schema-0.8a5}/datasette_edit_schema/templates/edit_schema_create_table.html +0 -0
  13. {datasette_edit_schema-0.8a2 → datasette_edit_schema-0.8a5}/datasette_edit_schema/templates/edit_schema_database.html +0 -0
  14. {datasette_edit_schema-0.8a2 → datasette_edit_schema-0.8a5}/datasette_edit_schema/templates/edit_schema_index.html +0 -0
  15. {datasette_edit_schema-0.8a2 → datasette_edit_schema-0.8a5}/datasette_edit_schema/utils.py +0 -0
  16. {datasette_edit_schema-0.8a2 → datasette_edit_schema-0.8a5}/datasette_edit_schema.egg-info/SOURCES.txt +0 -0
  17. {datasette_edit_schema-0.8a2 → datasette_edit_schema-0.8a5}/datasette_edit_schema.egg-info/dependency_links.txt +0 -0
  18. {datasette_edit_schema-0.8a2 → datasette_edit_schema-0.8a5}/datasette_edit_schema.egg-info/entry_points.txt +0 -0
  19. {datasette_edit_schema-0.8a2 → datasette_edit_schema-0.8a5}/datasette_edit_schema.egg-info/top_level.txt +0 -0
  20. {datasette_edit_schema-0.8a2 → datasette_edit_schema-0.8a5}/setup.cfg +0 -0
@@ -1,25 +1,25 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: datasette-edit-schema
3
- Version: 0.8a2
3
+ Version: 0.8a5
4
4
  Summary: Datasette plugin for modifying table schemas
5
5
  Author: Simon Willison
6
- License: Apache-2.0
6
+ License-Expression: Apache-2.0
7
7
  Project-URL: Homepage, https://datasette.io/plugins/datasette-edit-schema
8
8
  Project-URL: Changelog, https://github.com/simonw/datasette-edit-schema/releases
9
9
  Project-URL: Issues, https://github.com/simonw/datasette-edit-schema/issues
10
10
  Project-URL: CI, https://github.com/simonw/datasette-edit-schema/actions
11
11
  Classifier: Framework :: Datasette
12
- Classifier: License :: OSI Approved :: Apache Software License
13
- Requires-Python: >=3.8
12
+ Requires-Python: >=3.10
14
13
  Description-Content-Type: text/markdown
15
14
  License-File: LICENSE
16
- Requires-Dist: datasette>=1.0a13
15
+ Requires-Dist: datasette>=1.0a21
17
16
  Requires-Dist: sqlite-utils>=3.35
18
17
  Provides-Extra: test
19
18
  Requires-Dist: pytest; extra == "test"
20
19
  Requires-Dist: pytest-asyncio; extra == "test"
21
20
  Requires-Dist: beautifulsoup4; extra == "test"
22
21
  Requires-Dist: html5lib; extra == "test"
22
+ Dynamic: license-file
23
23
 
24
24
  # datasette-edit-schema
25
25
 
@@ -61,21 +61,15 @@ By default only [the root actor](https://datasette.readthedocs.io/en/stable/auth
61
61
 
62
62
  ## Permissions
63
63
 
64
- The `edit-schema` permission provides access to all functionality.
64
+ This plugin registers an `edit-schema` action that applies to databases. Granting that action gives an actor access to every feature in the UI. Instances launched with `datasette --root` automatically allow the signed-in root actor to perform this action.
65
65
 
66
- You can use permission plugins such as [datasette-permissions-sql](https://github.com/simonw/datasette-permissions-sql) to grant additional access to the write interface.
66
+ All permission checks now call `datasette.allowed()` with `DatabaseResource` or `TableResource` objects, so they work seamlessly with Datasette’s `permission_resources_sql()` hook and configuration-based permission rules. Plugins such as [datasette-permissions-sql](https://github.com/simonw/datasette-permissions-sql) can continue to be used to grant access to the write interface.
67
67
 
68
- These permission checks will call the `permission_allowed()` plugin hook with three arguments:
68
+ For finer control you can combine Datasette’s built-in actions:
69
69
 
70
- - `action` will be the string `"edit-schema"`
71
- - `actor` will be the currently authenticated actor - usually a dictionary
72
- - `resource` will be the string name of the database
73
-
74
- You can instead use more finely-grained permissions from the default Datasette permissions collection:
75
-
76
- - `create-table` allows users to create a new table. The `resource` will be the name of the database.
77
- - `drop-table` allows users to drop a table. The `resource` will be a tuple of `(database_name, table_name)`.
78
- - `alter-table` allows users to alter a table. The `resource` will be a tuple of `(database_name, table_name)`.
70
+ - `create-table` allows users to create a new table (database-level resource).
71
+ - `drop-table` allows users to drop a table (table-level resource).
72
+ - `alter-table` allows users to alter a table (table-level resource).
79
73
 
80
74
  To rename a table a user must have both `drop-table` permission for that table and `create-table` permission for that database.
81
75
 
@@ -38,21 +38,15 @@ By default only [the root actor](https://datasette.readthedocs.io/en/stable/auth
38
38
 
39
39
  ## Permissions
40
40
 
41
- The `edit-schema` permission provides access to all functionality.
41
+ This plugin registers an `edit-schema` action that applies to databases. Granting that action gives an actor access to every feature in the UI. Instances launched with `datasette --root` automatically allow the signed-in root actor to perform this action.
42
42
 
43
- You can use permission plugins such as [datasette-permissions-sql](https://github.com/simonw/datasette-permissions-sql) to grant additional access to the write interface.
43
+ All permission checks now call `datasette.allowed()` with `DatabaseResource` or `TableResource` objects, so they work seamlessly with Datasette’s `permission_resources_sql()` hook and configuration-based permission rules. Plugins such as [datasette-permissions-sql](https://github.com/simonw/datasette-permissions-sql) can continue to be used to grant access to the write interface.
44
44
 
45
- These permission checks will call the `permission_allowed()` plugin hook with three arguments:
45
+ For finer control you can combine Datasette’s built-in actions:
46
46
 
47
- - `action` will be the string `"edit-schema"`
48
- - `actor` will be the currently authenticated actor - usually a dictionary
49
- - `resource` will be the string name of the database
50
-
51
- You can instead use more finely-grained permissions from the default Datasette permissions collection:
52
-
53
- - `create-table` allows users to create a new table. The `resource` will be the name of the database.
54
- - `drop-table` allows users to drop a table. The `resource` will be a tuple of `(database_name, table_name)`.
55
- - `alter-table` allows users to alter a table. The `resource` will be a tuple of `(database_name, table_name)`.
47
+ - `create-table` allows users to create a new table (database-level resource).
48
+ - `drop-table` allows users to drop a table (table-level resource).
49
+ - `alter-table` allows users to alter a table (table-level resource).
56
50
 
57
51
  To rename a table a user must have both `drop-table` permission for that table and `create-table` permission for that database.
58
52
 
@@ -103,4 +97,4 @@ pip install -e '.[test]'
103
97
  To run the tests:
104
98
  ```bash
105
99
  pytest
106
- ```
100
+ ```
@@ -1,5 +1,7 @@
1
1
  from datasette import hookimpl
2
2
  from datasette.events import CreateTableEvent, AlterTableEvent, DropTableEvent
3
+ from datasette.permissions import Action
4
+ from datasette.resources import DatabaseResource, TableResource
3
5
  from datasette.utils.asgi import Response, NotFound, Forbidden
4
6
  from datasette.utils import sqlite3, tilde_decode, tilde_encode
5
7
  from urllib.parse import quote_plus, unquote_plus
@@ -22,14 +24,14 @@ FOREIGN_KEY_DETECTION_LIMIT = 10_000
22
24
 
23
25
 
24
26
  @hookimpl
25
- def permission_allowed(actor, action, resource):
26
- if (
27
- action == "edit-schema"
28
- and actor
29
- and actor.get("id") == "root"
30
- and resource != "_internal"
31
- ):
32
- return True
27
+ def register_actions(datasette):
28
+ return [
29
+ Action(
30
+ name="edit-schema",
31
+ description="Edit database schemas",
32
+ resource_class=DatabaseResource,
33
+ )
34
+ ]
33
35
 
34
36
 
35
37
  @hookimpl
@@ -51,25 +53,36 @@ def table_actions(datasette, actor, database, table):
51
53
 
52
54
 
53
55
  async def can_create_table(datasette, actor, database):
54
- if await datasette.permission_allowed(
55
- actor, "edit-schema", resource=database, default=False
56
+ database_resource = DatabaseResource(database)
57
+ if await datasette.allowed(
58
+ actor=actor,
59
+ action="edit-schema",
60
+ resource=database_resource,
56
61
  ):
57
62
  return True
58
63
  # Or maybe they have create-table
59
- if await datasette.permission_allowed(
60
- actor, "create-table", resource=database, default=False
64
+ if await datasette.allowed(
65
+ actor=actor,
66
+ action="create-table",
67
+ resource=database_resource,
61
68
  ):
62
69
  return True
63
70
  return False
64
71
 
65
72
 
66
73
  async def can_alter_table(datasette, actor, database, table):
67
- if await datasette.permission_allowed(
68
- actor, "edit-schema", resource=database, default=False
74
+ database_resource = DatabaseResource(database)
75
+ if await datasette.allowed(
76
+ actor=actor,
77
+ action="edit-schema",
78
+ resource=database_resource,
69
79
  ):
70
80
  return True
71
- if await datasette.permission_allowed(
72
- actor, "alter-table", resource=(database, table), default=False
81
+ table_resource = TableResource(database, table)
82
+ if await datasette.allowed(
83
+ actor=actor,
84
+ action="alter-table",
85
+ resource=table_resource,
73
86
  ):
74
87
  return True
75
88
  return False
@@ -84,13 +97,19 @@ async def can_rename_table(datasette, actor, database, table):
84
97
 
85
98
 
86
99
  async def can_drop_table(datasette, actor, database, table):
87
- if await datasette.permission_allowed(
88
- actor, "edit-schema", resource=database, default=False
100
+ database_resource = DatabaseResource(database)
101
+ if await datasette.allowed(
102
+ actor=actor,
103
+ action="edit-schema",
104
+ resource=database_resource,
89
105
  ):
90
106
  return True
91
107
  # Or maybe they have drop-table
92
- if await datasette.permission_allowed(
93
- actor, "drop-table", resource=(database, table), default=False
108
+ table_resource = TableResource(database, table)
109
+ if await datasette.allowed(
110
+ actor=actor,
111
+ action="drop-table",
112
+ resource=table_resource,
94
113
  ):
95
114
  return True
96
115
  return False
@@ -148,8 +167,10 @@ def get_databases(datasette):
148
167
 
149
168
 
150
169
  async def check_permissions(datasette, request, database):
151
- if not await datasette.permission_allowed(
152
- request.actor, "edit-schema", resource=database, default=False
170
+ if not await datasette.allowed(
171
+ actor=request.actor,
172
+ action="edit-schema",
173
+ resource=DatabaseResource(database),
153
174
  ):
154
175
  raise Forbidden("Permission denied for edit-schema")
155
176
 
@@ -160,8 +181,10 @@ async def edit_schema_index(datasette, request):
160
181
  allowed_databases = [
161
182
  name
162
183
  for name in database_names
163
- if await datasette.permission_allowed(
164
- request.actor, "edit-schema", resource=name, default=False
184
+ if await datasette.allowed(
185
+ actor=request.actor,
186
+ action="edit-schema",
187
+ resource=DatabaseResource(name),
165
188
  )
166
189
  ]
167
190
  if not allowed_databases:
@@ -14,13 +14,14 @@ html body input[type="search"] {
14
14
  font-size: 1em;
15
15
  font-family: Helvetica, sans-serif;
16
16
  }
17
- body form .button-red {
18
- background-color: red;
19
- border-color: red;
20
- }
21
- body form .button-small {
17
+ input[type=submit].button-small {
22
18
  font-size: 0.7em;
23
19
  }
20
+ form input[type=submit].button-red {
21
+ background: red;
22
+ border-color: rgb(171, 112, 112);
23
+ }
24
+
24
25
  select {
25
26
  border: 1px solid #ccc;
26
27
  border-radius: 3px;
@@ -91,7 +92,7 @@ html body label {
91
92
  {% if can_rename_table %}
92
93
  <h2>Rename table</h2>
93
94
 
94
- <form action="{{ base_url }}-/edit-schema/{{ database.name|quote_plus }}/{{ tilde_encode(table) }}" method="post">
95
+ <form class="core" action="{{ base_url }}-/edit-schema/{{ database.name|quote_plus }}/{{ tilde_encode(table) }}" method="post">
95
96
  <input type="hidden" name="csrftoken" value="{{ csrftoken() }}">
96
97
  <p><label>New name&nbsp; <input type="text" name="name"></label>
97
98
  <input type="hidden" name="rename_table" value="1">
@@ -99,7 +100,7 @@ html body label {
99
100
  </form>
100
101
  {% endif %}
101
102
 
102
- <form action="{{ base_url }}-/edit-schema/{{ database.name|quote_plus }}/{{ tilde_encode(table) }}" method="post">
103
+ <form class="core" action="{{ base_url }}-/edit-schema/{{ database.name|quote_plus }}/{{ tilde_encode(table) }}" method="post">
103
104
  <h2>Change existing columns</h2>
104
105
  <ul class="sortable-columns">
105
106
  {% for column in columns %}
@@ -134,7 +135,7 @@ html body label {
134
135
 
135
136
  <h2>Add a column</h2>
136
137
 
137
- <form action="{{ base_url }}-/edit-schema/{{ database.name|quote_plus }}/{{ tilde_encode(table) }}" method="post">
138
+ <form class="core" action="{{ base_url }}-/edit-schema/{{ database.name|quote_plus }}/{{ tilde_encode(table) }}" method="post">
138
139
  <input type="hidden" name="csrftoken" value="{{ csrftoken() }}">
139
140
  <input type="hidden" name="add_column" value="1">
140
141
  <p><label>Name &nbsp;<input type="text" name="name"></label>
@@ -156,7 +157,7 @@ table.foreign-key-options td {
156
157
  }
157
158
  </style>
158
159
 
159
- <form action="{{ base_url }}-/edit-schema/{{ database.name|quote_plus }}/{{ tilde_encode(table) }}" method="post">
160
+ <form class="core" action="{{ base_url }}-/edit-schema/{{ database.name|quote_plus }}/{{ tilde_encode(table) }}" method="post">
160
161
  <input type="hidden" name="csrftoken" value="{{ csrftoken() }}">
161
162
  <input type="hidden" name="action" value="update_foreign_keys">
162
163
  <table class="foreign-key-options">
@@ -180,7 +181,7 @@ table.foreign-key-options td {
180
181
 
181
182
  <p>The primary key column uniquely identifies each row in the table.</p>
182
183
 
183
- <form action="{{ base_url }}-/edit-schema/{{ database.name|quote_plus }}/{{ tilde_encode(table) }}" method="post">
184
+ <form class="core" action="{{ base_url }}-/edit-schema/{{ database.name|quote_plus }}/{{ tilde_encode(table) }}" method="post">
184
185
  <input type="hidden" name="csrftoken" value="{{ csrftoken() }}">
185
186
  <input type="hidden" name="action" value="update_primary_key">
186
187
  <label for="primary_key">Primary key column &nbsp;</label>
@@ -201,7 +202,7 @@ table.foreign-key-options td {
201
202
 
202
203
  <p>Indexes can speed up filter and sort operations against indexed columns.</p>
203
204
 
204
- <form action="{{ base_url }}-/edit-schema/{{ database.name|quote_plus }}/{{ tilde_encode(table) }}" method="post">
205
+ <form class="core" action="{{ base_url }}-/edit-schema/{{ database.name|quote_plus }}/{{ tilde_encode(table) }}" method="post">
205
206
  <input type="hidden" name="csrftoken" value="{{ csrftoken() }}">
206
207
  {% if non_primary_key_columns %}
207
208
  <p><label for="id_add_index_column">
@@ -233,7 +234,7 @@ table.foreign-key-options td {
233
234
  {% if can_drop_table %}
234
235
  <h2>Drop table</h2>
235
236
 
236
- <form id="drop-table-form" action="{{ base_url }}-/edit-schema/{{ database.name|quote_plus }}/{{ tilde_encode(table) }}" method="post">
237
+ <form class="core" id="drop-table-form" action="{{ base_url }}-/edit-schema/{{ database.name|quote_plus }}/{{ tilde_encode(table) }}" method="post">
237
238
  <input type="hidden" name="csrftoken" value="{{ csrftoken() }}">
238
239
  <input type="hidden" name="drop_table" value="1">
239
240
  <input type="submit" class="button-red" value="Drop this table">
@@ -1,25 +1,25 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: datasette-edit-schema
3
- Version: 0.8a2
3
+ Version: 0.8a5
4
4
  Summary: Datasette plugin for modifying table schemas
5
5
  Author: Simon Willison
6
- License: Apache-2.0
6
+ License-Expression: Apache-2.0
7
7
  Project-URL: Homepage, https://datasette.io/plugins/datasette-edit-schema
8
8
  Project-URL: Changelog, https://github.com/simonw/datasette-edit-schema/releases
9
9
  Project-URL: Issues, https://github.com/simonw/datasette-edit-schema/issues
10
10
  Project-URL: CI, https://github.com/simonw/datasette-edit-schema/actions
11
11
  Classifier: Framework :: Datasette
12
- Classifier: License :: OSI Approved :: Apache Software License
13
- Requires-Python: >=3.8
12
+ Requires-Python: >=3.10
14
13
  Description-Content-Type: text/markdown
15
14
  License-File: LICENSE
16
- Requires-Dist: datasette>=1.0a13
15
+ Requires-Dist: datasette>=1.0a21
17
16
  Requires-Dist: sqlite-utils>=3.35
18
17
  Provides-Extra: test
19
18
  Requires-Dist: pytest; extra == "test"
20
19
  Requires-Dist: pytest-asyncio; extra == "test"
21
20
  Requires-Dist: beautifulsoup4; extra == "test"
22
21
  Requires-Dist: html5lib; extra == "test"
22
+ Dynamic: license-file
23
23
 
24
24
  # datasette-edit-schema
25
25
 
@@ -61,21 +61,15 @@ By default only [the root actor](https://datasette.readthedocs.io/en/stable/auth
61
61
 
62
62
  ## Permissions
63
63
 
64
- The `edit-schema` permission provides access to all functionality.
64
+ This plugin registers an `edit-schema` action that applies to databases. Granting that action gives an actor access to every feature in the UI. Instances launched with `datasette --root` automatically allow the signed-in root actor to perform this action.
65
65
 
66
- You can use permission plugins such as [datasette-permissions-sql](https://github.com/simonw/datasette-permissions-sql) to grant additional access to the write interface.
66
+ All permission checks now call `datasette.allowed()` with `DatabaseResource` or `TableResource` objects, so they work seamlessly with Datasette’s `permission_resources_sql()` hook and configuration-based permission rules. Plugins such as [datasette-permissions-sql](https://github.com/simonw/datasette-permissions-sql) can continue to be used to grant access to the write interface.
67
67
 
68
- These permission checks will call the `permission_allowed()` plugin hook with three arguments:
68
+ For finer control you can combine Datasette’s built-in actions:
69
69
 
70
- - `action` will be the string `"edit-schema"`
71
- - `actor` will be the currently authenticated actor - usually a dictionary
72
- - `resource` will be the string name of the database
73
-
74
- You can instead use more finely-grained permissions from the default Datasette permissions collection:
75
-
76
- - `create-table` allows users to create a new table. The `resource` will be the name of the database.
77
- - `drop-table` allows users to drop a table. The `resource` will be a tuple of `(database_name, table_name)`.
78
- - `alter-table` allows users to alter a table. The `resource` will be a tuple of `(database_name, table_name)`.
70
+ - `create-table` allows users to create a new table (database-level resource).
71
+ - `drop-table` allows users to drop a table (table-level resource).
72
+ - `alter-table` allows users to alter a table (table-level resource).
79
73
 
80
74
  To rename a table a user must have both `drop-table` permission for that table and `create-table` permission for that database.
81
75
 
@@ -1,4 +1,4 @@
1
- datasette>=1.0a13
1
+ datasette>=1.0a21
2
2
  sqlite-utils>=3.35
3
3
 
4
4
  [test]
@@ -1,17 +1,16 @@
1
1
  [project]
2
2
  name = "datasette-edit-schema"
3
- version = "0.8a2"
3
+ version = "0.8a5"
4
4
  description = "Datasette plugin for modifying table schemas"
5
5
  readme = "README.md"
6
6
  authors = [{name = "Simon Willison"}]
7
- license = {text = "Apache-2.0"}
7
+ license = "Apache-2.0"
8
8
  classifiers=[
9
- "Framework :: Datasette",
10
- "License :: OSI Approved :: Apache Software License"
9
+ "Framework :: Datasette"
11
10
  ]
12
- requires-python = ">=3.8"
11
+ requires-python = ">=3.10"
13
12
  dependencies = [
14
- "datasette>=1.0a13",
13
+ "datasette>=1.0a21",
15
14
  "sqlite-utils>=3.35",
16
15
  ]
17
16
 
@@ -22,9 +22,15 @@ def get_last_event(datasette):
22
22
  return events[-1]
23
23
 
24
24
 
25
+ def root_datasette(*args, **kwargs):
26
+ ds = Datasette(*args, **kwargs)
27
+ ds.root_enabled = True
28
+ return ds
29
+
30
+
25
31
  @pytest.mark.asyncio
26
32
  async def test_csrf_required(db_path):
27
- ds = Datasette([db_path])
33
+ ds = root_datasette([db_path])
28
34
  response = await ds.client.post(
29
35
  "/edit-schema/data/creatures",
30
36
  data={"drop_table": "1"},
@@ -78,7 +84,7 @@ async def test_table_actions(permission_plugin, ds, actor_id, should_allow, tabl
78
84
 
79
85
  @pytest.mark.asyncio
80
86
  async def test_post_without_operation_raises_error(db_path):
81
- ds = Datasette([db_path])
87
+ ds = root_datasette([db_path])
82
88
  cookies = {"ds_actor": ds.sign({"a": {"id": "root"}}, "actor")}
83
89
  # Get a csrftoken
84
90
  csrftoken = (
@@ -104,7 +110,7 @@ async def test_post_without_operation_raises_error(db_path):
104
110
  ),
105
111
  )
106
112
  async def test_drop_table(permission_plugin, db_path, actor_id, should_allow):
107
- ds = Datasette([db_path], pdb=True)
113
+ ds = root_datasette([db_path], pdb=True)
108
114
  ds._rules_allow = [
109
115
  Rule(
110
116
  actor_id="user_with_edit_schema",
@@ -174,7 +180,7 @@ async def test_drop_table(permission_plugin, db_path, actor_id, should_allow):
174
180
  [("text", str), ("integer", int), ("real", float), ("blob", bytes)],
175
181
  )
176
182
  async def test_add_column(db_path, col_type, expected_type):
177
- ds = Datasette([db_path])
183
+ ds = root_datasette([db_path])
178
184
  db = sqlite_utils.Database(db_path)
179
185
  cookies = {"ds_actor": ds.sign({"a": {"id": "root"}}, "actor")}
180
186
  table = db["creatures"]
@@ -218,7 +224,7 @@ async def test_add_column(db_path, col_type, expected_type):
218
224
  ],
219
225
  )
220
226
  async def test_add_column_errors(db_path, name, type, expected_error):
221
- ds = Datasette([db_path])
227
+ ds = root_datasette([db_path])
222
228
  cookies = {"ds_actor": ds.sign({"a": {"id": "root"}}, "actor")}
223
229
  csrftoken = (
224
230
  await ds.client.get("/-/edit-schema/data/creatures", cookies=cookies)
@@ -345,7 +351,7 @@ async def test_add_column_errors(db_path, name, type, expected_error):
345
351
  async def test_transform_table(
346
352
  db_path, action, post_data, expected_columns_dict, expected_order, expected_message
347
353
  ):
348
- ds = Datasette([db_path])
354
+ ds = root_datasette([db_path])
349
355
  cookies = {"ds_actor": ds.sign({"a": {"id": "root"}}, "actor")}
350
356
  db = sqlite_utils.Database(db_path)
351
357
  table = db["creatures"]
@@ -378,7 +384,7 @@ async def test_transform_table(
378
384
  @pytest.mark.asyncio
379
385
  async def test_drop_column_from_table_that_is_part_of_a_view(db_path):
380
386
  # https://github.com/simonw/datasette-edit-schema/issues/35
381
- ds = Datasette([db_path], pdb=True)
387
+ ds = root_datasette([db_path], pdb=True)
382
388
  cookies = {"ds_actor": ds.sign({"a": {"id": "root"}}, "actor")}
383
389
  db = sqlite_utils.Database(db_path)
384
390
  db.create_view("creatures_view", "select * from creatures")
@@ -407,7 +413,7 @@ async def test_drop_column_from_table_that_is_part_of_a_view(db_path):
407
413
 
408
414
  @pytest.mark.asyncio
409
415
  async def test_static_assets(db_path):
410
- ds = Datasette([db_path])
416
+ ds = root_datasette([db_path])
411
417
  for path in (
412
418
  "/-/static-plugins/datasette-edit-schema/draggable.1.0.0-beta.11.bundle.min.js",
413
419
  ):
@@ -421,7 +427,7 @@ async def test_static_assets(db_path):
421
427
  )
422
428
  async def test_permission_edit_schema(db_path, path):
423
429
  # root user has edit-schema which allows access to all
424
- ds = Datasette([db_path])
430
+ ds = root_datasette([db_path])
425
431
  someuser_cookies = {"ds_actor": ds.sign({"a": {"id": "someuser"}}, "actor")}
426
432
  root_cookies = {"ds_actor": ds.sign({"a": {"id": "root"}}, "actor")}
427
433
  response = await ds.client.get(path)
@@ -615,7 +621,7 @@ async def test_table_form_contains_schema(permission_plugin, ds):
615
621
  ],
616
622
  )
617
623
  async def test_rename_table(db_path, new_name, should_work, expected_message):
618
- ds = Datasette([db_path])
624
+ ds = root_datasette([db_path])
619
625
  cookies = {"ds_actor": ds.sign({"a": {"id": "root"}}, "actor")}
620
626
  csrftoken = (
621
627
  await ds.client.get("/-/edit-schema/data/creatures", cookies=cookies)
@@ -674,7 +680,7 @@ async def test_rename_table(db_path, new_name, should_work, expected_message):
674
680
  ),
675
681
  )
676
682
  async def test_breadcrumbs(db_path, path, expected_breadcrumbs):
677
- ds = Datasette([db_path])
683
+ ds = root_datasette([db_path])
678
684
  cookies = {"ds_actor": ds.sign({"a": {"id": "root"}}, "actor")}
679
685
  response = await ds.client.get(path, cookies=cookies)
680
686
  assert response.status_code == 200
@@ -696,7 +702,7 @@ def test_potential_foreign_keys(db):
696
702
  @pytest.mark.asyncio
697
703
  async def test_edit_form_shows_suggestions(db_path):
698
704
  # Test for suggested foreign keys and primary keys
699
- ds = Datasette([db_path])
705
+ ds = root_datasette([db_path])
700
706
  cookies = {"ds_actor": ds.sign({"a": {"id": "root"}}, "actor")}
701
707
  response = await ds.client.get("/-/edit-schema/data/museums", cookies=cookies)
702
708
  assert response.status_code == 200
@@ -767,7 +773,7 @@ async def test_edit_form_shows_suggestions(db_path):
767
773
  @pytest.mark.asyncio
768
774
  async def test_edit_form_for_empty_table(db_path):
769
775
  # https://github.com/simonw/datasette-edit-schema/issues/38
770
- ds = Datasette([db_path])
776
+ ds = root_datasette([db_path])
771
777
  cookies = {"ds_actor": ds.sign({"a": {"id": "root"}}, "actor")}
772
778
  response = await ds.client.get("/-/edit-schema/data/empty_table", cookies=cookies)
773
779
  assert response.status_code == 200
@@ -859,7 +865,7 @@ async def test_edit_form_for_empty_table(db_path):
859
865
  async def test_edit_keys(
860
866
  db_path, table, post_data, expected_fks, expected_pk, expected_message
861
867
  ):
862
- ds = Datasette([db_path])
868
+ ds = root_datasette([db_path])
863
869
  # Grab a csrftoken
864
870
  cookies = {"ds_actor": ds.sign({"a": {"id": "root"}}, "actor")}
865
871
  csrftoken_r = await ds.client.get(
@@ -951,7 +957,7 @@ def get_options(soup, name):
951
957
  ),
952
958
  )
953
959
  async def test_create_table(db_path, post_data, expected_message, expected_schema):
954
- ds = Datasette([db_path])
960
+ ds = root_datasette([db_path])
955
961
  cookies = {"ds_actor": ds.sign({"a": {"id": "root"}}, "actor")}
956
962
  csrftoken_r = await ds.client.get("/-/edit-schema/data/-/create", cookies=cookies)
957
963
  csrftoken = csrftoken_r.cookies["ds_csrftoken"]
@@ -1107,7 +1113,7 @@ def test_potential_primary_keys_primary_key_only_table():
1107
1113
  async def test_add_remove_index(
1108
1114
  db_path, table, post_data, expected_message, expected_indexes
1109
1115
  ):
1110
- ds = Datasette([db_path])
1116
+ ds = root_datasette([db_path])
1111
1117
  cookies = {"ds_actor": ds.sign({"a": {"id": "root"}}, "actor")}
1112
1118
  get_response = await ds.client.get(
1113
1119
  "/-/edit-schema/data/{}".format(tilde_encode(table)), cookies=cookies
@@ -1144,7 +1150,7 @@ async def test_database_and_table_level_permissions(tmp_path):
1144
1150
  sales_db["notes"].insert({"id": 1, "note": "Hello"}, pk="id")
1145
1151
  sales_db["not_allowed"].insert({"id": 1}, pk="id")
1146
1152
 
1147
- ds = Datasette(
1153
+ ds = root_datasette(
1148
1154
  [marketing_path, sales_path],
1149
1155
  config={
1150
1156
  "databases": {