Changing struct parameters and Ownership

As part of my Mojo learning journy I wrote the below python code:

# mypython.py
from openai import OpenAI

client = OpenAI(base_url="http://localhost:8000/v1", api_key="EMPTY")

def get_embedding(text):
    response = client.embeddings.create(
        model="sentence-transformers/all-mpnet-base-v2",
        input=text,
    )
    return response.data[0].embedding

And the below mojo code:

# embedder.mojo
from python import Python, PythonObject

struct Embedder:
    var embedding_func: PythonObject  # Reference to the Python embedding function
    var length: Int                  # Length of the last generated embedding

    fn __init__(out self) raises:
        Python.add_to_path(".")
        var mypython = Python.import_module("mypython")
        # Validate that get_embedding exists
        try:
            self.embedding_func = mypython.get_embedding
        except:
            raise "mypython module does not have a get_embedding function"
        self.length = 0

    fn embed(self, text: String) raises -> (List[Float64], Int):
        # Generate the embedding using the Python function
        var py_embedding: PythonObject
        var mojo_list = List[Float64]()
        try:
            py_embedding = self.embedding_func(text)
            for val in py_embedding:
                mojo_list.append(Float64(val))
        except:
            raise "Failed to generate embedding from mypython.get_embedding"

        # Compute the length
        var length: Int
        try:
            length = len(py_embedding)
            # self.length = length # error: expression must be mutable in assignment
        except:
            raise "Failed to compute embedding length"
        return mojo_list, length

fn format_int(i: Int, fmt: String) raises -> String:
    return String(i).format(fmt)

fn main() raises:
    # Initialize the Embedder
    var embedder = Embedder()

    # Generate an embedding and its length
    embedding, length = embedder.embed("Run an embedding model with MAX Serve!")

    # Print the embedding length from the struct
    print("Mojo embedding length:", length)

    # Print the first 5 elements of the embedding (if available)
    print("First 5 elements:")
    var max_elements = min(5, length)
    for i in range(max_elements):
        var index_str = format_int(i, "{:03d}")
        var value = embedding.__getitem__(i)
        print(index_str, ":", Float64(value))

I wanted to to review the block code of fn embed()' so that I can modify the self.length inside it, with my current code I got the error: expression must be mutable in assignment

You need to use mut self. For more info, check out this page of the Mojo docs.

1 Like

Thanks a lot.