Fix registry geo_model to levels mapping

This commit is contained in:
phil 2023-12-26 17:20:36 +05:30
parent 741050db89
commit 6c5acd5a4d
4 changed files with 30 additions and 34 deletions

View file

@ -13,6 +13,7 @@ from gisaf.models.authentication import (
Role, RoleRead,
)
from gisaf.models.category import Category, CategoryRead
from gisaf.models.to_migrate import DataProvider
from gisaf.config import conf
from gisaf.models.bootstrap import BootstrapData
from gisaf.models.store import Store
@ -58,13 +59,16 @@ async def login_for_access_token(
return Token(access_token=access_token, token_type='bearer')
@api.get("/list")
async def list_data_providers():
async def list_data_providers() -> list[DataProvider]:
"""
Return a list of data providers, for use with the api (graphs, etc)
:return:
"""
return [{'name': m.__name__, 'store': m.get_store_name()}
for m in registry.values_for_model]
return [
DataProvider(
name=model.get_store_name(),
values=[value.get_store_name() for value in values]
) for model, values in registry.values_for_model.items()]
@api.get("/users")

View file

@ -16,3 +16,7 @@ class ModelAction(BaseModel):
name: str
icon: str
formFields: list[FormField]
class DataProvider(BaseModel):
name: str
values: list[str]

View file

@ -120,9 +120,12 @@ class DownloadPlugin:
class DownloadCSVPlugin(DownloadPlugin):
async def execute(self, model, item, request):
from gisaf.registry import registry
values_model = registry.values_for_model.get(model)
df = await values_model.get_as_dataframe(model_id=item.id)
csv = df.to_csv(date_format='%d/%m/%Y %H:%M', float_format=values_model.float_format)
values_models = registry.values_for_model.get(model)
for value_model in values_models:
df = await values_models.get_as_dataframe(model_id=item.id)
csv = df.to_csv(date_format='%d/%m/%Y %H:%M', float_format=value_model.float_format)
## TODO: implement multiple values for a model (search for values_for_model)
break
return {
'file_name': '{:s}.csv'.format(item.caption),
'content_type': 'text/csv',

View file

@ -6,13 +6,13 @@ import importlib
import pkgutil
from collections import defaultdict
from importlib.metadata import entry_points
from typing import Any, ClassVar
from typing import Any, ClassVar, Literal
from pydantic import create_model
from pydantic_core import PydanticUndefined
from sqlalchemy import text
from sqlalchemy.orm import selectinload
from sqlmodel import SQLModel, select
from sqlmodel import SQLModel, select, inspect
import pandas as pd
from gisaf.config import conf
@ -83,6 +83,8 @@ class ModelRegistry:
misc: dict[str, SQLModel]
raw_survey_models: dict[str, RawSurveyBaseModel]
survey_models: dict[str, SurveyModel]
## TODO: implement multiple values for a model (search for values_for_model)
values_for_model: dict[GeoModel, list[PlottableModel]]
def __init__(self) -> None:
"""
@ -261,17 +263,13 @@ class ModelRegistry:
'''
Build a dict for quick access to the values from a model
'''
logger.warning(ToMigrate('populate_values_for_model'))
return
self.values_for_model = {}
for model_value in self.values.values():
for field in model_value.model_fields.values():
foreign_key = getattr(field, 'foreign_key', False)
if foreign_key and foreign_key is not PydanticUndefined:
breakpoint()
model = ...
self.values_for_model[model] = model_value
for relationship in inspect(model_value).relationships:
model = self.stores.loc[relationship.target.fullname, 'model']
if model not in self.values_for_model:
self.values_for_model[model] = []
self.values_for_model[model].append(model_value)
def scan_entry_points(self, name):
"""
@ -286,15 +284,15 @@ class ModelRegistry:
logger.warning(err)
return named_objects
def add_model(self, model) -> str:
def add_model(self, model) -> Literal['GeoModel', 'PlottableModel', 'Other model']:
"""
Add the model
:return: Model type (one of {'GeoModel', 'PlottableModel', 'Other model'})
Add the model to its proper dict for reference, return the type
"""
# if not hasattr(model, 'get_store_name'):
# raise NotInRegistry()
table_name = model.get_store_name()
if issubclass(model, GeoModel) and not issubclass(model, RawSurveyBaseModel) and not model.hidden:
if issubclass(model, GeoModel) and not \
issubclass(model, RawSurveyBaseModel) and not model.hidden:
self.geom_custom[table_name] = model
return 'GeoModel'
elif issubclass(model, PlottableModel):
@ -358,19 +356,6 @@ class ModelRegistry:
resp['externalRecordUrl'] = item.get_external_record_url()
return resp
def get_other_model_from_table_name(self, table_name):
"""
Utility func to get a non-geom model from a table name
:param table_name: str
:return: model or None
"""
for model in registry.other.values():
if model.__tablename__ == table_name:
return model
for model in registry.values.values():
if model.__tablename__ == table_name:
return model
async def make_stores(self):
"""
Make registry for primary groups, categories and survey stores using Pandas dataframes.