Issues filtering provider specific fields on local implementation

Hey,

After the tutorial the other day, I wanted to migrate a database that I had to a local OPTIMADE server with a mongodb backend. Since my database has none of the OPTIMADE required fields, I have to use the BaseResourceMapper to transform it, something I’m still figuring out. One other thing I realized while playing around with the test_structures is that while I can add my own fields and they show up in both the structures and /info/structures endpoints (with the description, type and all in the latter, this took some time to figure out), I still can not filter results using this provider specific field. The field I’m trying to filter has a type of float so that’s the type I’m using when adding this OptimadeField and it also shows up as float in info/structures but unfortunately filtering returns an empty list. There is no errors with the response, it’s just that there isn’t anything returned.

I also tried changing the type to int but I still can’t seem to filter using this field. Is there something I am missing here?

Hi again Firat! I assume you are following the guide for optimade-python-tools at Setting up an OPTIMADE API - OPTIMADE Python tools

It’s quite hard to pin down your problem from what you wrote, but my first thought is whether you have set a “provider prefix” in your config, whether the field you want to query is listed in your config, and whether you are adding the “provider prefix” to your filter too? (see the section Setting up an OPTIMADE API - OPTIMADE Python tools)

If you are doing all of these things already, would you be able to post your code here, or raise an issue in the code repository so that the other developers can see it?

Cheers

Hey again Matthew. Yes, I’m following that guide and here are the provider specific fields in my config file

"provider": {
        "name": "example_provider",
        "description": "Provider used for examples, not to be assigned to a real database",
        "prefix": "ep",
        "homepage": "https://example.com"
    },
    "provider_fields": {
        "structures": [
            "bulk_modulus",
            "equilibrium_volume"
        ]
    }

These fields show up in structures endpoint with _ep_ prefixes and the corresponding values from my mongodb structures collection.

I also followed the steps to add description to provider specific fields under “More advanced usage” and modified optimade.server.schemas after which I was able to see the description for bulk_modulus at /v1/info/structures endpoint. Here’s my modification

class MyStructureResourceAttributes(StructureResourceAttributes):
    bulk_modulus: float = OptimadeField(
        0,
        description="Bulk modulus of the structure in units of GPa",
    queryable=SupportLevel.MUST)

    class Config:
        """Add a pydantic `Config` that defines the alias generator,
        based on our configured `provider_fields`.

        """
        @classmethod
        def alias_generator(cls, name: str) -> str:
            if name in CONFIG.provider_fields.get("structures", []):
                print(f"_{CONFIG.provider.prefix}_{name}")
                return f"_{CONFIG.provider.prefix}_{name}"
            return name


class MyStructureResource(StructureResource):
    attributes: MyStructureResourceAttributes

ENTRY_INFO_SCHEMAS["structures"] = MyStructureResource.schema

and finally, the filter I’m using in my request is "_ep_bulk_modulus<135" when I have a structure with a bulk modulus of 130 for example. The response to this request is 200, but only an empty list is returned under response.json()[‘data’] whereas the other fields like ‘meta’ and ‘links’ look fine.

Not sure what happened but filtering works now. I guess I should have restarted the server or something because I haven’t done anything other than that :slight_smile:

That’s a relief! I look forward to seeing what you end up hosting! Feel free to ask any other questions here or on our repository, we will hopefully be improving the guides on the website as we go forward.