stac-utils / stac-fastapi-sqlalchemy

PostgreSQL backend for stac-fastapi using SQLAlchemy
MIT License
9 stars 10 forks source link

bulk load of items not working (?) #22

Open keul opened 1 year ago

keul commented 1 year ago

Using the vanilla docker-compose provided by the project, and trying to use the /collections/{collection_id}/bulk_items endpoint on the stac_fastapi.sqlalchemy service.

For what I see from the swagger documentation, the POST payload must be something like:

{
  "items": {}
}

…and inspecting the code I guess items should a a structure of "item-id": { definition of item }

But I get an error:

stac-fastapi-sqlalchemy               |   File "/usr/local/lib/python3.8/site-packages/starlette/middleware/exceptions.py", line 64, in __call__
stac-fastapi-sqlalchemy               |     await self.app(scope, receive, sender)
stac-fastapi-sqlalchemy               |   File "/usr/local/lib/python3.8/site-packages/fastapi/middleware/asyncexitstack.py", line 21, in __call__
stac-fastapi-sqlalchemy               |     raise e
stac-fastapi-sqlalchemy               |   File "/usr/local/lib/python3.8/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in __call__
stac-fastapi-sqlalchemy               |     await self.app(scope, receive, send)
stac-fastapi-sqlalchemy               |   File "/usr/local/lib/python3.8/site-packages/starlette/routing.py", line 680, in __call__
stac-fastapi-sqlalchemy               |     await route.handle(scope, receive, send)
stac-fastapi-sqlalchemy               |   File "/usr/local/lib/python3.8/site-packages/starlette/routing.py", line 275, in handle
stac-fastapi-sqlalchemy               |     await self.app(scope, receive, send)
stac-fastapi-sqlalchemy               |   File "/usr/local/lib/python3.8/site-packages/starlette/routing.py", line 65, in app
stac-fastapi-sqlalchemy               |     response = await func(request)
stac-fastapi-sqlalchemy               |   File "/usr/local/lib/python3.8/site-packages/fastapi/routing.py", line 235, in app
stac-fastapi-sqlalchemy               |     raw_response = await run_endpoint_function(
stac-fastapi-sqlalchemy               |   File "/usr/local/lib/python3.8/site-packages/fastapi/routing.py", line 161, in run_endpoint_function
stac-fastapi-sqlalchemy               |     return await dependant.call(**values)
stac-fastapi-sqlalchemy               |   File "/app/stac_fastapi/api/stac_fastapi/api/routes.py", line 68, in _endpoint
stac-fastapi-sqlalchemy               |     await func(request_data, request=request), response_class
stac-fastapi-sqlalchemy               |   File "/app/stac_fastapi/api/stac_fastapi/api/routes.py", line 32, in run
stac-fastapi-sqlalchemy               |     return await run_in_threadpool(func, *args, **kwargs)
stac-fastapi-sqlalchemy               |   File "/usr/local/lib/python3.8/site-packages/starlette/concurrency.py", line 41, in run_in_threadpool
stac-fastapi-sqlalchemy               |     return await anyio.to_thread.run_sync(func, *args)
stac-fastapi-sqlalchemy               |   File "/usr/local/lib/python3.8/site-packages/anyio/to_thread.py", line 31, in run_sync
stac-fastapi-sqlalchemy               |     return await get_asynclib().run_sync_in_worker_thread(
stac-fastapi-sqlalchemy               |   File "/usr/local/lib/python3.8/site-packages/anyio/_backends/_asyncio.py", line 937, in run_sync_in_worker_thread
stac-fastapi-sqlalchemy               |     return await future
stac-fastapi-sqlalchemy               |   File "/usr/local/lib/python3.8/site-packages/anyio/_backends/_asyncio.py", line 867, in run
stac-fastapi-sqlalchemy               |     result = context.run(func, *args)
stac-fastapi-sqlalchemy               |   File "/app/stac_fastapi/sqlalchemy/stac_fastapi/sqlalchemy/transactions.py", line 194, in bulk_item_insert
stac-fastapi-sqlalchemy               |     processed_items = [self._preprocess_item(item) for item in items]
stac-fastapi-sqlalchemy               |   File "/app/stac_fastapi/sqlalchemy/stac_fastapi/sqlalchemy/transactions.py", line 194, in <listcomp>
stac-fastapi-sqlalchemy               |     processed_items = [self._preprocess_item(item) for item in items]
stac-fastapi-sqlalchemy               |   File "/app/stac_fastapi/sqlalchemy/stac_fastapi/sqlalchemy/transactions.py", line 182, in _preprocess_item
stac-fastapi-sqlalchemy               |     db_model = self.item_serializer.stac_to_db(item)
stac-fastapi-sqlalchemy               |   File "/app/stac_fastapi/sqlalchemy/stac_fastapi/sqlalchemy/serializers.py", line 124, in stac_to_db
stac-fastapi-sqlalchemy               |     collection_id=stac_data["collection"],
stac-fastapi-sqlalchemy               | KeyError: 'collection'

I suspect the JSON format is not the proper ones (but I'm using test data from the same project).

In facts, it try to find the "collection" id from the stac_data, but to be honest I think it should load it from the request path parameter.

keul commented 1 year ago

Ah! Digging into the code I found that transaction.create_item can also try to load the collection id from the item itself.

If I provide it in my item JSON, it works.

I'm not sure if this is the intended way to use this API. Right now I cannot pass the same item definition to the bulk upload and single upload endpoint (or at least, in the simple item upload I can skip this parameter, which seems optional).

I still think that the collection_id should be taken from the path parameter instead, but I can live this it! 😄