List metatx requesters with contracts and call requests calculated

pull/1124/head
kompotkot 2024-08-15 12:36:57 +00:00
rodzic 2b51aacf5e
commit 1c878329b0
5 zmienionych plików z 106 dodań i 9 usunięć

Wyświetl plik

@ -6,7 +6,7 @@ from concurrent.futures import ThreadPoolExecutor, as_completed
from datetime import datetime, timedelta
from typing import Any, Dict, List, Optional, Set, Tuple
from bugout.data import BugoutResourceHolder, BugoutResourceHolders, HolderType
from bugout.data import BugoutResourceHolder, HolderType
from sqlalchemy import func, or_, text, tuple_
from sqlalchemy.dialects.postgresql import insert
from sqlalchemy.engine import Row
@ -23,6 +23,7 @@ from .models import (
RegisteredContract,
)
from .settings import (
METATX_REQUESTER_TYPE,
MOONSTREAM_ADMIN_ACCESS_TOKEN,
MOONSTREAM_APPLICATION_ID,
bugout_client,
@ -186,7 +187,7 @@ def validate_method_and_params(
def create_resource_for_registered_contract(user_id: uuid.UUID) -> uuid.UUID:
resource_data = {"type": "metatx_requester"}
resource_data = {"type": METATX_REQUESTER_TYPE}
creator_permissions = ["create", "read", "update", "delete"]
resource = bugout_client.create_resource(
@ -847,6 +848,66 @@ def fetch_metatx_requester_ids(token: uuid.UUID) -> List[uuid.UUID]:
return metatx_requester_ids
def count_contracts_and_requests_for_requester(
db_session: Session, metatx_requester_ids: List[uuid.UUID]
) -> List[data.MetatxRequestersResponse]:
registered_contracts_subquery = (
db_session.query(
RegisteredContract.metatx_requester_id,
func.count(RegisteredContract.id).label("registered_contracts_count"),
)
.filter(RegisteredContract.metatx_requester_id.in_(metatx_requester_ids))
.group_by(RegisteredContract.metatx_requester_id)
.subquery()
)
call_requests_subquery = (
db_session.query(
CallRequest.metatx_requester_id,
func.count(CallRequest.id).label("call_requests_count"),
)
.filter(CallRequest.metatx_requester_id.in_(metatx_requester_ids))
.group_by(CallRequest.metatx_requester_id)
.subquery()
)
query = db_session.query(
registered_contracts_subquery.c.metatx_requester_id,
registered_contracts_subquery.c.registered_contracts_count,
call_requests_subquery.c.call_requests_count,
).outerjoin(
call_requests_subquery,
registered_contracts_subquery.c.metatx_requester_id
== call_requests_subquery.c.metatx_requester_id,
)
results = query.all()
metatx_requesters: List[data.MetatxRequestersResponse] = []
for r in results:
metatx_requester_id = r[0]
metatx_requesters.append(
data.MetatxRequestersResponse(
metatx_requester_id=metatx_requester_id,
registered_contracts_count=r[1],
call_requests_count=r[2],
)
)
metatx_requester_ids.remove(metatx_requester_id)
# Add empty metatx requesters
for r_id in metatx_requester_ids:
metatx_requesters.append(
data.MetatxRequestersResponse(
metatx_requester_id=r_id,
registered_contracts_count=0,
call_requests_count=0,
)
)
return metatx_requesters
def handle_register(args: argparse.Namespace) -> None:
"""
Handles the register command.

Wyświetl plik

@ -278,6 +278,12 @@ class RegisteredContractWithHoldersResponse(RegisteredContractResponse):
holders: List[RegisteredContractHolderResponse] = Field(default_factory=list)
class MetatxRequestersResponse(BaseModel):
metatx_requester_id: UUID
registered_contracts_count: int
call_requests_count: int
class CallSpecification(BaseModel):
caller: str
method: str

Wyświetl plik

@ -11,7 +11,7 @@ from typing import Dict, List, Optional, Set, Tuple
from uuid import UUID
from bugout.data import BugoutResourceHolder, BugoutUser
from fastapi import BackgroundTasks, Body, Depends, FastAPI, Form, Path, Query, Request
from fastapi import BackgroundTasks, Body, Depends, FastAPI, Path, Query, Request
from sqlalchemy.exc import NoResultFound
from sqlalchemy.orm import Session
from web3 import Web3
@ -40,6 +40,10 @@ tags_metadata = [
"description": DESCRIPTION,
},
{"name": "requests", "description": "Call requests for registered contracts."},
{
"name": "requesters",
"description": "Metatx requester represented by resource for registered contracts access.",
},
]
@ -304,6 +308,36 @@ async def delete_contract_route(
return parsed_registered_contract
@app.get(
"/requesters",
tags=["requesters"],
response_model=List[data.MetatxRequestersResponse],
)
async def list_metatx_requesters_route(
user_authorization: Tuple[BugoutUser, UUID] = Depends(request_user_auth),
db_session: Session = Depends(db.yield_db_read_only_session),
) -> List[data.MetatxRequestersResponse]:
"""
Get list of metatx requesters available to user.
Helps to track number of empty metatx requesters without registered contracts and call requests.
"""
_, token = user_authorization
try:
metatx_requester_ids = contracts_actions.fetch_metatx_requester_ids(token=token)
metatx_requesters = (
contracts_actions.count_contracts_and_requests_for_requester(
db_session=db_session, metatx_requester_ids=metatx_requester_ids
)
)
except Exception as err:
logger.error(repr(err))
raise EngineHTTPException(status_code=500)
return metatx_requesters
@app.get(
"/contracts/{contract_id}/holders",
tags=["contracts"],

Wyświetl plik

@ -3,16 +3,10 @@ import sys
import time
from typing import Any, Dict, List, Optional
from bugout.data import BugoutResourceHolder
from sqlalchemy.sql import delete, distinct, func, insert, update
from .. import db, models
from ..contracts_actions import create_resource_for_registered_contract
from ..settings import (
MOONSTREAM_ADMIN_ACCESS_TOKEN,
MOONSTREAM_APPLICATION_ID,
bugout_client,
)
def generate_handler(args: argparse.Namespace):

Wyświetl plik

@ -21,6 +21,8 @@ bugout_client = Bugout(brood_api_url=BUGOUT_BROOD_URL, spire_api_url=BUGOUT_SPIR
BUGOUT_MAX_CONCURRENT_REQUESTS = 4
bugout_client_semaphore = threading.Semaphore(BUGOUT_MAX_CONCURRENT_REQUESTS)
METATX_REQUESTER_TYPE = "metatx_requester"
ENGINE_DEV_RAW = os.environ.get("ENGINE_DEV", "")
ENGINE_DEV = True if ENGINE_DEV_RAW in {"1", "true", "yes", "t", "y"} else False