github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/clients/python-wrapper/lakefs/repository.py (about)

     1  """
     2  Module containing lakeFS repository implementation
     3  """
     4  
     5  from __future__ import annotations
     6  
     7  from typing import Optional, Generator
     8  
     9  import lakefs_sdk
    10  
    11  from lakefs.models import RepositoryProperties
    12  from lakefs.tag import Tag
    13  from lakefs.branch import Branch
    14  from lakefs.client import Client, _BaseLakeFSObject
    15  from lakefs.exceptions import api_exception_handler, ConflictException, LakeFSException
    16  from lakefs.reference import Reference, generate_listing
    17  
    18  
    19  class Repository(_BaseLakeFSObject):
    20      """
    21      Class representing a Repository in lakeFS.
    22      The Repository object provides the context for the other objects that are found in it.
    23      Access to these objects should be done from this class
    24      """
    25      _id: str
    26      _properties: RepositoryProperties = None
    27  
    28      def __init__(self, repository_id: str, client: Optional[Client] = None) -> None:
    29          self._id = repository_id
    30          super().__init__(client)
    31  
    32      def create(self,
    33                 storage_namespace: str,
    34                 default_branch: str = "main",
    35                 include_samples: bool = False,
    36                 exist_ok: bool = False,
    37                 **kwargs) -> Repository:
    38          """
    39          Create a new repository in lakeFS from this object
    40  
    41          :param storage_namespace: Repository's storage namespace
    42          :param default_branch: The default branch for the repository. If None, use server default name
    43          :param include_samples: Whether to include sample data in repository creation
    44          :param exist_ok: If False will throw an exception if a repository by this name already exists. Otherwise,
    45              return the existing repository without creating a new one
    46          :param kwargs: Additional Keyword Arguments to send to the server
    47          :return: The lakeFS SDK object representing the repository
    48          :raise NotAuthorizedException: if user is not authorized to perform this operation
    49          :raise ServerException: for any other errors
    50          """
    51          repository_creation = lakefs_sdk.RepositoryCreation(name=self._id,
    52                                                              storage_namespace=storage_namespace,
    53                                                              default_branch=default_branch,
    54                                                              sample_data=include_samples)
    55  
    56          def handle_conflict(e: LakeFSException):
    57              if isinstance(e, ConflictException) and exist_ok:
    58                  with api_exception_handler():
    59                      get_repo = self._client.sdk_client.repositories_api.get_repository(self._id)
    60                      self._properties = RepositoryProperties(**get_repo.dict())
    61                      return None
    62              return e
    63  
    64          with api_exception_handler(handle_conflict):
    65              repo = self._client.sdk_client.repositories_api.create_repository(repository_creation, **kwargs)
    66              self._properties = RepositoryProperties(**repo.dict())
    67          return self
    68  
    69      def delete(self) -> None:
    70          """
    71          Delete repository from lakeFS server
    72  
    73          :raise NotFoundException: if repository by this id does not exist
    74          :raise NotAuthorizedException: if user is not authorized to perform this operation
    75          :raise ServerException: for any other errors
    76          """
    77          with api_exception_handler():
    78              self._client.sdk_client.repositories_api.delete_repository(self._id)
    79  
    80      def branch(self, branch_id: str) -> Branch:
    81          """
    82          Return a branch object using the current repository id and client
    83          :param branch_id: name of the branch
    84          """
    85          return Branch(self._id, branch_id, self._client)
    86  
    87      def commit(self, commit_id: str) -> Reference:
    88          """
    89          Return a reference object using the current repository id and client
    90          :param commit_id: id of the commit reference
    91          """
    92          return Reference(self._id, commit_id, self._client)
    93  
    94      def ref(self, ref_id: str) -> Reference:
    95          """
    96          Return a reference object using the current repository id and client
    97          :param ref_id: branch name, commit id or tag id
    98          """
    99          return Reference(self._id, ref_id, self._client)
   100  
   101      def tag(self, tag_id: str) -> Tag:
   102          """
   103          Return a tag object using the current repository id and client
   104          :param tag_id: name of the tag
   105          """
   106          return Tag(self._id, tag_id, self._client)
   107  
   108      def branches(self, max_amount: Optional[int] = None,
   109                   after: Optional[str] = None, prefix: Optional[str] = None, **kwargs) -> Generator[Branch]:
   110          """
   111          Returns a generator listing for branches on the given repository
   112  
   113          :param max_amount: Stop showing changes after this amount
   114          :param after: Return items after this value
   115          :param prefix: Return items prefixed with this value
   116          :param kwargs: Additional Keyword Arguments to send to the server
   117          :raise NotFoundException: if repository does not exist
   118          :raise NotAuthorizedException: if user is not authorized to perform this operation
   119          :raise ServerException: for any other errors
   120          """
   121  
   122          for res in generate_listing(self._client.sdk_client.branches_api.list_branches, self._id,
   123                                      max_amount=max_amount, after=after, prefix=prefix, **kwargs):
   124              yield Branch(self._id, res.id, client=self._client)
   125  
   126      def tags(self, max_amount: Optional[int] = None,
   127               after: Optional[str] = None, prefix: Optional[str] = None, **kwargs) -> Generator[Tag]:
   128          """
   129          Returns a generator listing for tags on the given repository
   130  
   131          :param max_amount: Stop showing changes after this amount
   132          :param after: Return items after this value
   133          :param prefix: Return items prefixed with this value
   134          :param kwargs: Additional Keyword Arguments to send to the server
   135          :raise NotFoundException: if repository does not exist
   136          :raise NotAuthorizedException: if user is not authorized to perform this operation
   137          :raise ServerException: for any other errors
   138          """
   139          for res in generate_listing(self._client.sdk_client.tags_api.list_tags, self._id,
   140                                      max_amount=max_amount, after=after, prefix=prefix, **kwargs):
   141              yield Tag(self._id, res.id, client=self._client)
   142  
   143      @property
   144      def metadata(self) -> dict[str, str]:
   145          """
   146          Returns the repository metadata
   147          """
   148          with api_exception_handler():
   149              return self._client.sdk_client.repositories_api.get_repository_metadata(repository=self._id)
   150  
   151      @property
   152      def properties(self) -> RepositoryProperties:
   153          """
   154          Return the repository's properties object
   155          """
   156          if self._properties is None:
   157              with api_exception_handler():
   158                  repo = self._client.sdk_client.repositories_api.get_repository(self._id)
   159                  self._properties = RepositoryProperties(**repo.dict())
   160                  return self._properties
   161  
   162          return self._properties
   163  
   164      @property
   165      def id(self) -> str:
   166          """
   167          Returns the repository's id
   168          """
   169          return self._id
   170  
   171      def __repr__(self) -> str:
   172          return f'Repository(id="{self.id}")'
   173  
   174      def __str__(self):
   175          return str(self.properties)
   176  
   177  
   178  def repositories(client: Client = None,
   179                   prefix: Optional[str] = None,
   180                   after: Optional[str] = None,
   181                   **kwargs) -> Generator[Repository]:
   182      """
   183      Creates a repositories object generator listing lakeFS repositories
   184  
   185      :param client: The lakeFS client to use, if None, tries to use the default client
   186      :param prefix: Return items prefixed with this value
   187      :param after: Return items after this value
   188      :return: A generator listing lakeFS repositories
   189      """
   190      if client is None:  # Try to get default client
   191          client = Client()
   192  
   193      for res in generate_listing(client.sdk_client.repositories_api.list_repositories,
   194                                  prefix=prefix,
   195                                  after=after,
   196                                  **kwargs):
   197          yield Repository(res.id, client)