Beispiel #1
0
    def create(
        self,
        name: str = "Anonymous Python Stream",
        description: str = "No description provided",
        is_public: bool = True,
    ) -> str:
        """Create a new stream

        Arguments:
            name {str} -- the name of the string
            description {str} -- a short description of the stream
            is_public {bool} -- whether or not the stream can be viewed by anyone with the id

        Returns:
            id {str} -- the id of the newly created stream
        """
        metrics.track(metrics.STREAM_CREATE)
        query = gql("""
            mutation StreamCreate($stream: StreamCreateInput!) {
              streamCreate(stream: $stream)
            }
        """)

        params = {
            "stream": {
                "name": name,
                "description": description,
                "isPublic": is_public
            }
        }

        return self.make_request(query=query,
                                 params=params,
                                 return_type="streamCreate",
                                 parse_response=False)
Beispiel #2
0
def send(
    base: Base,
    transports: List[AbstractTransport] = [],
    use_default_cache: bool = True,
):
    """Sends an object via the provided transports. Defaults to the local cache.

    Arguments:
        obj {Base} -- the object you want to send
        transports {list} -- where you want to send them
        use_default_cache {bool} -- toggle for the default cache. If set to false, it will only send to the provided transports

    Returns:
        str -- the object id of the sent object
    """
    metrics.track(metrics.SEND)
    if not transports and not use_default_cache:
        raise SpeckleException(
            message="You need to provide at least one transport: cannot send with an empty transport list and no default cache"
        )
    if use_default_cache:
        transports.insert(0, SQLiteTransport())

    serializer = BaseObjectSerializer(write_transports=transports)

    for t in transports:
        t.begin_write()
    hash, _ = serializer.write_json(base=base)

    for t in transports:
        t.end_write()

    return hash
Beispiel #3
0
def get_local_accounts(base_path: str = None) -> List[Account]:
    """Gets all the accounts present in this environment

    Arguments:
        base_path {str} -- custom base path if you are not using the system default

    Returns:
        List[Account] -- list of all local accounts or an empty list if no accounts were found
    """
    metrics.track(metrics.ACCOUNT_LIST)
    account_storage = SQLiteTransport(scope="Accounts", base_path=base_path)
    json_path = os.path.join(account_storage._base_path, "Accounts")
    os.makedirs(json_path, exist_ok=True)
    json_acct_files = [
        file for file in os.listdir(json_path) if file.endswith(".json")
    ]

    accounts = []
    res = account_storage.get_all_objects()
    if res:
        accounts.extend(Account.parse_raw(r[1]) for r in res)
    if json_acct_files:
        try:
            accounts.extend(
                Account.parse_file(os.path.join(json_path, json_file))
                for json_file in json_acct_files)
        except Exception as ex:
            raise SpeckleException(
                "Invalid json accounts could not be read. Please fix or remove them.",
                ex,
            )

    return accounts
Beispiel #4
0
    def create(self,
               stream_id: str,
               name: str,
               description: str = "No description provided") -> str:
        """Create a new branch on this stream

        Arguments:
            name {str} -- the name of the new branch
            description {str} -- a short description of the branch

        Returns:
            id {str} -- the newly created branch's id
        """
        metrics.track(metrics.BRANCH, self.account, {"name": "create"})
        query = gql("""
            mutation BranchCreate($branch: BranchCreateInput!) {
              branchCreate(branch: $branch)
            }
          """)
        params = {
            "branch": {
                "streamId": stream_id,
                "name": name,
                "description": description,
            }
        }

        return self.make_request(query=query,
                                 params=params,
                                 return_type="branchCreate",
                                 parse_response=False)
Beispiel #5
0
    def revoke_permission(self, stream_id: str, user_id: str):
        """Revoke permissions from a user on a given stream

        Arguments:
            stream_id {str} -- the id of the stream to revoke permissions from
            user_id {str} -- the id of the user to revoke permissions from

        Returns:
            bool -- True if the operation was successful
        """
        metrics.track(metrics.PERMISSION, self.account, {"name": "revoke"})
        query = gql("""
            mutation StreamRevokePermission($permission_params: StreamRevokePermissionInput !) {
                streamRevokePermission(permissionParams: $permission_params)
            }
            """)

        params = {
            "permission_params": {
                "streamId": stream_id,
                "userId": user_id
            }
        }

        return self.make_request(
            query=query,
            params=params,
            return_type="streamRevokePermission",
            parse_response=False,
        )
Beispiel #6
0
    def get(self, id: str = None) -> User:
        """Gets the profile of a user. If no id argument is provided, will return the current authenticated user's profile (as extracted from the authorization header).

        Arguments:
            id {str} -- the user id

        Returns:
            User -- the retrieved user
        """
        metrics.track(metrics.USER, self.account, {"name": "get"})
        query = gql("""
            query User($id: String) {
                user(id: $id) {
                    id
                    email
                    name
                    bio
                    company
                    avatar
                    verified
                    profiles
                    role
                }
            }
          """)

        params = {"id": id}

        return self.make_request(query=query,
                                 params=params,
                                 return_type="user")
Beispiel #7
0
    def grant_permission(self, stream_id: str, user_id: str, role: str):
        """Grant permissions to a user on a given stream

        Arguments:
            stream_id {str} -- the id of the stream to grant permissions to
            user_id {str} -- the id of the user to grant permissions for
            role {str} -- the role to grant the user

        Returns:
            bool -- True if the operation was successful
        """
        metrics.track(metrics.PERMISSION, self.account, {
            "name": "add",
            "role": role
        })
        query = gql("""
            mutation StreamGrantPermission($permission_params: StreamGrantPermissionInput !) {
                streamGrantPermission(permissionParams: $permission_params)
            }
            """)

        params = {
            "permission_params": {
                "streamId": stream_id,
                "userId": user_id,
                "role": role,
            }
        }

        return self.make_request(
            query=query,
            params=params,
            return_type="streamGrantPermission",
            parse_response=False,
        )
Beispiel #8
0
    def search(self, search_query: str, limit: int = 25) -> List[User]:
        """Searches for user by name or email. The search query must be at least 3 characters long

        Arguments:
            search_query {str} -- a string to search for
            limit {int} -- the maximum number of results to return
        Returns:
            List[User] -- a list of User objects that match the search query
        """
        if len(search_query) < 3:
            return SpeckleException(
                message="User search query must be at least 3 characters")

        metrics.track(metrics.USER, self.account, {"name": "search"})
        query = gql("""
            query UserSearch($search_query: String!, $limit: Int!) {
                userSearch(query: $search_query, limit: $limit) {
                    items {
                        id
                        name
                        bio
                        company
                        avatar
                        verified
                    }
                }
            }
          """)
        params = {"search_query": search_query, "limit": limit}

        return self.make_request(query=query,
                                 params=params,
                                 return_type=["userSearch", "items"])
Beispiel #9
0
    def received(
        self,
        stream_id: str,
        commit_id: str,
        source_application: str = "python",
        message: Optional[str] = None,
    ) -> bool:
        """
        Mark a commit object a received by the source application.
        """
        metrics.track(metrics.COMMIT, self.account, {"name": "received"})
        query = gql("""
            mutation CommitReceive($receivedInput:CommitReceivedInput!){
                commitReceive(input:$receivedInput)
            }
            """)
        params = {
            "receivedInput": {
                "sourceApplication": source_application,
                "streamId": stream_id,
                "commitId": commit_id,
                "message": "message",
            }
        }

        try:
            return self.make_request(
                query=query,
                params=params,
                return_type="commitReceive",
                parse_response=False,
            )
        except Exception as ex:
            print(ex.with_traceback)
            return False
Beispiel #10
0
    def update(self, stream_id: str, commit_id: str, message: str) -> bool:
        """
        Update a commit

        Arguments:
            stream_id {str} -- the id of the stream that contains the commit you'd like to update
            commit_id {str} -- the id of the commit you'd like to update
            message {str} -- the updated commit message

        Returns:
            bool -- True if the operation succeeded
        """
        metrics.track(metrics.COMMIT, self.account, {"name": "update"})
        query = gql("""
            mutation CommitUpdate($commit: CommitUpdateInput!){ commitUpdate(commit: $commit)}
            """)
        params = {
            "commit": {
                "streamId": stream_id,
                "id": commit_id,
                "message": message
            }
        }

        return self.make_request(query=query,
                                 params=params,
                                 return_type="commitUpdate",
                                 parse_response=False)
Beispiel #11
0
    def list(self,
             stream_id: str,
             branches_limit: int = 10,
             commits_limit: int = 10):
        """Get a list of branches from a given stream

        Arguments:
            stream_id {str} -- the id of the stream to get the branches from
            branches_limit {int} -- maximum number of branches to get
            commits_limit {int} -- maximum number of commits to get

        Returns:
            List[Branch] -- the branches on the stream
        """
        metrics.track(metrics.BRANCH, self.account, {"name": "get"})
        query = gql("""
            query BranchesGet($stream_id: String!, $branches_limit: Int!, $commits_limit: Int!) {
                stream(id: $stream_id) {
                    branches(limit: $branches_limit) {
                        items {
                            id
                            name
                            description
                            commits(limit: $commits_limit) {
                                totalCount
                                items{
                                    id
                                    message
                                    referencedObject
                                    sourceApplication
                                    parents
                                    authorId
                                    authorName
                                    branchName
                                    createdAt
                                }
                            }
                        }
                    }
                }
            }
            """)

        params = {
            "stream_id": stream_id,
            "branches_limit": branches_limit,
            "commits_limit": commits_limit,
        }

        return self.make_request(query=query,
                                 params=params,
                                 return_type=["stream", "branches", "items"])
Beispiel #12
0
    def get(self, stream_id: str, name: str, commits_limit: int = 10):
        """Get a branch by name from a stream

        Arguments:
            stream_id {str} -- the id of the stream to get the branch from
            name {str} -- the name of the branch to get
            commits_limit {int} -- maximum number of commits to get

        Returns:
            Branch -- the fetched branch with its latest commits
        """
        metrics.track(metrics.BRANCH, self.account, {"name": "get"})
        query = gql("""
            query BranchGet($stream_id: String!, $name: String!, $commits_limit: Int!) {
                stream(id: $stream_id) {
                        branch(name: $name) {
                          id,
                          name,
                          description,
                          commits (limit: $commits_limit) {
                            totalCount,
                            cursor,
                            items {
                              id,
                              referencedObject,
                              sourceApplication,
                              totalChildrenCount,
                              message,
                              authorName,
                              authorId,
                              branchName,
                              parents,
                              createdAt
                            }
                        }
                    }                      
                }
            }
            """)

        params = {
            "stream_id": stream_id,
            "name": name,
            "commits_limit": commits_limit
        }

        return self.make_request(query=query,
                                 params=params,
                                 return_type=["stream", "branch"])
Beispiel #13
0
    def list(self, stream_limit: int = 10) -> List[Stream]:
        """Get a list of the user's streams

        Arguments:
            stream_limit {int} -- The maximum number of streams to return

        Returns:
            List[Stream] -- A list of Stream objects
        """
        metrics.track(metrics.STREAM_LIST)
        query = gql("""
            query User($stream_limit: Int!) {
              user {
                id
                email
                name
                bio
                company
                avatar
                verified
                profiles
                role
                streams(limit: $stream_limit) {
                  totalCount
                  cursor
                  items {
                    id
                    name
                    description
                    isPublic
                    createdAt
                    updatedAt
                    collaborators {
                      id
                      name
                      role
                    }
                  }
                }
              }
            }
          """)

        params = {"stream_limit": stream_limit}

        return self.make_request(query=query,
                                 params=params,
                                 return_type=["user", "streams", "items"])
Beispiel #14
0
def serialize(base: Base, write_transports: List[AbstractTransport] = []) -> str:
    """
    Serialize a base object. If no write transports are provided, the object will be serialized
    without detaching or chunking any of the attributes.

    Arguments:
        base {Base} -- the object to serialize
        write_transports {List[AbstractTransport]} -- optional: the transports to write to

    Returns:
        str -- the serialized object
    """
    metrics.track(metrics.SERIALIZE)
    serializer = BaseObjectSerializer(write_transports=write_transports)

    return serializer.write_json(base)[1]
Beispiel #15
0
def get_default_account(base_path: str = None) -> Account:
    """Gets this environment's default account if any. If there is no default, the first found will be returned and set as default.
    Arguments:
        base_path {str} -- custom base path if you are not using the system default

    Returns:
        Account -- the default account or None if no local accounts were found
    """
    metrics.track(metrics.ACCOUNT_DEFAULT)
    accounts = get_local_accounts(base_path=base_path)
    if not accounts:
        return None

    default = next((acc for acc in accounts if acc.isDefault), None)
    if not default:
        default = accounts[0]
        default.isDefault = True

    return default
Beispiel #16
0
    def create(
        self,
        stream_id: str,
        object_id: str,
        branch_name: str = "main",
        message: str = "",
        source_application: str = "python",
        parents: List[str] = None,
    ) -> str:
        """
        Creates a commit on a branch

        Arguments:
            stream_id {str} -- the stream you want to commit to
            object_id {str} -- the hash of your commit object
            branch_name {str} -- the name of the branch to commit to (defaults to "main")
            message {str} -- optional: a message to give more information about the commit
            source_application{str} -- optional: the application from which the commit was created (defaults to "python")
            parents {List[str]} -- optional: the id of the parent commits

        Returns:
            str -- the id of the created commit
        """
        metrics.track(metrics.COMMIT, self.account, {"name": "create"})
        query = gql("""
            mutation CommitCreate ($commit: CommitCreateInput!){ commitCreate(commit: $commit)}
            """)
        params = {
            "commit": {
                "streamId": stream_id,
                "branchName": branch_name,
                "objectId": object_id,
                "message": message,
                "sourceApplication": source_application,
            }
        }
        if parents:
            params["commit"]["parents"] = parents

        return self.make_request(query=query,
                                 params=params,
                                 return_type="commitCreate",
                                 parse_response=False)
Beispiel #17
0
def deserialize(obj_string: str, read_transport: AbstractTransport = None) -> Base:
    """
    Deserialize a string object into a Base object. If the object contains referenced child objects that are not stored in the local db, a read transport needs to be provided in order to recompose the base with the children objects.

    Arguments:
        obj_string {str} -- the string object to deserialize
        read_transport {AbstractTransport} -- the transport to fetch children objects from
                                              (defaults to SQLiteTransport)

    Returns:
        Base -- the deserialized object
    """
    metrics.track(metrics.DESERIALIZE)
    if not read_transport:
        read_transport = SQLiteTransport()

    serializer = BaseObjectSerializer(read_transport=read_transport)

    return serializer.read_json(obj_string=obj_string)
Beispiel #18
0
    def update(self,
               name: str = None,
               company: str = None,
               bio: str = None,
               avatar: str = None):
        """Updates your user profile. All arguments are optional.

        Arguments:
            name {str} -- your name
            company {str} -- the company you may or may not work for
            bio {str} -- tell us about yourself
            avatar {str} -- a nice photo of yourself

        Returns:
            bool -- True if your profile was updated successfully
        """
        metrics.track(metrics.USER, self.account, {"name": "update"})
        query = gql("""
            mutation UserUpdate($user: UserUpdateInput!) {
                userUpdate(user: $user)
            }
            """)
        params = {
            "name": name,
            "company": company,
            "bio": bio,
            "avatar": avatar
        }

        params = {"user": {k: v for k, v in params.items() if v is not None}}

        if not params["user"]:
            return SpeckleException(
                message=
                "You must provide at least one field to update your user profile"
            )

        return self.make_request(query=query,
                                 params=params,
                                 return_type="userUpdate",
                                 parse_response=False)
Beispiel #19
0
    def list(self, stream_id: str, limit: int = 10) -> List[Commit]:
        """
        Get a list of commits on a given stream

        Arguments:
            stream_id {str} -- the stream where the commits are
            limit {int} -- the maximum number of commits to fetch (default = 10)

        Returns:
            List[Commit] -- a list of the most recent commit objects
        """
        metrics.track(metrics.COMMIT, self.account, {"name": "get"})
        query = gql("""
            query Commits($stream_id: String!, $limit: Int!) {
                stream(id: $stream_id) {
                    commits(limit: $limit) {
                        items {
                            id
                            message
                            referencedObject
                            authorName
                            authorId
                            authorName
                            authorAvatar
                            branchName
                            createdAt
                            sourceApplication
                            totalChildrenCount
                            parents
                        }
                    }
                }
            }
            """)
        params = {"stream_id": stream_id, "limit": limit}

        return self.make_request(query=query,
                                 params=params,
                                 return_type=["stream", "commits", "items"])
Beispiel #20
0
    def delete(self, id: str) -> bool:
        """Delete a stream given its id

        Arguments:
            id {str} -- the id of the stream to delete

        Returns:
            bool -- whether the deletion was successful
        """
        metrics.track(metrics.STREAM_DELETE)
        query = gql("""
            mutation StreamDelete($id: String!) {
              streamDelete(id: $id)
            }
        """)

        params = {"id": id}

        return self.make_request(query=query,
                                 params=params,
                                 return_type="streamDelete",
                                 parse_response=False)
Beispiel #21
0
    def update(self,
               stream_id: str,
               branch_id: str,
               name: str = None,
               description: str = None):
        """Update a branch

        Arguments:
            stream_id {str} -- the id of the stream containing the branch to update
            branch_id {str} -- the id of the branch to update
            name {str} -- optional: the updated branch name
            description {str} -- optional: the updated branch description

        Returns:
            bool -- True if update is successfull
        """
        metrics.track(metrics.BRANCH, self.account, {"name": "update"})
        query = gql("""
            mutation  BranchUpdate($branch: BranchUpdateInput!) {
                branchUpdate(branch: $branch)
                }
            """)
        params = {
            "branch": {
                "streamId": stream_id,
                "id": branch_id,
            }
        }

        if name:
            params["branch"]["name"] = name
        if description:
            params["branch"]["description"] = description

        return self.make_request(query=query,
                                 params=params,
                                 return_type="branchUpdate",
                                 parse_response=False)
Beispiel #22
0
    def delete(self, stream_id: str, branch_id: str):
        """Delete a branch

        Arguments:
            stream_id {str} -- the id of the stream containing the branch to delete
            branch_id {str} -- the branch to delete

        Returns:
            bool -- True if deletion is successful
        """
        metrics.track(metrics.BRANCH, self.account, {"name": "delete"})
        query = gql("""
            mutation BranchDelete($branch: BranchDeleteInput!) {
                branchDelete(branch: $branch)
            }
            """)

        params = {"branch": {"streamId": stream_id, "id": branch_id}}

        return self.make_request(query=query,
                                 params=params,
                                 return_type="branchDelete",
                                 parse_response=False)
Beispiel #23
0
def receive(
    obj_id: str,
    remote_transport: AbstractTransport = None,
    local_transport: AbstractTransport = None,
) -> Base:
    """Receives an object from a transport.

    Arguments:
        obj_id {str} -- the id of the object to receive
        remote_transport {Transport} -- the transport to receive from
        local_transport {Transport} -- the local cache to check for existing objects
                                       (defaults to `SQLiteTransport`)

    Returns:
        Base -- the base object
    """
    metrics.track(metrics.RECEIVE)
    if not local_transport:
        local_transport = SQLiteTransport()

    serializer = BaseObjectSerializer(read_transport=local_transport)

    # try local transport first. if the parent is there, we assume all the children are there and continue wth deserialisation using the local transport
    obj_string = local_transport.get_object(obj_id)
    if obj_string:
        return serializer.read_json(obj_string=obj_string)

    if not remote_transport:
        raise SpeckleException(
            message="Could not find the specified object using the local transport, and you didn't provide a fallback remote from which to pull it."
        )

    obj_string = remote_transport.copy_object_and_children(
        id=obj_id, target_transport=local_transport
    )

    return serializer.read_json(obj_string=obj_string)
Beispiel #24
0
    def __init__(self, url: str) -> None:
        metrics.track("streamwrapper")
        self.stream_url = url
        parsed = urlparse(url)
        self.host = parsed.netloc
        self.use_ssl = parsed.scheme == "https"
        segments = parsed.path.strip("/").split("/")

        if not segments or len(segments) > 4 or len(segments) < 2:
            raise SpeckleException(
                f"Cannot parse {url} into a stream wrapper class - invalid URL provided."
            )

        while segments:
            segment = segments.pop(0)
            if segments and segment.lower() == "streams":
                self.stream_id = segments.pop(0)
            elif segments and segment.lower() == "commits":
                self.commit_id = segments.pop(0)
            elif segments and segment.lower() == "branches":
                self.branch_name = unquote(segments.pop(0))
            elif segments and segment.lower() == "objects":
                self.object_id = segments.pop(0)
            elif segment.lower() == "globals":
                self.branch_name = "globals"
                if segments:
                    self.commit_id = segments.pop(0)
            else:
                raise SpeckleException(
                    f"Cannot parse {url} into a stream wrapper class - invalid URL provided."
                )

        if not self.stream_id:
            raise SpeckleException(
                f"Cannot parse {url} into a stream wrapper class - no stream id found."
            )
Beispiel #25
0
    def update(self,
               id: str,
               name: str = None,
               description: str = None,
               is_public: bool = None) -> bool:
        """Update an existing stream

        Arguments:
            id {str} -- the id of the stream to be updated
            name {str} -- the name of the string
            description {str} -- a short description of the stream
            is_public {bool} -- whether or not the stream can be viewed by anyone with the id

        Returns:
            bool -- whether the stream update was successful
        """
        metrics.track(metrics.STREAM_UPDATE)
        query = gql("""
            mutation StreamUpdate($stream: StreamUpdateInput!) {
              streamUpdate(stream: $stream)
            }
        """)

        params = {
            "id": id,
            "name": name,
            "description": description,
            "isPublic": is_public,
        }
        # remove None values so graphql doesn't cry
        params = {"stream": {k: v for k, v in params.items() if v is not None}}

        return self.make_request(query=query,
                                 params=params,
                                 return_type="streamUpdate",
                                 parse_response=False)
Beispiel #26
0
    def get(self,
            id: str,
            branch_limit: int = 10,
            commit_limit: int = 10) -> Stream:
        """Get the specified stream from the server

        Arguments:
            id {str} -- the stream id
            branch_limit {int} -- the maximum number of branches to return
            commit_limit {int} -- the maximum number of commits to return

        Returns:
            Stream -- the retrieved stream
        """
        metrics.track(metrics.STREAM_GET)
        query = gql("""
            query Stream($id: String!, $branch_limit: Int!, $commit_limit: Int!) {
              stream(id: $id) {
                id
                name
                description
                isPublic
                createdAt
                updatedAt
                collaborators {
                  id
                  name
                  role
                  avatar
                }
                branches(limit: $branch_limit) {
                  totalCount
                  cursor
                  items {
                    id
                    name
                    description
                    commits(limit: $commit_limit) {
                      totalCount
                      cursor
                      items {
                        id
                        referencedObject
                        message
                        authorName
                        authorId
                        createdAt
                      }
                    }
                  }
                }
              }
            }
          """)

        params = {
            "id": id,
            "branch_limit": branch_limit,
            "commit_limit": commit_limit
        }

        return self.make_request(query=query,
                                 params=params,
                                 return_type="stream")
Beispiel #27
0
    def search(
        self,
        search_query: str,
        limit: int = 25,
        branch_limit: int = 10,
        commit_limit: int = 10,
    ):
        """Search for streams by name, description, or id

        Arguments:
            search_query {str} -- a string to search for
            limit {int} -- the maximum number of results to return
            branch_limit {int} -- the maximum number of branches to return
            commit_limit {int} -- the maximum number of commits to return

        Returns:
            List[Stream] -- a list of Streams that match the search query
        """
        metrics.track(metrics.STREAM_SEARCH)
        query = gql("""
            query StreamSearch($search_query: String!,$limit: Int!, $branch_limit:Int!, $commit_limit:Int!) {
              streams(query: $search_query, limit: $limit) {
                items {
                  id
                  name
                  description
                  isPublic
                  createdAt
                  updatedAt
                  collaborators {
                    id
                    name
                    role
                    avatar
                  }
                  branches(limit: $branch_limit) {
                    totalCount
                    cursor
                    items {
                      id
                      name
                      description
                      commits(limit: $commit_limit) {
                        totalCount
                        cursor
                        items {
                          id
                          referencedObject
                          message
                          authorName
                          authorId
                          createdAt
                        }
                      }
                    }
                  }
                }
              }
            }
          """)

        params = {
            "search_query": search_query,
            "limit": limit,
            "branch_limit": branch_limit,
            "commit_limit": commit_limit,
        }

        return self.make_request(query=query,
                                 params=params,
                                 return_type=["streams", "items"])