#Module split

1 messages · Page 1 of 1 (latest)

keen plover
#

Could be possible, but I'm not entirely sure what you mean. Can you show a simple example? What would main.py look like, for example?

eager flax
#

Hey Helder, sorry for the delay. I wasn't able to quickly reproduce in Dagger but in pure Python I was thinking something like this (uses Mixins):

main.py file:

import _mixin_class

class Print(_mixin_class.Extra_Functions):
    def __init__(self):
        self._a = "selfie"
        self._b = "so great"

    def print_self(self):
        print(f"{self._a}, {self._b}")

if __name__ == '__main__':
    prnt = Print()
    prnt.print_self()
    prnt.print_self_extra() 

_mixin_class.py file:

class Extra_Functions:
    def print_self_extra(self):
        print(f"OMG look at me: {self._a}, {self._b}!")

Then simply calling it to run (python ./main.py) returns:

selfie, so great
OMG look at me: selfie, so great!
#

So both of the prints are able to be called from the same class, and both prints have access to the class variables. But I am able to completely separate out these extra functions into their own files.

I quickly tried with Dagger but this didn't work (but I might've messed up with the decorators or something silly, just wasn't having the time lately to look into it).

#

I hope this helps clarify what i am looking to achieve.

keen plover
keen plover
#

As a module:

import dagger


class Extra:
    @dagger.function
    def extra(self) -> str:
        return f"OMG look at me: {self.a}, {self.b}!"


@dagger.object_type
class Split(Extra):
    a: str = "selfie"
    b: str = "so great"

    @dagger.function
    def myself(self) -> str:
        return f"{self.a}, {self.b}"
❯ dagger call myself
selfie, so great
❯ dagger call extra
OMG look at me: selfie, so great!
eager flax
#

yes that is pretty much it!
I ended up recreating what everything in a typical Dagger fashion:

This is all within a module called MixinDaggerTest:

In init.py

from .main import MixinDaggerTest as MixinDaggerTest

In main.py

import dagger
from dagger import dag, function, object_type

# Importing Mixin Class:
from ._print_class import PrintClass

@object_type
class MixinDaggerTest(PrintClass): # Combins the class

    def __init__(self):
        self._a = "selfie"
        self._b = "so great"

    @function
    def container_echo(self, string_arg: str) -> dagger.Container:
        """Returns a container that echoes whatever string argument is provided"""
        return dag.container().from_("alpine:latest").with_exec(["echo", string_arg])

    @function
    async def grep_dir(self, directory_arg: dagger.Directory, pattern: str) -> str:
        """Returns lines that match a pattern in the files of the provided Directory"""
        return await (
            dag.container()
            .from_("alpine:latest")
            .with_mounted_directory("/mnt", directory_arg)
            .with_workdir("/mnt")
            .with_exec(["grep", "-R", pattern, "."])
            .stdout()
        )

#

In _print_class.py

import dagger
from dagger import dag, function, object_type

@object_type
class PrintClass():
    @function
    def print_message(self, message: str) -> str:
        """function prints a message to the screen

        Very simple function that takes a string and prints it to the screen. Used for testing speed

        Args:
            message (str): message to be printed to screen

        Returns:
            str: The message given with a little extra preamble to the standard output
        """
        message = f"The string that you sent was: {message}."
        return dag.container().from_("alpine:latest").with_exec(["echo", message]).stdout()
    
    @function
    def print_self(self) -> str:
        """Prints self, see that mixins have access to their parent's 'self'"""
        message = f"{self._a}, {self._b}"
        return dag.container().from_("alpine:latest").with_exec(["echo",  message]).stdout()
#

Then running:

#

Then Running:
dagger -m ./ functions
Returns:

✔ connect 0.1s
✔ load module 0.9s

Name             Description
container-echo   Returns a container that echoes whatever string argument is provided
grep-dir         Returns lines that match a pattern in the files of the provided Directory
print-message    function prints a message to the screen
print-self       Prints self, see that mixins have access to their parent's 'self'

And Running:
dagger -m ./ call print-self
Returns:

✔ connect 0.1s
✔ load module 6.1s
✔ parsing command line arguments 0.0s

✔ mixinDaggerTest: MixinDaggerTest! 1.5s
✔ .printSelf: String! 2.2s

selfie, so great


Setup tracing at https://dagger.cloud/traces/setup. To hide set DAGGER_NO_NAG=1
keen plover
#

Do you really want the @object_type in the mixin? If it's used as a mixin I think you'd leave that out.

keen plover
#

And the constructor is unnecessary:

    def __init__(self):
        self._a = "selfie"
        self._b = "so great"

Because @object_type is a @dataclass, which generates a constructor for you.

eager flax
#

Oh I am not super familiar with @dataclass decorators, I'll look into that!

keen plover
#

You could even move that to the mixin if it's always the same, just decorate the mixin with @dataclass.

keen plover
eager flax
keen plover
#

I was saying you could move the attributes aand b, like:

@dataclass
class PrintClass:
    a: str = "selfie"
    b: str = "so great"

Because it's PrintClass that uses those. The other one will inherit them properly.

#

But I understand you're trying to make a point of the mixin "accessing the parent" 🙂

eager flax
#

Oh thanks, and I'll keep it in mind then when I need it!