diff --git a/config/settings/common_settings.py b/config/settings/common_settings.py index 7b8ab40d58..abd0e94204 100644 --- a/config/settings/common_settings.py +++ b/config/settings/common_settings.py @@ -66,7 +66,8 @@ def pipe_delim(pipe_string): MODERNRPC_METHODS_MODULES = [ 'mathesar.rpc.connections', - 'mathesar.rpc.columns' + 'mathesar.rpc.columns', + 'mathesar.rpc.schemas' ] TEMPLATES = [ diff --git a/docs/docs/api/rpc.md b/docs/docs/api/rpc.md index 12097fb5b1..44e7051d07 100644 --- a/docs/docs/api/rpc.md +++ b/docs/docs/api/rpc.md @@ -48,6 +48,14 @@ To use an RPC function: --- +::: mathesar.rpc.schemas + options: + members: + - list_ + - SchemaInfo + +--- + ::: mathesar.rpc.columns options: members: diff --git a/mathesar/rpc/schemas.py b/mathesar/rpc/schemas.py new file mode 100644 index 0000000000..1fdefa5b77 --- /dev/null +++ b/mathesar/rpc/schemas.py @@ -0,0 +1,55 @@ +""" +Classes and functions exposed to the RPC endpoint for managing schemas. +""" +from typing import Optional, TypedDict + +from modernrpc.core import rpc_method, REQUEST_KEY +from modernrpc.auth.basic import http_basic_auth_login_required + +from db.constants import INTERNAL_SCHEMAS +from db.schemas.operations.select import get_schemas +from mathesar.rpc.exceptions.handlers import handle_rpc_exceptions +from mathesar.rpc.utils import connect + + +class SchemaInfo(TypedDict): + """ + Information about a schema + + Attributes: + oid: The OID of the schema + name: The name of the schema + description: A description of the schema + table_count: The number of tables in the schema + exploration_count: The number of explorations in the schema + """ + oid: int + name: str + description: Optional[str] + table_count: int + exploration_count: int + + +@rpc_method(name="schemas.list") +@http_basic_auth_login_required +@handle_rpc_exceptions +def list_(*, database_id: int, **kwargs) -> list[SchemaInfo]: + """ + List information about schemas in a database. Exposed as `list`. + + Args: + database_id: The Django id of the database containing the table. + + Returns: + A list of schema details + """ + user = kwargs.get(REQUEST_KEY).user + with connect(database_id, user) as conn: + schemas = get_schemas(conn) + + user_defined_schemas = [s for s in schemas if s['name'] not in INTERNAL_SCHEMAS] + + # TODO_FOR_BETA: join exploration count from internal DB here after we've + # refactored the models so that each exploration is associated with a schema + # (by oid) in a specific database. + return [{**s, "exploration_count": 0} for s in user_defined_schemas] diff --git a/mathesar/tests/rpc/test_endpoints.py b/mathesar/tests/rpc/test_endpoints.py index 2cdfb1fe9b..09d2af3a64 100644 --- a/mathesar/tests/rpc/test_endpoints.py +++ b/mathesar/tests/rpc/test_endpoints.py @@ -10,7 +10,7 @@ from mathesar.rpc import columns from mathesar.rpc import connections - +from mathesar.rpc import schemas METHODS = [ ( @@ -27,7 +27,12 @@ connections.add_from_scratch, "connections.add_from_scratch", [user_is_superuser] - ) + ), + ( + schemas.list_, + "schemas.list", + [user_is_authenticated] + ), ]