ronantakizawa/codereview-bench huggingface dataset:
Repository: gventuri/pandas-ai
File: pandasai/helpers/code_manager.py (Python)

Code before:
        Returns:
            str: A clean code string.

        """

        # Clear recent optional dependencies
        self._additional_dependencies = []

        tree = ast.parse(code)

        # Check for imports and the node where analyze_data is defined
        new_body = []
        for node in tree.body:
            if isinstance(node, (ast.Import, ast.ImportFrom)):
                self._check_imports(node)
                continue

            if (
                self._is_df_overwrite(node)
                or self._is_jailbreak(node)
                or self._is_unsafe(node)
            ):
                continue

            # if generated code contain execute_sql_query def remove it
            # functioin already defined
            if self.check_direct_sql_func_def_exists(node):
                continue

            self.find_function_calls(node, context)

            new_body.append(node)

        new_tree = ast.Module(body=new_body)
        return astor.to_source(new_tree, pretty_source=lambda x: "".join(x)).strip()

    def _is_df_overwrite(self, node: ast.stmt) -> bool:
        """
        Remove df declarations from the code to prevent malicious code execution.

        Args:
            node (ast.stmt): A code node to be checked.

        Returns (bool):

        """

        return (
            isinstance(node, ast.Assign)
            and isinstance(node.targets[0], ast.Name)
            and node.targets[0].id == "dfs"

Review comment (suggestion):
```suggestion
            # function already defined
```

Code after:
        Returns:
            str: A clean code string.

        """

        # Clear recent optional dependencies
        self._additional_dependencies = []

        tree = ast.parse(code)

        # Check for imports and the node where analyze_data is defined
        new_body = []
        for node in tree.body:
            if isinstance(node, (ast.Import, ast.ImportFrom)):
                self._check_imports(node)
                continue

            if (
                self._is_df_overwrite(node)
                or self._is_jailbreak(node)
                or self._is_unsafe(node)
            ):
                continue

            # if generated code contain execute_sql_query def remove it
            # function already defined
            if self.check_direct_sql_func_def_exists(node):
                continue

            self.find_function_calls(node, context)

            new_body.append(node)

        new_tree = ast.Module(body=new_body)
        return astor.to_source(new_tree, pretty_source=lambda x: "".join(x)).strip()

    def _is_df_overwrite(self, node: ast.stmt) -> bool:
        """
        Remove df declarations from the code to prevent malicious code execution.

        Args:
            node (ast.stmt): A code node to be checked.

        Returns (bool):

        """

        return (
            isinstance(node, ast.Assign)
            and isinstance(node.targets[0], ast.Name)
            and node.targets[0].id == "dfs"
Repository: gventuri/pandas-ai
File: pandasai/connectors/base.py (Python)

Code before:

    @logger.setter
    def logger(self, logger: Logger):
        """
        Set the logger for the connector.

        Args:
            logger (Logger): The logger for the connector.
        """
        self._logger = logger

    @property
    def fallback_name(self):
        """
        Return the name of the table that the connector is connected to.
        """
        raise NotImplementedError

    @property
    def pandas_df(self):
        """
        Returns the pandas dataframe
        """
        raise NotImplementedError

    @property
    def type(self):
        """
        Return the name of the table that the connector is connected to.
        """
        raise NotImplementedError

    def equals(self, other):
        return self.__dict__ == other.__dict__

    @cache
    def get_head(self, n: int = 3) -> pd.DataFrame:
        """
        Return the head of the data source that the connector is connected to.
        This information is passed to the LLM to provide the schema of the
        data source.

        Args:
            n (int, optional): The number of rows to return. Defaults to 5.

        Returns:
            pd.DataFrame: The head of the data source that the connector is
                connected to.
        """
        return self.custom_head if self.custom_head is not None else self.head(n)


Review comment (refactor):
```suggestion
    @property
    @abstractmethod
```

Code after:

    @logger.setter
    def logger(self, logger: Logger):
        """
        Set the logger for the connector.

        Args:
            logger (Logger): The logger for the connector.
        """
        self._logger = logger

    @property
    def fallback_name(self):
        """
        Return the name of the table that the connector is connected to.
        """
        raise NotImplementedError

    @property
    def pandas_df(self):
        """
        Returns the pandas dataframe
        """
        raise NotImplementedError

    @property
    def type(self):
        """
        type of the connector
        """
        pass

    def equals(self, other):
        return self.__dict__ == other.__dict__

    @cache
    def get_head(self, n: int = 3) -> pd.DataFrame:
        """
        Return the head of the data source that the connector is connected to.
        This information is passed to the LLM to provide the schema of the
        data source.

        Args:
            n (int, optional): The number of rows to return. Defaults to 5.

        Returns:
            pd.DataFrame: The head of the data source that the connector is
                connected to.
        """
        return self.custom_head if self.custom_head is not None else self.head(n)
Repository: gventuri/pandas-ai
File: server/app/repositories/workspace.py (Python)

Code before:
        dataset_repository = DatasetRepository(Dataset, db_session=self.session)
        for dataset in datasets:
            dataset_repository.create({**dataset})

    async def add_dataset_to_space(self, workspace_id: str, dataset_id: str):
        dataset_space = DatasetSpace(workspace_id=workspace_id, dataset_id=dataset_id)
        self.session.add(dataset_space)

    async def get_space_datasets(self, workspace_id: str) -> List[Dataset]:
        result = await self.session.execute(
            select(Dataset)
            .join(DatasetSpace)
            .options(joinedload(Dataset.dataset_spaces))
            .filter(DatasetSpace.workspace_id == workspace_id)
        )
        return result.unique().scalars().all()

    async def get_users_by_workspace_id(self, workspace_id: str):
        users = await self.session.execute(
            select(UserSpace)
            .options(joinedload(UserSpace.user))
            .filter(UserSpace.workspace_id == workspace_id)
        )
        user_spaces = users.scalars().all()
        result = []
        for user_space in user_spaces:
            user = user_space.user
            user_info = {
                "first_name": user.first_name,
                "last_name": user.last_name,
                "email": user.email,
            }
            result.append(user_info)
        return result


Review comment (suggestion):
@shahrukh802 you don't need this loop for filtering you can handle that with pydantic to select particular fields check app/schema/responses 

Code after:
    async def create_csv_datasets(self, datasets: List[dict]) -> None:
        dataset_repository = DatasetRepository(Dataset, db_session=self.session)
        for dataset in datasets:
            dataset_repository.create({**dataset})

    async def add_dataset_to_space(self, workspace_id: str, dataset_id: str):
        dataset_space = DatasetSpace(workspace_id=workspace_id, dataset_id=dataset_id)
        self.session.add(dataset_space)

    async def get_space_datasets(self, workspace_id: str) -> List[Dataset]:
        result = await self.session.execute(
            select(Dataset)
            .join(DatasetSpace)
            .options(joinedload(Dataset.dataset_spaces))
            .filter(DatasetSpace.workspace_id == workspace_id)
        )
        return result.unique().scalars().all()

    async def get_users_by_workspace_id(self, workspace_id: str) -> List[WorkspaceUserResponse]:
        result = await self.session.execute(
            select(
                User.id,
                User.first_name,
                User.last_name,
                User.email
            ).join(UserSpace).filter(UserSpace.workspace_id == workspace_id)
        )
        return result.all()
Repository: gventuri/pandas-ai
File: pandasai/__init__.py (Python)

Code before:
    loader = DatasetLoader.create_loader_from_schema(schema, path)
    return loader.load()


# Global variable to store the current agent
_current_agent = None

config = ConfigManager()

api_key = APIKeyManager()


def clear_cache(filename: str = None):
    """Clear the cache"""
    cache = Cache(filename) if filename else Cache()
    cache.clear()


def chat(query: str, *dataframes: DataFrame, sandbox: Optional[Sandbox] = None):
    """
    Start a new chat interaction with the assistant on Dataframe(s).

    Args:
        query (str): The query to run against the dataframes.
        *dataframes: Variable number of dataframes to query.
        sandbox (Sandbox, optional): The sandbox to execute code securily.

    Returns:
        The result of the query.
    """
    global _current_agent
    if not dataframes:
        raise ValueError("At least one dataframe must be provided.")

    _current_agent = Agent(list(dataframes), sandbox=sandbox)
    return _current_agent.chat(query)


def follow_up(query: str):
    """
    Continue the existing chat interaction with the assistant on Dataframe(s).

    Args:
        query (str): The follow-up query to run.

    Returns:
        The result of the query.
    """
    global _current_agent

    if _current_agent is None:

Review comment (suggestion):
```suggestion
        sandbox (Sandbox, optional): The sandbox to execute code securely.
```

Code after:
    loader = DatasetLoader.create_loader_from_schema(schema, path)
    return loader.load()


# Global variable to store the current agent
_current_agent = None

config = ConfigManager()

api_key = APIKeyManager()


def clear_cache(filename: str = None):
    """Clear the cache"""
    cache = Cache(filename) if filename else Cache()
    cache.clear()


def chat(query: str, *dataframes: DataFrame, sandbox: Optional[Sandbox] = None):
    """
    Start a new chat interaction with the assistant on Dataframe(s).

    Args:
        query (str): The query to run against the dataframes.
        *dataframes: Variable number of dataframes to query.
        sandbox (Sandbox, optional): The sandbox to execute code securely.

    Returns:
        The result of the query.
    """
    global _current_agent
    if not dataframes:
        raise ValueError("At least one dataframe must be provided.")

    _current_agent = Agent(list(dataframes), sandbox=sandbox)
    return _current_agent.chat(query)


def follow_up(query: str):
    """
    Continue the existing chat interaction with the assistant on Dataframe(s).

    Args:
        query (str): The follow-up query to run.

    Returns:
        The result of the query.
    """
    global _current_agent

    if _current_agent is None:
Repository: gventuri/pandas-ai
File: tests/unit_tests/data_loader/test_transformation_schema.py (Python)

Code before:


def test_incompatible_source():
    source1 = Source(type="csv", path="path")
    source2 = Source(
        type="postgres",
        connection=SQLConnectionConfig(
            **{
                "host": "example.amazonaws.com",
                "port": 5432,
                "user": "user",
                "password": "password",
                "database": "db",
            }
        ),
        table="table",
    )
    assert not source1.is_compatible_source(source2)


def test_source_or_view_error():
    with pytest.raises(ValidationError):
        SemanticLayerSchema(name="ciao")


def test_column_must_be_definend_for_view():
    with pytest.raises(ValidationError):
        SemanticLayerSchema(name="ciao", view=True)


Review comment (suggestion):
```suggestion
def test_column_must_be_defined_for_view():
```

Code after:


def test_incompatible_source():
    source1 = Source(type="csv", path="path")
    source2 = Source(
        type="postgres",
        connection=SQLConnectionConfig(
            **{
                "host": "example.amazonaws.com",
                "port": 5432,
                "user": "user",
                "password": "password",
                "database": "db",
            }
        ),
        table="table",
    )
    assert not source1.is_compatible_source(source2)


def test_source_or_view_error():
    with pytest.raises(ValidationError):
        SemanticLayerSchema(name="ciao")


def test_column_must_be_defined_for_view():
    with pytest.raises(ValidationError):
        SemanticLayerSchema(name="ciao", view=True)
Repository: httpie/httpie
File: httpie/cli.py (Python)

Code before:
    new Location).

    """
)
network.add_argument(
    '--verify',
    default='yes',
    help="""
    Set to "no" to skip checking the host's SSL certificate. You can also pass
    the  path to a CA_BUNDLE file for private certs. You can also set the
    REQUESTS_CA_BUNDLE  environment variable. Defaults to "yes".

    """
)

network.add_argument(
    '--ssl-cert',
    default=None,
    help="""
    You can specify a local cert to use as client side SSL certificate.
    This file may either contain both private key and certificate or you may
    specify --ssl-key separately.

    """
)

network.add_argument(
    '--ssl-key',
    default=None,
    help="""
    The private key to use with SSL. Only needed if --ssl-cert is given and the
    certificate file does not contain the private key.

    """
)

network.add_argument(
    '--timeout',
    type=float,
    default=30,
    metavar='SECONDS',
    help="""
    The connection timeout of the request in seconds. The default value is
    30 seconds.

    """
)
network.add_argument(
    '--check-status',
    default=False,
    action='store_true',

Review comment (bug):
It would be good to specify also `type=FileType()` so that it fails with a user-friendly error message when the file does not exist or is not readable. 


Code after:
    Set this flag if full redirects are allowed (e.g. re-POST-ing of data at
    new Location).

    """
)
network.add_argument(
    '--verify',
    default='yes',
    help="""
    Set to "no" to skip checking the host's SSL certificate. You can also pass
    the  path to a CA_BUNDLE file for private certs. You can also set the
    REQUESTS_CA_BUNDLE  environment variable. Defaults to "yes".

    """
)

network.add_argument(
    '--cert',
    default=None,
    type=readable_file_arg,
    help="""
    You can specify a local cert to use as client side SSL certificate.
    This file may either contain both private key and certificate or you may
    specify --certkey separately.

    """
)

network.add_argument(
    '--certkey',
    default=None,
    type=readable_file_arg,
    help="""
    The private key to use with SSL. Only needed if --cert is given and the
    certificate file does not contain the private key.

    """
)

network.add_argument(
    '--timeout',
    type=float,
    default=30,
    metavar='SECONDS',
    help="""
    The connection timeout of the request in seconds. The default value is
    30 seconds.

    """
)
network.add_argument(
Repository: httpie/httpie
File: httpie/utils.py (Python)

Code before:
from __future__ import division
import argparse


def humanize_bytes(n, precision=2):
    # Author: Doug Latornell
    # Licence: MIT
    # URL: http://code.activestate.com/recipes/577081/
    """Return a humanized string representation of a number of bytes.

    Assumes `from __future__ import division`.

    >>> humanize_bytes(1)
    '1 byte'
    >>> humanize_bytes(1024)
    '1.0 kB'
    >>> humanize_bytes(1024 * 123)
    '123.0 kB'
    >>> humanize_bytes(1024 * 12342)
    '12.1 MB'
    >>> humanize_bytes(1024 * 12342, 2)
    '12.05 MB'
    >>> humanize_bytes(1024 * 1234, 2)
    '1.21 MB'
    >>> humanize_bytes(1024 * 1234 * 1111, 2)
    '1.31 GB'
    >>> humanize_bytes(1024 * 1234 * 1111, 1)
    '1.3 GB'

    """
    abbrevs = [
        (1 << 50, 'PB'),
        (1 << 40, 'TB'),
        (1 << 30, 'GB'),
        (1 << 20, 'MB'),
        (1 << 10, 'kB'),
        (1, 'B')
    ]

    if n == 1:
        return '1 B'

    for factor, suffix in abbrevs:
        if n >= factor:
            break

    return '%.*f %s' % (precision, n / factor, suffix)


def existing_file(filename):
    try:
        open(filename, 'rb')
    except IOError as ex:
        raise argparse.ArgumentTypeError(
            '%s: %s' % (filename, ex.args[1]))
    return filename


Review comment (suggestion):
Maybe `readable_file_arg` would be a better name? (It has to both exist and be readable by the current user, and also it's tied to `argparse` .)

As for the location, I think `httpie.input` would be a good place.


Code after:
from __future__ import division


def humanize_bytes(n, precision=2):
    # Author: Doug Latornell
    # Licence: MIT
    # URL: http://code.activestate.com/recipes/577081/
    """Return a humanized string representation of a number of bytes.

    Assumes `from __future__ import division`.

    >>> humanize_bytes(1)
    '1 byte'
    >>> humanize_bytes(1024)
    '1.0 kB'
    >>> humanize_bytes(1024 * 123)
    '123.0 kB'
    >>> humanize_bytes(1024 * 12342)
    '12.1 MB'
    >>> humanize_bytes(1024 * 12342, 2)
    '12.05 MB'
    >>> humanize_bytes(1024 * 1234, 2)
    '1.21 MB'
    >>> humanize_bytes(1024 * 1234 * 1111, 2)
    '1.31 GB'
    >>> humanize_bytes(1024 * 1234 * 1111, 1)
    '1.3 GB'

    """
    abbrevs = [
        (1 << 50, 'PB'),
        (1 << 40, 'TB'),
        (1 << 30, 'GB'),
        (1 << 20, 'MB'),
        (1 << 10, 'kB'),
        (1, 'B')
    ]

    if n == 1:
        return '1 B'

    for factor, suffix in abbrevs:
        if n >= factor:
            break

    return '%.*f %s' % (precision, n / factor, suffix)
Repository: httpie/httpie
File: httpie/cli/constants.py (Python)

Code before:

"""
import re
import ssl


# TODO: Use MultiDict for headers once added to `requests`.
# <https://github.com/jakubroztocil/httpie/issues/130>


# ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
# <https://tools.ietf.org/html/rfc3986#section-3.1>
URL_SCHEME_RE = re.compile(r'^[a-z][a-z0-9.+-]*://', re.IGNORECASE)

HTTP_POST = 'POST'
HTTP_GET = 'GET'

# Various separators used in args
SEPARATOR_HEADER = ':'
SEPARATOR_HEADER_EMPTY = ';'
SEPARATOR_CREDENTIALS = ':'
SEPARATOR_PROXY = ':'
SEPARATOR_DATA_STRING = '='
SEPARATOR_DATA_RAW_JSON = ':='
SEPARATOR_FILE_UPLOAD = '@'
SEPARATOR_FILE_UPLOAD_TYPE = ';type='
SEPARATOR_DATA_EMBED_FILE_CONTENTS = '=@'
SEPARATOR_DATA_EMBED_RAW_JSON_FILE = ':=@'
SEPARATOR_QUERY_PARAM = '=='

# Separators that become request data
SEPARATOR_GROUP_DATA_ITEMS = frozenset({
    SEPARATOR_DATA_STRING,
    SEPARATOR_DATA_RAW_JSON,
    SEPARATOR_FILE_UPLOAD,
    SEPARATOR_DATA_EMBED_FILE_CONTENTS,
    SEPARATOR_DATA_EMBED_RAW_JSON_FILE
})

# Separators for items whose value is a filename to be embedded
SEPARATOR_GROUP_DATA_EMBED_ITEMS = frozenset({
    SEPARATOR_DATA_EMBED_FILE_CONTENTS,
    SEPARATOR_DATA_EMBED_RAW_JSON_FILE,
})

# Separators for raw JSON items
SEPARATOR_GROUP_RAW_JSON_ITEMS = frozenset([
    SEPARATOR_DATA_RAW_JSON,
    SEPARATOR_DATA_EMBED_RAW_JSON_FILE,
])


Review comment (suggestion):
```suggestion
SEPARATOR_FILE_UPLOAD_TYPE = ';type='  # in already parsed file upload path only

Code after:

"""
import re
import ssl


# TODO: Use MultiDict for headers once added to `requests`.
# <https://github.com/jakubroztocil/httpie/issues/130>


# ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
# <https://tools.ietf.org/html/rfc3986#section-3.1>
URL_SCHEME_RE = re.compile(r'^[a-z][a-z0-9.+-]*://', re.IGNORECASE)

HTTP_POST = 'POST'
HTTP_GET = 'GET'

# Various separators used in args
SEPARATOR_HEADER = ':'
SEPARATOR_HEADER_EMPTY = ';'
SEPARATOR_CREDENTIALS = ':'
SEPARATOR_PROXY = ':'
SEPARATOR_DATA_STRING = '='
SEPARATOR_DATA_RAW_JSON = ':='
SEPARATOR_FILE_UPLOAD = '@'
SEPARATOR_FILE_UPLOAD_TYPE = ';type='  # in already parsed file upload path only
SEPARATOR_DATA_EMBED_FILE_CONTENTS = '=@'
SEPARATOR_DATA_EMBED_RAW_JSON_FILE = ':=@'
SEPARATOR_QUERY_PARAM = '=='

# Separators that become request data
SEPARATOR_GROUP_DATA_ITEMS = frozenset({
    SEPARATOR_DATA_STRING,
    SEPARATOR_DATA_RAW_JSON,
    SEPARATOR_FILE_UPLOAD,
    SEPARATOR_DATA_EMBED_FILE_CONTENTS,
    SEPARATOR_DATA_EMBED_RAW_JSON_FILE
})

# Separators for items whose value is a filename to be embedded
SEPARATOR_GROUP_DATA_EMBED_ITEMS = frozenset({
    SEPARATOR_DATA_EMBED_FILE_CONTENTS,
    SEPARATOR_DATA_EMBED_RAW_JSON_FILE,
})

# Separators for raw JSON items
SEPARATOR_GROUP_RAW_JSON_ITEMS = frozenset([
    SEPARATOR_DATA_RAW_JSON,
    SEPARATOR_DATA_EMBED_RAW_JSON_FILE,
])
Repository: httpie/httpie
File: httpie/cli/definition.py (Python)

Code before:

    '''
)
content_type.add_argument(
    '--multipart',
    action='store_const',
    const=RequestType.MULTIPART,
    dest='request_type',
    help='''
    Similar to --form, but always sends a multipart/form-data
    request (i.e., even without files).

    '''
)
content_type.add_argument(
    '--boundary',
    help='''
    Specify a custom boundary string for multipart/form-data requests.
    Only has effect only together with --form.

    '''
)
content_type.add_argument(
    '--request', '-r',
    help='''
    Specify the raw request body without extra processing whatsoever.

    '''
)


#######################################################################
# Content processing.
#######################################################################

content_processing = parser.add_argument_group(
    title='Content Processing Options',
    description=None
)

content_processing.add_argument(
    '--compress', '-x',
    action='count',
    default=0,
    help='''
    Content compressed (encoded) with Deflate algorithm.
    The Content-Encoding header is set to deflate.

    Compression is skipped if it appears that compression ratio is
    negative. Compression can be forced by repeating the argument.


Review comment (suggestion):
```suggestion
    This option allows you to pass raw request data without extra processing 
    (as opposed to the structured request items syntax):
     
        $ http --request='data' pie.dev/post
        
    You can achieve the same by piping the data via stdin:
    
        $ echo data | http pie.dev/post
        
    Or have HTTPie load the raw data from a file:
    
        $ http pie.dev/post @data.txt
    
```

Code after:

    '''
)
content_type.add_argument(
    '--multipart',
    action='store_const',
    const=RequestType.MULTIPART,
    dest='request_type',
    help='''
    Similar to --form, but always sends a multipart/form-data
    request (i.e., even without files).

    '''
)
content_type.add_argument(
    '--boundary',
    help='''
    Specify a custom boundary string for multipart/form-data requests.
    Only has effect only together with --form.

    '''
)
content_type.add_argument(
    '--raw',
    help='''
    This option allows you to pass raw request data without extra processing
    (as opposed to the structured request items syntax):

        $ http --raw='data' pie.dev/post

    You can achieve the same by piping the data via stdin:

        $ echo data | http pie.dev/post

    Or have HTTPie load the raw data from a file:

        $ http pie.dev/post @data.txt


    '''
)


#######################################################################
# Content processing.
#######################################################################

content_processing = parser.add_argument_group(
    title='Content Processing Options',
    description=None
)