Skip to content

Commit

Permalink
Moving board_deparse to boards.py (#247)
Browse files Browse the repository at this point in the history
* Moving board_deparse to boards.py

* Pass doctest
  • Loading branch information
nathanjmcdougall authored Jul 19, 2024
1 parent 0aefeea commit 2c53d3c
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 66 deletions.
2 changes: 1 addition & 1 deletion pins/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
# Imports ----
from .cache import cache_prune, cache_info
from .constructors import (
board_deparse,
board_folder,
board_temp,
board_local,
Expand All @@ -25,3 +24,4 @@
board_gcs,
board,
)
from .boards import board_deparse
63 changes: 60 additions & 3 deletions pins/boards.py
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,66 @@ def _touch_cache(self, path):
return touch_access_time(path_to_hashed)


def board_deparse(board: BaseBoard):
"""Return a representation of how a board could be reconstructed.
Note that this function does not try to represent the exact arguments used
to construct a board, but key pieces (like the path to the board). You may
need to specify environment variables with API keys to complete the connection.
Parameters
----------
board:
A pins board to be represented.
Examples
--------
The example below deparses a board connected to Posit Connect.
>>> from pins.constructors import board_connect
>>> board_deparse(board_connect(server_url="http://example.com", api_key="xxx"))
"board_connect(server_url='http://example.com')"
Note that the deparsing a Posit Connect board does not keep the api_key,
which is sensitive information. In this case, you can set the CONNECT_API_KEY
environment variable to connect.
Below is an example of representing a board connected to a local folder.
>>> from pins.constructors import board_folder
>>> board_deparse(board_folder("a/b/c"))
"board_folder('a/b/c')"
>>> board_deparse(board_folder(path="a/b/c", allow_pickle_read=True))
"board_folder('a/b/c', allow_pickle_read=True)"
"""
if board.allow_pickle_read is not None:
allow_pickle = f", allow_pickle_read={repr(board.allow_pickle_read)}"
else:
allow_pickle = ""

prot = board.fs.protocol

if prot == "rsc":
url = board.fs.api.server_url
return f"board_connect(server_url={repr(url)}{allow_pickle})"
elif prot in ["file", ("file", "local")]:
return f"board_folder({repr(board.board)}{allow_pickle})"
elif set(prot) == {"s3", "s3a"}:
return f"board_s3({repr(board.board)}{allow_pickle})"
elif prot == "abfs":
return f"board_azure({repr(board.board)}{allow_pickle})"
elif set(prot) == {"gcs", "gs"} or prot == "gs":
return f"board_gcs({repr(board.board)}{allow_pickle})"
elif prot == "http":
return f"board_url({repr(board.board)}, {board.pin_paths}{allow_pickle})"
else:
raise NotImplementedError(
f"board deparsing currently not supported for protocol: {prot}"
)


class BoardManual(BaseBoard):
"""Simple board that accepts a dictionary of form `pin_name: path`.
Expand Down Expand Up @@ -1089,9 +1149,6 @@ def user_name(self):
return self._user_name

def prepare_pin_version(self, pin_dir_path, x, name: "str | None", *args, **kwargs):
# TODO: should move board_deparse into utils, to avoid circular import
from .constructors import board_deparse

# RSC pin names can have form <user_name>/<name>, but this will try to
# create the object in a directory named <user_name>. So we grab just
# the <name> part.
Expand Down
66 changes: 4 additions & 62 deletions pins/constructors.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,76 +2,18 @@
import os
import tempfile

from .boards import BaseBoard, BoardRsConnect, BoardManual
from .boards import BaseBoard, BoardRsConnect, BoardManual, board_deparse
from .cache import PinsCache, PinsRscCacheMapper, PinsAccessTimeCache, prefix_cache
from .config import get_data_dir, get_cache_dir

# Kept here for backward-compatibility reasons.
board_deparse # Note that this is not a constructor, but a function to represent them.


class DEFAULT:
pass


# Representing constructors ===================================================

# Note that this is not a constructor, but a function to represent them.
def board_deparse(board: BaseBoard):
"""Return a representation of how a board could be reconstructed.
Note that this function does not try to represent the exact arguments used
to construct a board, but key pieces (like the path to the board). You may
need to specify environment variables with API keys to complete the connection.
Parameters
----------
board:
A pins board to be represented.
Examples
--------
The example below deparses a board connected to Posit Connect.
>>> board_deparse(board_connect(server_url="http://example.com", api_key="xxx"))
"board_connect(server_url='http://example.com')"
Note that the deparsing a Posit Connect board does not keep the api_key,
which is sensitive information. In this case, you can set the CONNECT_API_KEY
environment variable to connect.
Below is an example of representing a board connected to a local folder.
>>> board_deparse(board_folder("a/b/c"))
"board_folder('a/b/c')"
>>> board_deparse(board_folder(path="a/b/c", allow_pickle_read=True))
"board_folder('a/b/c', allow_pickle_read=True)"
"""
if board.allow_pickle_read is not None:
allow_pickle = f", allow_pickle_read={repr(board.allow_pickle_read)}"
else:
allow_pickle = ""

prot = board.fs.protocol

if prot == "rsc":
url = board.fs.api.server_url
return f"board_connect(server_url={repr(url)}{allow_pickle})"
elif prot in ["file", ("file", "local")]:
return f"board_folder({repr(board.board)}{allow_pickle})"
elif set(prot) == {"s3", "s3a"}:
return f"board_s3({repr(board.board)}{allow_pickle})"
elif prot == "abfs":
return f"board_azure({repr(board.board)}{allow_pickle})"
elif set(prot) == {"gcs", "gs"} or prot == "gs":
return f"board_gcs({repr(board.board)}{allow_pickle})"
elif prot == "http":
return f"board_url({repr(board.board)}, {board.pin_paths}{allow_pickle})"
else:
raise NotImplementedError(
f"board deparsing currently not supported for protocol: {prot}"
)


# Board constructors ==========================================================
# note that libraries not used by board classes above are imported within these
# functions. may be worth moving these funcs into their own module.
Expand Down

0 comments on commit 2c53d3c

Please sign in to comment.