crc165-api


Namecrc165-api JSON
Version 0.1.4 PyPI version JSON
download
home_pagehttps://gitlab.ruhr-uni-bochum.de/icams-mids/crc1625rdmswrapper
SummaryPython wrapper for the CRC 1625 MatInf VRO API
upload_time2025-08-25 18:48:42
maintainerNone
docs_urlNone
authorDoaa Mohamed
requires_python>=3.7
licenseNone
keywords materials fair api crc165 data-management
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # CRC_API

A Python wrapper for the MatInf VRO API used in CRC 1625. It allows querying samples, associated objects, compositions, and properties.

## Installation

```bash
pip install crc1625-api
```

## 1. Initialize the client
```python
### Full Summary Query Example
from matinfwebapi.Api import MatInfWebApiClient


crc_api = MatInfWebApiClient(
    service_url="https://your-api-endpoint",  # e.g., "https://matinf-api.crc1625.de"
    api_key="your-api-token"
)
```
## 🧭 get_summary_fields() – Discover What You Can Search and Filter
Before performing a detailed query, it's helpful to know what types, elements, properties, and users exist in the database.
The get_summary_fields() method helps you explore all available options.

It retrieves:

 ✅ Associated Object Types – e.g., 'EDX CSV', 'Photo', 'Bandgap Plot'
 
 ✅ Property Names – e.g., 'Bandgap', 'Thickness', 'Resistance'

 ✅ Element Names – e.g., 'Ag', 'Pd', 'Pt', 'Cu'
 
 ✅ Creator Emails – list of all users who created objects

 ✅ Creator Usernames – system usernames linked to object creation

This is useful for building dropdowns in a UI, validating user input, or just understanding the structure of your research data.

##### 📌 Example:
You can use the output of this function to:
    Suggest available filters for users

    Know which properties or elements are supported

    Pre-fill search fields in automated scripts


```python
summary_fields = CRC_API.get_summary_fields()
# Convert and display each field as a table
display(pd.DataFrame(summary_fields["distinct_associated_typenames"], columns=["Associated Object Types"]))
```

## What Does get_summary() Do?
The get_summary() function collects detailed information about research objects (like samples) from the MatInf database. You can use it to:

#### ✅ Filter objects by:
    Type (e.g. "Sample")

    Date range (e.g. created between Jan 2024 and May 2025)

    Specific associated data types (e.g. EDX, Photo, Resistance CSV)

    Specific elements (e.g. only samples that contain Ag and Pd)

    Optional element percentage ranges (e.g. Pd between 5–20%)

#### ✅ Include in the output:

    Linked files (associated objects like images, CSVs, etc.)

    Properties of the object (e.g. Bandgap)

    Composition (element percentages)

    Properties of linked objects (e.g. bandgap of associated analysis file)

#### ✅ Export results:
    As a readable list of Python dictionaries Or save it as a .json file for reuse or sharing

##### 🧠 Example:
    We are retrieving all Sample objects:
       Created between 2024-01-01 and 2025-05-31, that are linked to EDX CSV, photo, and HTTS resistance CSV files, that contain Pd (5–20%) and Ag (any amount), and include the bandgap property (if available)

    The result will be saved in the results/ folder as summary_Sample.json.

### Full Summary Query Example
```python
summary = crc_api.get_summary(
    main_object="Sample",                        # Main object type to search
    start_date="2023-01-01",                         # Start of creation date range
    end_date="2025-01-01",                           # End of creation date range
    include_associated=True,                         # Include linked objects
    include_properties=True,                         # Include main object properties
    include_composition=True,                        # Include element composition
    include_linked_properties=True,                  # Include properties of associated objects
    user_associated_typenames=["EDX CSV", "HTTS Resistance CSV"],  # Associated object types to include
    property_names=["Bandgap"],        # Properties to extract
    required_elements={"Pt": (10, 90), "Pd": None},  # Filter for samples with elements in given range
    required_properties=["Bandgap"],                 # Filter for samples that include this property
    save_to_json=True,                               # Save summary to disk
    output_folder="summary_results"                  # Folder to save output
)

```

## Search and Download  Objects by Type, Elements, and Metadata

### 💡 What You Can Do with It:
    Query objects (e.g., Samples) by type, creation date, and creator.

    Filter objects based on associated data types (e.g., EDX, Photos, Resistance data).

    Refine your search using specific elements (e.g., Ag, Pd), including optional percentage ranges (e.g., Pd between 5% and 20%).

    Save results locally as .csv and .json files.

    Automatically download all linked files into structured folders for offline use.

    Export an Excel report that shows which users contributed to which data types.

    Support strict filtering, so only objects that match all required associated types are returned.

### 📘 Example Use Case in This Notebook:
    We are searching for:

        All Sample objects created between 2024-01-01 and 2025-05-31.

        That are linked to at least these types: EDX CSV, Photo, and HTTS Resistance CSV.

        That contain Ag (any amount) and Pd (between 5% and 20%) in their composition.

        (Optional) That were created by a specific user (filtered by email).

    All results will be saved locally, and relevant files will be downloaded automatically.

This tool supports FAIR data practices and can be useful for building datasets for machine learning, publication, or collaborative research.
```python
# Define parameters for processing data
typename_list = ['EDX CSV', 'Photo', 'HTTS Resistance CSV']
main_object = 'Sample'
start_date = '2024-01-01'
end_date = '2025-05-31'

# Elements with their percentage range (min, max)
element_criteria = {
    'Ag': (5, 20),
    'Pd': (5, 20)
}

# Define save location and output filename
save_location = "./results"
output_filename = "search_result.csv"

# Filter by creator's email
creator_email = "felix.thelen.rub@gmail.com"

# Call the search function with creator
df = CRC_API.search(
    associated_typenames=typename_list,
    main_object=main_object,
    start_date=start_date,
    end_date=end_date,
    element_criteria=element_criteria,
    #creator=creator_email,  
    strict=True,
    save_location=save_location,
    output_filename=output_filename
)


```

### Get the measurement with the object id
```python
main_objectID = 11104
associated_types = ["EDX CSV", "Photo"]
CRC_API.download_by_main_objectid( main_objectID , associated_types, download_folder="downloaded_files")
```

### 🧩 get_sample_typename_matrix(main_object="Sample")
Builds a binary matrix that shows which samples are associated with which object types (typenames).

✅ Features:

    Rows = Sample object IDs

    Columns = All typenames in the database

    Values = 1 if the sample has an association with that type, else 0

📘 Example:
```python
matrix_df = crc_api.get_sample_typename_matrix()
print(matrix_df.head())
```

### 🔗 get_sample_and_linked_properties()

Collects properties for each sample and its linked objects. Supports filtering by property type and name.

✅ Features:

    Retrieves Sample properties (Float, Int, String, BigString)

    Retrieves Linked object properties and averages numeric values across linked objects

    Supports filtering by property names and types

    Optionally includes or excludes objectname

    Can save results directly as CSV

🔧 Parameters:

    property_type: "float", "int", "string", "bigstring", or "all" (default = "all")

    property_names: list of property names to filter (default = all)

    include_objectname: whether to include the objectname column (default = True)

    save_to_csv: path to save CSV (default = None)

📘 Example:
```python
matrix_df = crc_api.get_sample_typename_matrix()
print(matrix_df.head())
```

## 📊 get_composition_table(value_type="ValuePercent")

Builds a pivot table showing the composition (element percentages or absolutes) for each measurement area, mapping from composition object → actual sample → measurement index.

✅ Output:

    composition_objectid

    actual_sample_objectid

    compoundindex

    measurement_area_index

    Wide-format element columns (e.g., Ag, Pd, Pt)

🔧 Parameters:

    value_type: "ValuePercent" (default) or "ValueAbsolute"

📘 Example:

```python
composition_df = crc_api.get_composition_table(value_type="ValuePercent")
```

## ⚡ extract_resistance_data()

Downloads and processes resistance measurement data (HTTS Resistance CSV), matches each with its linked Sample, and computes average resistance (R), current (I), and voltage (V) values over (x, y) positions.

✅ Outputs:

    Raw CSVs in resistance/

    Averaged CSVs in averaged_data/

    Merged result in output/resistance_summary.csv

📘 Example:

```python
crc_api.extract_resistance_data()
```

## 🧬 extract_xrd_data()

Processes XRD files of type "XRD CSV (342 columns)", links each XRD object to its Sample, performs interpolation on the two_theta range (e.g., 50% resampling), and saves results in both JSON and wide-format CSV.

✅ Outputs:

    Interpolated XRD data in JSON and CSV

    Output folder: XRD_CSV_342/

🔧 Parameters:

    percentage: Percentage of points to retain (default = 50.0)

    json_filename: JSON file name to save

    csv_filename: CSV file name to save

📘 Example:

```python
crc_api.extract_xrd_data(percentage=50.0)
```

## 📏 extract_thickness_data_from_typeid40()

Downloads .zip files of type ID 40 (thickness), extracts .dat files, parses numeric thickness values, computes statistics (mean, std), and links them to Sample objects.

✅ Outputs:

    Summary CSV with average and std dev per .dat file

    Output folders:

    Zips: thickness_zip/

    Extracted: thickness_data/

    Final summary: output/thickness_summary.csv

📘 Example:

```python
crc_api.extract_thickness_data_from_typeid40()
```

            

Raw data

            {
    "_id": null,
    "home_page": "https://gitlab.ruhr-uni-bochum.de/icams-mids/crc1625rdmswrapper",
    "name": "crc165-api",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": null,
    "keywords": "materials, FAIR, API, CRC165, data-management",
    "author": "Doaa Mohamed",
    "author_email": "Doaa Mohamed <doaamahmoud262@yahoo.com>",
    "download_url": "https://files.pythonhosted.org/packages/c4/a0/f61381d63ac4fe583794f3df39133149490256b724fce3a01e36063b00da/crc165_api-0.1.4.tar.gz",
    "platform": null,
    "description": "# CRC_API\r\n\r\nA Python wrapper for the MatInf VRO API used in CRC 1625. It allows querying samples, associated objects, compositions, and properties.\r\n\r\n## Installation\r\n\r\n```bash\r\npip install crc1625-api\r\n```\r\n\r\n## 1. Initialize the client\r\n```python\r\n### Full Summary Query Example\r\nfrom matinfwebapi.Api import MatInfWebApiClient\r\n\r\n\r\ncrc_api = MatInfWebApiClient(\r\n    service_url=\"https://your-api-endpoint\",  # e.g., \"https://matinf-api.crc1625.de\"\r\n    api_key=\"your-api-token\"\r\n)\r\n```\r\n## \ud83e\udded get_summary_fields() \u2013 Discover What You Can Search and Filter\r\nBefore performing a detailed query, it's helpful to know what types, elements, properties, and users exist in the database.\r\nThe get_summary_fields() method helps you explore all available options.\r\n\r\nIt retrieves:\r\n\r\n \u2705 Associated Object Types \u2013 e.g., 'EDX CSV', 'Photo', 'Bandgap Plot'\r\n \r\n \u2705 Property Names \u2013 e.g., 'Bandgap', 'Thickness', 'Resistance'\r\n\r\n \u2705 Element Names \u2013 e.g., 'Ag', 'Pd', 'Pt', 'Cu'\r\n \r\n \u2705 Creator Emails \u2013 list of all users who created objects\r\n\r\n \u2705 Creator Usernames \u2013 system usernames linked to object creation\r\n\r\nThis is useful for building dropdowns in a UI, validating user input, or just understanding the structure of your research data.\r\n\r\n##### \ud83d\udccc Example:\r\nYou can use the output of this function to:\r\n    Suggest available filters for users\r\n\r\n    Know which properties or elements are supported\r\n\r\n    Pre-fill search fields in automated scripts\r\n\r\n\r\n```python\r\nsummary_fields = CRC_API.get_summary_fields()\r\n# Convert and display each field as a table\r\ndisplay(pd.DataFrame(summary_fields[\"distinct_associated_typenames\"], columns=[\"Associated Object Types\"]))\r\n```\r\n\r\n## What Does get_summary() Do?\r\nThe get_summary() function collects detailed information about research objects (like samples) from the MatInf database. You can use it to:\r\n\r\n#### \u2705 Filter objects by:\r\n    Type (e.g. \"Sample\")\r\n\r\n    Date range (e.g. created between Jan 2024 and May 2025)\r\n\r\n    Specific associated data types (e.g. EDX, Photo, Resistance CSV)\r\n\r\n    Specific elements (e.g. only samples that contain Ag and Pd)\r\n\r\n    Optional element percentage ranges (e.g. Pd between 5\u201320%)\r\n\r\n#### \u2705 Include in the output:\r\n\r\n    Linked files (associated objects like images, CSVs, etc.)\r\n\r\n    Properties of the object (e.g. Bandgap)\r\n\r\n    Composition (element percentages)\r\n\r\n    Properties of linked objects (e.g. bandgap of associated analysis file)\r\n\r\n#### \u2705 Export results:\r\n    As a readable list of Python dictionaries Or save it as a .json file for reuse or sharing\r\n\r\n##### \ud83e\udde0 Example:\r\n    We are retrieving all Sample objects:\r\n       Created between 2024-01-01 and 2025-05-31, that are linked to EDX CSV, photo, and HTTS resistance CSV files, that contain Pd (5\u201320%) and Ag (any amount), and include the bandgap property (if available)\r\n\r\n    The result will be saved in the results/ folder as summary_Sample.json.\r\n\r\n### Full Summary Query Example\r\n```python\r\nsummary = crc_api.get_summary(\r\n    main_object=\"Sample\",                        # Main object type to search\r\n    start_date=\"2023-01-01\",                         # Start of creation date range\r\n    end_date=\"2025-01-01\",                           # End of creation date range\r\n    include_associated=True,                         # Include linked objects\r\n    include_properties=True,                         # Include main object properties\r\n    include_composition=True,                        # Include element composition\r\n    include_linked_properties=True,                  # Include properties of associated objects\r\n    user_associated_typenames=[\"EDX CSV\", \"HTTS Resistance CSV\"],  # Associated object types to include\r\n    property_names=[\"Bandgap\"],        # Properties to extract\r\n    required_elements={\"Pt\": (10, 90), \"Pd\": None},  # Filter for samples with elements in given range\r\n    required_properties=[\"Bandgap\"],                 # Filter for samples that include this property\r\n    save_to_json=True,                               # Save summary to disk\r\n    output_folder=\"summary_results\"                  # Folder to save output\r\n)\r\n\r\n```\r\n\r\n## Search and Download  Objects by Type, Elements, and Metadata\r\n\r\n### \ud83d\udca1 What You Can Do with It:\r\n    Query objects (e.g., Samples) by type, creation date, and creator.\r\n\r\n    Filter objects based on associated data types (e.g., EDX, Photos, Resistance data).\r\n\r\n    Refine your search using specific elements (e.g., Ag, Pd), including optional percentage ranges (e.g., Pd between 5% and 20%).\r\n\r\n    Save results locally as .csv and .json files.\r\n\r\n    Automatically download all linked files into structured folders for offline use.\r\n\r\n    Export an Excel report that shows which users contributed to which data types.\r\n\r\n    Support strict filtering, so only objects that match all required associated types are returned.\r\n\r\n### \ud83d\udcd8 Example Use Case in This Notebook:\r\n    We are searching for:\r\n\r\n        All Sample objects created between 2024-01-01 and 2025-05-31.\r\n\r\n        That are linked to at least these types: EDX CSV, Photo, and HTTS Resistance CSV.\r\n\r\n        That contain Ag (any amount) and Pd (between 5% and 20%) in their composition.\r\n\r\n        (Optional) That were created by a specific user (filtered by email).\r\n\r\n    All results will be saved locally, and relevant files will be downloaded automatically.\r\n\r\nThis tool supports FAIR data practices and can be useful for building datasets for machine learning, publication, or collaborative research.\r\n```python\r\n# Define parameters for processing data\r\ntypename_list = ['EDX CSV', 'Photo', 'HTTS Resistance CSV']\r\nmain_object = 'Sample'\r\nstart_date = '2024-01-01'\r\nend_date = '2025-05-31'\r\n\r\n# Elements with their percentage range (min, max)\r\nelement_criteria = {\r\n    'Ag': (5, 20),\r\n    'Pd': (5, 20)\r\n}\r\n\r\n# Define save location and output filename\r\nsave_location = \"./results\"\r\noutput_filename = \"search_result.csv\"\r\n\r\n# Filter by creator's email\r\ncreator_email = \"felix.thelen.rub@gmail.com\"\r\n\r\n# Call the search function with creator\r\ndf = CRC_API.search(\r\n    associated_typenames=typename_list,\r\n    main_object=main_object,\r\n    start_date=start_date,\r\n    end_date=end_date,\r\n    element_criteria=element_criteria,\r\n    #creator=creator_email,  \r\n    strict=True,\r\n    save_location=save_location,\r\n    output_filename=output_filename\r\n)\r\n\r\n\r\n```\r\n\r\n### Get the measurement with the object id\r\n```python\r\nmain_objectID = 11104\r\nassociated_types = [\"EDX CSV\", \"Photo\"]\r\nCRC_API.download_by_main_objectid( main_objectID , associated_types, download_folder=\"downloaded_files\")\r\n```\r\n\r\n### \ud83e\udde9 get_sample_typename_matrix(main_object=\"Sample\")\r\nBuilds a binary matrix that shows which samples are associated with which object types (typenames).\r\n\r\n\u2705 Features:\r\n\r\n    Rows = Sample object IDs\r\n\r\n    Columns = All typenames in the database\r\n\r\n    Values = 1 if the sample has an association with that type, else 0\r\n\r\n\ud83d\udcd8 Example:\r\n```python\r\nmatrix_df = crc_api.get_sample_typename_matrix()\r\nprint(matrix_df.head())\r\n```\r\n\r\n### \ud83d\udd17 get_sample_and_linked_properties()\r\n\r\nCollects properties for each sample and its linked objects. Supports filtering by property type and name.\r\n\r\n\u2705 Features:\r\n\r\n    Retrieves Sample properties (Float, Int, String, BigString)\r\n\r\n    Retrieves Linked object properties and averages numeric values across linked objects\r\n\r\n    Supports filtering by property names and types\r\n\r\n    Optionally includes or excludes objectname\r\n\r\n    Can save results directly as CSV\r\n\r\n\ud83d\udd27 Parameters:\r\n\r\n    property_type: \"float\", \"int\", \"string\", \"bigstring\", or \"all\" (default = \"all\")\r\n\r\n    property_names: list of property names to filter (default = all)\r\n\r\n    include_objectname: whether to include the objectname column (default = True)\r\n\r\n    save_to_csv: path to save CSV (default = None)\r\n\r\n\ud83d\udcd8 Example:\r\n```python\r\nmatrix_df = crc_api.get_sample_typename_matrix()\r\nprint(matrix_df.head())\r\n```\r\n\r\n## \ud83d\udcca get_composition_table(value_type=\"ValuePercent\")\r\n\r\nBuilds a pivot table showing the composition (element percentages or absolutes) for each measurement area, mapping from composition object \u2192 actual sample \u2192 measurement index.\r\n\r\n\u2705 Output:\r\n\r\n    composition_objectid\r\n\r\n    actual_sample_objectid\r\n\r\n    compoundindex\r\n\r\n    measurement_area_index\r\n\r\n    Wide-format element columns (e.g., Ag, Pd, Pt)\r\n\r\n\ud83d\udd27 Parameters:\r\n\r\n    value_type: \"ValuePercent\" (default) or \"ValueAbsolute\"\r\n\r\n\ud83d\udcd8 Example:\r\n\r\n```python\r\ncomposition_df = crc_api.get_composition_table(value_type=\"ValuePercent\")\r\n```\r\n\r\n## \u26a1 extract_resistance_data()\r\n\r\nDownloads and processes resistance measurement data (HTTS Resistance CSV), matches each with its linked Sample, and computes average resistance (R), current (I), and voltage (V) values over (x, y) positions.\r\n\r\n\u2705 Outputs:\r\n\r\n    Raw CSVs in resistance/\r\n\r\n    Averaged CSVs in averaged_data/\r\n\r\n    Merged result in output/resistance_summary.csv\r\n\r\n\ud83d\udcd8 Example:\r\n\r\n```python\r\ncrc_api.extract_resistance_data()\r\n```\r\n\r\n## \ud83e\uddec extract_xrd_data()\r\n\r\nProcesses XRD files of type \"XRD CSV (342 columns)\", links each XRD object to its Sample, performs interpolation on the two_theta range (e.g., 50% resampling), and saves results in both JSON and wide-format CSV.\r\n\r\n\u2705 Outputs:\r\n\r\n    Interpolated XRD data in JSON and CSV\r\n\r\n    Output folder: XRD_CSV_342/\r\n\r\n\ud83d\udd27 Parameters:\r\n\r\n    percentage: Percentage of points to retain (default = 50.0)\r\n\r\n    json_filename: JSON file name to save\r\n\r\n    csv_filename: CSV file name to save\r\n\r\n\ud83d\udcd8 Example:\r\n\r\n```python\r\ncrc_api.extract_xrd_data(percentage=50.0)\r\n```\r\n\r\n## \ud83d\udccf extract_thickness_data_from_typeid40()\r\n\r\nDownloads .zip files of type ID 40 (thickness), extracts .dat files, parses numeric thickness values, computes statistics (mean, std), and links them to Sample objects.\r\n\r\n\u2705 Outputs:\r\n\r\n    Summary CSV with average and std dev per .dat file\r\n\r\n    Output folders:\r\n\r\n    Zips: thickness_zip/\r\n\r\n    Extracted: thickness_data/\r\n\r\n    Final summary: output/thickness_summary.csv\r\n\r\n\ud83d\udcd8 Example:\r\n\r\n```python\r\ncrc_api.extract_thickness_data_from_typeid40()\r\n```\r\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Python wrapper for the CRC 1625 MatInf VRO API",
    "version": "0.1.4",
    "project_urls": {
        "Homepage": "https://pypi.org/project/crc165-api/",
        "Source": "https://gitlab.ruhr-uni-bochum.de/icams-mids/crc1625rdmswrapper",
        "Tracker": "https://gitlab.ruhr-uni-bochum.de/icams-mids/crc1625rdmswrapper/issues"
    },
    "split_keywords": [
        "materials",
        " fair",
        " api",
        " crc165",
        " data-management"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "6113af44b47c17c41b29fd9c16d61010d7c54f6c262319e255bd15665d65acfc",
                "md5": "8d4cc8a0bcca88767a05454a6680b0ea",
                "sha256": "220899b967b74b7096768e47b175db20655b23dc13b17bdf3875b946caafdfab"
            },
            "downloads": -1,
            "filename": "crc165_api-0.1.4-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "8d4cc8a0bcca88767a05454a6680b0ea",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 18605,
            "upload_time": "2025-08-25T18:48:41",
            "upload_time_iso_8601": "2025-08-25T18:48:41.410525Z",
            "url": "https://files.pythonhosted.org/packages/61/13/af44b47c17c41b29fd9c16d61010d7c54f6c262319e255bd15665d65acfc/crc165_api-0.1.4-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "c4a0f61381d63ac4fe583794f3df39133149490256b724fce3a01e36063b00da",
                "md5": "0196dd2c072e92fbb6e443feab29ef19",
                "sha256": "87f36d00957bc75b5ff0c46456145226fe33cb026d2faadbcecc39f306838e0d"
            },
            "downloads": -1,
            "filename": "crc165_api-0.1.4.tar.gz",
            "has_sig": false,
            "md5_digest": "0196dd2c072e92fbb6e443feab29ef19",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 26515,
            "upload_time": "2025-08-25T18:48:42",
            "upload_time_iso_8601": "2025-08-25T18:48:42.664013Z",
            "url": "https://files.pythonhosted.org/packages/c4/a0/f61381d63ac4fe583794f3df39133149490256b724fce3a01e36063b00da/crc165_api-0.1.4.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-25 18:48:42",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "crc165-api"
}
        
Elapsed time: 0.99068s