diff --git a/examples/connect/shiny-python/app.py b/examples/connect/shiny-python/app.py index 4a1cb695..bf97579e 100644 --- a/examples/connect/shiny-python/app.py +++ b/examples/connect/shiny-python/app.py @@ -16,7 +16,7 @@ app_ui = ui.page_fluid(ui.output_text("text"), ui.output_data_frame("result")) -def server(input: Inputs, output: Outputs, session: Session): +def server(i: Inputs, o: Outputs, session: Session): """ Shiny for Python example application that shows user information and the first few rows from a table hosted in Databricks. diff --git a/pyproject.toml b/pyproject.toml index a2989b6b..3a2c3d87 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,7 +44,32 @@ docstring-code-format = true docstring-code-line-length = "dynamic" [tool.ruff.lint] -select = ["D", "F401", "I"] +select = [ + # flake8-builtins + # https://docs.astral.sh/ruff/rules/#flake8-builtins-a + # + # Check for builtin shadowing (i.e., naming a variable 'for', which is a builtin.) + "A", + + # pydocstyle + # https://docs.astral.sh/ruff/rules/#pydocstyle-d + # https://docs.astral.sh/ruff/faq/#does-ruff-support-numpy-or-google-style-docstrings + # + # Check docstring formatting. Many of these rules are intentionally ignored below. + "D", + + # pyflakes - unused-import + # https://docs.astral.sh/ruff/rules/unused-import/ + # + # Check for unused imports. + "F401", + + # isort + # https://docs.astral.sh/ruff/rules/#isort-i + # + # Sort imports. + "I" +] ignore = [ # NumPy style docstring convention with noted exceptions. # https://docs.astral.sh/ruff/faq/#does-ruff-support-numpy-or-google-style-docstrings @@ -67,7 +92,7 @@ ignore = [ 'D415', 'D416', 'D417', - 'D418', # The Python Language Server can accomdate documentation for individual methods. + 'D418', # The Python Language Server can accomodate documentation for individual methods. # TODO(#135) resarch D418 and determine if we should continue ignoring it. ] diff --git a/src/posit/connect/bundles.py b/src/posit/connect/bundles.py index fa6eb194..b38ea7dd 100644 --- a/src/posit/connect/bundles.py +++ b/src/posit/connect/bundles.py @@ -235,7 +235,7 @@ def __init__( super().__init__(params) self.content_guid = content_guid - def create(self, input: io.BufferedReader | bytes | str) -> Bundle: + def create(self, archive: io.BufferedReader | bytes | str) -> Bundle: """ Create a bundle. @@ -243,8 +243,8 @@ def create(self, input: io.BufferedReader | bytes | str) -> Bundle: Parameters ---------- - input : io.BufferedReader, bytes, or str - Input archive for bundle creation. A 'str' type assumes a relative or absolute filepath. + archive : io.BufferedReader, bytes, or str + Archive for bundle creation. A 'str' type assumes a relative or absolute filepath. Returns ------- @@ -273,14 +273,14 @@ def create(self, input: io.BufferedReader | bytes | str) -> Bundle: >>> bundle.create("bundle.tar.gz") None """ - if isinstance(input, (io.BufferedReader, bytes)): - data = input - elif isinstance(input, str): - with open(input, "rb") as file: + if isinstance(archive, (io.BufferedReader, bytes)): + data = archive + elif isinstance(archive, str): + with open(archive, "rb") as file: data = file.read() else: raise TypeError( - f"create() expected argument type 'io.BufferedReader', 'bytes', or 'str', but got '{type(input).__name__}'" + f"create() expected argument type 'io.BufferedReader', 'bytes', or 'str', but got '{type(archive).__name__}'" ) path = f"v1/content/{self.content_guid}/bundles" @@ -314,12 +314,12 @@ def find_one(self) -> Bundle | None: bundles = self.find() return next(iter(bundles), None) - def get(self, id: str) -> Bundle: + def get(self, uid: str) -> Bundle: """Get a bundle. Parameters ---------- - id : str + uid : str Identifier of the bundle to retrieve. Returns @@ -327,7 +327,7 @@ def get(self, id: str) -> Bundle: Bundle The bundle with the specified ID. """ - path = f"v1/content/{self.content_guid}/bundles/{id}" + path = f"v1/content/{self.content_guid}/bundles/{uid}" url = self.url + path response = self.session.get(url) result = response.json() diff --git a/src/posit/connect/cursors.py b/src/posit/connect/cursors.py index 98a039d6..ec8cf44e 100644 --- a/src/posit/connect/cursors.py +++ b/src/posit/connect/cursors.py @@ -45,17 +45,17 @@ def fetch_pages(self) -> Generator[CursorPage, None, None]: ------ Generator[Page, None, None] """ - next = None + next_page = None while True: - page = self.fetch_page(next) + page = self.fetch_page(next_page) yield page cursors: dict = page.paging.get("cursors", {}) - next = cursors.get("next") - if not next: + next_page = cursors.get("next") + if not next_page: # stop if a next page is not defined return - def fetch_page(self, next: str | None = None) -> CursorPage: + def fetch_page(self, next_page: str | None = None) -> CursorPage: """Fetch a page. Parameters @@ -69,7 +69,7 @@ def fetch_page(self, next: str | None = None) -> CursorPage: """ params = { **self.params, - "next": next, + "next": next_page, "limit": _MAX_PAGE_SIZE, } response = self.session.get(self.url, params=params) diff --git a/src/posit/connect/permissions.py b/src/posit/connect/permissions.py index 118d7ba4..54f1e296 100644 --- a/src/posit/connect/permissions.py +++ b/src/posit/connect/permissions.py @@ -149,19 +149,19 @@ def find_one(self, *args, **kwargs) -> Permission | None: permissions = self.find(*args, **kwargs) return next(iter(permissions), None) - def get(self, id: str) -> Permission: + def get(self, uid: str) -> Permission: """Get a permission. Parameters ---------- - id : str + uid : str The permission id. Returns ------- Permission """ - path = f"v1/content/{self.content_guid}/permissions/{id}" + path = f"v1/content/{self.content_guid}/permissions/{uid}" url = self.url + path response = self.session.get(url) return Permission(self.params, **response.json()) diff --git a/src/posit/connect/tasks.py b/src/posit/connect/tasks.py index 83d17b3b..3e735ab1 100644 --- a/src/posit/connect/tasks.py +++ b/src/posit/connect/tasks.py @@ -144,12 +144,12 @@ def wait_for(self) -> None: class Tasks(resources.Resources): @overload - def get(self, id: str, first: int, wait: int) -> Task: + def get(self, uid: str, first: int, wait: int) -> Task: """Get a task. Parameters ---------- - id : str + uid : str Task identifier. first : int, default 0 Line to start output on. @@ -163,12 +163,12 @@ def get(self, id: str, first: int, wait: int) -> Task: ... @overload - def get(self, id: str, *args, **kwargs) -> Task: + def get(self, uid: str, *args, **kwargs) -> Task: """Get a task. Parameters ---------- - id : str + uid : str Task identifier. Returns @@ -177,12 +177,12 @@ def get(self, id: str, *args, **kwargs) -> Task: """ ... - def get(self, id: str, *args, **kwargs) -> Task: + def get(self, uid: str, *args, **kwargs) -> Task: """Get a task. Parameters ---------- - id : str + uid : str Task identifier. Returns @@ -190,7 +190,7 @@ def get(self, id: str, *args, **kwargs) -> Task: Task """ params = dict(*args, **kwargs) - path = f"v1/tasks/{id}" + path = f"v1/tasks/{uid}" url = self.url + path response = self.session.get(url, params=params) result = response.json() diff --git a/src/posit/connect/users.py b/src/posit/connect/users.py index cccb72ad..e8cc26aa 100644 --- a/src/posit/connect/users.py +++ b/src/posit/connect/users.py @@ -230,8 +230,8 @@ def find_one(self, *args, **kwargs) -> User | None: ) return next(users, None) - def get(self, id: str) -> User: - url = self.url + f"v1/users/{id}" + def get(self, uid: str) -> User: + url = self.url + f"v1/users/{uid}" response = self.session.get(url) return User( self.params, diff --git a/tests/posit/connect/test_client.py b/tests/posit/connect/test_client.py index e873ce8e..efe716e3 100644 --- a/tests/posit/connect/test_client.py +++ b/tests/posit/connect/test_client.py @@ -7,19 +7,19 @@ from .api import load_mock # type: ignore -@pytest.fixture +@pytest.fixture() def MockAuth(): with patch("posit.connect.client.Auth") as mock: yield mock -@pytest.fixture +@pytest.fixture() def MockConfig(): with patch("posit.connect.client.Config") as mock: yield mock -@pytest.fixture +@pytest.fixture() def MockSession(): with patch("posit.connect.client.Session") as mock: yield mock diff --git a/tests/posit/connect/test_env.py b/tests/posit/connect/test_env.py index afd0367c..418e5127 100644 --- a/tests/posit/connect/test_env.py +++ b/tests/posit/connect/test_env.py @@ -304,10 +304,10 @@ def test_find(): content = c.content.get(guid) # invoke - vars = content.environment_variables.find() + envvars = content.environment_variables.find() # assert - assert vars == ["TEST"] + assert envvars == ["TEST"] assert mock_get_content.call_count == 1 assert mock_get_environment.call_count == 1 diff --git a/tests/posit/connect/test_permissions.py b/tests/posit/connect/test_permissions.py index 03099af9..2f37879a 100644 --- a/tests/posit/connect/test_permissions.py +++ b/tests/posit/connect/test_permissions.py @@ -15,12 +15,12 @@ class TestPermissionDelete: @responses.activate def test(self): # data - id = "94" + uid = "94" content_guid = "f2f37341-e21d-3d80-c698-a935ad614066" # behavior mock_delete = responses.delete( - f"https://connect.example/__api__/v1/content/{content_guid}/permissions/{id}" + f"https://connect.example/__api__/v1/content/{content_guid}/permissions/{uid}" ) # setup @@ -28,7 +28,7 @@ def test(self): requests.Session(), Url("https://connect.example/__api__") ) fake_permission = load_mock( - f"v1/content/{content_guid}/permissions/{id}.json" + f"v1/content/{content_guid}/permissions/{uid}.json" ) permission = Permission(params, **fake_permission) @@ -43,7 +43,7 @@ class TestPermissionUpdate: @responses.activate def test_request_shape(self): # test data - id = random.randint(0, 100) + uid = random.randint(0, 100) content_guid = str(uuid.uuid4()) principal_guid = str(uuid.uuid4()) principal_type = "principal_type" @@ -52,7 +52,7 @@ def test_request_shape(self): # define api behavior responses.put( - f"https://connect.example/__api__/v1/content/{content_guid}/permissions/{id}", + f"https://connect.example/__api__/v1/content/{content_guid}/permissions/{uid}", json={ # doesn't matter for this test }, @@ -77,7 +77,7 @@ def test_request_shape(self): ) permission = Permission( params, - id=id, + id=uid, content_guid=content_guid, principal_guid=principal_guid, principal_type=principal_type, @@ -94,18 +94,18 @@ def test_role_update(self): old_role = "owner" new_role = "viewer" - id = "94" + uid = "94" content_guid = "f2f37341-e21d-3d80-c698-a935ad614066" fake_permission = load_mock( - f"v1/content/{content_guid}/permissions/{id}.json" + f"v1/content/{content_guid}/permissions/{uid}.json" ) fake_permission.update(role=new_role) # define api behavior - id = random.randint(0, 100) + uid = random.randint(0, 100) content_guid = str(uuid.uuid4()) responses.put( - f"https://connect.example/__api__/v1/content/{content_guid}/permissions/{id}", + f"https://connect.example/__api__/v1/content/{content_guid}/permissions/{uid}", json=fake_permission, match=[ matchers.json_params_matcher( @@ -123,7 +123,7 @@ def test_role_update(self): requests.Session(), Url("https://connect.example/__api__") ) permission = Permission( - params, id=id, content_guid=content_guid, role=old_role + params, id=uid, content_guid=content_guid, role=old_role ) # assert role change with respect to api response @@ -164,13 +164,13 @@ class TestPermissionsCreate: @responses.activate def test(self): # data - id = "94" + uid = "94" content_guid = "f2f37341-e21d-3d80-c698-a935ad614066" principal_guid = str(uuid.uuid4()) principal_type = "user" role = "owner" fake_permission = { - **load_mock(f"v1/content/{content_guid}/permissions/{id}.json"), + **load_mock(f"v1/content/{content_guid}/permissions/{uid}.json"), "principal_guid": principal_guid, "principal_type": principal_type, "role": role, @@ -268,15 +268,15 @@ class TestPermissionsGet: @responses.activate def test(self): # data - id = "94" + uid = "94" content_guid = "f2f37341-e21d-3d80-c698-a935ad614066" fake_permission = load_mock( - f"v1/content/{content_guid}/permissions/{id}.json" + f"v1/content/{content_guid}/permissions/{uid}.json" ) # behavior responses.get( - f"https://connect.example/__api__/v1/content/{content_guid}/permissions/{id}", + f"https://connect.example/__api__/v1/content/{content_guid}/permissions/{uid}", json=fake_permission, ) @@ -287,7 +287,7 @@ def test(self): permissions = Permissions(params, content_guid=content_guid) # invoke - permission = permissions.get(id) + permission = permissions.get(uid) # assert assert permission == fake_permission diff --git a/tests/posit/connect/test_tasks.py b/tests/posit/connect/test_tasks.py index 134d8017..bd09a34d 100644 --- a/tests/posit/connect/test_tasks.py +++ b/tests/posit/connect/test_tasks.py @@ -43,23 +43,23 @@ def test_result(self): class TestTaskUpdate: @responses.activate def test(self): - id = "jXhOhdm5OOSkGhJw" + uid = "jXhOhdm5OOSkGhJw" # behavior mock_tasks_get = [0] * 2 mock_tasks_get[0] = responses.get( - f"https://connect.example/__api__/v1/tasks/{id}", - json={**load_mock(f"v1/tasks/{id}.json"), "finished": False}, + f"https://connect.example/__api__/v1/tasks/{uid}", + json={**load_mock(f"v1/tasks/{uid}.json"), "finished": False}, ) mock_tasks_get[1] = responses.get( - f"https://connect.example/__api__/v1/tasks/{id}", - json={**load_mock(f"v1/tasks/{id}.json"), "finished": True}, + f"https://connect.example/__api__/v1/tasks/{uid}", + json={**load_mock(f"v1/tasks/{uid}.json"), "finished": True}, ) # setup c = connect.Client("https://connect.example", "12345") - task = c.tasks.get(id) + task = c.tasks.get(uid) assert not task.is_finished # invoke @@ -72,25 +72,25 @@ def test(self): @responses.activate def test_with_params(self): - id = "jXhOhdm5OOSkGhJw" + uid = "jXhOhdm5OOSkGhJw" params = {"first": 10, "wait": 10} # behavior mock_tasks_get = [0] * 2 mock_tasks_get[0] = responses.get( - f"https://connect.example/__api__/v1/tasks/{id}", - json={**load_mock(f"v1/tasks/{id}.json"), "finished": False}, + f"https://connect.example/__api__/v1/tasks/{uid}", + json={**load_mock(f"v1/tasks/{uid}.json"), "finished": False}, ) mock_tasks_get[1] = responses.get( - f"https://connect.example/__api__/v1/tasks/{id}", - json={**load_mock(f"v1/tasks/{id}.json"), "finished": True}, + f"https://connect.example/__api__/v1/tasks/{uid}", + json={**load_mock(f"v1/tasks/{uid}.json"), "finished": True}, match=[matchers.query_param_matcher(params)], ) # setup c = connect.Client("https://connect.example", "12345") - task = c.tasks.get(id) + task = c.tasks.get(uid) assert not task.is_finished # invoke @@ -105,23 +105,23 @@ def test_with_params(self): class TestTaskWaitFor: @responses.activate def test(self): - id = "jXhOhdm5OOSkGhJw" + uid = "jXhOhdm5OOSkGhJw" # behavior mock_tasks_get = [0] * 2 mock_tasks_get[0] = responses.get( - f"https://connect.example/__api__/v1/tasks/{id}", - json={**load_mock(f"v1/tasks/{id}.json"), "finished": False}, + f"https://connect.example/__api__/v1/tasks/{uid}", + json={**load_mock(f"v1/tasks/{uid}.json"), "finished": False}, ) mock_tasks_get[1] = responses.get( - f"https://connect.example/__api__/v1/tasks/{id}", - json={**load_mock(f"v1/tasks/{id}.json"), "finished": True}, + f"https://connect.example/__api__/v1/tasks/{uid}", + json={**load_mock(f"v1/tasks/{uid}.json"), "finished": True}, ) # setup c = connect.Client("https://connect.example", "12345") - task = c.tasks.get(id) + task = c.tasks.get(uid) assert not task.is_finished # invoke @@ -136,20 +136,20 @@ def test(self): class TestTasksGet: @responses.activate def test(self): - id = "jXhOhdm5OOSkGhJw" + uid = "jXhOhdm5OOSkGhJw" # behavior mock_tasks_get = responses.get( - f"https://connect.example/__api__/v1/tasks/{id}", - json={**load_mock(f"v1/tasks/{id}.json"), "finished": False}, + f"https://connect.example/__api__/v1/tasks/{uid}", + json={**load_mock(f"v1/tasks/{uid}.json"), "finished": False}, ) # setup c = connect.Client("https://connect.example", "12345") # invoke - task = c.tasks.get(id) + task = c.tasks.get(uid) # assert - assert task.id == id + assert task.id == uid assert mock_tasks_get.call_count == 1