Skip to content

Commit ae4e6cc

Browse files
committed
typecheck yourself before you wreck yourself
1 parent 397f234 commit ae4e6cc

File tree

4 files changed

+41
-39
lines changed

4 files changed

+41
-39
lines changed

rsconnect/actions_content.py

+18-14
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
import traceback
1010
from concurrent.futures import ThreadPoolExecutor, as_completed
1111
from datetime import datetime, timedelta
12-
from typing import Iterator, Literal, Optional, Sequence, cast
12+
from typing import Iterator, Literal, Optional, Sequence, cast, Union
1313

1414
import semver
1515

16-
from .api import PositConnectServer, RSConnectClient, emit_task_log
16+
from .api import RSConnectServer, SPCSConnectServer, RSConnectClient, emit_task_log
1717
from .exception import RSConnectException
1818
from .log import logger
1919
from .metadata import ContentBuildStore, ContentItemWithBuildState
@@ -33,7 +33,7 @@ def content_build_store() -> ContentBuildStore:
3333
return _content_build_store
3434

3535

36-
def ensure_content_build_store(connect_server: PositConnectServer) -> ContentBuildStore:
36+
def ensure_content_build_store(connect_server: Union[RSConnectServer, SPCSConnectServer]) -> ContentBuildStore:
3737
global _content_build_store
3838
if not _content_build_store:
3939
logger.info("Initializing ContentBuildStore for %s" % connect_server.url)
@@ -42,7 +42,7 @@ def ensure_content_build_store(connect_server: PositConnectServer) -> ContentBui
4242

4343

4444
def build_add_content(
45-
connect_server: PositConnectServer,
45+
connect_server: Union[RSConnectServer, SPCSConnectServer],
4646
content_guids_with_bundle: Sequence[ContentGuidWithBundle],
4747
):
4848
"""
@@ -85,7 +85,7 @@ def _validate_build_rm_args(guid: Optional[str], all: bool, purge: bool):
8585

8686

8787
def build_remove_content(
88-
connect_server: PositConnectServer,
88+
connect_server: Union[RSConnectServer, SPCSConnectServer],
8989
guid: Optional[str],
9090
all: bool,
9191
purge: bool,
@@ -109,20 +109,20 @@ def build_remove_content(
109109
return guids
110110

111111

112-
def build_list_content(connect_server: PositConnectServer, guid: str, status: Optional[str]):
112+
def build_list_content(connect_server: Union[RSConnectServer, SPCSConnectServer], guid: str, status: Optional[str]):
113113
build_store = ensure_content_build_store(connect_server)
114114
if guid:
115115
return [build_store.get_content_item(g) for g in guid]
116116
else:
117117
return build_store.get_content_items(status=status)
118118

119119

120-
def build_history(connect_server: PositConnectServer, guid: str):
120+
def build_history(connect_server: Union[RSConnectServer, SPCSConnectServer], guid: str):
121121
return ensure_content_build_store(connect_server).get_build_history(guid)
122122

123123

124124
def build_start(
125-
connect_server: PositConnectServer,
125+
connect_server: Union[RSConnectServer, SPCSConnectServer],
126126
parallelism: int,
127127
aborted: bool = False,
128128
error: bool = False,
@@ -251,7 +251,9 @@ def build_start(
251251
build_monitor.shutdown()
252252

253253

254-
def _monitor_build(connect_server: PositConnectServer, content_items: list[ContentItemWithBuildState]):
254+
def _monitor_build(
255+
connect_server: Union[RSConnectServer, SPCSConnectServer], content_items: list[ContentItemWithBuildState]
256+
):
255257
"""
256258
:return bool: True if the build completed without errors, False otherwise
257259
"""
@@ -296,7 +298,9 @@ def _monitor_build(connect_server: PositConnectServer, content_items: list[Conte
296298
return True
297299

298300

299-
def _build_content_item(connect_server: PositConnectServer, content: ContentItemWithBuildState, poll_wait: int):
301+
def _build_content_item(
302+
connect_server: Union[RSConnectServer, SPCSConnectServer], content: ContentItemWithBuildState, poll_wait: int
303+
):
300304
build_store = ensure_content_build_store(connect_server)
301305
with RSConnectClient(connect_server) as client:
302306
# Pending futures will still try to execute when ThreadPoolExecutor.shutdown() is called
@@ -351,7 +355,7 @@ def write_log(line: str):
351355

352356

353357
def emit_build_log(
354-
connect_server: PositConnectServer,
358+
connect_server: Union[RSConnectServer, SPCSConnectServer],
355359
guid: str,
356360
format: str,
357361
task_id: Optional[str] = None,
@@ -369,7 +373,7 @@ def emit_build_log(
369373
raise RSConnectException("Log file not found for content: %s" % guid)
370374

371375

372-
def download_bundle(connect_server: PositConnectServer, guid_with_bundle: ContentGuidWithBundle):
376+
def download_bundle(connect_server: Union[RSConnectServer, SPCSConnectServer], guid_with_bundle: ContentGuidWithBundle):
373377
"""
374378
:param guid_with_bundle: models.ContentGuidWithBundle
375379
"""
@@ -387,7 +391,7 @@ def download_bundle(connect_server: PositConnectServer, guid_with_bundle: Conten
387391
return client.download_bundle(guid_with_bundle.guid, guid_with_bundle.bundle_id)
388392

389393

390-
def get_content(connect_server: PositConnectServer, guid: str | list[str]):
394+
def get_content(connect_server: Union[RSConnectServer, SPCSConnectServer], guid: str | list[str]):
391395
"""
392396
:param guid: a single guid as a string or list of guids.
393397
:return: a list of content items.
@@ -401,7 +405,7 @@ def get_content(connect_server: PositConnectServer, guid: str | list[str]):
401405

402406

403407
def search_content(
404-
connect_server: PositConnectServer,
408+
connect_server: Union[RSConnectServer, SPCSConnectServer],
405409
published: bool,
406410
unpublished: bool,
407411
content_type: Sequence[str],

rsconnect/api.py

+11-12
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,6 @@ def exchange_token(self) -> str:
323323

324324

325325
TargetableServer = typing.Union[ShinyappsServer, RSConnectServer, CloudServer, SPCSConnectServer]
326-
PositConnectServer = typing.Union[RSConnectServer, SPCSConnectServer]
327326

328327

329328
class S3Server(AbstractRemoteServer):
@@ -340,7 +339,7 @@ class RSConnectClientDeployResult(TypedDict):
340339

341340

342341
class RSConnectClient(HTTPServer):
343-
def __init__(self, server: PositConnectServer, cookies: Optional[CookieJar] = None):
342+
def __init__(self, server: Union[RSConnectServer, SPCSConnectServer], cookies: Optional[CookieJar] = None):
344343
if cookies is None:
345344
cookies = server.cookie_jar
346345
super().__init__(
@@ -1007,7 +1006,7 @@ def deploy_bundle(self):
10071006
if self.bundle is None:
10081007
raise RSConnectException("A bundle must be created before deploying it.")
10091008

1010-
if isinstance(self.remote_server, PositConnectServer):
1009+
if isinstance(self.remote_server, (RSConnectServer, SPCSConnectServer)):
10111010
if not isinstance(self.client, RSConnectClient):
10121011
raise RSConnectException("client must be an RSConnectClient.")
10131012
result = self.client.deploy(
@@ -1086,7 +1085,7 @@ def emit_task_log(
10861085
:param raise_on_error: whether to raise an exception when a task is failed, otherwise we
10871086
return the task_result so we can record the exit code.
10881087
"""
1089-
if isinstance(self.remote_server, PositConnectServer):
1088+
if isinstance(self.remote_server, (RSConnectServer, SPCSConnectServer)):
10901089
if not isinstance(self.client, RSConnectClient):
10911090
raise RSConnectException("To emit task log, client must be a RSConnectClient.")
10921091

@@ -1128,7 +1127,7 @@ def save_deployed_info(self):
11281127

11291128
@cls_logged("Verifying deployed content...")
11301129
def verify_deployment(self):
1131-
if isinstance(self.remote_server, PositConnectServer):
1130+
if isinstance(self.remote_server, (RSConnectServer, SPCSConnectServer)):
11321131
if not isinstance(self.client, RSConnectClient):
11331132
raise RSConnectException("To verify deployment, client must be a RSConnectClient.")
11341133
deployed_info = self.deployed_info
@@ -1883,7 +1882,7 @@ def verify_api_key(connect_server: RSConnectServer) -> str:
18831882
return result["username"]
18841883

18851884

1886-
def get_python_info(connect_server: PositConnectServer):
1885+
def get_python_info(connect_server: Union[RSConnectServer, SPCSConnectServer]):
18871886
"""
18881887
Return information about versions of Python that are installed on the indicated
18891888
Connect server.
@@ -1897,7 +1896,7 @@ def get_python_info(connect_server: PositConnectServer):
18971896
return result
18981897

18991898

1900-
def get_app_info(connect_server: PositConnectServer, app_id: str):
1899+
def get_app_info(connect_server: Union[RSConnectServer, SPCSConnectServer], app_id: str):
19011900
"""
19021901
Return information about an application that has been created in Connect.
19031902
@@ -1918,7 +1917,7 @@ def get_posit_app_info(server: PositServer, app_id: str):
19181917
return response["source"]
19191918

19201919

1921-
def get_app_config(connect_server: PositConnectServer, app_id: str):
1920+
def get_app_config(connect_server: Union[RSConnectServer, SPCSConnectServer], app_id: str):
19221921
"""
19231922
Return the configuration information for an application that has been created
19241923
in Connect.
@@ -1934,7 +1933,7 @@ def get_app_config(connect_server: PositConnectServer, app_id: str):
19341933

19351934

19361935
def emit_task_log(
1937-
connect_server: PositConnectServer,
1936+
connect_server: Union[RSConnectServer, SPCSConnectServer],
19381937
app_id: str,
19391938
task_id: str,
19401939
log_callback: Optional[Callable[[str], None]],
@@ -1970,7 +1969,7 @@ def emit_task_log(
19701969

19711970

19721971
def retrieve_matching_apps(
1973-
connect_server: PositConnectServer,
1972+
connect_server: Union[RSConnectServer, SPCSConnectServer],
19741973
filters: Optional[dict[str, str | int]] = None,
19751974
limit: Optional[int] = None,
19761975
mapping_function: Optional[Callable[[RSConnectClient, ContentItemV0], AbbreviatedAppItem | None]] = None,
@@ -2046,7 +2045,7 @@ class AbbreviatedAppItem(TypedDict):
20462045
config_url: str
20472046

20482047

2049-
def override_title_search(connect_server: PositConnectServer, app_id: str, app_title: str):
2048+
def override_title_search(connect_server: Union[RSConnectServer, SPCSConnectServer], app_id: str, app_title: str):
20502049
"""
20512050
Returns a list of abbreviated app data that contains apps with a title
20522051
that matches the given one and/or the specific app noted by its ID.
@@ -2127,7 +2126,7 @@ def find_unique_name(remote_server: TargetableServer, name: str):
21272126
:param name: the default name for an app.
21282127
:return: the name, potentially with a suffixed number to guarantee uniqueness.
21292128
"""
2130-
if isinstance(remote_server, PositConnectServer):
2129+
if isinstance(remote_server, (RSConnectServer, SPCSConnectServer)):
21312130
existing_names = retrieve_matching_apps(
21322131
remote_server,
21332132
filters={"search": name},

rsconnect/main.py

+9-10
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@
5050
search_content,
5151
)
5252
from .api import (
53-
PositConnectServer,
5453
RSConnectClient,
5554
RSConnectExecutor,
5655
RSConnectServer,
@@ -670,7 +669,7 @@ def details(
670669
set_verbosity(verbose)
671670

672671
ce = RSConnectExecutor(ctx, name, server, api_key, snowflake_connection_name, insecure, cacert).validate_server()
673-
if not isinstance(ce.remote_server, PositConnectServer):
672+
if not isinstance(ce.remote_server, (RSConnectServer, SPCSConnectServer)):
674673
raise RSConnectException("`rsconnect details` requires a Posit Connect server.")
675674

676675
click.echo(" Posit Connect URL: %s" % ce.remote_server.url)
@@ -2422,7 +2421,7 @@ def content_search(
24222421
cacert=cacert,
24232422
logger=None,
24242423
).validate_server()
2425-
if not isinstance(ce.remote_server, PositConnectServer):
2424+
if not isinstance(ce.remote_server, (RSConnectServer, SPCSConnectServer)):
24262425
raise RSConnectException("`rsconnect content search` requires a Posit Connect server.")
24272426
result = search_content(
24282427
ce.remote_server, published, unpublished, content_type, r_version, py_version, title_contains, order_by
@@ -2472,7 +2471,7 @@ def content_describe(
24722471
cacert=cacert,
24732472
logger=None,
24742473
).validate_server()
2475-
if not isinstance(ce.remote_server, PositConnectServer):
2474+
if not isinstance(ce.remote_server, (RSConnectServer, SPCSConnectServer)):
24762475
raise RSConnectException("`rsconnect content describe` requires a Posit Connect server.")
24772476
result = get_content(ce.remote_server, guid)
24782477
json.dump(result, sys.stdout, indent=2)
@@ -2532,7 +2531,7 @@ def content_bundle_download(
25322531
cacert=cacert,
25332532
logger=None,
25342533
).validate_server()
2535-
if not isinstance(ce.remote_server, PositConnectServer):
2534+
if not isinstance(ce.remote_server, (RSConnectServer, SPCSConnectServer)):
25362535
raise RSConnectException("`rsconnect content download-bundle` requires a Posit Connect server.")
25372536
if exists(output) and not overwrite:
25382537
raise RSConnectException("The output file already exists: %s" % output)
@@ -2589,7 +2588,7 @@ def add_content_build(
25892588
cacert=cacert,
25902589
logger=None,
25912590
).validate_server()
2592-
if not isinstance(ce.remote_server, PositConnectServer):
2591+
if not isinstance(ce.remote_server, (RSConnectServer, SPCSConnectServer)):
25932592
raise RSConnectException("`rsconnect content build add` requires a Posit Connect server.")
25942593
build_add_content(ce.remote_server, guid)
25952594
if len(guid) == 1:
@@ -2708,7 +2707,7 @@ def list_content_build(
27082707
cacert=cacert,
27092708
logger=None,
27102709
).validate_server()
2711-
if not isinstance(ce.remote_server, PositConnectServer):
2710+
if not isinstance(ce.remote_server, (RSConnectServer, SPCSConnectServer)):
27122711
raise RSConnectException("`rsconnect content build ls` requires a Posit Connect server.")
27132712
result = build_list_content(ce.remote_server, guid, status)
27142713
json.dump(result, sys.stdout, indent=2)
@@ -2753,7 +2752,7 @@ def get_build_history(
27532752
logger=None,
27542753
)
27552754
ce.validate_server()
2756-
if not isinstance(ce.remote_server, PositConnectServer):
2755+
if not isinstance(ce.remote_server, (RSConnectServer, SPCSConnectServer)):
27572756
raise RSConnectException("`rsconnect content build history` requires a Posit Connect server.")
27582757
result = build_history(ce.remote_server, guid)
27592758
json.dump(result, sys.stdout, indent=2)
@@ -2815,7 +2814,7 @@ def get_build_logs(
28152814
cacert=cacert,
28162815
logger=None,
28172816
).validate_server()
2818-
if not isinstance(ce.remote_server, PositConnectServer):
2817+
if not isinstance(ce.remote_server, (RSConnectServer, SPCSConnectServer)):
28192818
raise RSConnectException("`rsconnect content build logs` requires a Posit Connect server.")
28202819
for line in emit_build_log(ce.remote_server, guid, format, task_id):
28212820
sys.stdout.write(line)
@@ -2901,7 +2900,7 @@ def start_content_build(
29012900
cacert=cacert,
29022901
logger=None,
29032902
).validate_server()
2904-
if not isinstance(ce.remote_server, PositConnectServer):
2903+
if not isinstance(ce.remote_server, (RSConnectServer, SPCSConnectServer)):
29052904
raise RSConnectException("rsconnect content build run` requires a Posit Connect server.")
29062905
build_start(ce.remote_server, parallelism, aborted, error, running, retry, all, poll_wait, debug, force)
29072906

rsconnect/metadata.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from io import BufferedWriter
1616
from os.path import abspath, basename, dirname, exists, join
1717
from threading import Lock
18-
from typing import TYPE_CHECKING, Callable, Dict, Generic, Mapping, Optional, TypeVar
18+
from typing import TYPE_CHECKING, Callable, Dict, Generic, Mapping, Optional, TypeVar, Union
1919
from urllib.parse import urlparse
2020

2121
# Even though TypedDict is available in Python 3.8, because it's used with NotRequired,
@@ -28,7 +28,7 @@
2828

2929

3030
if TYPE_CHECKING:
31-
from .api import PositConnectServer
31+
from .api import RSConnectServer, SPCSConnectServer
3232

3333
from .exception import RSConnectException
3434
from .log import logger
@@ -602,7 +602,7 @@ class ContentBuildStore(DataStore[Dict[str, object]]):
602602

603603
def __init__(
604604
self,
605-
server: PositConnectServer,
605+
server: Union[RSConnectServer, SPCSConnectServer],
606606
base_dir: str = os.getenv("CONNECT_CONTENT_BUILD_DIR", DEFAULT_BUILD_DIR),
607607
):
608608
# This type declaration is a bit of a hack. It is needed because data model used

0 commit comments

Comments
 (0)