# Tool Methods in Python Class Missing self Argument When Used in Custom Agents

**URL:** <https://community.crewai.com/t/tool-methods-in-python-class-missing-self-argument-when-used-in-custom-agents/2549>\
**Category:** Crews\
**Tags:** tools\_issues, agent, crewai\
**Created:** [January 7, 2025, 9:03am UTC](https://community.crewai.com/t/tool-methods-in-python-class-missing-self-argument-when-used-in-custom-agents/2549 "2025-01-07T09:03:52Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Alan\_Quartermaine](https://sea1.discourse-cdn.com/flex025/user_avatar/community.crewai.com/alan_quartermaine/32/1857_2.png) [@Alan\_Quartermaine](https://community.crewai.com/u/Alan_Quartermaine)\
**Post date:** [January 7, 2025, 9:03am UTC](https://community.crewai.com/t/tool-methods-in-python-class-missing-self-argument-when-used-in-custom-agents/2549/1 "2025-01-07T09:03:53Z")

</div>

I am working on a custom implementation of AI agents using Python, where the agents rely on langchain tools (methods) for interacting with a PostgreSQL database. The **ToolWithConnection** class initializes a database connection and defines tools like **list\_tables** , **tables\_schema** , **check\_sql** , and **execute\_sql\_to\_df**. These tools are later used by **CrewAI** agents to perform various tasks.

Here’s the relevant part of the code:

- _ **Connection Method:** _

```auto
def connection(x):
    postgres_schm = x["database_schm"]
    postgres_host = x["database_host"]
    postgres_port = x["database_port"]
    postgres_user = x["database_user"]
    postgres_pass = x["database_pass"]
    postgres_dryr = x["database_dryr"]

    if postgres_dryr == "true":
        postgres_pass_dec = postgres_pass        
    else:
        postgres_pass_dec = decrypt_string(postgres_pass)
        
    CONNECTION_STRING = (
        f"postgresql+psycopg2://{postgres_user}:{postgres_pass_dec}@{postgres_host}:{postgres_port}/{postgres_schm}"
    )
    
    db = SQLDatabase.from_uri(
        CONNECTION_STRING,
        schema=postgres_schm,
        view_support=True
    )
    return db

```

- _ **Tool Class:** _

```auto
class ToolWithConnection:
    def __init__ (self, x):
        """Initialize with a connection based on the input 'x'."""
        self.db = connection(x)
        print('>> Initialize db connection ✔\n')

    @tool("list_tables")
    def list_tables(self) -> str:
        """List the available tables in the database."""
        return ListSQLDatabaseTool(db=self.db).invoke("")
        
    @tool("tables_schema")
    def tables_schema(self, tables: str) -> str:
        """Get the schema of specified tables."""
        tool = InfoSQLDatabaseTool(db=self.db)
        return tool.invoke(tables)

```

- _ **CrewAI Wrapper :** _

```auto
class CrewAIWrapper:
    def __init__ (self, x):
        self.x = x
        self.llm_crew = LLM(model='azure/GPT4o')
        tool_instance = ToolWithConnection(self.x)

        self.sql_dev = Agent(
            role="Senior Database Developer",
            goal="Construct and execute PostgreSQL queries based on a query {query}",
            tools=[
                tool_instance.list_tables,  
                tool_instance.tables_schema,
            ],
            allow_delegation=False,
            memory=False,
            verbose=True,
        )

    def kickoff_crew(self):
        extract_data_task = Task(
            description="Extract data that is required for the query {query}.",
            agent=self.sql_dev,
        )

        my_crew = Crew(
            agents=[self.sql_dev],
            tasks=[extract_data_task],
            verbose=True,
        )

        try:
            crew_result = my_crew.kickoff(
                inputs={"query": self.x['question']}
            )
            return crew_result.raw
        except Exception as e:
            print(f"Error during task execution: {str(e)}")

```

- _ **Chain setup:** _

```auto
class CustomCrewAILLM(LLM):
    model: str
        
    def __init__ (self, model='azure/GPT4o'):
        super(). __init__ (model=model)
        
    @property
    def _llm_type(self):
        return 'custom_crew_ai'
    
    def _call(self, obj: dict,) -> str:
        crew_ai_wrapper = CrewAIWrapper(obj, )
        result = crew_ai_wrapper.kickoff_crew()
        print(type(result))
        # print(result)
        return result
class InputType(BaseModel):
    crewai_input: Optional[str]
    db: Optional[SQLDatabase] = Field(default=None, exclude=True) # Exclude from schema validation
    database_schm: str
    database_host: str
    database_port: str
    database_user: str
    database_pass: str
    database_name: str
    database_dryr: str
    class Config:
        arbitrary_types_allowed = True # Allow non-Pydantic types like SQLDatabase

    # @field_validator("crewai_input")
    # def validate_input(cls, v):
    # if not isinstance(v, str):
    # raise ValidationError(f"Expected crewai_input to be a str, got {type(v)} instead.")
    # return v

class OutputType(BaseModel):
    crewai_output: Optional[str]

    # @field_validator("crewai_output")
    # def validate_output(cls, v):
    # if not isinstance(v, str):
    # raise ValidationError(f"Expected crewai_output to be a str, got {type(v)} instead.")
    # return v

chain = (
    RunnablePassthrough.assign(
        crewai_output=RunnableLambda(lambda x: CustomCrewAILLM()._call(x))
        )
        ).with_types(input_type=InputType,
                     output_type=OutputType
                     )

```

- _ **The Problem:** _  
When I run the CrewAIWrapper with the agents and tools, I get the following error for the list\_tables tool:

```auto
I encountered an error while trying to use the tool. This was the error: ToolWithConnection.list_tables() missing 1 required positional argument: 'self'.

```

- _ **Question:** _

- Why is the self argument missing when calling list\_tables?

- How can I properly pass instance methods (like list\_tables) from a class to agents without encountering this error?

---

<div class="post-metadata">

**Author:** ![LouisLecouturier](https://avatars.discourse-cdn.com/v4/letter/l/49beb7/32.png) [@LouisLecouturier](https://community.crewai.com/u/LouisLecouturier)\
**Post date:** [September 3, 2025, 2:07pm UTC](https://community.crewai.com/t/tool-methods-in-python-class-missing-self-argument-when-used-in-custom-agents/2549/2 "2025-09-03T14:07:29Z")

</div>

Hi, did you find any solution ?
