diff --git a/README.md b/README.md index 9d4474d..ecb6476 100644 --- a/README.md +++ b/README.md @@ -24,15 +24,20 @@ pipx install git+https://github.com/MeltanoLabs/tap-file.git | protocol | True | None | The protocol to use to retrieve data. One of `file` or `s3`. | | filepath | True | None | The path to obtain files from. Example: `/foo/bar`. Or, for `protocol==s3`, use `s3-bucket-name` instead. | | file_regex | False | None | A regex pattern to only include certain files. Example: `.*\.csv`. | -| file_type | False | detect | Can be any of `csv`, `tsv`, `json`, `avro`, or `detect`. Indicates how to determine a file's type. If set to `detect`, file names containing a matching extension will be read as that type and other files will not be read. If set to a file type, *all* files will be read as that type. | -| compression | False | detect | The encoding to use to decompress data. One of `zip`, `bz2`, `gzip`, `lzma`, `xz`, `none`, or `detect`. | -| delimiter | False | detect | The character used to separate records in a CSV/TSV. Can be any character or the special value `detect`. If a character is provided, all CSV and TSV files will use that value. `detect` will use `,` for CSV files and `\t` for TSV files. | -| quote_character | False | " | The character used to indicate when a record in a CSV contains a delimiter character. | +| file_type | False | delimited | Can be any of `delimited`, `jsonl`, or `avro`. Indicates the type of file to sync, where `delimited` is for CSV/TSV files and similar. Note that *all* files will be read as that type, regardless of file extension. To only read from files with a matching file extension, appropriately configure `file_regex`. | +| compression | False | detect | The encoding to use to decompress data. One of `zip`, `bz2`, `gzip`, `lzma`, `xz`, `none`, or `detect`. If set to `none` or any encoding, that setting will be applied to *all* files, regardless of file extension. If set to `detect`, encodings will be applied based on file extension. | +| additional_info | False | 1 | If `True`, each row in tap's output will have two additional columns: `_sdc_file_name` and `_sdc_line_number`. If `False`, these columns will not be present. | +| delimited_delimiter | False | detect | The character used to separate records in a delimited file. Can be any character or the special value `detect`. If a character is provided, all delimited files will use that value. `detect` will use `,` for `.csv` files, `\t` for `.tsv` files, and fail if other file types are present. | +| delimited_quote_character | False | " | The character used to indicate when a record in a delimited file contains a delimiter character. | +| delimited_header_skip | False | 0 | The number of initial rows to skip at the beginning of each delimited file. | +| delimited_footer_skip | False | 0 | The number of initial rows to skip at the end of each delimited file. | +| delimited_override_headers | False | None | An optional array of headers used to override the default column name in delimited files, allowing for headerless files to be correctly read. | | jsonl_sampling_strategy | False | first | The strategy determining how to read the keys in a JSONL file. Must be one of `first` or `all`. Currently, only `first` is supported, which will assume that the first record in a file is representative of all keys. | -| jsonl_type_coercion_strategy| False | any | The strategy determining how to construct the schema for JSONL files when the types represented are ambiguous. Must be one of `any`, `string`, or `blob`. `any` will provide a generic schema for all keys, allowing them to be any valid JSON type. `string` will require all keys to be strings and will convert other values accordingly. `blob` will deliver each JSONL row as a JSON object with no internal schema. Currently, only `any` and `string` are supported. | +| jsonl_type_coercion_strategy| False | any | The strategy determining how to construct the schema for JSONL files when the types represented are ambiguous. Must be one of `any`, `string`, or `envelope`. `any` will provide a generic schema for all keys, allowing them to be any valid JSON type. `string` will require all keys to be strings and will convert other values accordingly. `envelope` will deliver each JSONL row as a JSON object with no internal schema. | +| avro_type_coercion_strategy | False | convert | The strategy determining how to construct the schema for Avro files when conversion between schema types is ambiguous. Must be one of `convert` or `envelope`. `convert` will attempt to convert from Avro Schema to JSON Schema and will fail if a type can't be easily coerced. `envelope` will wrap each record in an object without providing an internal schema for the record. | | s3_anonymous_connection | False | 0 | Whether to use an anonymous S3 connection, without any credentials. Ignored if `protocol!=s3`. | -| AWS_ACCESS_KEY_ID | False | $AWS_ACCESS_KEY_ID | The access key to use when authenticating to S3. Ignored if `protocol!=s3` or `s3_anonymous_connection=True`. Defaults to the value of the environment variable of the same name. | -| AWS_SECRET_ACCESS_KEY | False | $AWS_SECRET_ACCESS_KEY | The access key secret to use when authenticating to S3. Ignored if `protocol!=s3` or `s3_anonymous_connection=True`. Defaults to the value of the environment variable of the same name. | +| AWS_ACCESS_KEY_ID | False | $AWS_ACCESS_KEY_ID | The access key to use when authenticating to S3. Ignored if `protocol!=s3` or `s3_anonymous_connection=True`. Defaults to the value of the environment variable of the same name. | +| AWS_SECRET_ACCESS_KEY | False | $AWS_SECRET_ACCESS_KEY | The access key secret to use when authenticating to S3. Ignored if `protocol!=s3` or `s3_anonymous_connection=True`. Defaults to the value of the environment variable of the same name. | | caching_strategy | False | once | *DEVELOPERS ONLY* The caching method to use when `protocol!=file`. One of `none`, `once`, or `persistent`. `none` does not use caching at all. `once` (the default) will cache all files for the duration of the tap's invocation, then discard them upon completion. `peristent` will allow caches to persist between invocations of the tap, storing them in your OS's temp directory. It is recommended that you do not modify this setting. | | stream_maps | False | None | Config object for stream maps capability. For more information check out [Stream Maps](https://sdk.meltano.com/en/latest/stream_maps.html). | | stream_map_config | False | None | User-defined config values to be used within map expressions. | diff --git a/meltano.yml b/meltano.yml index 672278b..a940cef 100644 --- a/meltano.yml +++ b/meltano.yml @@ -22,10 +22,19 @@ plugins: - name: file_regex - name: file_type - name: compression - - name: delimiter - - name: quote_character + - name: additional_info + kind: boolean + - name: delimited_delimiter + - name: delimited_quote_character + - name: delimited_header_skip + kind: integer + - name: delimited_footer_skip + kind: integer + - name: delimited_override_headers + kind: array - name: jsonl_sampling_strategy - name: jsonl_type_coercion_strategy + - name: avro_type_coercion_strategy - name: s3_anonymous_connection - name: AWS_ACCESS_KEY_ID kind: password diff --git a/poetry.lock b/poetry.lock index fb56b1a..8cb9eec 100644 --- a/poetry.lock +++ b/poetry.lock @@ -204,6 +204,21 @@ docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib- tests = ["attrs[tests-no-zope]", "zope-interface"] tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +[[package]] +name = "avro" +version = "1.11.1" +description = "Avro is a serialization and RPC framework." +category = "main" +optional = true +python-versions = ">=3.6" +files = [ + {file = "avro-1.11.1.tar.gz", hash = "sha256:f123623ecc648d0e20ce14f8ed85162140c13cc4b108865d1b2529fbfa06c008"}, +] + +[package.extras] +snappy = ["python-snappy"] +zstandard = ["zstandard"] + [[package]] name = "backoff" version = "2.2.1" @@ -1106,14 +1121,14 @@ files = [ [[package]] name = "platformdirs" -version = "3.5.3" +version = "3.8.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "platformdirs-3.5.3-py3-none-any.whl", hash = "sha256:0ade98a4895e87dc51d47151f7d2ec290365a585151d97b4d8d6312ed6132fed"}, - {file = "platformdirs-3.5.3.tar.gz", hash = "sha256:e48fabd87db8f3a7df7150a4a5ea22c546ee8bc39bc2473244730d4b56d2cc4e"}, + {file = "platformdirs-3.8.0-py3-none-any.whl", hash = "sha256:ca9ed98ce73076ba72e092b23d3c93ea6c4e186b3f1c3dad6edd98ff6ffcca2e"}, + {file = "platformdirs-3.8.0.tar.gz", hash = "sha256:b0cabcb11063d21a0b261d557acb0a9d2126350e63b70cdf7db6347baea456dc"}, ] [package.extras] @@ -1122,14 +1137,14 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest- [[package]] name = "pluggy" -version = "1.0.0" +version = "1.2.0" description = "plugin and hook calling mechanisms for python" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, - {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, + {file = "pluggy-1.2.0-py3-none-any.whl", hash = "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849"}, + {file = "pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3"}, ] [package.extras] @@ -1217,14 +1232,14 @@ files = [ [[package]] name = "pytest" -version = "7.3.2" +version = "7.4.0" description = "pytest: simple powerful testing with Python" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "pytest-7.3.2-py3-none-any.whl", hash = "sha256:cdcbd012c9312258922f8cd3f1b62a6580fdced17db6014896053d47cddf9295"}, - {file = "pytest-7.3.2.tar.gz", hash = "sha256:ee990a3cc55ba808b80795a79944756f315c67c12b56abd3ac993a7b8c17030b"}, + {file = "pytest-7.4.0-py3-none-any.whl", hash = "sha256:78bf16451a2eb8c7a2ea98e32dc119fd2aa758f1d5d66dbf0a59d69a3969df32"}, + {file = "pytest-7.4.0.tar.gz", hash = "sha256:b4bf8c45bd59934ed84001ad51e11b4ee40d40a1229d2c79f9c592b0a3f6bd8a"}, ] [package.dependencies] @@ -1447,14 +1462,14 @@ crt = ["botocore[crt] (>=1.20.29,<2.0a.0)"] [[package]] name = "setuptools" -version = "67.8.0" +version = "68.0.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "setuptools-67.8.0-py3-none-any.whl", hash = "sha256:5df61bf30bb10c6f756eb19e7c9f3b473051f48db77fddbe06ff2ca307df9a6f"}, - {file = "setuptools-67.8.0.tar.gz", hash = "sha256:62642358adc77ffa87233bc4d2354c4b2682d214048f500964dbe760ccedf102"}, + {file = "setuptools-68.0.0-py3-none-any.whl", hash = "sha256:11e52c67415a381d10d6b462ced9cfb97066179f0e871399e006c4ab101fc85f"}, + {file = "setuptools-68.0.0.tar.gz", hash = "sha256:baf1fdb41c6da4cd2eae722e135500da913332ab3f2f5c7d33af9b492acb5235"}, ] [package.extras] @@ -1916,9 +1931,10 @@ docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] [extras] +avro = ["avro"] s3 = ["fs-s3fs", "s3fs"] [metadata] lock-version = "2.0" python-versions = "<3.12,>=3.8" -content-hash = "be520c6704788a13c5c23cfff41e5d10fba2841ff7f86a7cd9a3542344ab5b55" +content-hash = "c44b45e7a12437695e49e8b4ebab6f6d24277f99a9ce408cf9afb27f5cbef02b" diff --git a/pyproject.toml b/pyproject.toml index 18c5709..0e6ead7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,6 +16,7 @@ singer-sdk = { version="^0.28.0" } fsspec = "^2023.5.0" s3fs = { version = "^2023.5.0", optional = true} fs-s3fs = { version = "^1.1.1", optional = true} +avro = "^1.1.11" [tool.poetry.extras] s3=["s3fs", "fs-s3fs"] diff --git a/tap_file/client.py b/tap_file/client.py index 30473a5..e86d9cf 100644 --- a/tap_file/client.py +++ b/tap_file/client.py @@ -30,6 +30,38 @@ def filesystem(self) -> fsspec.AbstractFileSystem: """ return FilesystemManager(self.config, self.logger).get_filesystem() + @cached_property + def schema(self) -> dict: + """Orchestrates schema creation for all streams. + + Returns: + A schema constructed using the get_properties() method of whichever stream + is currently in use. + """ + properties = self.get_properties() + additional_info = self.config["additional_info"] + if additional_info: + properties.update({"_sdc_file_name": {"type": ["string"]}}) + properties.update({"_sdc_line_number": {"type": ["integer"]}}) + return {"properties": properties} + + def add_additional_info(self, row: dict, file_name: str, line_number: int) -> dict: + """Adds _sdc-prefixed additional columns to a row, dependent on config. + + Args: + row: The row to add info to. + file_name: The name of the file that the row came from. + line_number: The line number of the row within its file. + + Returns: + A dictionary representing a row containing additional information columns. + """ + additional_info = self.config["additional_info"] + if additional_info: + row.update({"_sdc_file_name": file_name}) + row.update({"_sdc_line_number": line_number}) + return row + def get_files(self) -> Generator[str, None, None]: """Gets file names to be synced. @@ -72,6 +104,18 @@ def get_rows(self) -> Generator[dict[str | Any, str | Any], None, None]: msg = "get_rows must be implemented by subclass." raise NotImplementedError(msg) + def get_properties(self) -> dict: + """Gets properties for the purpose of schema generation. + + Raises: + NotImplementedError: This must be implemented by a subclass. + + Returns: + A dictionary representing a series of properties for schema generation. + """ + msg = "get_properties must be implemented by subclass." + raise NotImplementedError(msg) + def get_compression(self, file: str) -> str | None: # noqa: PLR0911 """Determines what compression encoding is appropraite for a given file. diff --git a/tap_file/streams.py b/tap_file/streams.py index 7df3b4d..cb0eeda 100644 --- a/tap_file/streams.py +++ b/tap_file/streams.py @@ -5,9 +5,13 @@ import csv import json import re -from functools import cached_property from typing import Any, Generator +import avro +import avro.datafile +import avro.io +import avro.schema + from tap_file.client import FileStream @@ -20,53 +24,93 @@ def get_rows(self) -> Generator[dict[str | Any, str | Any], None, None]: Yields: A dictionary containing information about a row in a *SV. """ - for reader in self._get_readers(): + for reader_dict in self._get_reader_dicts(): + reader = reader_dict["reader"] + line_number = 1 for row in reader: - yield row + yield self.add_additional_info( + row, + reader_dict["file_name"], + line_number, + ) + line_number += 1 - @cached_property - def schema(self) -> dict[str, dict]: - """Create a schema for a *SV file. + def get_properties(self) -> dict: + """Get a list of properties for a *SV file, to be used in creating a schema. Each column in the *SV will have its own entry in the schema. All entries will be of the form: `'FIELD_NAME': {'type': ['null', 'string']}` Returns: - A schema representing a *SV. + A list of properties representing a *SV file. """ properties = {} - for reader in self._get_readers(): + for reader_dict in self._get_reader_dicts(): + reader = reader_dict["reader"] + if reader.fieldnames is None: + msg = ( + "Column names could not be read because they don't exist. Try " + "manually specifying them using 'delimited_override_headers'." + ) + raise RuntimeError(msg) for field in reader.fieldnames: properties.update({field: {"type": ["null", "string"]}}) - return {"properties": properties} + return properties - def _get_readers(self) -> Generator[csv.DictReader[str], None, None]: - quote_character: str = self.config["quote_character"] + def _get_reader_dicts( + self, + ) -> Generator[dict[str, str | csv.DictReader[str]], None, None]: + quote_character: str = self.config["delimited_quote_character"] + override_headers: list | None = self.config.get( + "delimited_override_headers", + None, + ) for file in self.get_files(): - if self.config["delimiter"] == "detect": + if self.config["delimited_delimiter"] == "detect": if re.match(".*\\.csv.*", file): delimiter = "," elif re.match(".*\\.tsv.*", file): delimiter = "\t" else: msg = ( - "Configuration option 'delimiter' is set to 'detect' but a " - "non-csv non-tsv file is present. Please manually specify " - "'delimiter'." + "Configuration option 'delimited_delimiter' is set to 'detect' " + "but a non-csv non-tsv file is present. Please manually " + "specify 'delimited_delimiter'." ) raise RuntimeError(msg) else: - delimiter = self.config["delimiter"] + delimiter = self.config["delimited_delimiter"] - with self.filesystem.open( - path=file, - mode="rt", - compression=self.get_compression(file=file), - ) as f: - yield csv.DictReader(f, delimiter=delimiter, quotechar=quote_character) + yield { + "reader": csv.DictReader( + f=self._skip_rows(file), + delimiter=delimiter, + quotechar=quote_character, + fieldnames=override_headers, + ), + "file_name": file, + } + + def _skip_rows(self, file: str) -> list[str]: + with self.filesystem.open( + path=file, + mode="rt", + compression=self.get_compression(file=file), + ) as f: + file_list = [] + file_list.extend(f) + for _ in range(self.config["delimited_header_skip"]): + if len(file_list) == 0: + return file_list + file_list.pop(0) + for _ in range(self.config["delimited_footer_skip"]): + if len(file_list) == 0: + return file_list + file_list.pop() + return file_list class JSONLStream(FileStream): @@ -84,23 +128,28 @@ def get_rows(self) -> Generator[dict[str, Any], None, None]: mode="rt", compression=self.get_compression(file=file), ) as f: + line_number = 1 for row in f: - yield self._pre_process(json.loads(row)) + yield self.add_additional_info( + self._pre_process(json.loads(row)), + file, + line_number, + ) + line_number += 1 - @cached_property - def schema(self) -> dict[str, dict]: - """Create a schema for a JSONL file. + def get_properties(self) -> dict: + """Get a list of properties for a JSONL file, to be used in creating a schema. The format of the schema will depend on the jsonl_type_coercion_strategy config option, but will always be a dictionary of field names and associated types. Returns: - A schema representing a JSONL file. + A list of properties representing a JSONL file. """ properties = {} for field in self._get_fields(): properties.update(self._get_property(field=field)) - return {"properties": properties} + return properties def _get_property(self, field: str) -> dict[str, dict[str, list[str]]]: strategy = self.config["jsonl_type_coercion_strategy"] @@ -120,7 +169,7 @@ def _get_property(self, field: str) -> dict[str, dict[str, list[str]]]: } if strategy == "string": return {field: {"type": ["null", "string"]}} - if strategy == "blob": + if strategy == "envelope": return {field: {"type": ["null", "object"]}} msg = f"The coercion strategy '{strategy}' is not valid." raise ValueError(msg) @@ -147,7 +196,100 @@ def _pre_process(self, row: dict[str, Any]) -> dict[str, Any]: for entry in row: row[entry] = str(row[entry]) return row - if strategy == "blob": + if strategy == "envelope": + return {"record": row} + msg = f"The coercion strategy '{strategy}' is not valid." + raise ValueError(msg) + + +class AvroStream(FileStream): + """Stream for reading Avro files.""" + + def get_rows(self) -> Generator[dict[str, Any], None, None]: + """Retrive all rows from all Avro files. + + Yields: + A dictionary containing information about a row in a Avro file. + """ + for reader_dict in self._get_reader_dicts(): + reader = reader_dict["reader"] + line_number = 1 + for row in reader: + yield self.add_additional_info( + self._pre_process(row), + reader_dict["file_name"], + line_number, + ) + line_number += 1 + + def get_properties(self) -> dict: + """Get a list of properties for an Avro file, to be used in creating a schema. + + Returns: + A list of properties representing an Avro file. + """ + properties = {} + for field in self._get_fields(): + properties.update(self._get_property(field)) + return properties + + def _get_fields(self) -> Generator[dict | str, None, None]: + strategy = self.config["avro_type_coercion_strategy"] + if strategy == "convert": + for reader_dict in self._get_reader_dicts(): + reader = reader_dict["reader"] + for field in json.loads(reader.schema)["fields"]: + yield field + return + if strategy == "envelope": + yield "record" + return + msg = f"The coercion strategy '{strategy}' is not valid." + raise ValueError(msg) + + def _get_property(self, field: dict | str) -> dict[str, dict[str, list[str]]]: + strategy = self.config["avro_type_coercion_strategy"] + if strategy == "convert": + return {field["name"]: {"type": [self._type_convert(field["type"])]}} + if strategy == "envelope": + return {field: {"type": ["null", "object"]}} + msg = f"The coercion strategy '{strategy}' is not valid." + raise ValueError(msg) + + def _type_convert(self, field_type: str) -> str: + if type(field_type) != str: + msg = f"The field type '{field_type}' has not been implemented." + raise NotImplementedError(msg) + if field_type in {"null", "boolean", "string"}: + return field_type + if field_type in {"int", "long"}: + return "integer" + if field_type in {"float", "double"}: + return "number" + if field_type == "bytes": + return "string" + msg = f"The field type '{field_type} has not been implemented." + raise NotImplementedError(msg) + + def _pre_process(self, row: dict[str, Any]) -> dict[str, Any]: + strategy = self.config["avro_type_coercion_strategy"] + if strategy == "convert": + return row + if strategy == "envelope": return {"record": row} msg = f"The coercion strategy '{strategy}' is not valid." raise ValueError(msg) + + def _get_reader_dicts( + self, + ) -> Generator[dict[str, str | avro.datafile.DataFileReader], None, None]: + for file in self.get_files(): + with self.filesystem.open( + path=file, + mode="rb", + compression=self.get_compression(file=file), + ) as f: + yield { + "reader": avro.datafile.DataFileReader(f, avro.io.DatumReader()), + "file_name": file, + } diff --git a/tap_file/tap.py b/tap_file/tap.py index 5d620ea..1a8933d 100644 --- a/tap_file/tap.py +++ b/tap_file/tap.py @@ -72,7 +72,17 @@ class TapFile(Tap): ), ), th.Property( - "delimiter", + "additional_info", + th.BooleanType, + default=True, + description=( + "If `True`, each row in tap's output will have two additional columns: " + "`_sdc_file_name` and `_sdc_line_number`. If `False`, these columns " + "will not be present." + ), + ), + th.Property( + "delimited_delimiter", th.StringType, default="detect", description=( @@ -84,12 +94,38 @@ class TapFile(Tap): ), ), th.Property( - "quote_character", + "delimited_quote_character", th.StringType, default='"', description=( - "The character used to indicate when a record in a CSV contains a " - "delimiter character." + "The character used to indicate when a record in a delimited file " + "contains a delimiter character." + ), + ), + th.Property( + "delimited_header_skip", + th.IntegerType, + default=0, + description=( + "The number of initial rows to skip at the beginning of each delimited " + "file." + ), + ), + th.Property( + "delimited_footer_skip", + th.IntegerType, + default=0, + description=( + "The number of initial rows to skip at the end of each delimited file." + ), + ), + th.Property( + "delimited_override_headers", + th.ArrayType(th.StringType), + description=( + "An optional array of headers used to override the default column " + "name in delimited files, allowing for headerless files to be " + "correctly read." ), ), th.Property( @@ -107,16 +143,30 @@ class TapFile(Tap): th.Property( "jsonl_type_coercion_strategy", th.StringType, - allowed_values=["any", "string", "blob"], + allowed_values=["any", "string", "envelope"], default="any", description=( "The strategy determining how to construct the schema for JSONL files " "when the types represented are ambiguous. Must be one of `any`, " - "`string`, or `blob`. `any` will provide a generic schema for all " + "`string`, or `envelope`. `any` will provide a generic schema for all " "keys, allowing them to be any valid JSON type. `string` will require " "all keys to be strings and will convert other values accordingly. " - "`blob` will deliver each JSONL row as a JSON object with no internal " - "schema. Currently, only `any` and `string` are supported." + "`envelope` will deliver each JSONL row as a JSON object with no " + "internal schema." + ), + ), + th.Property( + "avro_type_coercion_strategy", + th.StringType, + allowed_values=["convert", "envelope"], + default="convert", + description=( + "The strategy determining how to construct the schema for Avro files " + "when conversion between schema types is ambiguous. Must be one of " + "`convert` or `envelope`. `convert` will attempt to convert from Avro " + "Schema to JSON Schema and will fail if a type can't be easily " + "coerced. `envelope` will wrap each record in an object without " + "providing an internal schema for the record." ), ), th.Property( @@ -178,12 +228,14 @@ def discover_streams(self) -> list[streams.FileStream]: if file_type == "jsonl": return [streams.JSONLStream(self, name=name)] if file_type == "avro": - msg = "avro has not yet been implemented." - raise NotImplementedError(msg) - if file_type in {"csv", "tsv"}: - msg = f"{file_type} is not a valid 'file_type'. Did you mean 'delimited'?" + return [streams.AvroStream(self, name=name)] + if file_type in {"csv", "tsv", "txt"}: + msg = f"'{file_type}' is not a valid file_type. Did you mean 'delimited'?" + raise ValueError(msg) + if file_type in {"json", "ndjson"}: + msg = f"'{file_type}' is not a valid file_type. Did you mean 'jsonl'?" raise ValueError(msg) - msg = f"{file_type} is not a valid 'file_type'." + msg = f"'{file_type}' is not a valid file_type." raise ValueError(msg) diff --git a/tests/data/athletes.avro b/tests/data/athletes.avro new file mode 100644 index 0000000..4885e5d Binary files /dev/null and b/tests/data/athletes.avro differ diff --git a/tests/data/cats.csv b/tests/data/cats.csv new file mode 100644 index 0000000..d3d0ae4 --- /dev/null +++ b/tests/data/cats.csv @@ -0,0 +1,10 @@ +Here are three +rows that +should be skipped +id,name,agility,size,description +1,House Cat,4,1,A common pet +2,Lion,2,4,King of the jungle +3,Tiger,3,3,Striped all over +Here are three +more rows that +should be skipped \ No newline at end of file diff --git a/tests/data/employees.jsonl b/tests/data/employees.jsonl new file mode 100644 index 0000000..4f8dc2a --- /dev/null +++ b/tests/data/employees.jsonl @@ -0,0 +1,100 @@ +{ "_id": "FOBEHC8ZL2O8JV67", "name": "Romaine Carman", "dob": "2016-12-02", "address": { "street": "2325 Alnwick", "town": "Markethill", "postode": "NE50 5ZQ" }, "telephone": "+964-2485-606-428", "pets": [ "Luna", "Duke" ], "score": 7.6, "email": "phillipnelson865@jan.lillehammer.no", "url": "http://represented.com", "description": "per tunisia username sections plastic", "verified": true, "salary": 23829 } +{ "_id": "XQN31K76TASJZS5T", "name": "Jacelyn Cassell", "dob": "2015-08-20", "address": { "street": "3995 Houseley Avenue", "town": "Bradley Stoke", "postode": "HX49 1UY" }, "telephone": "+20-4487-115-732", "pets": [ "bandit", "Nala" ], "score": 2.1, "email": "yahaira-apple2@gmail.com", "url": "http://revealed.bømlo.no", "description": "survival holders commander rabbit honor", "verified": true, "salary": 54273 } +{ "_id": "E8HPSLGIQ0BLFFK5", "name": "Epifania Hancock", "dob": "2018-10-05", "address": { "street": "3410 Caldbeck Lane", "town": "Fivemiletown", "postode": "S56 8LJ" }, "telephone": "+260-7632-416-923", "pets": [ "Marley", "Ruby" ], "score": 9.1, "email": "sherrie_oreilly8780@apartment.com", "url": "http://www.hammer.copenhagen.museum", "description": "terms submit tested designing oe", "verified": true, "salary": 40744 } +{ "_id": "VMBNDUGB5P12RHG8", "name": "Ruby Hurd", "dob": "2014-06-03", "address": { "street": "1453 Sandal", "town": "Netherfield", "postode": "RM7 3HP" }, "telephone": "+972-3991-075-906", "pets": [ "Boots", "Bear" ], "score": 1.6, "email": "analisa-edmondson48@fired.cherkassy.ua", "url": "http://www.lies.com", "description": "northwest stationery med selection leasing", "verified": false, "salary": 24515 } +{ "_id": "TH3GZ7GM5O6OXYQD", "name": "Jacinda Charlton", "dob": "2019-01-03", "address": { "street": "2769 Nately", "town": "Chipping Campden", "postode": "CA6 4MR" }, "telephone": "+216-2133-267-492", "pets": [ "Oscar", "Teddy" ], "score": 8.4, "email": "luciladion-fincher41@require.com", "url": "http://nissan.com", "description": "reception fox coordinates cant sims", "verified": true, "salary": 50494 } +{ "_id": "T62I3B6574YZ00OI", "name": "Marlene Raney", "dob": "2019-03-30", "address": { "street": "9152 Lakenheath", "town": "Brentwood", "postode": "LL98 1EG" }, "telephone": "+962-2331-431-154", "pets": [ "Sadie", "Max" ], "score": 1, "email": "siobhan-sharpe@pharmaceutical.com", "url": "https://boom.com", "description": "banners accounts temporary revealed rb", "verified": true, "salary": 57957 } +{ "_id": "RKQ9DGQXJUPBBJJJ", "name": "Jimmie Lentz", "dob": "2016-02-21", "address": { "street": "0895 Marsden Road", "town": "Dartmouth", "postode": "GU5 6IO" }, "telephone": "+974-5039-135-386", "pets": [ "Zoe", "Lucky" ], "score": 6.8, "email": "ashli_emmons3359@checks.com", "url": "http://lovers.com", "description": "stats attribute fellow approve ivory", "verified": true, "salary": 48128 } +{ "_id": "NLJYCU06X5FDTKD3", "name": "Frederica Prather", "dob": "2018-01-17", "address": { "street": "9549 Hallam Street", "town": "Killamarsh", "postode": "SA03 0HH" }, "telephone": "+60-0356-481-691", "pets": [ "Blackie", "Teddy" ], "score": 3.5, "email": "guillermodenning93725@projection.com", "url": "http://sin.com", "description": "elvis enhancements feb versions sharp", "verified": true, "salary": 57600 } +{ "_id": "7MJGIO6X0B3N53O2", "name": "Libby Tierney", "dob": "2014-02-20", "address": { "street": "4377 Spring Avenue", "town": "Cleckheaton", "postode": "NW78 4GL" }, "telephone": "+260-5551-454-951", "pets": [ "Peanut", "Cooper" ], "score": 4.1, "email": "josefina_bean6479@door.bi.it", "url": "https://www.habitat.money.museum", "description": "andy thereby facts seats tumor", "verified": false, "salary": 15754 } +{ "_id": "TL7UAVN6KZ94EAS8", "name": "Coretta Oakes", "dob": "2019-08-27", "address": { "street": "1833 Mooredge", "town": "Derby", "postode": "ST6 5XN" }, "telephone": "+241-8196-187-431", "pets": [ "Romeo", "Tucker" ], "score": 3.9, "email": "nicolagreenfield2@yahoo.com", "url": "http://distinct.com", "description": "fusion icq counting mitchell economics", "verified": false, "salary": 14756 } +{ "_id": "BDXAB8MI4GGQQEMM", "name": "Talisha Trice", "dob": "2014-03-26", "address": { "street": "0258 Consul Street", "town": "Benarty", "postode": "BR2 0EW" }, "telephone": "+57-2580-702-831", "pets": [ "Sasha", "Lexi" ], "score": 4.2, "email": "katharine5520@geological.com", "url": "https://clearing.com", "description": "actor ericsson marriott broadway customize", "verified": false, "salary": 68632 } +{ "_id": "5AMECQVQ4BESMR3C", "name": "Jacquie Bruno", "dob": "2014-12-04", "address": { "street": "9173 Arm Lane", "town": "Maud", "postode": "ML5 0JE" }, "telephone": "+27-2857-935-322", "pets": [ "Pepper", "Scout" ], "score": 4.3, "email": "mallie_ring4@nokia.com", "url": "https://www.km.com", "description": "proven ala witness lamp ii", "verified": false, "salary": 48384 } +{ "_id": "NSSH0XRO7RI0FAPG", "name": "Eun Cave", "dob": "2020-12-31", "address": { "street": "8975 Cottonwood Road", "town": "East Calder", "postode": "ML01 3AU" }, "telephone": "+595-4055-254-499", "pets": [ "Belle", "Stella" ], "score": 2.1, "email": "lasandra-sellers5964@hotmail.com", "url": "http://particles.com", "description": "sic infinite heritage athletes muslims", "verified": true, "salary": 68859 } +{ "_id": "ZMARX79Q9ATMV77J", "name": "Josephine Calhoun", "dob": "2014-04-24", "address": { "street": "8494 Linfield Street", "town": "Carrog", "postode": "SP4 7WY" }, "telephone": "+39-3892-174-969", "pets": [ "Jasper", "Henry" ], "score": 4.9, "email": "alvera7761@yahoo.com", "url": "https://www.hood.com", "description": "raises madonna years cornwall occur", "verified": true, "salary": 50546 } +{ "_id": "D6YY0IA0TKYGHOF5", "name": "Berenice Velasquez", "dob": "2021-06-03", "address": { "street": "5655 Villars", "town": "Lisburn", "postode": "AL92 2WN" }, "telephone": "+268-5282-114-714", "pets": [ "Scooter", "Duke" ], "score": 1, "email": "floydalves0@yahoo.com", "url": "http://www.custom.com", "description": "filtering circumstances featuring frontpage easy", "verified": true, "salary": 66818 } +{ "_id": "XVG4OKODX6P3RQM5", "name": "Tama Robles", "dob": "2016-02-26", "address": { "street": "0535 Empress Road", "town": "Eastleigh", "postode": "NG9 6JQ" }, "telephone": "+268-0039-288-103", "pets": [ "George", "Buddy" ], "score": 3.5, "email": "king662@gmail.com", "url": "https://www.healthy.com", "description": "stuffed representing netherlands pleasure athletic", "verified": true, "salary": 56676 } +{ "_id": "11QFIGKGFRIGL79Y", "name": "Latricia Conte", "dob": "2021-10-05", "address": { "street": "4057 Back Lane", "town": "Kettering", "postode": "N58 7OS" }, "telephone": "+44-4140-112-456", "pets": [ "Pepper", "Lucky" ], "score": 3.9, "email": "mignon353@recommends.com", "url": "http://sodium.com", "description": "variance walls cleared hosts islam", "verified": true, "salary": 12654 } +{ "_id": "RKIRT45SEK8FIOJA", "name": "Dewitt Coulter", "dob": "2021-08-24", "address": { "street": "3434 Astbury", "town": "Carlton Colville", "postode": "RH30 7OO" }, "telephone": "+689-5197-046-567", "pets": [ "Sweetie", "Max" ], "score": 6.5, "email": "alberto-aranda@yahoo.com", "url": "https://www.mysimon.com", "description": "capital compressed franchise faqs keyboards", "verified": true, "salary": 12549 } +{ "_id": "5TTIUFZO4OYNQ56F", "name": "Brandy Strong", "dob": "2016-10-26", "address": { "street": "8419 Spring Circle", "town": "Bishop's Stortford", "postode": "HD0 1IG" }, "telephone": "+98-7538-668-610", "pets": [ "MIMI", "Lexi" ], "score": 4.5, "email": "ema55810@silicon.com", "url": "https://societies.com", "description": "boats potter hamilton christine mali", "verified": true, "salary": 62143 } +{ "_id": "5LZYYOE4OVFH1E9R", "name": "Lenita Velez", "dob": "2020-10-13", "address": { "street": "3966 Brow Lane", "town": "Gorleston", "postode": "RM4 8KP" }, "telephone": "+679-6899-922-818", "pets": [ "SUGAR", "Dexter" ], "score": 8.1, "email": "eula9234@yahoo.com", "url": "https://www.balloon.com", "description": "tomatoes perspectives marks cds namely", "verified": true, "salary": 43034 } +{ "_id": "QJL86E6EFXTE5L61", "name": "Estefana Moll", "dob": "2018-05-31", "address": { "street": "4787 Dorchester Road", "town": "Daventry", "postode": "EH63 3CS" }, "telephone": "+255-3694-326-863", "pets": [ "Fiona", "Scout" ], "score": 8.6, "email": "maile_stock-sam9@hotmail.com", "url": "http://www.apple.com", "description": "temporary hiking maple symbol structured", "verified": false, "salary": 49769 } +{ "_id": "KINQTYJVF5CQ8E6Y", "name": "Terica Feeney", "dob": "2016-11-29", "address": { "street": "0879 Wilmot Street", "town": "Earl Shilton", "postode": "DH9 4HS" }, "telephone": "+350-0945-276-951", "pets": [ "Fiona", "Rosie" ], "score": 9.9, "email": "mario_cardwell14381@gmail.com", "url": "http://www.solutions.com", "description": "wondering charms formed guam temple", "verified": true, "salary": 21697 } +{ "_id": "8CDRJRON3NFGV0G5", "name": "Florencia Yoo", "dob": "2023-05-26", "address": { "street": "9101 Camp", "town": "Sawbridgeworth", "postode": "SL9 0UW" }, "telephone": "+32-0949-493-394", "pets": [ "Toby", "Charlie" ], "score": 3.4, "email": "gwenda-towns@hotmail.com", "url": "https://microphone.com", "description": "deviation feat rings demands initiated", "verified": true, "salary": 14543 } +{ "_id": "JGDXO1QXNTKAV82N", "name": "Tobi Abney", "dob": "2020-03-01", "address": { "street": "5771 Foscarn", "town": "Hyde", "postode": "HS0 7NU" }, "telephone": "+507-0188-669-459", "pets": [ "Baby", "Bear" ], "score": 3, "email": "haileylanier36990@muslim.com", "url": "https://www.incomplete.com", "description": "wrap dinner code durable traditional", "verified": true, "salary": 54564 } +{ "_id": "GK7LTHZMDMG0ZCXE", "name": "Princess Moyer", "dob": "2019-06-04", "address": { "street": "9451 Tabor Lane", "town": "Boston", "postode": "BS07 0KE" }, "telephone": "+354-0011-286-574", "pets": [ "George", "Murphy" ], "score": 5.1, "email": "timmy65624@yahoo.com", "url": "http://www.wing.com", "description": "via laura linux consultation nano", "verified": true, "salary": 40865 } +{ "_id": "G5PI276NQZD1P7D5", "name": "Salley Chester", "dob": "2015-11-22", "address": { "street": "4190 Eldermount Street", "town": "Whiston", "postode": "TS87 1AM" }, "telephone": "+66-1861-913-385", "pets": [ "Nala", "Nala" ], "score": 2.8, "email": "karissamull30712@hotmail.com", "url": "https://www.cork.com", "description": "ir nepal except officially sample", "verified": false, "salary": 19945 } +{ "_id": "UZKZND3RH5MIK5KF", "name": "Kayleen Lane", "dob": "2014-01-23", "address": { "street": "1700 Chester", "town": "Hanley Grange", "postode": "BL5 7UY" }, "telephone": "+593-6323-367-869", "pets": [ "Rocky", "Jax" ], "score": 2.1, "email": "linh-benner5@independence.berlin.museum", "url": "https://www.literature.froya.no", "description": "expired diane zoo thumbnails academic", "verified": true, "salary": 50451 } +{ "_id": "GJTU3UQNY0FALTD8", "name": "Dorthy Mcintosh", "dob": "2021-06-22", "address": { "street": "0801 Herbert Lane", "town": "Ashbourne", "postode": "DY5 9NE" }, "telephone": "+673-7360-683-953", "pets": [ "Shadow", "Harley" ], "score": 7.2, "email": "chelsey2@gmail.com", "url": "https://collapse.ud.it", "description": "namespace finish disco longitude maria", "verified": true, "salary": 27786 } +{ "_id": "00IZKJR3H0P335B2", "name": "Walker Arndt", "dob": "2021-07-31", "address": { "street": "0580 Wemyss Street", "town": "Newlyn", "postode": "TA08 2VN" }, "telephone": "+598-4141-426-515", "pets": [ "Simon", "Ruby" ], "score": 9.2, "email": "scott7707@preparing.obninsk.su", "url": "http://www.delivery.com", "description": "fill studying compared estonia utilities", "verified": true, "salary": 45932 } +{ "_id": "XXNX23QYH1JSNCK0", "name": "Jeffie Mortensen", "dob": "2022-09-28", "address": { "street": "9135 Brick Road", "town": "Holyhead", "postode": "LD54 1WV" }, "telephone": "+39-8347-175-085", "pets": [ "bandit", "Jake" ], "score": 4.5, "email": "tai-gay140@gmail.com", "url": "https://dsl.com", "description": "ice jean charm oclc information", "verified": true, "salary": 26610 } +{ "_id": "7TOVVJQ8HNV6ZX2Y", "name": "Joshua Alvarez", "dob": "2017-01-29", "address": { "street": "5814 Dencombe Circle", "town": "Omagh", "postode": "NE4 1TM" }, "telephone": "+39-6769-761-895", "pets": [ "Dusty", "Scout" ], "score": 4.8, "email": "daphine-chu@robot.com", "url": "http://podcasts.com", "description": "xanax recipients differ den trainers", "verified": true, "salary": 34383 } +{ "_id": "BU59LEXP81A5IQG4", "name": "Yulanda Finney", "dob": "2017-02-19", "address": { "street": "5498 Cranbrook Circle", "town": "Halewood", "postode": "SP36 1CO" }, "telephone": "+256-9462-611-943", "pets": [ "Charlie", "Sam" ], "score": 9.3, "email": "asley995@parameters.edu.vc", "url": "https://www.revenge.com", "description": "prostate secret dennis decline junior", "verified": true, "salary": 12694 } +{ "_id": "NQ4O5N1ZY5VE1PTS", "name": "Cordell Ruth", "dob": "2014-09-23", "address": { "street": "4723 Kemble Circle", "town": "Shildon", "postode": "ZE96 2ED" }, "telephone": "+502-0948-696-279", "pets": [ "Scooter", "Murphy" ], "score": 9.5, "email": "jacquelyne194@beads.com", "url": "https://www.name.2.bg", "description": "overhead dell periodically representatives enlarge", "verified": true, "salary": 48509 } +{ "_id": "O6O8VCLP9NMB14OD", "name": "Gianna Huang", "dob": "2017-04-27", "address": { "street": "5631 Flers Circle", "town": "Kearsley", "postode": "CW13 3RX" }, "telephone": "+502-7275-519-201", "pets": [ "Gizmo", "Riley" ], "score": 3.3, "email": "arnoldo.mcfall1@library.com", "url": "https://www.vegetable.com", "description": "jones entered war reproduce framed", "verified": false, "salary": 24173 } +{ "_id": "Y1EM1VQBMHGTX9FH", "name": "Kourtney Gonsalves", "dob": "2016-11-15", "address": { "street": "5310 Frieston Street", "town": "Rainham", "postode": "HU4 4MP" }, "telephone": "+972-4353-037-979", "pets": [ "Chloe", "Sam" ], "score": 4, "email": "bradford_rinehart4590@dictionaries.com", "url": "http://www.data.com", "description": "lc municipal wrist hydrocodone jefferson", "verified": true, "salary": 16022 } +{ "_id": "HRRR7MBDPK68F3V6", "name": "Sharen Cheng", "dob": "2015-03-15", "address": { "street": "8875 Watling", "town": "Holyhead", "postode": "BN84 9HM" }, "telephone": "+43-7967-872-839", "pets": [ "Lily", "Zeus" ], "score": 9.7, "email": "cherryl839@informal.com", "url": "http://nonprofit.mango", "description": "specialized mirror diane caring colleges", "verified": true, "salary": 25890 } +{ "_id": "3V9CH9YC27KSQHS2", "name": "Korey Urbina", "dob": "2022-01-28", "address": { "street": "5429 Delves", "town": "Gainsborough", "postode": "IV1 4RD" }, "telephone": "+968-9041-669-408", "pets": [ "Zoe", "Rocky" ], "score": 8.7, "email": "kandice-sanders0398@gmail.com", "url": "https://www.painted.ilawa.pl", "description": "carried monte stewart languages jeans", "verified": false, "salary": 66997 } +{ "_id": "F7LXSTLJJUBKFMQ7", "name": "Joelle Holloman", "dob": "2019-05-27", "address": { "street": "1666 Kellet", "town": "Bridge of Allan", "postode": "DH06 9QS" }, "telephone": "+508-6772-530-001", "pets": [ "Precious", "Oliver" ], "score": 1.7, "email": "rozella.rich038@patches.com", "url": "https://www.remind.com", "description": "macedonia apparatus rounds porcelain presentations", "verified": false, "salary": 27931 } +{ "_id": "GMJO0ZRJQPDKN2XQ", "name": "Daphine Adkins", "dob": "2018-01-03", "address": { "street": "3893 Hollywood Circle", "town": "Welwyn Garden City", "postode": "W0 7IV" }, "telephone": "+56-5798-821-542", "pets": [ "Felix", "Ginger" ], "score": 6.1, "email": "ignaciostamps8819@yahoo.com", "url": "https://factory.com", "description": "singapore ireland facilitate external bruce", "verified": false, "salary": 49411 } +{ "_id": "Q4YQC5R0D5ZVHHUO", "name": "Leonora Salcido", "dob": "2023-04-03", "address": { "street": "5237 Dougill Circle", "town": "Wick", "postode": "DD17 1OK" }, "telephone": "+66-7053-472-105", "pets": [ "Leo", "Harley" ], "score": 7.6, "email": "merlinclough@gmail.com", "url": "http://generator.toyooka.hyogo.jp", "description": "ecology src steve hungary classified", "verified": true, "salary": 34374 } +{ "_id": "41T22DMVPRCKOCL9", "name": "Nan Hedrick", "dob": "2018-06-16", "address": { "street": "4427 Woodseats", "town": "Bradninch", "postode": "OX6 3FA" }, "telephone": "+66-1128-487-902", "pets": [ "Precious", "Gus" ], "score": 3.1, "email": "modesta_chambliss@yahoo.com", "url": "https://www.beatles.com", "description": "cordless drive leather botswana presents", "verified": false, "salary": 10948 } +{ "_id": "V7BXULEU5QSUH5LJ", "name": "Ona Heffner", "dob": "2018-04-23", "address": { "street": "8426 Cakebread Circle", "town": "Goodwick", "postode": "HR38 1XC" }, "telephone": "+506-8785-366-931", "pets": [ "Jake", "Tucker" ], "score": 8.1, "email": "wesley_beck22422@decorating.com", "url": "https://thoughts.com", "description": "payroll every hans ribbon everybody", "verified": true, "salary": 66084 } +{ "_id": "XRYZ6GKBQSFY4IMJ", "name": "Libbie Muhammad", "dob": "2020-01-28", "address": { "street": "4806 Stancross Lane", "town": "Paddock Wood", "postode": "TA8 9BX" }, "telephone": "+36-3671-280-679", "pets": [ "Lilly", "Stella" ], "score": 6.5, "email": "rosann-eldridge@investing.com", "url": "http://ashley.com", "description": "vulnerable tamil ringtones vip dealing", "verified": true, "salary": 14956 } +{ "_id": "Q2CYFVCASH5EKHMV", "name": "Ashley Nelson", "dob": "2020-01-27", "address": { "street": "7151 Bamburgh", "town": "Winterton", "postode": "CB18 5XV" }, "telephone": "+60-3111-152-628", "pets": [ "Chester", "Scout" ], "score": 5.4, "email": "evalynclancy1940@hotmail.com", "url": "http://www.send.com", "description": "aka counsel bottom celebrate concerning", "verified": true, "salary": 41390 } +{ "_id": "8XOI3O9MKSIXR9EY", "name": "Reena Barringer", "dob": "2020-01-18", "address": { "street": "9859 Eastbank Street", "town": "Carnoustie", "postode": "HR0 0DX" }, "telephone": "+965-3734-750-937", "pets": [ "Kitty", "Lucky" ], "score": 1.2, "email": "candace_joy02@gmail.com", "url": "https://powerseller.com", "description": "item toshiba flower knife banners", "verified": true, "salary": 20734 } +{ "_id": "VL6Q2C37V5CQ1BNL", "name": "Matilda Word", "dob": "2017-01-23", "address": { "street": "8630 Reynell Circle", "town": "Bishop's Castle", "postode": "ST0 8OL" }, "telephone": "+503-8764-562-934", "pets": [ "Precious", "Cody" ], "score": 5, "email": "nestorhowe5@hotmail.com", "url": "https://www.vocational.com", "description": "ball came available tulsa kong", "verified": true, "salary": 54129 } +{ "_id": "O882UF9BTNHODJO6", "name": "Lavonna Rush", "dob": "2019-12-18", "address": { "street": "6432 Glamis Road", "town": "Madeley", "postode": "GL9 5WD" }, "telephone": "+508-0962-122-803", "pets": [ "Peaches", "Nala" ], "score": 4.8, "email": "beverlee.janes2@accept.com", "url": "https://www.cubic.com", "description": "matt infringement females trackback brilliant", "verified": true, "salary": 61184 } +{ "_id": "74A37IPUXZYU9NOX", "name": "Brain Chaffin", "dob": "2019-04-11", "address": { "street": "6395 Branksome Lane", "town": "Rothbury", "postode": "TR28 5TB" }, "telephone": "+20-2569-211-252", "pets": [ "Lilly", "Ellie" ], "score": 6, "email": "glennie-kearney@yahoo.com", "url": "http://jessica.yugawa.fukushima.jp", "description": "pot seemed teaching japanese word", "verified": true, "salary": 66218 } +{ "_id": "QVRLY4BQQKKNMOCQ", "name": "Aracely Gillespie", "dob": "2021-07-01", "address": { "street": "8975 Lesser", "town": "Holsworthy", "postode": "WD89 8KV" }, "telephone": "+965-1970-796-604", "pets": [ "cupcake", "Mia" ], "score": 9.9, "email": "ahmedgill@preventing.com", "url": "https://shorts.com", "description": "behaviour education sonic bringing subsection", "verified": true, "salary": 53874 } +{ "_id": "V1ZDMQ4VTMJ5PSVV", "name": "Adaline Truitt", "dob": "2014-04-10", "address": { "street": "0378 Marland Avenue", "town": "Lanark", "postode": "SM54 3MO" }, "telephone": "+90-6966-498-731", "pets": [ "Lucy", "Harley" ], "score": 7.7, "email": "gilbert_amundson4781@cost.com", "url": "http://www.birmingham.com", "description": "baseline acceptable working curve mexican", "verified": true, "salary": 23615 } +{ "_id": "LL1U91CO5M3RPB2C", "name": "Stephaine Tidwell", "dob": "2019-08-05", "address": { "street": "9866 Gamble Street", "town": "Donaghadee", "postode": "TQ8 7UC" }, "telephone": "+27-7185-526-067", "pets": [ "Patches", "Murphy" ], "score": 3.1, "email": "jalisa_hickey2071@institute.com", "url": "https://www.pike.com", "description": "check wins paths verse sudan", "verified": true, "salary": 47237 } +{ "_id": "Q2QHMYZARFYE379F", "name": "Stephania Copeland", "dob": "2020-04-05", "address": { "street": "5999 Lemnos Circle", "town": "Stanley", "postode": "KY1 0XY" }, "telephone": "+37-5775-713-807", "pets": [ "boo", "Emma" ], "score": 9.4, "email": "valerie-bunting@supreme.com", "url": "http://www.citizenship.com", "description": "inflation college mw gordon vp", "verified": true, "salary": 12850 } +{ "_id": "PC4IMIGFMUKCFCTA", "name": "Daphne Fielder", "dob": "2015-11-14", "address": { "street": "6446 Hurst Street", "town": "Evesham", "postode": "B1 9OJ" }, "telephone": "+595-8918-844-874", "pets": [ "Lily", "Buddy" ], "score": 5.5, "email": "ardeliabowser4212@rough.com", "url": "http://integrity.odo.br", "description": "cabinets height software wrote roll", "verified": true, "salary": 61523 } +{ "_id": "QCR83CPSNP991ZVK", "name": "Cecille Almeida", "dob": "2020-11-07", "address": { "street": "6391 Woodroyd Street", "town": "Billingham", "postode": "RG7 4FY" }, "telephone": "+503-3105-170-471", "pets": [ "BatMan", "Jax" ], "score": 2.2, "email": "henrietta375@testament.com", "url": "https://investigator.com", "description": "babe nothing lucy vegetable directories", "verified": true, "salary": 36549 } +{ "_id": "OIOUNP4M3RXT8PGA", "name": "Creola Vickery", "dob": "2017-06-12", "address": { "street": "2530 Painswick Avenue", "town": "Glanamman", "postode": "UB39 8CJ" }, "telephone": "+357-6508-089-188", "pets": [ "Buddy", "Henry" ], "score": 8.2, "email": "sharanfallon1@phrases.my", "url": "http://www.volt.com", "description": "org automatically contributing parents cure", "verified": true, "salary": 15188 } +{ "_id": "FSUV7XDK0936XIGT", "name": "Yulanda Moreno", "dob": "2021-05-14", "address": { "street": "1115 Wall Road", "town": "Ilkley", "postode": "RG0 0WR" }, "telephone": "+503-0487-308-395", "pets": [ "Sammy", "Rosie" ], "score": 3.3, "email": "kathy.ratcliff@hotmail.com", "url": "http://www.promising.zhytomyr.ua", "description": "polls imagine wagner midnight thousand", "verified": false, "salary": 52026 } +{ "_id": "KB1B0NSNS9525ABG", "name": "Noble Vest", "dob": "2015-09-28", "address": { "street": "3111 Bryn Street", "town": "Stamford", "postode": "EN2 9EZ" }, "telephone": "+234-7725-616-792", "pets": [ "sox", "Jack" ], "score": 6.7, "email": "kathlinedawson@yahoo.com", "url": "https://www.complexity.com", "description": "lounge opt cited terror insertion", "verified": false, "salary": 57583 } +{ "_id": "G068CATMMU7EAJ4M", "name": "Duane Thurman", "dob": "2015-08-16", "address": { "street": "4424 Minshull Avenue", "town": "Kelloholm", "postode": "AL21 5VY" }, "telephone": "+264-6491-949-195", "pets": [ "Fluffy", "Mia" ], "score": 6.2, "email": "chanelle0@groove.com", "url": "http://cars.com", "description": "utility portions edges science feedback", "verified": true, "salary": 17212 } +{ "_id": "T7E81NEXFYAS5UXQ", "name": "Alayna Garber", "dob": "2020-05-06", "address": { "street": "5700 Tilley", "town": "Brynmawr", "postode": "WV92 0TU" }, "telephone": "+671-0433-475-483", "pets": [ "Murphy", "Duke" ], "score": 7.8, "email": "londaingram558@yahoo.com", "url": "http://clinical.com", "description": "spending mask sponsored fiscal southampton", "verified": true, "salary": 37846 } +{ "_id": "9M8SFXQN681CUPLJ", "name": "Benton Edmondson", "dob": "2014-07-26", "address": { "street": "0886 Senna", "town": "Staveley", "postode": "SK5 1JF" }, "telephone": "+687-2860-865-309", "pets": [ "Luna", "Dexter" ], "score": 7.1, "email": "etha.pearson3580@yahoo.com", "url": "http://suzuki.com", "description": "actively ra gi bs registry", "verified": false, "salary": 34358 } +{ "_id": "8311NQ52POFSJV7E", "name": "Cathey Babcock", "dob": "2022-05-08", "address": { "street": "7789 Bridge Lane", "town": "Horsforth", "postode": "NP0 8VB" }, "telephone": "+965-3691-201-143", "pets": [ "Jasmine", "Milo" ], "score": 8.1, "email": "raul_dawkins9@gmail.com", "url": "https://mo.com", "description": "carefully belize protest lopez flight", "verified": true, "salary": 13227 } +{ "_id": "KBA6RGKC9S1SUN0U", "name": "Dedra Molina", "dob": "2019-10-14", "address": { "street": "3412 Fairless Circle", "town": "Haverhill", "postode": "LS7 9HE" }, "telephone": "+46-3372-238-868", "pets": [ "Scooter", "Jax" ], "score": 6.3, "email": "milton-bunn3797@gmail.com", "url": "https://www.http.cityeats", "description": "memorabilia adsl paraguay strongly mathematical", "verified": true, "salary": 51151 } +{ "_id": "QO5D8ZGGLQKH9EQL", "name": "Cammy Mondragon", "dob": "2015-02-19", "address": { "street": "1199 Marsh Street", "town": "Didcot", "postode": "BR64 9WN" }, "telephone": "+670-7943-403-201", "pets": [ "Rocky", "Scout" ], "score": 1.9, "email": "michikosena@hotmail.com", "url": "https://www.reduces.toyama.toyama.jp", "description": "tag manage fonts consultants rip", "verified": true, "salary": 17604 } +{ "_id": "P62U5K13ELK6FMT0", "name": "Roxanna Connor", "dob": "2018-11-05", "address": { "street": "9299 Buckden", "town": "Chertsey", "postode": "KW3 8YL" }, "telephone": "+599-0138-831-758", "pets": [ "Scooter", "Oliver" ], "score": 7.1, "email": "natisha177@discipline.com", "url": "https://www.believe.com", "description": "geology modem techniques airlines release", "verified": true, "salary": 39898 } +{ "_id": "YSGIM2QJQR95T20I", "name": "Manda Sample", "dob": "2021-12-09", "address": { "street": "5946 John Lane", "town": "Biggleswade", "postode": "DG44 0NZ" }, "telephone": "+503-5955-796-772", "pets": [ "Fluffy", "Rocky" ], "score": 4.5, "email": "cheree2@publication.fetsund.no", "url": "http://mc.com", "description": "brooklyn kings og brave faq", "verified": true, "salary": 17537 } +{ "_id": "0RX5O4FA7BLVGL5K", "name": "Magaret Strunk", "dob": "2021-11-21", "address": { "street": "0670 Sale Avenue", "town": "Tring", "postode": "HP1 3YD" }, "telephone": "+20-4138-530-743", "pets": [ "Toby", "Milo" ], "score": 4, "email": "crystle.kiser36687@grades.com", "url": "http://www.boundary.com", "description": "principal witnesses sbjct motorcycles matters", "verified": true, "salary": 63924 } +{ "_id": "MDTGF6BJKBI5H6QQ", "name": "Neoma Hargis", "dob": "2019-12-26", "address": { "street": "4843 Thornby Road", "town": "Haslemere", "postode": "WS10 8UF" }, "telephone": "+92-1762-320-990", "pets": [ "Marley", "Scout" ], "score": 3.5, "email": "lucie25@weight.com", "url": "http://www.motel.vikna.no", "description": "herbal egg bed protocol injured", "verified": true, "salary": 53557 } +{ "_id": "65PXB56NB6YY4QCA", "name": "Aleta Groves", "dob": "2017-06-07", "address": { "street": "2861 Haven", "town": "Carlisle", "postode": "AB8 8JS" }, "telephone": "+251-2144-394-653", "pets": [ "Lucky", "Emma" ], "score": 3.1, "email": "conchita_carrillo@gmail.com", "url": "http://accessed.com", "description": "wolf champion maritime collectibles subjects", "verified": true, "salary": 62310 } +{ "_id": "YXANQEK4RRNSZF6B", "name": "Donnette Gaddis", "dob": "2019-11-15", "address": { "street": "7470 Dagenham Circle", "town": "Uxbridge", "postode": "CW31 6OY" }, "telephone": "+684-8261-982-235", "pets": [ "Sammy", "Milo" ], "score": 4.9, "email": "weston.chavarria3@gmail.com", "url": "https://www.lesbians.com", "description": "titanium danger sip seat rl", "verified": true, "salary": 66027 } +{ "_id": "GC9V0QE943EKQFRD", "name": "Dennis Ogle", "dob": "2017-11-30", "address": { "street": "1362 Owley", "town": "East Ham", "postode": "TQ83 7EI" }, "telephone": "+501-9667-575-954", "pets": [ "Chloe", "Gus" ], "score": 3.1, "email": "georgiana-vail05313@specifies.com", "url": "http://www.helps.com", "description": "handle pan leaves substance js", "verified": false, "salary": 28090 } +{ "_id": "X9RXZCHI5305LR99", "name": "Laraine Zook", "dob": "2022-03-10", "address": { "street": "6691 Haywood", "town": "Rosyth", "postode": "SM7 9BF" }, "telephone": "+55-0172-054-778", "pets": [ "Milo", "Cooper" ], "score": 2.6, "email": "jenifer_maes9@elimination.com", "url": "http://democrat.com", "description": "locking routines wt total smell", "verified": true, "salary": 65261 } +{ "_id": "3EZTB3B9TT4HTH1Z", "name": "Laurine Mendes", "dob": "2014-06-23", "address": { "street": "9749 Mottram Circle", "town": "Shipston on Stour", "postode": "MK4 1EG" }, "telephone": "+507-8371-387-381", "pets": [ "Toby", "Milo" ], "score": 9.5, "email": "karljacobs6836@timing.com", "url": "http://www.tribunal.com", "description": "rico w manufactured engaging universal", "verified": true, "salary": 14118 } +{ "_id": "13ZUB9BH2ZMMIIMS", "name": "Vicente Moss-Cramer", "dob": "2016-08-30", "address": { "street": "5825 Jauncey Circle", "town": "Doncaster", "postode": "PE54 6EC" }, "telephone": "+968-9334-419-869", "pets": [ "Sophie", "Jake" ], "score": 2.6, "email": "dacia_slater@collapse.today", "url": "https://fears.com", "description": "reducing array obituaries premises entity", "verified": true, "salary": 44550 } +{ "_id": "3SX3MFIZU75QBOCD", "name": "Dong Lundy", "dob": "2022-05-26", "address": { "street": "7892 Wade Circle", "town": "St Ives", "postode": "SL35 9UL" }, "telephone": "+501-1352-923-488", "pets": [ "Maggie", "Roxy" ], "score": 9.1, "email": "piedad-casas@disturbed.com", "url": "http://www.recipe.health.nz", "description": "op tracking cj displaying scholars", "verified": false, "salary": 27034 } +{ "_id": "CX6RSNDQC4IX8ENG", "name": "Angella Glass", "dob": "2020-08-16", "address": { "street": "8579 Denis Circle", "town": "Wirksworth", "postode": "CB51 4UM" }, "telephone": "+358-2816-535-245", "pets": [ "Gizmo", "Leo" ], "score": 2.2, "email": "augustina85598@defense.com", "url": "http://www.delicious.com", "description": "browsers baseball impact solely stones", "verified": true, "salary": 41420 } +{ "_id": "BJ4H32KEEBVH322P", "name": "Nisha Mcfall", "dob": "2017-01-25", "address": { "street": "2983 Glencoyne Lane", "town": "Bexhill on Sea", "postode": "B58 7DU" }, "telephone": "+41-9793-205-724", "pets": [ "Oscar", "Milo" ], "score": 6.3, "email": "eli99971@hotmail.com", "url": "https://www.approx.com", "description": "doctors depot dealtime psp hitting", "verified": true, "salary": 66446 } +{ "_id": "BBGQV52D5AUAYXQI", "name": "Candance Scanlon", "dob": "2020-09-10", "address": { "street": "9563 Bartlemore Street", "town": "Derby", "postode": "DD3 3PF" }, "telephone": "+973-4021-252-925", "pets": [ "Phoebe", "Max" ], "score": 4.3, "email": "margarete_lafleur15@accommodations.com", "url": "https://www.wishing.com", "description": "wage alignment about telescope republicans", "verified": false, "salary": 20825 } +{ "_id": "EO9ZZ5DHJ3R0G7ZD", "name": "Hester Rector", "dob": "2022-04-28", "address": { "street": "2858 Cote Circle", "town": "Tow Law", "postode": "TW9 1AI" }, "telephone": "+251-6539-533-585", "pets": [ "George", "Henry" ], "score": 2.9, "email": "antonietta-buffington37@partner.historichouses.museum", "url": "http://pediatric.com", "description": "teach varying legislature establishing no", "verified": true, "salary": 14279 } +{ "_id": "E1QTF5FKBM6X2L4E", "name": "Yolando Archibald", "dob": "2016-02-09", "address": { "street": "1707 Stonepail Road", "town": "Scunthorpe", "postode": "UB54 9AE" }, "telephone": "+41-5763-502-999", "pets": [ "MIMI", "Gus" ], "score": 9.7, "email": "selina-concepcion6657@gmail.com", "url": "https://turner.com", "description": "islam girls handbags districts serious", "verified": true, "salary": 19483 } +{ "_id": "3FRO9M7UF97HLYS0", "name": "Daina Perreault", "dob": "2017-04-02", "address": { "street": "5584 Stringer", "town": "Chichester", "postode": "M9 2WB" }, "telephone": "+509-6574-765-363", "pets": [ "Sadie", "Roxy" ], "score": 1.7, "email": "kylie68541@authors.com", "url": "https://party.com", "description": "end upset depending beliefs wrap", "verified": true, "salary": 29947 } +{ "_id": "I7ATJ4BE5SGG9CRG", "name": "Wilford Yancey", "dob": "2023-06-08", "address": { "street": "5863 Half Street", "town": "Birnam", "postode": "WC90 7NY" }, "telephone": "+353-3635-945-399", "pets": [ "Charlie", "Lilly" ], "score": 1.1, "email": "thomasine_mccarter42@cdt.herøy.møre-og-romsdal.no", "url": "https://periods.com", "description": "char ntsc strap counsel incident", "verified": true, "salary": 69098 } +{ "_id": "X8EYB4S013QLRPJ7", "name": "Theo Reich", "dob": "2020-06-08", "address": { "street": "7217 Fitzhugh Street", "town": "Stretford", "postode": "HS8 4MB" }, "telephone": "+268-1483-860-721", "pets": [ "Fiona", "Harley" ], "score": 6.7, "email": "bessie-burleson52582@hotmail.com", "url": "http://www.desert.com", "description": "membership wheel fruits loop had", "verified": true, "salary": 58050 } +{ "_id": "CL3358RXSRLO44AN", "name": "Zella Deluca", "dob": "2015-06-24", "address": { "street": "9506 Tottington Avenue", "town": "Barnstaple", "postode": "LL6 0HU" }, "telephone": "+263-8465-642-452", "pets": [ "BatMan", "Stella" ], "score": 1.9, "email": "misha64371@russell.com", "url": "http://vegetation.com", "description": "compilation atmospheric prescribed kde glass", "verified": false, "salary": 40821 } +{ "_id": "XUMOI6NLJZSB9BLK", "name": "Branda Novak", "dob": "2021-01-17", "address": { "street": "2620 Leycett Street", "town": "Cupar", "postode": "ZE94 2WT" }, "telephone": "+31-7905-823-325", "pets": [ "BatMan", "Lucky" ], "score": 4.4, "email": "olympia_angel690@hotmail.com", "url": "http://luggage.com", "description": "healthcare armstrong outreach milwaukee dx", "verified": true, "salary": 10422 } +{ "_id": "HQ1FYFFHYR9MJMQ3", "name": "Majorie Fortney-Cheney", "dob": "2022-04-29", "address": { "street": "6521 Russel", "town": "Tunbridge Wells", "postode": "HS25 1MI" }, "telephone": "+37-6741-146-828", "pets": [ "Tigger", "Marley" ], "score": 7.9, "email": "earlene73288@yahoo.com", "url": "http://www.acid.com", "description": "continuity mathematics colorado jail web", "verified": true, "salary": 66456 } +{ "_id": "UFK88AU0UXA913BZ", "name": "Hae Royal", "dob": "2020-05-23", "address": { "street": "7219 MMU Street", "town": "Otley", "postode": "PA3 0KW" }, "telephone": "+687-8548-956-921", "pets": [ "Izzy", "Bailey" ], "score": 5.9, "email": "jeanett-heffner07874@hotmail.com", "url": "http://www.affiliate.com", "description": "hierarchy oct scripts impressed typically", "verified": true, "salary": 31420 } +{ "_id": "6N6EQV5JRQEVHUTV", "name": "Isreal Beatty", "dob": "2015-06-07", "address": { "street": "4128 Massey", "town": "Earley", "postode": "IP3 9JU" }, "telephone": "+263-1074-543-935", "pets": [ "Tiger", "Apollo" ], "score": 8.9, "email": "vihedrick@letters.ina.saitama.jp", "url": "http://situated.com", "description": "findings advocate gc providers networking", "verified": true, "salary": 69211 } +{ "_id": "MLYI97CKBG6JPZXA", "name": "Laci Barksdale", "dob": "2022-06-13", "address": { "street": "8446 Halston Road", "town": "Newtown St Boswells", "postode": "KA8 6KV" }, "telephone": "+501-5307-271-175", "pets": [ "Sophie", "Sam" ], "score": 8, "email": "rubi-montenegro167@jp.com", "url": "http://www.reactions.com", "description": "thank pads additions philip thee", "verified": true, "salary": 21200 } +{ "_id": "GHL5Q201AVFKZ1B7", "name": "Lonna Stockton", "dob": "2017-09-18", "address": { "street": "0781 Carpenters Street", "town": "Newhaven", "postode": "GU34 8UV" }, "telephone": "+967-7755-136-259", "pets": [ "Gracie", "Cody" ], "score": 6.2, "email": "sonia-durant5234@gmail.com", "url": "http://pepper.com", "description": "nov je semi chad organized", "verified": true, "salary": 46566 } +{ "_id": "VBJRTR1Y2BN2XG6E", "name": "Galina Russo", "dob": "2017-07-05", "address": { "street": "7690 Badger Circle", "town": "Lyme Regis", "postode": "HP89 4LM" }, "telephone": "+47-9234-238-223", "pets": [ "Kitty", "Mia" ], "score": 2, "email": "hortense-schulze4@hotmail.com", "url": "https://www.non.com", "description": "cause chicks glad sunglasses extraction", "verified": true, "salary": 68844 } +{ "_id": "PC6B8IHY5SKM8LDY", "name": "Lakeesha Denson", "dob": "2021-09-14", "address": { "street": "9126 Back", "town": "Petersfield", "postode": "HA4 8IL" }, "telephone": "+51-6707-809-809", "pets": [ "Missy", "Bentley" ], "score": 1, "email": "maryam07128@hotmail.com", "url": "http://chance.smile", "description": "workstation india qualification royal productivity", "verified": true, "salary": 15256 } +{ "_id": "9SSTEATRFDYPP353", "name": "Roslyn Worthington", "dob": "2023-06-18", "address": { "street": "3429 Freshfield Road", "town": "Hednesford", "postode": "BH29 1EC" }, "telephone": "+57-5482-992-507", "pets": [ "Phoebe", "Jack" ], "score": 4.8, "email": "trudy34@yahoo.com", "url": "http://www.starts.com", "description": "influences comfort villages desert pricing", "verified": true, "salary": 60420 } +{ "_id": "TQUIJH7AIYLY8Q5J", "name": "Joana Dowd", "dob": "2015-10-06", "address": { "street": "3319 Ohio Circle", "town": "Egham", "postode": "IV0 8EJ" }, "telephone": "+679-3870-864-668", "pets": [ "Oscar", "Ginger" ], "score": 5.7, "email": "antonetta_voigt@yahoo.com", "url": "https://telecharger.com", "description": "sq shape supplemental airport logistics", "verified": true, "salary": 33798 } +{ "_id": "8XPIU25QT8F5P1YV", "name": "Milford Robson", "dob": "2019-10-03", "address": { "street": "0227 Joiner", "town": "Stockport", "postode": "CM75 2KB" }, "telephone": "+689-0073-488-183", "pets": [ "Precious", "Sam" ], "score": 5.4, "email": "tonja3505@wrestling.trentinsuedtirol.it", "url": "https://www.communications.barrel-of-knowledge.info", "description": "handheld karaoke iran someone quarterly", "verified": false, "salary": 26373 } +{ "_id": "26L0ZCVKTBXQTJ5Z", "name": "Augustus Fitzsimmons", "dob": "2023-03-20", "address": { "street": "4669 Jauncey Road", "town": "Shepton Mallet", "postode": "PL7 7DC" }, "telephone": "+231-7384-032-429", "pets": [ "Precious", "Lilly" ], "score": 2.1, "email": "kristal.coley@yahoo.com", "url": "http://www.reliable.microlight.aero", "description": "headed jessica tracking biggest realtor", "verified": true, "salary": 60290 } +{ "_id": "QAGMZSQ1ZEPK2138", "name": "Susannah Dobson", "dob": "2016-03-18", "address": { "street": "8348 Willowdale Road", "town": "Carrog", "postode": "HD8 7OI" }, "telephone": "+41-7611-523-131", "pets": [ "Murphy", "Leo" ], "score": 6, "email": "yolandowaters015@always.com", "url": "https://www.familiar.katashina.gunma.jp", "description": "brake geneva conservative economics geography", "verified": true, "salary": 50066 } +{ "_id": "XU8YPAJQXEO53U5U", "name": "Latarsha Mcpherson", "dob": "2019-12-17", "address": { "street": "6660 Mafeking Road", "town": "Stotfold", "postode": "SS33 4EF" }, "telephone": "+94-0203-467-834", "pets": [ "Dusty", "Tucker" ], "score": 1.7, "email": "vicky.burke3@yahoo.com", "url": "http://william.health.nz", "description": "ability chrome hygiene spa saturn", "verified": true, "salary": 21243 } +{ "_id": "AVLCMOPQEQ4PSBM0", "name": "Han Yeager", "dob": "2017-03-02", "address": { "street": "9794 Laurel Lane", "town": "Crawley", "postode": "KT65 0IA" }, "telephone": "+886-4300-653-644", "pets": [ "Muffin", "Henry" ], "score": 2.1, "email": "verda_browne72@yukon.com", "url": "https://restriction.beskidy.pl", "description": "supposed discussing threads neighbors journey", "verified": false, "salary": 37022 } +{ "_id": "FRRME38L2LE75UYP", "name": "Carleen Hewitt", "dob": "2017-02-02", "address": { "street": "0791 St", "town": "Sheringham", "postode": "DN0 9AC" }, "telephone": "+254-9286-013-016", "pets": [ "Tigger", "Zeus" ], "score": 9.7, "email": "darlene.earl2@gmail.com", "url": "https://www.melissa.nikaho.akita.jp", "description": "dairy parameters creek predict automatic", "verified": true, "salary": 37239 } +{ "_id": "GXTLKUZ38EY7F4GQ", "name": "Jeff Mccullough", "dob": "2018-08-15", "address": { "street": "2686 Stonehead Road", "town": "Castlederg", "postode": "ML31 7NU" }, "telephone": "+66-8821-226-479", "pets": [ "George", "Cooper" ], "score": 9.4, "email": "gala_jaramillo3@yahoo.com", "url": "https://www.reveal.gildeskål.no", "description": "coaching incentive dragon wishing fireplace", "verified": true, "salary": 56157 } \ No newline at end of file diff --git a/tests/data/fruit_records.csv b/tests/data/fruit_records.csv new file mode 100644 index 0000000..bf5fd1c --- /dev/null +++ b/tests/data/fruit_records.csv @@ -0,0 +1,1001 @@ +id,name,quantity,price_per_unit,total_price,supplier_name,expiration_date,organic,country_of_origin +1,pineapple,67,1.84,123.28,Homespun Pastures,10/29/2022,false,Panama +2,grape,49,6.46,316.54,Homespun Pastures,7/7/2022,false,China +3,orange,91,6.91,628.81,Green Grocers,11/13/2022,false,Australia +4,apple,43,2.1,90.3,Fresh Fruits Inc.,2/23/2022,false,Indonesia +5,grape,10,2.91,29.1,Green Grocers,7/17/2022,true,Sweden +6,pineapple,61,3.9,237.9,Fresh Fruits Inc.,1/11/2022,false,China +7,banana,19,9.85,187.15,Green Grocers,12/15/2022,true,Peru +8,banana,70,8.94,625.8,Homespun Pastures,7/8/2022,false,China +9,grapefruit,5,3.75,18.75,Fresh Fruits Inc.,1/23/2022,false,Indonesia +10,apricot,49,5.52,270.48,Homespun Pastures,2/26/2022,true,China +11,banana,55,6.94,381.7,Homespun Pastures,3/21/2022,false,Philippines +12,strawberry,97,2.37,229.89,Green Grocers,3/25/2022,false,Canada +13,strawberry,24,2.2,52.8,Homespun Pastures,9/24/2022,true,Brazil +14,grapefruit,29,0.97,28.13,Green Grocers,2/27/2022,true,Haiti +15,apple,24,2.79,66.96,Green Grocers,9/9/2022,false,Greece +16,banana,53,5.68,301.04,Fresh Fruits Inc.,11/20/2022,true,Russia +17,banana,77,9.87,759.99,Homespun Pastures,12/11/2022,true,China +18,grapefruit,68,1.0,68.0,Fresh Fruits Inc.,12/19/2022,false,Croatia +19,orange,10,7.0,70.0,Fresh Fruits Inc.,10/31/2022,false,Argentina +20,grape,39,4.95,193.05,Green Grocers,4/22/2022,true,Portugal +21,apricot,60,3.47,208.2,Fresh Fruits Inc.,7/14/2022,false,Laos +22,grape,9,6.99,153.78,Homespun Pastures,8/17/2022,false,Portugal +23,grape,36,8.61,309.96,Green Grocers,5/25/2022,true,United States +24,mango,67,2.98,199.66,Green Grocers,7/30/2022,false,Iran +25,grapefruit,49,6.11,299.39,Fresh Fruits Inc.,5/19/2022,true,China +26,mango,45,9.66,434.7,Green Grocers,4/25/2022,false,New Zealand +27,pineapple,96,9.19,882.24,Fresh Fruits Inc.,8/8/2022,false,Poland +28,banana,1,1.12,1.12,Homespun Pastures,8/21/2022,true,Saudi Arabia +29,orange,66,5.46,360.36,Green Grocers,6/25/2022,false,France +30,banana,32,9.03,288.96,Fresh Fruits Inc.,9/29/2022,false,Indonesia +31,banana,67,3.85,257.95,Green Grocers,6/7/2022,false,Sweden +32,mango,21,2.02,42.42,Fresh Fruits Inc.,10/14/2022,false,Japan +33,strawberry,37,6.44,238.28,Green Grocers,7/25/2022,false,Spain +34,grapefruit,55,7.97,438.35,Green Grocers,2/2/2022,false,China +35,banana,71,1.19,84.49,Fresh Fruits Inc.,12/2/2022,false,Russia +36,orange,92,8.69,799.48,Homespun Pastures,9/10/2022,true,Russia +37,apple,60,6.84,410.4,Green Grocers,1/24/2022,false,Spain +38,strawberry,47,1.46,68.62,Fresh Fruits Inc.,4/25/2022,true,Brazil +39,apple,18,8.96,161.28,Green Grocers,3/9/2022,false,Japan +40,grape,5,1.89,9.45,Fresh Fruits Inc.,9/17/2022,false,Iran +41,mango,36,4.52,162.72,Homespun Pastures,1/15/2022,false,Haiti +42,pineapple,88,9.14,804.32,Fresh Fruits Inc.,12/23/2022,true,Sweden +43,pineapple,69,4.97,342.93,Homespun Pastures,7/27/2022,false,Bulgaria +44,grapefruit,20,9.61,192.2,Green Grocers,11/18/2022,false,Sierra Leone +45,grapefruit,36,1.42,51.12,Fresh Fruits Inc.,11/2/2022,true,China +46,mango,44,7.09,311.96,Green Grocers,5/17/2022,true,Sweden +47,apricot,77,9.39,723.03,Fresh Fruits Inc.,10/17/2022,false,Philippines +48,mango,48,5.11,245.28,Fresh Fruits Inc.,5/19/2022,true,Brazil +49,strawberry,97,6.11,592.67,Fresh Fruits Inc.,7/19/2022,true,China +50,strawberry,63,7.69,484.47,Green Grocers,6/19/2022,false,Indonesia +51,strawberry,59,2.62,154.58,Green Grocers,8/10/2022,false,Philippines +52,mango,87,4.26,370.62,Homespun Pastures,6/14/2022,false,Philippines +53,strawberry,47,6.48,304.56,Green Grocers,1/24/2022,true,China +54,grape,33,5.79,191.07,Homespun Pastures,5/5/2022,false,Peru +55,grapefruit,90,4.51,405.9,Homespun Pastures,3/5/2022,true,China +56,mango,2,4.73,9.46,Fresh Fruits Inc.,10/7/2022,true,Portugal +57,orange,49,3.31,162.19,Homespun Pastures,10/31/2022,true,Mongolia +58,mango,57,0.28,15.96,Green Grocers,10/25/2022,true,Ukraine +59,orange,49,2.69,131.81,Green Grocers,7/8/2022,false,Bulgaria +60,pineapple,8,8.99,71.92,Homespun Pastures,2/26/2022,true,Sweden +61,grapefruit,59,7.53,444.27,Fresh Fruits Inc.,3/24/2022,false,Philippines +62,grapefruit,29,2.32,67.28,Homespun Pastures,1/26/2022,true,Indonesia +63,apple,79,2.85,225.15,Homespun Pastures,4/22/2022,true,Indonesia +64,apple,6,5.2,31.2,Fresh Fruits Inc.,10/27/2022,true,Russia +65,orange,12,1.77,21.24,Homespun Pastures,6/6/2022,false,Bulgaria +66,mango,74,4.76,352.24,Fresh Fruits Inc.,6/19/2022,false,Azerbaijan +67,pineapple,68,6.82,463.76,Fresh Fruits Inc.,7/8/2022,false,Morocco +68,strawberry,96,3.87,371.52,Homespun Pastures,9/6/2022,false,Philippines +69,grape,78,1.28,99.84,Green Grocers,5/26/2022,false,China +70,orange,50,6.6,330.0,Green Grocers,10/23/2022,true,Russia +71,mango,9,3.52,31.68,Fresh Fruits Inc.,8/27/2022,true,China +72,apple,31,9.58,296.98,Green Grocers,6/30/2022,false,Russia +73,pineapple,48,0.79,37.92,Fresh Fruits Inc.,11/8/2022,false,United States +74,grape,69,4.2,289.8,Homespun Pastures,10/8/2022,false,Germany +75,orange,57,4.76,271.32,Fresh Fruits Inc.,3/10/2022,false,China +76,strawberry,81,7.94,643.14,Green Grocers,9/14/2022,true,Bolivia +77,grape,81,8.74,707.94,Fresh Fruits Inc.,6/29/2022,false,France +78,apple,51,3.49,177.99,Green Grocers,9/11/2022,true,China +79,grapefruit,59,5.83,343.97,Fresh Fruits Inc.,6/11/2022,true,Portugal +80,apricot,69,9.38,647.22,Green Grocers,2/1/2022,true,Sweden +81,apricot,33,5.75,189.75,Fresh Fruits Inc.,1/24/2022,false,Brazil +82,grapefruit,76,9.77,742.52,Homespun Pastures,9/18/2022,false,Brazil +83,strawberry,12,8.35,100.2,Fresh Fruits Inc.,5/18/2022,false,South Korea +84,apricot,83,5.03,417.49,Green Grocers,8/9/2022,true,Indonesia +85,apricot,45,9.4,423.0,Homespun Pastures,9/27/2022,true,Albania +86,pineapple,83,8.55,709.65,Fresh Fruits Inc.,5/14/2022,false,China +87,grape,89,3.01,267.89,Homespun Pastures,4/25/2022,false,China +88,grapefruit,43,7.36,316.48,Fresh Fruits Inc.,9/1/2022,true,Tanzania +89,apple,69,6.76,466.44,Homespun Pastures,1/15/2022,true,China +90,grapefruit,23,2.37,54.51,Green Grocers,5/28/2022,true,Portugal +91,grape,2,2.81,5.62,Green Grocers,11/3/2022,true,Colombia +92,pineapple,79,8.76,692.04,Fresh Fruits Inc.,6/14/2022,true,China +93,apple,21,2.7,56.7,Green Grocers,7/29/2022,false,Mauritius +94,grapefruit,26,9.12,237.12,Homespun Pastures,2/18/2022,false,Vietnam +95,apple,76,4.34,329.84,Homespun Pastures,1/26/2022,true,China +96,mango,82,2.82,231.24,Homespun Pastures,2/16/2022,true,Russia +97,grape,57,6.05,344.85,Green Grocers,6/19/2022,false,Thailand +98,mango,93,6.66,619.38,Fresh Fruits Inc.,5/25/2022,true,China +99,strawberry,66,1.15,75.9,Homespun Pastures,7/4/2022,true,Afghanistan +100,banana,50,4.9,245.0,Homespun Pastures,4/7/2022,true,China +101,strawberry,45,7.87,354.15,Green Grocers,10/3/2022,true,Brazil +102,orange,6,1.41,8.46,Fresh Fruits Inc.,5/9/2022,false,Venezuela +103,orange,6,8.74,52.44,Fresh Fruits Inc.,8/11/2022,true,Morocco +104,strawberry,2,0.05,0.1,Green Grocers,7/3/2022,false,Japan +105,grapefruit,94,6.53,613.82,Homespun Pastures,8/18/2022,true,Honduras +106,mango,84,5.93,498.12,Fresh Fruits Inc.,6/18/2022,true,Ukraine +107,strawberry,27,4.34,117.18,Fresh Fruits Inc.,4/21/2022,true,China +108,pineapple,80,2.47,197.6,Homespun Pastures,8/1/2022,true,Indonesia +109,strawberry,42,6.02,252.84,Green Grocers,11/10/2022,false,China +110,grape,87,4.47,388.89,Homespun Pastures,9/6/2022,true,Vietnam +111,pineapple,60,4.25,255.0,Fresh Fruits Inc.,1/2/2022,true,Indonesia +112,apple,54,7.46,402.84,Green Grocers,8/15/2022,false,Czech Republic +113,apricot,16,8.7,139.2,Green Grocers,9/15/2022,true,Indonesia +114,orange,10,7.06,70.6,Homespun Pastures,3/21/2022,false,Panama +115,grapefruit,61,0.85,51.85,Fresh Fruits Inc.,3/14/2022,false,Indonesia +116,apricot,7,0.23,1.61,Green Grocers,5/20/2022,false,Greece +117,orange,40,7.53,301.2,Homespun Pastures,7/13/2022,false,Kyrgyzstan +118,grapefruit,80,8.62,689.6,Homespun Pastures,3/14/2022,true,China +119,grape,5,4.0,20.0,Fresh Fruits Inc.,9/16/2022,true,Indonesia +120,grapefruit,74,6.47,478.78,Fresh Fruits Inc.,12/22/2022,true,Indonesia +121,apple,43,4.15,178.45,Homespun Pastures,10/2/2022,false,Mexico +122,banana,34,4.26,144.84,Homespun Pastures,1/25/2022,false,China +123,grapefruit,83,9.24,766.92,Fresh Fruits Inc.,12/15/2022,true,Belarus +124,apricot,29,2.5,72.5,Homespun Pastures,5/28/2022,false,Philippines +125,mango,61,3.07,187.27,Green Grocers,2/9/2022,true,Argentina +126,grape,74,3.41,252.34,Homespun Pastures,9/6/2022,false,Tajikistan +127,pineapple,43,0.64,27.52,Homespun Pastures,5/31/2022,true,Philippines +128,apricot,50,0.52,26.0,Fresh Fruits Inc.,8/9/2022,false,Panama +129,mango,90,4.81,432.9,Green Grocers,5/24/2022,true,Ukraine +130,strawberry,71,5.38,381.98,Homespun Pastures,10/11/2022,true,Indonesia +131,grape,79,9.84,777.36,Homespun Pastures,12/25/2022,false,Guatemala +132,strawberry,7,0.46,3.22,Fresh Fruits Inc.,7/31/2022,false,Portugal +133,apple,4,1.05,4.2,Green Grocers,7/19/2022,false,Indonesia +134,pineapple,80,8.3,664.0,Green Grocers,8/15/2022,true,Peru +135,strawberry,53,9.89,524.17,Green Grocers,7/16/2022,false,Portugal +136,mango,6,1.59,9.54,Fresh Fruits Inc.,5/2/2022,true,Germany +137,orange,74,4.11,304.14,Green Grocers,6/1/2022,true,Indonesia +138,pineapple,56,1.05,58.8,Homespun Pastures,1/31/2022,true,Brazil +139,apricot,28,1.5,42.0,Green Grocers,3/4/2022,false,Ireland +140,grapefruit,19,5.3,100.7,Fresh Fruits Inc.,8/29/2022,true,Greece +141,apple,55,8.25,453.75,Fresh Fruits Inc.,10/28/2022,true,China +142,mango,88,3.79,333.52,Green Grocers,10/17/2022,true,Portugal +143,orange,56,3.74,209.44,Fresh Fruits Inc.,5/12/2022,false,China +144,apple,12,2.72,32.64,Homespun Pastures,8/2/2022,false,Russia +145,grape,10,0.79,7.9,Fresh Fruits Inc.,7/16/2022,false,Finland +146,grapefruit,47,6.55,307.85,Fresh Fruits Inc.,12/15/2022,false,Sweden +147,apricot,80,0.52,41.6,Green Grocers,4/2/2022,true,Vietnam +148,apricot,73,9.02,658.46,Fresh Fruits Inc.,12/11/2022,true,France +149,orange,28,1.92,53.76,Green Grocers,3/13/2022,true,Vietnam +150,banana,100,5.29,529.0,Homespun Pastures,2/2/2022,false,Philippines +151,apricot,20,7.52,150.4,Fresh Fruits Inc.,4/29/2022,true,Canada +152,mango,83,4.56,378.48,Fresh Fruits Inc.,10/6/2022,true,Kosovo +153,apple,7,3.99,27.93,Homespun Pastures,10/9/2022,true,China +154,grapefruit,70,6.01,420.7,Fresh Fruits Inc.,12/10/2022,true,Russia +155,grape,36,1.11,39.96,Fresh Fruits Inc.,6/10/2022,true,Brazil +156,mango,83,8.3,688.9,Green Grocers,10/19/2022,false,Poland +157,orange,77,4.42,340.34,Homespun Pastures,6/20/2022,false,New Zealand +158,mango,9,6.11,54.99,Green Grocers,1/31/2022,false,Bosnia and Herzegovina +159,apricot,92,7.11,654.12,Fresh Fruits Inc.,2/26/2022,true,Canada +160,grapefruit,71,5.87,416.77,Green Grocers,7/4/2022,true,Serbia +161,grape,48,0.5,24.0,Homespun Pastures,1/25/2022,true,China +162,grapefruit,79,6.88,543.52,Homespun Pastures,11/9/2022,false,Indonesia +163,pineapple,1,2.39,2.39,Fresh Fruits Inc.,4/28/2022,false,China +164,pineapple,20,9.38,187.6,Homespun Pastures,1/3/2022,false,China +165,strawberry,48,7.72,370.56,Fresh Fruits Inc.,4/23/2022,false,Kosovo +166,apple,96,9.74,935.04,Homespun Pastures,3/31/2022,true,Myanmar +167,banana,20,6.38,127.6,Homespun Pastures,2/7/2022,false,Argentina +168,pineapple,63,3.52,221.76,Homespun Pastures,12/29/2022,true,Portugal +169,strawberry,6,7.27,43.62,Fresh Fruits Inc.,1/24/2022,false,Indonesia +170,grape,78,6.06,472.68,Homespun Pastures,3/14/2022,false,Colombia +171,pineapple,70,9.24,646.8,Green Grocers,7/29/2022,false,Albania +172,mango,10,5.04,50.4,Homespun Pastures,12/14/2022,false,China +173,grapefruit,27,8.95,241.65,Fresh Fruits Inc.,6/28/2022,false,Sweden +174,grape,27,9.17,247.59,Fresh Fruits Inc.,4/27/2022,true,United States +175,apricot,84,7.33,615.72,Homespun Pastures,3/8/2022,false,Indonesia +176,apple,20,9.36,187.2,Homespun Pastures,11/5/2022,true,Colombia +177,pineapple,30,2.1,63.0,Homespun Pastures,4/14/2022,true,France +178,strawberry,51,7.95,405.45,Homespun Pastures,4/12/2022,true,Faroe Islands +179,grape,22,0.03,0.66,Green Grocers,3/25/2022,true,Lithuania +180,grape,19,7.56,143.64,Fresh Fruits Inc.,7/31/2022,false,Philippines +181,apricot,92,4.51,414.92,Fresh Fruits Inc.,2/24/2022,false,China +182,banana,46,6.06,278.76,Fresh Fruits Inc.,10/2/2022,false,Sweden +183,apricot,44,8.86,389.84,Fresh Fruits Inc.,11/2/2022,true,Slovenia +184,banana,41,2.85,116.85,Fresh Fruits Inc.,8/18/2022,false,Democratic Republic of the Congo +185,banana,90,8.24,741.6,Fresh Fruits Inc.,3/24/2022,true,Uruguay +186,apricot,41,2.16,88.56,Homespun Pastures,12/28/2022,true,Portugal +187,grapefruit,1,5.82,5.82,Homespun Pastures,11/30/2022,false,Albania +188,orange,5,2.53,12.65,Green Grocers,2/9/2022,true,Poland +189,apple,45,2.91,130.95,Homespun Pastures,4/26/2022,false,Cameroon +190,mango,86,7.7,662.2,Fresh Fruits Inc.,10/30/2022,false,Japan +191,mango,5,6.39,31.95,Green Grocers,5/22/2022,false,Guadeloupe +192,banana,69,1.41,97.29,Homespun Pastures,2/15/2022,true,China +193,mango,36,2.88,103.68,Homespun Pastures,8/26/2022,false,Indonesia +194,mango,76,4.47,339.72,Green Grocers,10/16/2022,false,Colombia +195,strawberry,89,1.11,98.79,Fresh Fruits Inc.,1/16/2022,true,Venezuela +196,apple,85,6.52,554.2,Fresh Fruits Inc.,2/3/2022,true,China +197,apple,54,0.49,26.46,Green Grocers,11/23/2022,true,Belgium +198,strawberry,51,4.2,214.2,Fresh Fruits Inc.,4/5/2022,false,Madagascar +199,pineapple,45,1.06,47.7,Fresh Fruits Inc.,3/16/2022,true,Argentina +200,mango,88,1.83,161.04,Green Grocers,9/29/2022,false,Uruguay +201,orange,87,8.02,697.74,Green Grocers,4/6/2022,true,Indonesia +202,grapefruit,74,5.53,409.22,Green Grocers,7/14/2022,false,Peru +203,strawberry,60,5.65,339.0,Homespun Pastures,2/20/2022,true,Pakistan +204,pineapple,74,2.49,184.26,Fresh Fruits Inc.,12/26/2022,false,Indonesia +205,grape,88,6.77,595.76,Homespun Pastures,10/21/2022,true,Argentina +206,apricot,91,0.92,83.72,Homespun Pastures,3/6/2022,true,Libya +207,pineapple,27,1.11,29.97,Fresh Fruits Inc.,7/23/2022,true,China +208,grapefruit,87,8.69,756.03,Homespun Pastures,10/5/2022,true,Zimbabwe +209,strawberry,87,6.92,602.04,Homespun Pastures,10/7/2022,true,Colombia +210,banana,66,9.27,611.82,Homespun Pastures,10/12/2022,false,China +211,apricot,61,8.04,490.44,Fresh Fruits Inc.,9/16/2022,true,Poland +212,apple,49,9.92,486.08,Fresh Fruits Inc.,3/22/2022,true,China +213,grapefruit,98,8.23,806.54,Green Grocers,7/4/2022,false,China +214,banana,23,6.32,145.36,Fresh Fruits Inc.,7/16/2022,false,Peru +215,grape,57,7.42,422.94,Green Grocers,6/17/2022,true,Malaysia +216,apricot,47,6.3,296.1,Fresh Fruits Inc.,1/13/2022,true,Russia +217,apple,4,3.29,13.16,Homespun Pastures,4/27/2022,false,Colombia +218,strawberry,41,6.42,263.22,Homespun Pastures,10/20/2022,true,South Africa +219,apple,56,4.42,247.52,Green Grocers,4/19/2022,true,China +220,apricot,59,4.94,291.46,Homespun Pastures,10/12/2022,true,Mongolia +221,mango,46,6.96,320.16,Fresh Fruits Inc.,4/20/2022,true,Malaysia +222,banana,14,4.86,68.04,Homespun Pastures,6/26/2022,true,Czech Republic +223,mango,15,9.07,136.05,Homespun Pastures,12/9/2022,false,Philippines +224,apple,56,2.34,131.04,Fresh Fruits Inc.,10/13/2022,false,China +225,grapefruit,80,3.81,304.8,Green Grocers,10/26/2022,true,Poland +226,strawberry,88,0.51,44.88,Homespun Pastures,5/3/2022,false,Brazil +227,grapefruit,93,1.76,163.68,Fresh Fruits Inc.,10/6/2022,false,China +228,apple,44,7.54,331.76,Homespun Pastures,7/4/2022,false,China +229,strawberry,30,8.63,258.9,Green Grocers,3/3/2022,false,Mauritania +230,grapefruit,9,0.39,3.51,Homespun Pastures,9/18/2022,true,Sweden +231,orange,24,0.8,19.2,Homespun Pastures,4/7/2022,true,China +232,mango,6,4.19,25.14,Homespun Pastures,7/28/2022,true,Peru +233,strawberry,79,8.2,647.8,Green Grocers,10/13/2022,false,Russia +234,grape,67,3.14,210.38,Homespun Pastures,9/2/2022,false,China +235,apple,100,2.64,264.0,Homespun Pastures,8/7/2022,false,Yemen +236,apricot,35,7.42,259.7,Green Grocers,5/25/2022,true,China +237,strawberry,70,3.73,261.1,Green Grocers,8/11/2022,true,China +238,banana,7,8.27,57.89,Green Grocers,6/29/2022,true,Uganda +239,pineapple,45,8.08,363.6,Homespun Pastures,2/13/2022,false,China +240,apricot,16,0.61,9.76,Homespun Pastures,10/5/2022,true,Somalia +241,apple,92,8.31,764.52,Fresh Fruits Inc.,11/22/2022,false,Egypt +242,orange,74,7.24,535.76,Homespun Pastures,9/16/2022,true,Indonesia +243,pineapple,4,7.54,30.16,Fresh Fruits Inc.,6/1/2022,true,Brazil +244,grape,95,9.58,910.1,Fresh Fruits Inc.,7/4/2022,false,Sweden +245,grape,52,0.86,44.72,Green Grocers,8/6/2022,false,Indonesia +246,banana,7,9.84,68.88,Fresh Fruits Inc.,7/28/2022,true,Nigeria +247,orange,79,9.41,743.39,Fresh Fruits Inc.,6/2/2022,true,Czech Republic +248,apricot,78,7.76,605.28,Homespun Pastures,1/4/2022,true,Russia +249,orange,45,9.47,426.15,Green Grocers,5/31/2022,false,Japan +250,grapefruit,14,3.85,53.9,Homespun Pastures,7/13/2022,false,Czech Republic +251,banana,45,4.7,211.5,Fresh Fruits Inc.,11/22/2022,false,China +252,orange,14,5.17,72.38,Homespun Pastures,12/12/2022,true,France +253,mango,89,0.27,24.03,Fresh Fruits Inc.,12/10/2022,false,Russia +254,orange,69,4.97,342.93,Fresh Fruits Inc.,7/17/2022,true,Portugal +255,strawberry,45,7.64,343.8,Homespun Pastures,1/13/2022,false,China +256,grapefruit,49,5.7,279.3,Homespun Pastures,5/9/2022,true,France +257,banana,4,3.24,12.96,Green Grocers,7/21/2022,true,Syria +258,grape,40,7.36,294.4,Homespun Pastures,10/17/2022,true,Russia +259,apricot,69,3.46,238.74,Homespun Pastures,7/23/2022,true,Italy +260,grapefruit,71,0.03,2.13,Homespun Pastures,6/21/2022,false,Indonesia +261,pineapple,54,7.56,408.24,Homespun Pastures,8/11/2022,true,China +262,apricot,10,8.7,87.0,Green Grocers,10/4/2022,false,China +263,mango,81,9.3,753.3,Fresh Fruits Inc.,1/9/2022,true,Poland +264,apple,34,7.26,246.84,Green Grocers,11/6/2022,false,China +265,mango,85,8.82,749.7,Fresh Fruits Inc.,1/23/2022,true,Indonesia +266,strawberry,16,0.95,15.2,Green Grocers,5/6/2022,true,Russia +267,grape,44,8.57,377.08,Homespun Pastures,10/25/2022,false,Albania +268,apple,74,8.66,640.84,Fresh Fruits Inc.,1/24/2022,true,Portugal +269,mango,30,3.77,113.1,Fresh Fruits Inc.,10/9/2022,false,Indonesia +270,apple,96,5.52,529.92,Fresh Fruits Inc.,3/12/2022,false,Bosnia and Herzegovina +271,mango,65,9.19,597.35,Fresh Fruits Inc.,5/28/2022,false,China +272,orange,4,8.06,32.24,Fresh Fruits Inc.,2/17/2022,false,France +273,pineapple,78,0.91,70.98,Fresh Fruits Inc.,5/29/2022,false,China +274,mango,83,3.5,290.5,Fresh Fruits Inc.,2/19/2022,true,United States +275,orange,89,6.84,608.76,Homespun Pastures,6/25/2022,true,China +276,strawberry,20,1.41,28.2,Homespun Pastures,7/4/2022,false,Czech Republic +277,mango,69,7.19,496.11,Homespun Pastures,4/9/2022,true,Serbia +278,orange,94,1.47,138.18,Homespun Pastures,9/26/2022,false,Zimbabwe +279,apple,70,0.29,20.3,Green Grocers,12/2/2022,true,China +280,grape,40,0.2,8.0,Green Grocers,3/16/2022,false,Indonesia +281,mango,81,9.63,780.03,Green Grocers,12/22/2022,true,Russia +282,grapefruit,25,9.81,245.25,Homespun Pastures,9/11/2022,true,Macedonia +283,orange,84,7.41,622.44,Homespun Pastures,4/29/2022,true,Benin +284,apricot,85,0.53,45.05,Homespun Pastures,11/3/2022,true,France +285,pineapple,15,4.96,74.4,Green Grocers,11/28/2022,true,China +286,orange,27,0.08,2.16,Fresh Fruits Inc.,7/11/2022,false,France +287,grapefruit,71,3.1,220.1,Homespun Pastures,6/8/2022,false,Portugal +288,strawberry,25,0.48,12.0,Fresh Fruits Inc.,10/15/2022,true,Czech Republic +289,grape,80,4.6,368.0,Fresh Fruits Inc.,11/29/2022,false,China +290,banana,14,2.82,39.48,Fresh Fruits Inc.,1/4/2022,true,Italy +291,apple,37,6.16,227.92,Homespun Pastures,4/24/2022,false,United States +292,apple,75,0.7,52.5,Fresh Fruits Inc.,4/15/2022,false,Russia +293,mango,72,2.54,182.88,Green Grocers,11/13/2022,false,Poland +294,apple,83,2.83,234.89,Fresh Fruits Inc.,11/23/2022,false,Japan +295,pineapple,71,2.66,188.86,Homespun Pastures,7/26/2022,true,Indonesia +296,strawberry,92,0.92,84.64,Homespun Pastures,6/2/2022,false,Colombia +297,mango,81,1.56,126.36,Green Grocers,9/28/2022,true,China +298,grape,98,1.06,103.88,Homespun Pastures,4/25/2022,false,Indonesia +299,pineapple,48,8.14,390.72,Green Grocers,10/6/2022,false,Philippines +300,pineapple,100,4.28,428.0,Green Grocers,7/29/2022,false,Portugal +301,banana,41,1.21,49.61,Green Grocers,7/28/2022,true,Indonesia +302,strawberry,87,1.88,163.56,Homespun Pastures,3/21/2022,true,Russia +303,banana,2,9.77,19.54,Homespun Pastures,10/4/2022,false,Senegal +304,apricot,45,2.63,118.35,Fresh Fruits Inc.,3/21/2022,true,Afghanistan +305,grape,44,4.64,204.16,Homespun Pastures,9/2/2022,true,Indonesia +306,grapefruit,28,9.6,268.8,Green Grocers,4/3/2022,false,China +307,apricot,87,9.5,826.5,Fresh Fruits Inc.,6/11/2022,false,Jamaica +308,grape,52,0.26,13.52,Green Grocers,12/15/2022,false,China +309,banana,16,2.73,43.68,Green Grocers,6/14/2022,true,Philippines +310,mango,24,8.9,213.6,Green Grocers,1/7/2022,true,China +311,pineapple,93,0.56,52.08,Fresh Fruits Inc.,2/14/2022,false,South Korea +312,strawberry,43,2.46,105.78,Green Grocers,10/17/2022,true,China +313,orange,76,0.42,31.92,Green Grocers,1/5/2022,true,United States +314,pineapple,13,8.32,108.16,Green Grocers,5/6/2022,true,China +315,grape,38,2.59,98.42,Homespun Pastures,5/28/2022,true,Dominican Republic +316,apple,14,0.79,11.06,Homespun Pastures,12/9/2022,false,Philippines +317,banana,13,4.46,57.98,Fresh Fruits Inc.,10/10/2022,true,Indonesia +318,grapefruit,98,4.16,407.68,Green Grocers,9/2/2022,true,Kazakhstan +319,mango,21,9.72,204.12,Homespun Pastures,10/16/2022,false,Japan +320,apple,36,9.52,342.72,Fresh Fruits Inc.,2/28/2022,true,Czech Republic +321,orange,20,4.41,88.2,Fresh Fruits Inc.,12/9/2022,true,Georgia +322,apple,11,9.76,107.36,Fresh Fruits Inc.,7/14/2022,true,China +323,mango,79,9.54,753.66,Fresh Fruits Inc.,2/8/2022,true,Brazil +324,strawberry,85,3.09,262.65,Homespun Pastures,11/16/2022,false,Uganda +325,banana,46,6.3,289.8,Fresh Fruits Inc.,11/18/2022,true,Philippines +326,apple,97,8.5,824.5,Homespun Pastures,7/12/2022,false,Brunei +327,pineapple,76,6.12,465.12,Homespun Pastures,5/5/2022,true,Syria +328,apricot,16,8.86,141.76,Green Grocers,9/2/2022,true,Morocco +329,orange,1,8.97,8.97,Green Grocers,8/2/2022,true,Russia +330,apple,28,4.96,138.88,Green Grocers,6/30/2022,true,Poland +331,apple,79,2.98,235.42,Fresh Fruits Inc.,11/13/2022,true,Netherlands +332,orange,6,8.87,53.22,Fresh Fruits Inc.,6/12/2022,false,Indonesia +333,apricot,87,8.97,780.39,Green Grocers,10/21/2022,false,Brazil +334,strawberry,18,4.97,89.46,Homespun Pastures,7/31/2022,true,Croatia +335,pineapple,54,1.02,55.08,Green Grocers,1/15/2022,true,Russia +336,grapefruit,58,1.03,59.74,Homespun Pastures,4/24/2022,false,China +337,pineapple,8,6.19,49.52,Fresh Fruits Inc.,3/17/2022,true,China +338,grape,20,6.11,122.2,Homespun Pastures,5/14/2022,true,Honduras +339,banana,55,0.31,17.05,Fresh Fruits Inc.,1/12/2022,true,Guatemala +340,banana,31,9.5,294.5,Fresh Fruits Inc.,12/6/2022,true,Italy +341,strawberry,69,2.25,155.25,Green Grocers,6/26/2022,false,Libya +342,apple,9,5.71,51.39,Green Grocers,12/16/2022,true,Portugal +343,banana,83,4.87,404.21,Homespun Pastures,9/29/2022,true,Indonesia +344,grapefruit,31,5.99,185.69,Fresh Fruits Inc.,2/2/2022,true,Thailand +345,pineapple,29,0.2,5.8,Green Grocers,9/26/2022,true,Vietnam +346,apple,100,4.81,481.0,Homespun Pastures,3/26/2022,true,Czech Republic +347,pineapple,72,7.49,539.28,Green Grocers,6/29/2022,true,Micronesia +348,grape,46,4.53,208.38,Homespun Pastures,11/26/2022,true,Philippines +349,grape,15,9.08,136.2,Green Grocers,5/26/2022,true,Macedonia +350,grape,43,1.31,56.33,Homespun Pastures,7/1/2022,false,Russia +351,grape,12,3.48,41.76,Green Grocers,3/14/2022,true,China +352,mango,92,5.39,495.88,Fresh Fruits Inc.,11/8/2022,false,Sweden +353,mango,21,9.43,198.03,Green Grocers,12/6/2022,true,Philippines +354,mango,24,1.74,41.76,Green Grocers,6/6/2022,true,China +355,apricot,10,8.86,88.6,Homespun Pastures,7/31/2022,false,Argentina +356,banana,18,7.44,133.92,Green Grocers,10/12/2022,false,Philippines +357,orange,85,4.75,403.75,Fresh Fruits Inc.,9/28/2022,false,Philippines +358,pineapple,59,5.6,330.4,Homespun Pastures,5/1/2022,false,Bolivia +359,strawberry,78,8.79,685.62,Homespun Pastures,6/25/2022,true,Uruguay +360,apricot,15,6.26,93.9,Green Grocers,12/17/2022,true,China +361,mango,24,5.88,141.12,Green Grocers,10/23/2022,true,Kazakhstan +362,grapefruit,88,5.28,464.64,Fresh Fruits Inc.,5/11/2022,true,China +363,mango,61,5.96,363.56,Green Grocers,11/16/2022,false,Russia +364,orange,51,6.58,335.58,Homespun Pastures,6/8/2022,true,Philippines +365,mango,42,7.59,318.78,Homespun Pastures,6/22/2022,true,China +366,grape,72,1.05,75.6,Fresh Fruits Inc.,4/15/2022,false,Yemen +367,apricot,87,5.62,488.94,Homespun Pastures,7/27/2022,false,Russia +368,pineapple,25,9.96,249.0,Fresh Fruits Inc.,1/30/2022,false,Haiti +369,strawberry,60,7.29,437.4,Fresh Fruits Inc.,2/15/2022,true,Bolivia +370,pineapple,81,9.5,769.5,Fresh Fruits Inc.,12/15/2022,false,Brazil +371,grapefruit,3,2.04,6.12,Fresh Fruits Inc.,6/27/2022,false,Netherlands +372,strawberry,23,3.92,90.16,Homespun Pastures,2/8/2022,false,France +373,orange,36,9.99,359.64,Fresh Fruits Inc.,6/9/2022,true,Colombia +374,banana,73,5.88,429.24,Homespun Pastures,10/6/2022,false,Tajikistan +375,strawberry,63,8.89,560.07,Fresh Fruits Inc.,4/6/2022,false,Brazil +376,apple,93,9.87,917.91,Homespun Pastures,5/1/2022,false,France +377,apple,29,5.49,159.21,Green Grocers,2/20/2022,true,Philippines +378,orange,60,2.75,165.0,Homespun Pastures,3/24/2022,false,Tunisia +379,apple,75,9.76,732.0,Homespun Pastures,7/2/2022,true,Vietnam +380,apricot,89,7.58,674.62,Homespun Pastures,9/11/2022,true,China +381,pineapple,6,2.81,16.86,Fresh Fruits Inc.,3/4/2022,false,Azerbaijan +382,orange,91,6.42,584.22,Fresh Fruits Inc.,12/19/2022,true,Morocco +383,mango,70,4.38,306.6,Green Grocers,1/23/2022,true,Mexico +384,mango,51,9.71,495.21,Fresh Fruits Inc.,9/28/2022,false,China +385,strawberry,77,8.25,635.25,Green Grocers,2/6/2022,false,Brazil +386,banana,57,8.15,464.55,Homespun Pastures,12/16/2022,true,Japan +387,grapefruit,87,8.45,735.15,Fresh Fruits Inc.,1/21/2022,false,China +388,apple,22,4.48,98.56,Green Grocers,12/25/2022,false,China +389,strawberry,39,2.13,83.07,Green Grocers,12/3/2022,true,Egypt +390,pineapple,51,2.68,136.68,Fresh Fruits Inc.,4/26/2022,true,Luxembourg +391,apricot,47,9.13,429.11,Homespun Pastures,3/8/2022,false,Indonesia +392,pineapple,61,6.95,423.95,Green Grocers,10/26/2022,true,Bulgaria +393,banana,42,4.38,183.96,Fresh Fruits Inc.,6/21/2022,true,United States +394,apple,82,2.76,226.32,Homespun Pastures,5/22/2022,true,Sweden +395,grape,42,9.41,395.22,Fresh Fruits Inc.,11/8/2022,true,Ukraine +396,apricot,22,1.13,24.86,Green Grocers,7/20/2022,true,Philippines +397,apricot,51,2.2,112.2,Homespun Pastures,10/11/2022,true,China +398,apricot,80,6.63,530.4,Green Grocers,11/10/2022,false,China +399,mango,51,0.23,11.73,Fresh Fruits Inc.,6/5/2022,false,Syria +400,apple,15,2.23,33.45,Green Grocers,2/7/2022,true,Palestinian Territory +401,pineapple,68,5.97,405.96,Fresh Fruits Inc.,11/1/2022,true,China +402,apple,51,1.63,83.13,Homespun Pastures,1/7/2022,false,Indonesia +403,orange,12,4.26,51.12,Fresh Fruits Inc.,11/2/2022,true,Djibouti +404,banana,15,3.1,46.5,Fresh Fruits Inc.,6/7/2022,false,Nepal +405,grapefruit,43,2.3,98.9,Homespun Pastures,1/3/2022,true,Indonesia +406,apple,75,3.58,268.5,Green Grocers,6/14/2022,true,Argentina +407,apple,39,5.88,229.32,Fresh Fruits Inc.,9/15/2022,true,China +408,mango,38,6.78,257.64,Homespun Pastures,2/26/2022,true,Brazil +409,grape,48,9.79,469.92,Fresh Fruits Inc.,11/9/2022,true,Yemen +410,apple,18,5.9,106.2,Homespun Pastures,6/17/2022,false,China +411,grapefruit,77,6.53,502.81,Green Grocers,10/30/2022,false,Thailand +412,grapefruit,32,5.78,184.96,Homespun Pastures,1/14/2022,true,Armenia +413,grape,39,7.95,310.05,Green Grocers,2/17/2022,false,Russia +414,apple,32,1.16,37.12,Green Grocers,5/25/2022,true,France +415,apple,95,2.04,193.8,Green Grocers,2/9/2022,true,Syria +416,mango,48,7.06,338.88,Fresh Fruits Inc.,9/26/2022,false,Japan +417,grape,89,1.13,100.57,Homespun Pastures,10/24/2022,false,Netherlands +418,apricot,36,8.93,321.48,Homespun Pastures,11/15/2022,true,China +419,orange,11,2.74,30.14,Green Grocers,8/1/2022,true,China +420,mango,87,1.93,167.91,Homespun Pastures,6/5/2022,false,Finland +421,strawberry,73,4.08,297.84,Green Grocers,6/14/2022,false,Poland +422,strawberry,86,2.51,215.86,Green Grocers,3/23/2022,true,China +423,mango,56,6.3,352.8,Homespun Pastures,12/16/2022,false,Ethiopia +424,pineapple,42,8.71,365.82,Green Grocers,8/4/2022,true,Poland +425,strawberry,42,6.97,292.74,Homespun Pastures,7/29/2022,true,Poland +426,pineapple,60,6.87,412.2,Fresh Fruits Inc.,1/11/2022,false,China +427,grapefruit,51,2.22,113.22,Green Grocers,5/20/2022,true,Honduras +428,apple,88,3.65,321.2,Fresh Fruits Inc.,7/10/2022,true,Poland +429,mango,21,9.62,202.02,Homespun Pastures,6/18/2022,true,China +430,mango,35,2.46,86.1,Homespun Pastures,2/19/2022,false,Russia +431,banana,67,2.34,156.78,Fresh Fruits Inc.,7/3/2022,false,China +432,mango,56,0.15,8.4,Homespun Pastures,3/26/2022,true,Philippines +433,grape,16,5.87,93.92,Homespun Pastures,5/9/2022,true,Philippines +434,mango,5,0.96,4.8,Green Grocers,2/6/2022,false,Russia +435,orange,55,3.02,166.1,Fresh Fruits Inc.,2/9/2022,false,United Kingdom +436,pineapple,31,7.09,219.79,Homespun Pastures,7/23/2022,false,Poland +437,mango,29,9.73,282.17,Homespun Pastures,6/21/2022,false,Russia +438,apple,88,1.03,90.64,Green Grocers,12/8/2022,true,China +439,grape,56,5.98,334.88,Green Grocers,4/18/2022,false,Philippines +440,apple,33,5.71,188.43,Homespun Pastures,12/26/2022,false,Iran +441,grapefruit,75,8.05,603.75,Green Grocers,3/13/2022,false,China +442,strawberry,53,0.24,12.72,Homespun Pastures,10/30/2022,true,Canada +443,apricot,49,2.01,98.49,Fresh Fruits Inc.,12/21/2022,true,Philippines +444,mango,76,6.86,521.36,Homespun Pastures,4/22/2022,true,Paraguay +445,strawberry,12,1.03,12.36,Homespun Pastures,10/26/2022,true,China +446,banana,77,4.1,315.7,Green Grocers,4/27/2022,false,Argentina +447,grape,39,6.06,236.34,Green Grocers,5/23/2022,true,Philippines +448,banana,15,1.8,27.0,Homespun Pastures,1/1/2022,true,Indonesia +449,grape,60,6.72,403.2,Green Grocers,5/20/2022,false,Serbia +450,orange,42,3.23,135.66,Fresh Fruits Inc.,10/17/2022,true,Central African Republic +451,orange,38,3.21,121.98,Green Grocers,11/4/2022,true,Croatia +452,orange,88,4.59,403.92,Green Grocers,9/9/2022,false,Finland +453,pineapple,77,4.44,341.88,Fresh Fruits Inc.,5/16/2022,true,Canada +454,strawberry,82,3.26,267.32,Fresh Fruits Inc.,8/26/2022,false,Czech Republic +455,mango,66,2.78,183.48,Homespun Pastures,4/22/2022,true,Madagascar +456,pineapple,36,4.79,172.44,Green Grocers,11/6/2022,true,Colombia +457,apricot,4,0.16,0.64,Fresh Fruits Inc.,5/4/2022,false,Cameroon +458,orange,18,6.12,110.16,Green Grocers,3/28/2022,false,Indonesia +459,apple,66,0.28,18.48,Homespun Pastures,12/20/2022,true,Georgia +460,strawberry,35,6.61,231.35,Green Grocers,12/8/2022,false,France +461,mango,65,3.92,254.8,Homespun Pastures,4/10/2022,true,Cuba +462,banana,50,2.97,148.5,Green Grocers,3/10/2022,true,Finland +463,apricot,69,9.11,628.59,Homespun Pastures,6/3/2022,false,Philippines +464,apple,99,6.63,656.37,Fresh Fruits Inc.,11/13/2022,true,Indonesia +465,grape,31,8.29,256.99,Green Grocers,2/13/2022,false,Russia +466,grapefruit,60,5.06,303.6,Green Grocers,5/3/2022,true,Canada +467,banana,61,9.84,600.24,Green Grocers,9/24/2022,false,North Korea +468,apricot,68,4.57,310.76,Homespun Pastures,12/11/2022,true,Syria +469,apple,54,8.29,447.66,Green Grocers,2/4/2022,false,Costa Rica +470,orange,100,7.83,783.0,Homespun Pastures,1/28/2022,false,Sweden +471,strawberry,72,9.52,685.44,Fresh Fruits Inc.,1/21/2022,true,Indonesia +472,apricot,98,5.67,555.66,Homespun Pastures,10/9/2022,false,Croatia +473,strawberry,64,7.92,506.88,Green Grocers,12/9/2022,false,China +474,banana,94,0.77,72.38,Homespun Pastures,3/11/2022,false,China +475,orange,72,7.15,514.8,Fresh Fruits Inc.,12/22/2022,false,China +476,mango,28,6.7,187.6,Fresh Fruits Inc.,8/1/2022,false,Yemen +477,grape,3,0.49,1.47,Fresh Fruits Inc.,11/14/2022,true,Tunisia +478,orange,89,9.11,810.79,Homespun Pastures,11/17/2022,true,Jamaica +479,grape,31,5.07,157.17,Fresh Fruits Inc.,11/24/2022,true,Malaysia +480,apple,89,2.08,185.12,Homespun Pastures,12/20/2022,true,Denmark +481,apricot,54,5.97,322.38,Homespun Pastures,2/22/2022,true,Netherlands +482,banana,100,9.38,938.0,Homespun Pastures,3/5/2022,false,Morocco +483,apple,61,9.66,589.26,Green Grocers,12/6/2022,false,Poland +484,grape,89,7.81,695.09,Green Grocers,10/1/2022,true,Poland +485,grapefruit,61,9.62,586.82,Homespun Pastures,2/17/2022,true,Tanzania +486,mango,39,5.0,195.0,Green Grocers,4/12/2022,false,France +487,apple,23,6.53,150.19,Green Grocers,9/30/2022,false,Czech Republic +488,orange,100,9.58,958.0,Homespun Pastures,7/21/2022,true,Japan +489,apricot,56,4.76,266.56,Green Grocers,1/21/2022,true,Philippines +490,strawberry,61,0.63,38.43,Green Grocers,10/1/2022,false,Mexico +491,pineapple,24,5.95,142.8,Green Grocers,2/27/2022,true,Portugal +492,orange,19,7.2,136.8,Homespun Pastures,5/11/2022,false,Luxembourg +493,pineapple,86,0.03,2.58,Homespun Pastures,6/15/2022,false,China +494,mango,32,5.15,164.8,Green Grocers,6/19/2022,true,Armenia +495,orange,57,9.03,514.71,Green Grocers,1/26/2022,false,Portugal +496,apricot,95,6.34,602.3,Homespun Pastures,11/4/2022,true,Tunisia +497,grape,38,5.51,209.38,Homespun Pastures,3/24/2022,false,Spain +498,mango,100,8.01,801.0,Homespun Pastures,8/1/2022,true,Indonesia +499,apple,80,5.2,416.0,Fresh Fruits Inc.,2/4/2022,true,Armenia +500,grape,60,4.77,286.2,Green Grocers,12/22/2022,true,Denmark +501,apple,22,8.39,184.58,Homespun Pastures,1/3/2022,false,Philippines +502,banana,16,6.64,106.24,Homespun Pastures,11/11/2022,false,Guinea +503,strawberry,2,6.01,12.02,Fresh Fruits Inc.,10/22/2022,false,Canada +504,apricot,72,3.33,239.76,Fresh Fruits Inc.,7/28/2022,true,Philippines +505,orange,11,4.29,47.19,Green Grocers,4/20/2022,false,China +506,apricot,36,4.06,146.16,Homespun Pastures,10/12/2022,false,Portugal +507,apple,52,9.43,490.36,Green Grocers,10/31/2022,false,China +508,orange,19,4.82,91.58,Homespun Pastures,5/15/2022,true,Malawi +509,grapefruit,12,7.59,91.08,Homespun Pastures,5/1/2022,false,Indonesia +510,apple,94,4.18,392.92,Fresh Fruits Inc.,11/28/2022,false,Thailand +511,grape,59,7.78,459.02,Fresh Fruits Inc.,2/28/2022,false,Uzbekistan +512,grape,61,7.05,430.05,Fresh Fruits Inc.,4/12/2022,true,Japan +513,orange,44,0.58,25.52,Fresh Fruits Inc.,12/19/2022,true,China +514,apricot,35,7.91,276.85,Homespun Pastures,1/23/2022,true,Thailand +515,banana,71,5.97,423.87,Homespun Pastures,7/27/2022,false,Peru +516,apricot,7,1.05,7.35,Homespun Pastures,11/23/2022,true,China +517,apricot,54,8.42,454.68,Fresh Fruits Inc.,7/11/2022,true,China +518,grapefruit,20,3.58,71.6,Homespun Pastures,11/1/2022,true,Netherlands +519,pineapple,71,4.85,344.35,Green Grocers,1/2/2022,true,Latvia +520,banana,51,0.59,30.09,Fresh Fruits Inc.,10/7/2022,true,Poland +521,orange,78,8.88,692.64,Homespun Pastures,10/13/2022,true,Indonesia +522,pineapple,86,5.01,430.86,Homespun Pastures,11/23/2022,false,Brazil +523,mango,89,8.97,798.33,Fresh Fruits Inc.,12/12/2022,true,Philippines +524,apple,77,3.12,240.24,Fresh Fruits Inc.,4/18/2022,false,Vietnam +525,pineapple,89,4.05,360.45,Homespun Pastures,12/3/2022,false,Cameroon +526,apricot,74,2.34,173.16,Homespun Pastures,1/17/2022,true,Mexico +527,strawberry,43,5.85,251.55,Green Grocers,5/14/2022,false,Poland +528,orange,37,3.17,117.29,Homespun Pastures,7/21/2022,true,Brazil +529,banana,30,0.3,9.0,Homespun Pastures,7/26/2022,false,China +530,grapefruit,2,4.46,8.92,Fresh Fruits Inc.,1/8/2022,false,Indonesia +531,grape,29,4.72,136.88,Homespun Pastures,1/12/2022,true,Uzbekistan +532,apple,30,7.04,211.2,Fresh Fruits Inc.,3/8/2022,false,Philippines +533,banana,55,6.34,348.7,Homespun Pastures,9/8/2022,false,China +534,strawberry,72,1.86,133.92,Homespun Pastures,7/7/2022,true,United States +535,grape,21,4.33,90.93,Homespun Pastures,8/30/2022,false,Brazil +536,apricot,31,2.39,74.09,Green Grocers,11/24/2022,false,Russia +537,pineapple,34,7.88,267.92,Green Grocers,5/18/2022,false,China +538,apple,5,0.39,1.95,Homespun Pastures,8/22/2022,true,China +539,apricot,97,9.32,904.04,Green Grocers,9/12/2022,false,China +540,strawberry,35,5.43,190.05,Green Grocers,4/9/2022,true,Canada +541,grapefruit,50,3.74,187.0,Fresh Fruits Inc.,1/9/2022,true,Thailand +542,mango,41,1.99,81.59,Green Grocers,8/10/2022,true,China +543,grape,98,5.67,555.66,Homespun Pastures,8/21/2022,true,Indonesia +544,pineapple,9,5.91,53.19,Fresh Fruits Inc.,6/26/2022,true,Malaysia +545,apricot,100,5.8,580.0,Fresh Fruits Inc.,5/30/2022,false,Colombia +546,banana,44,9.14,402.16,Homespun Pastures,1/13/2022,false,Pakistan +547,grapefruit,17,3.13,53.21,Homespun Pastures,2/17/2022,false,Syria +548,mango,100,6.28,628.0,Fresh Fruits Inc.,4/9/2022,false,Canada +549,banana,88,8.75,770.0,Homespun Pastures,11/6/2022,true,Russia +550,grape,7,4.29,30.03,Homespun Pastures,6/24/2022,false,Paraguay +551,apricot,56,5.89,329.84,Green Grocers,8/28/2022,false,Argentina +552,apple,94,6.01,564.94,Fresh Fruits Inc.,12/23/2022,true,Czech Republic +553,pineapple,70,5.5,385.0,Homespun Pastures,10/30/2022,false,Portugal +554,orange,59,2.45,144.55,Fresh Fruits Inc.,6/22/2022,false,Dominica +555,apricot,89,8.2,729.8,Homespun Pastures,8/15/2022,true,Indonesia +556,pineapple,88,0.83,73.04,Homespun Pastures,2/9/2022,true,Pakistan +557,apple,22,1.2,26.4,Green Grocers,11/23/2022,false,Japan +558,orange,51,8.55,436.05,Fresh Fruits Inc.,5/26/2022,true,China +559,grapefruit,67,1.59,106.53,Homespun Pastures,6/4/2022,false,South Africa +560,grape,52,9.56,497.12,Homespun Pastures,11/8/2022,false,Greece +561,strawberry,45,3.8,171.0,Fresh Fruits Inc.,4/15/2022,true,Jamaica +562,pineapple,31,6.84,212.04,Homespun Pastures,2/17/2022,false,China +563,apricot,22,4.88,107.36,Fresh Fruits Inc.,6/15/2022,false,Philippines +564,apricot,3,4.94,14.82,Fresh Fruits Inc.,2/24/2022,false,Argentina +565,strawberry,65,1.95,126.75,Green Grocers,12/29/2022,false,Cameroon +566,grapefruit,100,1.74,174.0,Green Grocers,11/24/2022,false,Democratic Republic of the Congo +567,orange,69,2.76,190.44,Homespun Pastures,8/26/2022,false,Philippines +568,mango,87,9.39,816.93,Green Grocers,4/20/2022,false,Honduras +569,apple,74,1.06,78.44,Fresh Fruits Inc.,2/13/2022,true,Russia +570,orange,52,0.92,47.84,Homespun Pastures,4/29/2022,true,Brazil +571,orange,100,6.44,644.0,Green Grocers,4/6/2022,true,Belarus +572,banana,2,7.53,15.06,Homespun Pastures,10/10/2022,true,China +573,banana,23,4.1,94.3,Fresh Fruits Inc.,10/17/2022,false,Indonesia +574,strawberry,99,3.38,334.62,Fresh Fruits Inc.,2/21/2022,false,China +575,grapefruit,91,0.13,11.83,Green Grocers,8/9/2022,true,Indonesia +576,orange,14,7.98,111.72,Homespun Pastures,6/17/2022,false,Burkina Faso +577,pineapple,82,0.42,34.44,Fresh Fruits Inc.,9/26/2022,true,China +578,strawberry,4,0.87,3.48,Homespun Pastures,9/20/2022,true,Paraguay +579,apricot,15,4.92,73.8,Homespun Pastures,6/24/2022,true,Belgium +580,mango,83,9.42,781.86,Homespun Pastures,1/24/2022,false,Poland +581,pineapple,57,2.44,139.08,Green Grocers,4/23/2022,false,China +582,strawberry,64,7.19,460.16,Fresh Fruits Inc.,8/1/2022,false,Philippines +583,orange,13,6.61,85.93,Fresh Fruits Inc.,4/25/2022,false,Russia +584,orange,33,8.36,275.88,Fresh Fruits Inc.,6/21/2022,false,Czech Republic +585,mango,14,0.72,10.08,Fresh Fruits Inc.,3/21/2022,true,Indonesia +586,banana,33,2.16,71.28,Homespun Pastures,1/19/2022,false,Brazil +587,strawberry,31,4.16,128.96,Homespun Pastures,6/8/2022,true,Portugal +588,banana,93,7.06,656.58,Green Grocers,10/8/2022,false,China +589,mango,76,2.62,199.12,Fresh Fruits Inc.,1/9/2022,false,Macedonia +590,apricot,46,2.13,97.98,Green Grocers,12/10/2022,true,Latvia +591,grapefruit,98,4.16,407.68,Homespun Pastures,9/20/2022,false,Armenia +592,apricot,84,3.57,299.88,Homespun Pastures,12/30/2022,true,South Korea +593,grape,15,3.16,47.4,Fresh Fruits Inc.,10/3/2022,true,Azerbaijan +594,grapefruit,16,2.35,37.6,Fresh Fruits Inc.,5/6/2022,true,Panama +595,grape,46,4.52,207.92,Green Grocers,6/16/2022,true,Indonesia +596,pineapple,61,8.49,517.89,Fresh Fruits Inc.,4/13/2022,false,Philippines +597,grapefruit,25,0.37,9.25,Fresh Fruits Inc.,9/20/2022,false,Indonesia +598,apricot,1,1.3,1.3,Green Grocers,3/20/2022,false,Russia +599,apricot,67,1.96,131.32,Fresh Fruits Inc.,1/10/2022,true,China +600,pineapple,57,7.24,412.68,Fresh Fruits Inc.,3/11/2022,true,South Africa +601,grape,95,3.77,358.15,Fresh Fruits Inc.,3/27/2022,true,French Polynesia +602,apricot,57,0.71,40.47,Homespun Pastures,5/22/2022,false,Bulgaria +603,pineapple,19,9.14,173.66,Homespun Pastures,7/6/2022,true,Bosnia and Herzegovina +604,apple,44,4.37,192.28,Fresh Fruits Inc.,3/10/2022,false,Canada +605,grape,31,7.3,226.3,Green Grocers,8/13/2022,false,China +606,grape,74,0.89,65.86,Fresh Fruits Inc.,3/3/2022,false,Indonesia +607,strawberry,91,1.98,180.18,Homespun Pastures,3/15/2022,false,China +608,apricot,98,4.69,459.62,Green Grocers,6/10/2022,false,Mexico +609,grape,14,2.72,38.08,Green Grocers,5/17/2022,false,United States +610,grapefruit,38,3.69,140.22,Fresh Fruits Inc.,1/7/2022,false,Bulgaria +611,grapefruit,56,7.28,407.68,Homespun Pastures,10/19/2022,true,Kenya +612,apricot,30,8.05,241.5,Green Grocers,12/13/2022,true,China +613,grapefruit,80,3.92,313.6,Homespun Pastures,11/21/2022,true,Indonesia +614,apple,72,7.33,527.76,Homespun Pastures,10/19/2022,true,Bosnia and Herzegovina +615,strawberry,50,1.74,87.0,Green Grocers,1/6/2022,true,Argentina +616,mango,90,1.08,97.2,Fresh Fruits Inc.,1/21/2022,true,Russia +617,pineapple,68,2.91,197.88,Fresh Fruits Inc.,10/4/2022,false,Philippines +618,apricot,90,5.42,487.8,Homespun Pastures,12/28/2022,true,Philippines +619,pineapple,40,6.98,279.2,Green Grocers,2/26/2022,true,Russia +620,pineapple,86,4.14,356.04,Fresh Fruits Inc.,8/4/2022,false,Belgium +621,grapefruit,64,0.94,60.16,Fresh Fruits Inc.,12/30/2022,false,China +622,strawberry,25,1.07,26.75,Fresh Fruits Inc.,4/8/2022,false,China +623,pineapple,49,9.92,486.08,Green Grocers,6/1/2022,true,Morocco +624,pineapple,71,0.98,69.58,Fresh Fruits Inc.,3/11/2022,true,Kazakhstan +625,banana,51,4.45,226.95,Fresh Fruits Inc.,1/28/2022,true,China +626,mango,48,2.17,104.16,Green Grocers,10/6/2022,true,China +627,pineapple,68,3.44,233.92,Green Grocers,3/16/2022,true,China +628,orange,28,7.47,209.16,Fresh Fruits Inc.,3/19/2022,true,Indonesia +629,mango,25,0.57,14.25,Fresh Fruits Inc.,1/2/2022,false,China +630,banana,50,8.04,402.0,Green Grocers,4/1/2022,false,Philippines +631,orange,74,8.21,607.54,Green Grocers,4/27/2022,false,Philippines +632,grapefruit,91,3.12,283.92,Green Grocers,5/5/2022,true,Philippines +633,banana,96,9.27,889.92,Green Grocers,7/12/2022,false,Iceland +634,banana,95,6.03,572.85,Fresh Fruits Inc.,7/20/2022,true,China +635,strawberry,73,6.88,502.24,Homespun Pastures,9/6/2022,true,China +636,mango,19,6.12,116.28,Fresh Fruits Inc.,6/3/2022,true,Philippines +637,apricot,12,8.16,97.92,Green Grocers,6/17/2022,true,Ireland +638,mango,37,9.39,347.43,Green Grocers,11/11/2022,true,Philippines +639,grapefruit,61,0.62,37.82,Green Grocers,1/28/2022,true,Lebanon +640,apricot,93,5.39,501.27,Green Grocers,3/13/2022,true,Russia +641,strawberry,100,8.26,826.0,Homespun Pastures,8/16/2022,true,Russia +642,grape,32,0.56,17.92,Green Grocers,10/29/2022,false,Philippines +643,apricot,20,9.07,181.4,Fresh Fruits Inc.,6/2/2022,true,Madagascar +644,strawberry,74,5.42,401.08,Green Grocers,11/26/2022,true,Indonesia +645,strawberry,91,9.66,879.06,Fresh Fruits Inc.,6/5/2022,true,Finland +646,grape,76,2.88,218.88,Fresh Fruits Inc.,1/22/2022,true,Luxembourg +647,orange,27,0.47,12.69,Homespun Pastures,3/11/2022,true,Moldova +648,strawberry,73,3.47,253.31,Green Grocers,2/27/2022,false,Brazil +649,apple,74,3.42,253.08,Fresh Fruits Inc.,2/20/2022,true,Thailand +650,grape,33,8.49,280.17,Fresh Fruits Inc.,11/19/2022,false,Montenegro +651,orange,31,4.68,145.08,Green Grocers,3/9/2022,false,Sweden +652,grapefruit,57,0.76,43.32,Green Grocers,4/23/2022,false,Philippines +653,strawberry,100,1.79,179.0,Green Grocers,12/28/2022,false,Vietnam +654,apricot,30,9.52,285.6,Fresh Fruits Inc.,5/21/2022,true,Brazil +655,grape,60,2.81,168.6,Green Grocers,12/29/2022,true,Ukraine +656,orange,71,3.02,214.42,Fresh Fruits Inc.,5/13/2022,false,China +657,apricot,5,9.28,46.4,Fresh Fruits Inc.,12/20/2022,false,Indonesia +658,apple,47,1.48,69.56,Homespun Pastures,1/12/2022,false,Marshall Islands +659,grape,38,6.3,239.4,Fresh Fruits Inc.,3/6/2022,true,Philippines +660,apricot,5,3.76,18.8,Homespun Pastures,3/21/2022,true,China +661,mango,33,2.34,77.22,Fresh Fruits Inc.,1/31/2022,false,Madagascar +662,mango,59,5.11,301.49,Homespun Pastures,4/14/2022,true,Thailand +663,grapefruit,71,7.67,544.57,Homespun Pastures,2/23/2022,true,Thailand +664,apricot,97,9.51,922.47,Homespun Pastures,2/20/2022,false,Russia +665,pineapple,41,5.59,229.19,Fresh Fruits Inc.,9/2/2022,false,Russia +666,grapefruit,37,4.89,180.93,Fresh Fruits Inc.,7/6/2022,false,China +667,grapefruit,8,7.16,57.28,Homespun Pastures,10/22/2022,false,Australia +668,grapefruit,45,5.51,247.95,Green Grocers,2/1/2022,true,Argentina +669,grape,50,3.68,184.0,Homespun Pastures,9/12/2022,false,Thailand +670,pineapple,22,0.33,7.26,Fresh Fruits Inc.,12/11/2022,true,Argentina +671,banana,19,1.85,35.15,Homespun Pastures,9/5/2022,false,Bangladesh +672,apple,84,5.73,481.32,Green Grocers,6/9/2022,false,Canada +673,grape,55,6.5,357.5,Green Grocers,1/28/2022,true,China +674,banana,27,8.01,216.27,Green Grocers,6/25/2022,true,Spain +675,pineapple,92,4.49,413.08,Fresh Fruits Inc.,11/27/2022,true,Indonesia +676,grapefruit,15,5.0,75.0,Homespun Pastures,6/7/2022,false,China +677,orange,52,0.74,38.48,Green Grocers,8/21/2022,false,United States +678,orange,22,6.19,136.18,Green Grocers,9/14/2022,true,Indonesia +679,grape,61,5.18,315.98,Green Grocers,4/20/2022,false,Russia +680,grape,21,4.43,93.03,Fresh Fruits Inc.,12/5/2022,false,Sweden +681,grape,42,3.78,158.76,Fresh Fruits Inc.,2/14/2022,true,China +682,apple,19,5.69,108.11,Fresh Fruits Inc.,12/6/2022,false,Mexico +683,banana,14,6.07,84.98,Homespun Pastures,2/23/2022,true,Indonesia +684,orange,9,4.05,36.45,Green Grocers,7/17/2022,false,China +685,grape,46,6.2,285.2,Fresh Fruits Inc.,5/23/2022,false,Indonesia +686,apricot,40,6.54,261.6,Homespun Pastures,8/13/2022,false,Brazil +687,strawberry,82,3.25,266.5,Green Grocers,10/3/2022,false,China +688,pineapple,20,9.92,198.4,Green Grocers,6/28/2022,false,Israel +689,apricot,3,3.96,11.88,Fresh Fruits Inc.,4/18/2022,false,China +690,apple,96,7.27,697.92,Fresh Fruits Inc.,1/29/2022,true,China +691,mango,31,5.46,169.26,Fresh Fruits Inc.,9/7/2022,false,Syria +692,apricot,13,6.39,83.07,Green Grocers,9/28/2022,true,Peru +693,banana,80,6.77,541.6,Fresh Fruits Inc.,5/22/2022,true,China +694,grapefruit,48,6.25,300.0,Fresh Fruits Inc.,8/30/2022,false,Indonesia +695,mango,47,1.39,65.33,Green Grocers,9/15/2022,false,China +696,grape,8,3.08,24.64,Fresh Fruits Inc.,2/11/2022,false,Slovenia +697,orange,86,2.57,221.02,Fresh Fruits Inc.,8/13/2022,true,Syria +698,grape,100,1.71,171.0,Green Grocers,3/2/2022,true,Hungary +699,apple,65,6.84,444.6,Homespun Pastures,9/5/2022,false,Peru +700,mango,60,4.26,255.6,Fresh Fruits Inc.,10/30/2022,false,China +701,orange,65,9.44,613.6,Green Grocers,9/10/2022,true,Philippines +702,banana,44,5.45,239.8,Green Grocers,7/15/2022,false,Vietnam +703,grape,51,9.64,491.64,Homespun Pastures,3/29/2022,false,Mexico +704,mango,42,7.59,318.78,Fresh Fruits Inc.,9/10/2022,false,South Korea +705,apple,60,7.69,461.4,Green Grocers,9/22/2022,true,Poland +706,pineapple,10,2.04,20.4,Green Grocers,6/23/2022,false,Indonesia +707,banana,66,6.18,407.88,Fresh Fruits Inc.,12/6/2022,false,Madagascar +708,grapefruit,76,8.92,677.92,Homespun Pastures,8/10/2022,false,Tajikistan +709,mango,92,3.98,366.16,Homespun Pastures,4/25/2022,true,North Korea +710,pineapple,99,6.92,685.08,Homespun Pastures,3/15/2022,false,China +711,grapefruit,35,5.8,203.0,Green Grocers,11/16/2022,false,Portugal +712,mango,20,7.02,140.4,Fresh Fruits Inc.,8/8/2022,false,Indonesia +713,apple,3,3.92,11.76,Green Grocers,11/26/2022,true,China +714,grapefruit,98,2.12,207.76,Homespun Pastures,6/8/2022,false,Philippines +715,banana,92,6.39,587.88,Homespun Pastures,6/3/2022,true,Czech Republic +716,mango,90,9.76,878.4,Homespun Pastures,4/16/2022,true,Brazil +717,grapefruit,64,1.98,126.72,Fresh Fruits Inc.,9/13/2022,true,China +718,orange,72,8.93,642.96,Homespun Pastures,4/24/2022,true,Poland +719,strawberry,77,0.79,60.83,Fresh Fruits Inc.,12/3/2022,true,Finland +720,grape,17,5.57,94.69,Homespun Pastures,10/26/2022,true,Indonesia +721,banana,100,4.51,451.0,Fresh Fruits Inc.,12/7/2022,false,Japan +722,grapefruit,4,9.87,39.48,Green Grocers,9/21/2022,false,Bangladesh +723,apple,100,1.78,178.0,Green Grocers,8/20/2022,true,Philippines +724,grapefruit,60,2.85,171.0,Green Grocers,1/3/2022,false,Sweden +725,grapefruit,59,0.63,37.17,Homespun Pastures,10/5/2022,false,China +726,grape,35,9.66,338.1,Homespun Pastures,1/4/2022,false,China +727,grape,84,8.08,678.72,Green Grocers,4/13/2022,false,Russia +728,grapefruit,80,0.61,48.8,Fresh Fruits Inc.,3/31/2022,false,Poland +729,strawberry,15,4.05,60.75,Green Grocers,11/22/2022,true,China +730,apple,55,1.06,58.3,Homespun Pastures,10/8/2022,false,Kyrgyzstan +731,grapefruit,68,1.11,75.48,Green Grocers,10/21/2022,false,Indonesia +732,mango,20,7.41,148.2,Fresh Fruits Inc.,5/18/2022,false,Indonesia +733,pineapple,54,7.99,431.46,Green Grocers,3/17/2022,true,Dominican Republic +734,apple,99,2.31,228.69,Green Grocers,3/14/2022,false,Peru +735,pineapple,41,1.7,69.7,Homespun Pastures,10/20/2022,false,Belarus +736,apricot,35,6.04,211.4,Homespun Pastures,11/29/2022,false,Portugal +737,apple,44,3.43,150.92,Fresh Fruits Inc.,7/4/2022,true,Portugal +738,orange,36,7.06,254.16,Fresh Fruits Inc.,11/22/2022,true,Indonesia +739,strawberry,97,4.96,481.12,Fresh Fruits Inc.,7/23/2022,false,South Africa +740,strawberry,51,7.58,386.58,Homespun Pastures,8/23/2022,false,Pakistan +741,grapefruit,16,3.49,55.84,Green Grocers,12/17/2022,true,Sweden +742,grape,9,3.28,29.52,Fresh Fruits Inc.,6/20/2022,true,Azerbaijan +743,grape,81,0.75,60.75,Green Grocers,12/21/2022,true,France +744,mango,31,1.41,43.71,Green Grocers,10/6/2022,true,Moldova +745,banana,32,1.52,48.64,Homespun Pastures,3/20/2022,true,Sweden +746,apple,89,8.75,778.75,Homespun Pastures,2/11/2022,false,Philippines +747,mango,11,2.51,27.61,Green Grocers,4/18/2022,false,China +748,pineapple,51,7.33,373.83,Homespun Pastures,3/28/2022,true,Japan +749,pineapple,2,8.93,17.86,Fresh Fruits Inc.,3/15/2022,true,Indonesia +750,grape,70,9.73,681.1,Green Grocers,2/19/2022,true,Portugal +751,apricot,2,7.16,14.32,Green Grocers,6/20/2022,false,China +752,orange,90,2.29,206.1,Green Grocers,3/2/2022,false,France +753,strawberry,40,5.05,202.0,Green Grocers,6/15/2022,false,Brazil +754,banana,75,2.92,219.0,Green Grocers,11/13/2022,false,China +755,strawberry,76,9.45,718.2,Green Grocers,10/4/2022,true,Peru +756,strawberry,11,7.45,81.95,Green Grocers,6/24/2022,false,China +757,strawberry,16,2.22,35.52,Homespun Pastures,7/31/2022,false,China +758,apricot,73,5.47,399.31,Fresh Fruits Inc.,3/31/2022,false,China +759,pineapple,27,5.97,161.19,Homespun Pastures,9/16/2022,true,Colombia +760,strawberry,44,8.07,355.08,Homespun Pastures,3/21/2022,true,Indonesia +761,orange,30,9.1,273.0,Green Grocers,12/25/2022,false,Pakistan +762,strawberry,54,0.9,48.6,Fresh Fruits Inc.,10/27/2022,true,France +763,grapefruit,45,7.75,348.75,Fresh Fruits Inc.,1/4/2022,true,Philippines +764,orange,5,4.67,23.35,Fresh Fruits Inc.,9/22/2022,true,Indonesia +765,pineapple,23,6.07,139.61,Green Grocers,8/9/2022,true,Nicaragua +766,strawberry,80,7.76,620.8,Homespun Pastures,2/13/2022,false,France +767,pineapple,29,9.62,278.98,Green Grocers,6/17/2022,false,Indonesia +768,strawberry,73,1.99,145.27,Green Grocers,6/2/2022,false,China +769,strawberry,8,9.52,76.16,Green Grocers,3/2/2022,true,Morocco +770,mango,32,6.61,211.52,Green Grocers,6/28/2022,false,United States +771,mango,86,2.62,225.32,Green Grocers,7/15/2022,false,Canada +772,orange,92,8.76,805.92,Homespun Pastures,2/14/2022,false,Indonesia +773,banana,33,4.5,148.5,Homespun Pastures,8/10/2022,true,Brazil +774,apricot,30,7.88,236.4,Homespun Pastures,9/22/2022,true,Indonesia +775,grapefruit,89,6.01,534.89,Green Grocers,2/4/2022,true,Japan +776,apple,23,3.21,73.83,Homespun Pastures,1/8/2022,true,Philippines +777,apple,97,6.8,659.6,Homespun Pastures,12/29/2022,true,Russia +778,apple,92,6.69,615.48,Homespun Pastures,11/6/2022,false,Sweden +779,banana,7,4.21,29.47,Green Grocers,4/30/2022,false,Indonesia +780,mango,100,2.07,207.0,Homespun Pastures,5/5/2022,true,Portugal +781,grape,35,0.84,29.4,Fresh Fruits Inc.,9/26/2022,true,China +782,apricot,30,9.98,299.4,Green Grocers,7/16/2022,true,Indonesia +783,pineapple,48,1.76,84.48,Fresh Fruits Inc.,1/30/2022,false,Uganda +784,apricot,21,9.5,199.5,Fresh Fruits Inc.,2/2/2022,false,China +785,grapefruit,41,9.57,392.37,Fresh Fruits Inc.,3/11/2022,false,Iran +786,banana,73,5.04,367.92,Green Grocers,9/22/2022,false,China +787,banana,24,8.25,198.0,Homespun Pastures,3/12/2022,false,China +788,grape,77,0.43,33.11,Green Grocers,7/14/2022,false,China +789,orange,59,6.04,356.36,Homespun Pastures,5/29/2022,false,Somalia +790,banana,39,9.04,352.56,Fresh Fruits Inc.,12/30/2022,false,China +791,banana,78,5.11,398.58,Homespun Pastures,2/27/2022,false,China +792,strawberry,89,2.55,226.95,Green Grocers,6/17/2022,true,Brazil +793,banana,8,1.48,11.84,Fresh Fruits Inc.,8/27/2022,false,China +794,apple,74,7.17,530.58,Homespun Pastures,7/27/2022,false,Czech Republic +795,strawberry,7,3.92,27.44,Homespun Pastures,9/10/2022,true,France +796,apple,81,9.15,741.15,Green Grocers,11/19/2022,false,Macedonia +797,strawberry,24,8.58,205.92,Green Grocers,5/24/2022,false,Kosovo +798,apricot,68,4.54,308.72,Homespun Pastures,8/1/2022,true,Thailand +799,strawberry,58,2.32,134.56,Fresh Fruits Inc.,9/30/2022,true,Sweden +800,strawberry,84,7.99,671.16,Fresh Fruits Inc.,10/12/2022,true,China +801,grape,62,1.47,91.14,Homespun Pastures,6/3/2022,true,Mozambique +802,apricot,91,1.43,130.13,Homespun Pastures,10/25/2022,false,Philippines +803,grape,16,8.72,139.52,Homespun Pastures,3/17/2022,false,Norway +804,strawberry,7,0.58,4.06,Green Grocers,2/14/2022,false,France +805,apricot,78,7.8,608.4,Green Grocers,11/29/2022,true,Indonesia +806,grapefruit,39,4.1,159.9,Homespun Pastures,4/15/2022,false,China +807,apple,97,5.77,559.69,Fresh Fruits Inc.,11/15/2022,true,China +808,banana,55,6.87,377.85,Green Grocers,10/15/2022,false,Kyrgyzstan +809,strawberry,70,9.99,699.3,Homespun Pastures,11/16/2022,false,United States +810,apple,100,0.32,32.0,Homespun Pastures,3/30/2022,false,China +811,orange,22,9.11,200.42,Green Grocers,8/16/2022,false,China +812,grape,83,4.71,390.93,Fresh Fruits Inc.,1/6/2022,true,Nigeria +813,apple,50,8.79,439.5,Fresh Fruits Inc.,9/17/2022,true,China +814,banana,59,4.62,272.58,Green Grocers,6/17/2022,false,Portugal +815,mango,39,3.94,153.66,Green Grocers,7/12/2022,false,Madagascar +816,grapefruit,80,0.44,35.2,Homespun Pastures,6/18/2022,false,Myanmar +817,orange,71,5.5,390.5,Fresh Fruits Inc.,7/7/2022,true,Portugal +818,mango,46,5.44,250.24,Fresh Fruits Inc.,6/15/2022,false,Nigeria +819,apricot,7,2.2,15.4,Green Grocers,1/4/2022,false,Finland +820,pineapple,35,0.93,32.55,Fresh Fruits Inc.,10/22/2022,true,Indonesia +821,pineapple,49,0.15,7.35,Fresh Fruits Inc.,3/7/2022,false,Saint Lucia +822,banana,1,2.99,2.99,Homespun Pastures,6/30/2022,false,Portugal +823,orange,92,4.54,417.68,Fresh Fruits Inc.,7/7/2022,false,Ivory Coast +824,grape,19,8.13,154.47,Green Grocers,11/29/2022,false,Mexico +825,grape,98,8.21,804.58,Fresh Fruits Inc.,5/4/2022,true,Philippines +826,strawberry,64,9.89,632.96,Fresh Fruits Inc.,2/20/2022,true,China +827,grape,76,3.26,247.76,Fresh Fruits Inc.,2/1/2022,true,Morocco +828,mango,57,8.87,505.59,Green Grocers,11/23/2022,true,Philippines +829,banana,71,5.6,397.6,Homespun Pastures,2/8/2022,true,China +830,mango,60,4.19,251.4,Homespun Pastures,7/3/2022,false,Niue +831,grape,83,8.46,702.18,Homespun Pastures,10/27/2022,true,Philippines +832,apricot,55,2.19,120.45,Fresh Fruits Inc.,8/19/2022,false,Mongolia +833,mango,19,9.33,177.27,Homespun Pastures,5/6/2022,true,Russia +834,apple,5,0.15,0.75,Green Grocers,7/16/2022,false,Slovenia +835,orange,84,7.66,643.44,Green Grocers,11/12/2022,false,Russia +836,mango,37,1.69,62.53,Green Grocers,6/12/2022,false,Paraguay +837,pineapple,76,9.54,725.04,Fresh Fruits Inc.,8/26/2022,true,Vietnam +838,banana,7,9.88,69.16,Homespun Pastures,3/13/2022,false,Philippines +839,apple,78,2.61,203.58,Homespun Pastures,9/12/2022,false,Oman +840,banana,24,0.66,15.84,Fresh Fruits Inc.,11/21/2022,false,Malta +841,orange,37,6.13,226.81,Homespun Pastures,2/3/2022,false,Sweden +842,apple,30,5.06,151.8,Green Grocers,3/17/2022,false,Mexico +843,grapefruit,86,7.28,626.08,Green Grocers,3/13/2022,false,Venezuela +844,banana,73,2.88,210.24,Green Grocers,1/5/2022,false,Japan +845,pineapple,57,2.29,130.53,Green Grocers,7/1/2022,true,Brazil +846,strawberry,78,4.37,340.86,Fresh Fruits Inc.,2/20/2022,true,Indonesia +847,banana,39,8.59,335.01,Green Grocers,4/12/2022,false,Cape Verde +848,pineapple,37,0.42,15.54,Fresh Fruits Inc.,10/13/2022,false,Poland +849,apple,27,0.97,26.19,Green Grocers,12/26/2022,false,China +850,mango,20,0.85,17.0,Green Grocers,12/1/2022,false,Philippines +851,grape,21,4.9,102.9,Green Grocers,3/6/2022,false,Greece +852,strawberry,59,0.96,56.64,Homespun Pastures,11/11/2022,false,Thailand +853,mango,44,6.88,302.72,Fresh Fruits Inc.,5/20/2022,true,Russia +854,apricot,71,8.79,624.09,Green Grocers,4/13/2022,true,Georgia +855,apricot,29,5.66,164.14,Green Grocers,12/2/2022,false,Indonesia +856,grape,91,9.04,822.64,Fresh Fruits Inc.,12/13/2022,false,Iran +857,banana,79,5.3,418.7,Green Grocers,2/14/2022,true,Norway +858,strawberry,30,6.87,206.1,Fresh Fruits Inc.,4/26/2022,false,Macedonia +859,apricot,7,1.62,11.34,Homespun Pastures,4/5/2022,false,Latvia +860,orange,38,2.79,106.02,Green Grocers,8/22/2022,true,Philippines +861,banana,47,9.36,439.92,Green Grocers,1/8/2022,false,South Korea +862,grape,40,0.62,24.8,Green Grocers,6/19/2022,true,Vietnam +863,strawberry,76,2.02,153.52,Fresh Fruits Inc.,12/27/2022,true,Philippines +864,grapefruit,65,8.67,563.55,Homespun Pastures,10/17/2022,true,China +865,apricot,49,0.19,9.31,Homespun Pastures,11/28/2022,false,Pakistan +866,mango,97,5.41,524.77,Green Grocers,2/13/2022,false,China +867,apricot,90,7.98,718.2,Fresh Fruits Inc.,4/3/2022,false,China +868,grape,99,1.58,156.42,Homespun Pastures,9/28/2022,false,Brazil +869,grapefruit,65,1.59,103.35,Homespun Pastures,3/25/2022,true,Brazil +870,grapefruit,67,2.0,134.0,Green Grocers,12/12/2022,true,China +871,orange,29,4.71,136.59,Homespun Pastures,3/5/2022,true,Indonesia +872,apricot,12,1.08,12.96,Fresh Fruits Inc.,5/27/2022,false,China +873,pineapple,38,9.01,342.38,Green Grocers,10/24/2022,false,Brazil +874,apricot,51,2.91,148.41,Homespun Pastures,10/30/2022,false,Latvia +875,apple,33,0.34,11.22,Fresh Fruits Inc.,11/19/2022,true,China +876,apricot,89,2.71,241.19,Green Grocers,3/8/2022,true,Sweden +877,strawberry,9,6.07,54.63,Homespun Pastures,11/25/2022,true,Sudan +878,apricot,42,1.77,74.34,Homespun Pastures,4/4/2022,true,Nicaragua +879,banana,20,5.56,111.2,Fresh Fruits Inc.,9/6/2022,false,Czech Republic +880,pineapple,47,7.86,369.42,Fresh Fruits Inc.,8/17/2022,false,Indonesia +881,apple,16,1.62,25.92,Green Grocers,8/10/2022,true,China +882,orange,98,3.46,339.08,Fresh Fruits Inc.,1/3/2022,true,Portugal +883,strawberry,17,1.66,28.22,Fresh Fruits Inc.,7/4/2022,true,South Africa +884,orange,13,9.9,128.7,Fresh Fruits Inc.,5/24/2022,false,China +885,mango,25,5.74,143.5,Fresh Fruits Inc.,4/12/2022,false,Greece +886,grape,72,9.67,696.24,Green Grocers,1/30/2022,false,Portugal +887,pineapple,19,0.93,17.67,Green Grocers,2/7/2022,true,Japan +888,orange,86,6.34,545.24,Fresh Fruits Inc.,9/1/2022,true,Indonesia +889,apple,46,7.04,323.84,Fresh Fruits Inc.,4/9/2022,true,Japan +890,strawberry,28,9.77,273.56,Fresh Fruits Inc.,1/30/2022,true,Colombia +891,strawberry,45,4.79,215.55,Green Grocers,11/14/2022,true,Indonesia +892,apple,16,3.28,52.48,Fresh Fruits Inc.,2/17/2022,true,United States +893,grapefruit,11,9.26,101.86,Fresh Fruits Inc.,10/10/2022,true,Palestinian Territory +894,apricot,44,7.49,329.56,Homespun Pastures,2/10/2022,true,Kazakhstan +895,grape,98,2.94,288.12,Fresh Fruits Inc.,7/23/2022,false,Philippines +896,grape,60,6.41,384.6,Green Grocers,9/30/2022,true,Indonesia +897,pineapple,19,6.03,114.57,Fresh Fruits Inc.,5/24/2022,false,France +898,grape,8,7.39,59.12,Homespun Pastures,10/18/2022,false,China +899,banana,87,9.36,814.32,Green Grocers,7/17/2022,false,Brazil +900,mango,45,4.41,198.45,Fresh Fruits Inc.,7/13/2022,true,Brazil +901,strawberry,17,1.06,18.02,Fresh Fruits Inc.,2/13/2022,false,Japan +902,mango,44,8.69,382.36,Fresh Fruits Inc.,12/3/2022,true,Egypt +903,grape,29,9.13,264.77,Green Grocers,6/16/2022,false,China +904,grapefruit,29,4.67,135.43,Homespun Pastures,10/14/2022,false,Russia +905,apricot,2,7.48,14.96,Green Grocers,4/14/2022,true,Honduras +906,mango,78,8.09,631.02,Fresh Fruits Inc.,12/2/2022,true,South Africa +907,strawberry,40,8.82,352.8,Homespun Pastures,11/22/2022,true,China +908,orange,90,9.76,878.4,Green Grocers,2/11/2022,true,Poland +909,apricot,47,3.76,176.72,Green Grocers,2/3/2022,true,Brazil +910,mango,39,6.45,251.55,Green Grocers,8/12/2022,false,China +911,strawberry,18,9.65,173.7,Green Grocers,5/21/2022,true,Cape Verde +912,apricot,30,5.06,151.8,Fresh Fruits Inc.,7/15/2022,false,Indonesia +913,mango,74,1.93,142.82,Homespun Pastures,3/9/2022,true,Croatia +914,mango,98,9.15,896.7,Fresh Fruits Inc.,3/27/2022,true,China +915,mango,81,4.55,368.55,Homespun Pastures,1/25/2022,false,Yemen +916,mango,58,0.8,46.4,Fresh Fruits Inc.,11/26/2022,true,Indonesia +917,banana,20,4.74,94.8,Green Grocers,10/17/2022,true,Russia +918,strawberry,85,4.47,379.95,Fresh Fruits Inc.,8/21/2022,true,Colombia +919,apricot,20,7.09,141.8,Homespun Pastures,7/6/2022,false,China +920,orange,47,0.47,22.09,Fresh Fruits Inc.,7/25/2022,true,China +921,apricot,28,7.53,210.84,Green Grocers,1/18/2022,false,Mauritius +922,grapefruit,31,6.06,187.86,Green Grocers,8/16/2022,false,China +923,grapefruit,50,1.2,60.0,Green Grocers,5/19/2022,true,Finland +924,mango,14,2.52,35.28,Green Grocers,6/29/2022,true,France +925,orange,2,8.65,17.3,Green Grocers,10/19/2022,false,Ukraine +926,banana,72,7.96,573.12,Fresh Fruits Inc.,6/28/2022,false,Indonesia +927,grapefruit,43,7.67,329.81,Homespun Pastures,10/3/2022,false,Portugal +928,grape,35,9.46,331.1,Green Grocers,1/23/2022,false,Brazil +929,apricot,26,7.76,201.76,Homespun Pastures,11/8/2022,true,Lithuania +930,orange,74,2.22,164.28,Homespun Pastures,4/8/2022,true,Sweden +931,apricot,5,7.07,35.35,Fresh Fruits Inc.,1/5/2022,false,Indonesia +932,pineapple,52,0.75,39.0,Fresh Fruits Inc.,3/6/2022,true,Afghanistan +933,apple,84,6.94,582.96,Green Grocers,12/4/2022,true,United States +934,pineapple,44,8.78,386.32,Green Grocers,1/27/2022,true,Peru +935,mango,35,6.44,225.4,Fresh Fruits Inc.,10/1/2022,true,Canada +936,grapefruit,1,5.23,5.23,Homespun Pastures,9/3/2022,true,Bangladesh +937,grape,68,6.55,445.4,Green Grocers,2/25/2022,true,Sweden +938,strawberry,35,7.52,263.2,Green Grocers,2/2/2022,false,Indonesia +939,grapefruit,33,6.44,212.52,Green Grocers,1/29/2022,true,Indonesia +940,strawberry,73,3.28,239.44,Homespun Pastures,1/27/2022,true,Peru +941,apple,45,0.45,20.25,Homespun Pastures,8/9/2022,true,China +942,apple,26,6.3,163.8,Green Grocers,11/3/2022,false,China +943,grape,60,2.25,135.0,Green Grocers,12/6/2022,false,Finland +944,strawberry,95,3.88,368.6,Homespun Pastures,2/9/2022,true,Portugal +945,grapefruit,54,2.69,145.26,Green Grocers,4/15/2022,true,Vietnam +946,strawberry,79,8.01,632.79,Fresh Fruits Inc.,10/17/2022,true,Brazil +947,banana,31,1.12,34.72,Fresh Fruits Inc.,7/27/2022,true,Thailand +948,banana,85,9.05,769.25,Fresh Fruits Inc.,11/8/2022,true,Mexico +949,pineapple,63,5.74,361.62,Fresh Fruits Inc.,6/20/2022,true,Kuwait +950,orange,60,3.93,235.8,Homespun Pastures,4/10/2022,true,Luxembourg +951,pineapple,74,9.22,682.28,Green Grocers,1/22/2022,true,China +952,apple,43,6.52,280.36,Homespun Pastures,5/30/2022,true,Indonesia +953,apple,65,6.33,411.45,Homespun Pastures,9/7/2022,false,Ethiopia +954,orange,68,5.31,361.08,Fresh Fruits Inc.,4/10/2022,true,Brazil +955,orange,71,1.76,124.96,Green Grocers,6/15/2022,true,Russia +956,mango,37,2.68,99.16,Homespun Pastures,10/12/2022,true,Czech Republic +957,orange,20,3.35,67.0,Green Grocers,10/4/2022,false,China +958,strawberry,65,9.27,602.55,Green Grocers,11/14/2022,false,Belarus +959,orange,5,3.04,15.2,Fresh Fruits Inc.,2/22/2022,false,Czech Republic +960,grape,88,8.59,755.92,Fresh Fruits Inc.,4/16/2022,false,Czech Republic +961,orange,98,6.2,607.6,Fresh Fruits Inc.,3/2/2022,true,Myanmar +962,apricot,9,5.96,53.64,Fresh Fruits Inc.,3/24/2022,false,Cuba +963,apple,26,4.39,114.14,Green Grocers,1/22/2022,true,Portugal +964,apricot,56,0.19,10.64,Homespun Pastures,4/7/2022,true,France +965,grapefruit,16,1.51,24.16,Homespun Pastures,8/28/2022,true,Lithuania +966,apple,73,9.0,657.0,Fresh Fruits Inc.,10/10/2022,true,Colombia +967,grapefruit,83,4.61,382.63,Green Grocers,8/10/2022,true,China +968,grape,80,1.48,118.4,Fresh Fruits Inc.,7/19/2022,true,Afghanistan +969,apple,89,6.64,590.96,Homespun Pastures,8/4/2022,true,Latvia +970,orange,57,4.69,267.33,Fresh Fruits Inc.,9/10/2022,true,Philippines +971,orange,68,6.95,472.6,Homespun Pastures,3/9/2022,false,France +972,orange,7,9.67,67.69,Fresh Fruits Inc.,12/20/2022,true,United States +973,mango,28,5.55,155.4,Fresh Fruits Inc.,10/14/2022,false,China +974,strawberry,99,8.74,865.26,Green Grocers,10/26/2022,false,Ireland +975,banana,47,0.83,39.01,Green Grocers,3/30/2022,false,Czech Republic +976,banana,18,9.55,171.9,Green Grocers,11/20/2022,true,China +977,pineapple,48,2.24,107.52,Green Grocers,10/28/2022,false,China +978,grape,34,8.39,285.26,Homespun Pastures,12/15/2022,false,Nigeria +979,pineapple,72,0.06,4.32,Green Grocers,12/28/2022,false,Poland +980,strawberry,59,1.77,104.43,Homespun Pastures,1/20/2022,true,France +981,grape,51,7.03,358.53,Fresh Fruits Inc.,11/30/2022,true,China +982,grapefruit,63,9.67,609.21,Green Grocers,4/1/2022,false,Greece +983,mango,48,2.61,125.28,Fresh Fruits Inc.,12/24/2022,true,Philippines +984,orange,69,9.3,641.7,Fresh Fruits Inc.,12/13/2022,true,Colombia +985,mango,71,3.79,269.09,Homespun Pastures,6/17/2022,false,Czech Republic +986,pineapple,60,4.19,251.4,Homespun Pastures,12/6/2022,true,Ukraine +987,strawberry,74,3.76,278.24,Fresh Fruits Inc.,12/23/2022,false,China +988,apricot,36,7.68,276.48,Fresh Fruits Inc.,3/25/2022,false,Brazil +989,apricot,53,5.92,313.76,Homespun Pastures,9/15/2022,true,Philippines +990,grape,11,9.59,105.49,Fresh Fruits Inc.,4/11/2022,false,Portugal +991,grapefruit,38,4.69,178.22,Homespun Pastures,4/10/2022,true,Canada +992,pineapple,9,0.15,1.35,Fresh Fruits Inc.,4/4/2022,true,Libya +993,banana,50,4.76,238.0,Fresh Fruits Inc.,5/18/2022,true,Indonesia +994,pineapple,81,3.95,319.95,Fresh Fruits Inc.,4/13/2022,true,Russia +995,banana,51,2.55,130.05,Green Grocers,10/10/2022,false,France +996,grapefruit,8,9.32,74.56,Fresh Fruits Inc.,7/7/2022,true,Indonesia +997,orange,32,9.51,304.32,Green Grocers,8/9/2022,true,Panama +998,banana,83,2.48,205.84,Homespun Pastures,11/5/2022,true,Norway +999,grapefruit,1,1.4,1.4,Fresh Fruits Inc.,1/16/2022,false,Indonesia +1000,pineapple,91,4.89,444.99,Fresh Fruits Inc.,11/13/2022,false,Norway diff --git a/tests/data/fruit_records.csv.bz2 b/tests/data/fruit_records.csv.bz2 new file mode 100644 index 0000000..e5dd479 Binary files /dev/null and b/tests/data/fruit_records.csv.bz2 differ diff --git a/tests/data/fruit_records.csv.gz b/tests/data/fruit_records.csv.gz new file mode 100644 index 0000000..022614a Binary files /dev/null and b/tests/data/fruit_records.csv.gz differ diff --git a/tests/data/fruit_records.csv.lzma b/tests/data/fruit_records.csv.lzma new file mode 100644 index 0000000..ecb9495 Binary files /dev/null and b/tests/data/fruit_records.csv.lzma differ diff --git a/tests/data/fruit_records.csv.xz b/tests/data/fruit_records.csv.xz new file mode 100644 index 0000000..bedc4eb Binary files /dev/null and b/tests/data/fruit_records.csv.xz differ diff --git a/tests/data/fruit_records.zip b/tests/data/fruit_records.zip new file mode 100644 index 0000000..6fa7a30 Binary files /dev/null and b/tests/data/fruit_records.zip differ diff --git a/tests/data/small_fruit.csv b/tests/data/small_fruit.csv new file mode 100644 index 0000000..6e94681 --- /dev/null +++ b/tests/data/small_fruit.csv @@ -0,0 +1,6 @@ +id,name,quantity,supplier_name,organic,country_of_origin +1,pineapple,67,Homespun Pastures,false,Panama +2,grape,49,Homespun Pastures,false,China +3,orange,91,Green Grocers,false,Australia +4,apple,43,Fresh Fruits Inc.,false,Indonesia +5,grape,10,Green Grocers,true,Sweden diff --git a/tests/test_core.py b/tests/test_core.py index 9b7e9b7..a2d5cbc 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -1,17 +1,156 @@ """Tests standard tap features using the built-in SDK tests library.""" +# flake8: noqa +import io +import json +from collections import defaultdict +from contextlib import redirect_stdout +from pathlib import Path from singer_sdk.testing import get_tap_test_class from tap_file.tap import TapFile -SAMPLE_CONFIG = { - "protocol": "s3", - "filepath": "tap-file-taptesting/grocery", - # S3 access key and secret are retrieved from environment variables. +# Helper functions + + +def data_dir() -> str: + """Gets the directory in tests/data where data is stored. + + Returns: + A str representing a filepath to tests/data. + """ + return str(Path(__file__).parent / Path("./data")) + + +base_file_config = { + "protocol": "file", + "filepath": data_dir(), } -# Run standard built-in tap tests from the SDK: + +def execute_tap(config: dict = {}): + """Executes a TapFile tap. + + Args: + config: Configuration for the tap. Defaults to {}. + + Returns: + A dictionary containing messages about the tap's invocation, including, schema, + records (both messages about them and the records themselves), and state. + """ + schema_messages: list[dict] = [] + record_messages: list[dict] = [] + state_messages: list[dict] = [] + records: defaultdict = defaultdict(list) + + stdout_buf = io.StringIO() + with redirect_stdout(stdout_buf): + TapFile(config=config).run_sync_dry_run(dry_run_record_limit=None) + stdout_buf.seek(0) + + for message in [ + json.loads(line) for line in stdout_buf.read().strip().split("\n") if line + ]: + if message: + if message["type"] == "STATE": + state_messages.append(message) + continue + if message["type"] == "SCHEMA": + schema_messages.append(message) + continue + if message["type"] == "RECORD": + stream_name = message["stream"] + record_messages.append(message) + records[stream_name].append(message["record"]) + continue + return { + "schema_messages": schema_messages, + "record_messages": record_messages, + "state_messages": state_messages, + "records": records, + } + + +# Run standard built-in tap tests from the SDK on a simple csv. + +sample_config = base_file_config.copy() +sample_config.update({"file_regex": "fruit_records\\.csv"}) + TestTapFile = get_tap_test_class( tap_class=TapFile, - config=SAMPLE_CONFIG, + config=sample_config, +) + +# Run custom tests + +sdc_config = base_file_config.copy() +sdc_config.update({"file_regex": "^fruit_records\\.csv$", "additional_info": True}) +delimited_config = base_file_config.copy() +delimited_config.update( + {"file_type": "delimited", "file_regex": "^fruit_records\\.csv$"}, +) +jsonl_config = base_file_config.copy() +jsonl_config.update( + { + "file_type": "jsonl", + "file_regex": "^employees\\.jsonl$", + "jsonl_sampling_strategy": "first", + "jsonl_type_coercion_strategy": "string", + }, ) +avro_config = base_file_config.copy() +avro_config.update( + { + "file_type": "avro", + "file_regex": "^athletes\\.avro$", + "avro_type_coercion_strategy": "convert", + }, +) +s3_config = {"protocol": "s3", "filepath": "tap-file-taptesting/grocery"} +compression_config = base_file_config.copy() +compression_config.update( + { + "file_regex": "fruit_records", + "compression": "detect", + "delimited_delimiter": ",", + }, +) +header_footer_config = base_file_config.copy() +header_footer_config.update( + { + "file_regex": "^cats\\.csv$", + "delimited_header_skip": 3, + "delimited_footer_skip": 3, + }, +) + + +def test_sdc_fields_present(): + messages = execute_tap(sdc_config) + properties = messages["schema_messages"][0]["schema"]["properties"] + assert properties["_sdc_line_number"], "_sdc_line_number is not present in schema" + assert properties["_sdc_file_name"], "_sdc_file_name is not present in schema" + + +def test_delimited_execution(): + execute_tap(delimited_config) + + +def test_jsonl_execution(): + execute_tap(jsonl_config) + + +def test_avro_execution(): + execute_tap(avro_config) + + +def test_s3_execution(): + execute_tap(s3_config) + + +def test_compression_execution(): + execute_tap(compression_config) + + +def test_header_footer_execution(): + execute_tap(header_footer_config)