Skip to content

Commit

Permalink
LITE-29320 LITE-29322 Draft for XVS extension enhanced filtering and …
Browse files Browse the repository at this point in the history
…sort
  • Loading branch information
Ivan Grebenshchikov authored and Ivan Grebenshchikov committed Jan 11, 2024
1 parent b14e05c commit 1e0cfa1
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 23 deletions.
109 changes: 94 additions & 15 deletions connect_ext_ppr/filters.py
Original file line number Diff line number Diff line change
@@ -1,76 +1,155 @@
from typing import List, Optional


from pydantic import BaseModel
from pydantic import BaseModel, validator
from fastapi_filter import FilterDepends, with_prefix
from fastapi_filter.contrib.sqlalchemy import Filter

from connect_ext_ppr.models.deployment import (
Deployment, DeploymentRequest, MarketplaceConfiguration,
)
from connect_ext_ppr.models.ppr import PPRVersion
from connect_ext_ppr.models.replicas import Product, Account
from connect_ext_ppr.models.task import Task


# TODO: Make mixin
def restrict_sortable_fields_base(value, allowed_field_names):
if value is None:
return None

for field_name in value:
field_name = field_name.replace("+", "").replace("-", "") #

if field_name not in allowed_field_names:
raise ValueError(f"You may only sort by: {', '.join(allowed_field_names)}")

return value


class ProductFilter(Filter):
name: Optional[str]
name__ilike: Optional[str]

class Constants(Filter.Constants):
model = Product


class VendorFilter(Filter):
name: Optional[str]
name__ilike: Optional[str]

class Constants(Filter.Constants):
model = Account


class DeploymentFilter(Filter):
id: Optional[str]
hub_id: Optional[str]
hub__name: Optional[str] # custom filter
hub__name__like: Optional[str] # custom filter
product_id: Optional[str]
product: Optional[ProductFilter] = FilterDepends(with_prefix('product', ProductFilter))
status: Optional[str]
vendor_id: Optional[str]
vendor: Optional[VendorFilter] = FilterDepends(with_prefix('vendor', VendorFilter))

order_by: Optional[list[str]]
custom_order_by: Optional[str]

@validator("order_by")
@classmethod
def restrict_sortable_fields(cls, value):
return restrict_sortable_fields_base(value, ['id', 'product_id'])

@validator("hub__name", "hub__name__like", "custom_order_by")
@classmethod
def validate_hub_name(cls, value):
pass

class Constants(Filter.Constants):
model = Deployment


class PPRVersionFilter(Filter):
id: Optional[str]
version: Optional[int]
status: Optional[str]
description: Optional[str]
description__ilike: Optional[str]

order_by: Optional[List[str]]

@validator("order_by")
@classmethod
def restrict_sortable_fields(cls, value):
return restrict_sortable_fields_base(value, ['version'])

class Constants(Filter.Constants):
model = PPRVersion


class DeploymentRequestFilter(Filter):
status: Optional[str]
delegate_l2: Optional[bool]

"""For specific deployment"""
id: Optional[str]
manually: Optional[bool]
ppr: Optional[PPRVersionFilter] = FilterDepends(with_prefix('ppr', PPRVersionFilter))
status: Optional[str]

order_by: Optional[List[str]]

@validator("order_by")
@classmethod
def restrict_sortable_fields(cls, value):
return restrict_sortable_fields_base(value, ['id'])

class Constants(Filter.Constants):
model = DeploymentRequest


class DeploymentRequestExtendedFilter(DeploymentRequestFilter):
"""For all deployments"""
delegate_l2: Optional[bool]

deployment_id: Optional[str]
deployment: Optional[DeploymentFilter] = FilterDepends(
with_prefix('deployment', DeploymentFilter),
)

@validator("order_by")
@classmethod
def restrict_sortable_fields(cls, value):
return restrict_sortable_fields_base(value, ['id', 'deployment_id'])


class MarketplaceConfigurationFilter(Filter):
"""For specific DeploymentRequest"""
marketplace: Optional[str]
ppr: Optional[PPRVersionFilter] = FilterDepends(with_prefix('ppr', PPRVersionFilter))

order_by: Optional[List[str]]

class Constants(Filter.Constants):
model = MarketplaceConfiguration


class DeploymentRequestExtendedFilter(DeploymentRequestFilter):
id: Optional[str]

deployment: Optional[DeploymentFilter] = FilterDepends(
with_prefix('deployment', DeploymentFilter),
)

class Constants(Filter.Constants):
model = DeploymentRequest
class MarketplaceConfigurationExtendedFilter(MarketplaceConfigurationFilter):
"""For Deployment"""
ppr: Optional[PPRVersionFilter] = FilterDepends(with_prefix('ppr', PPRVersionFilter))


class PricingBatchFilter(BaseModel):
marketplace_id: Optional[str]


class TaskFilter(Filter):
id: Optional[str]
status: Optional[str]

order_by: Optional[List[str]]

@validator("order_by")
@classmethod
def restrict_sortable_fields(cls, value):
return restrict_sortable_fields_base(value, ['id'])

class Constants(Filter.Constants):
model = Task
34 changes: 26 additions & 8 deletions connect_ext_ppr/webapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
from connect_ext_ppr.filters import (
DeploymentFilter, DeploymentRequestExtendedFilter, DeploymentRequestFilter,
MarketplaceConfigurationFilter, PPRVersionFilter, PricingBatchFilter, TaskFilter,
MarketplaceConfigurationExtendedFilter,
)
from connect_ext_ppr.models.configuration import Configuration
from connect_ext_ppr.models.deployment import (
Expand Down Expand Up @@ -202,7 +203,7 @@ def list_deployment_requests(
DeploymentRequest.deployment, DeploymentRequest.ppr,
).filter(
DeploymentRequest.deployment_id.in_(deployments),
).order_by(desc(DeploymentRequest.created_at))
)
deployment_requests = dr_filter.filter(deployment_requests)
deployment_requests = dr_filter.sort(deployment_requests)
deployment_requests = apply_pagination(deployment_requests, db, pagination_params, response)
Expand Down Expand Up @@ -265,8 +266,9 @@ def list_deployment_request_tasks(
dr = get_deployment_request_by_id(depl_req_id, db, installation)
if dr:
task_list = []
qs = db.query(Task).filter_by(deployment_request_id=dr.id).order_by(Task.id)
qs = db.query(Task).filter_by(deployment_request_id=dr.id)
qs = task_filter.filter(qs)
qs = task_filter.sort(qs)

for task in apply_pagination(qs, db, pagination_params, response):
task_list.append(get_task_schema(task))
Expand Down Expand Up @@ -404,8 +406,9 @@ def list_requests_for_deployment(
db
.query(DeploymentRequest)
.filter_by(deployment_id=deployment_id)
.order_by(desc(DeploymentRequest.id))
)
).join(DeploymentRequest.ppr)
qs = dr_filter.filter(qs)
qs = dr_filter.sort(qs)

for dr in apply_pagination(qs, db, pagination_params, response):
response_list.append(get_deployment_request_schema(dr, hub))
Expand All @@ -426,18 +429,32 @@ def get_deployments(
installation: dict = Depends(get_installation),
):
deployments = db.query(Deployment).filter_by(account_id=installation['owner']['id'])
deployments = deployment_filter.filter(deployments)
deployments = apply_pagination(deployments, db, pagination_params, response)
deployments = deployment_filter.filter(deployments.join(Deployment.product))
listings = get_all_listing_info(client)
vendors = [li['vendor'] for li in listings]
hubs = [hub['hub'] for li in listings for hub in li['contract']['marketplace']['hubs']]

if deployment_filter.hub__name: # custom filter by hub name
dep_ids = [dep.id for dep in deployments if filter_object_list_by_id(hubs, dep.hub_id)['name'] == deployment_filter.hub__name]
deployments = deployments.filter(Deployment.id.in_(dep_ids))

if deployment_filter.hub__name__like: # custom filter by hub name
dep_ids = [dep.id for dep in deployments if deployment_filter.hub__name__like in filter_object_list_by_id(hubs, dep.hub_id)['name']]
deployments = deployments.filter(Deployment.id.in_(dep_ids))

deployments = deployment_filter.sort(deployments)
if deployment_filter.custom_order_by == 'product__name': # custom sort by product name
deployments = deployments.order_by(Product.name)
deployments = apply_pagination(deployments, db, pagination_params, response)

response_list = []
for dep in deployments:
vendor = filter_object_list_by_id(vendors, dep.vendor_id)
hub = filter_object_list_by_id(hubs, dep.hub_id)
response_list.append(
get_deployment_schema(dep, dep.product, vendor, hub),
)

return response_list

@router.get(
Expand Down Expand Up @@ -610,7 +627,6 @@ def get_pprs(
.filter_by(deployment=deployment_id)
.join(File, PPRVersion.file == File.id)
.outerjoin(Configuration, PPRVersion.configuration == Configuration.id)
.order_by(desc(PPRVersion.version))
)
ppr_file_conf_qs = ppr_filter.filter(ppr_file_conf_qs)
ppr_file_conf_qs = ppr_filter.sort(ppr_file_conf_qs)
Expand Down Expand Up @@ -674,7 +690,9 @@ def add_ppr(
def get_marketplaces_by_deployment(
self,
deployment_id: str,
m_filter: MarketplaceConfigurationFilter = FilterDepends(MarketplaceConfigurationFilter),
m_filter: MarketplaceConfigurationExtendedFilter = FilterDepends(
MarketplaceConfigurationExtendedFilter,
),
pagination_params: PaginationParams = Depends(),
response: Response = None,
client: ConnectClient = Depends(get_installation_client),
Expand Down

0 comments on commit 1e0cfa1

Please sign in to comment.