kopia lustrzana https://github.com/bugout-dev/moonstream
List metatx requesters with contracts and call requests calculated
rodzic
2b51aacf5e
commit
1c878329b0
|
@ -6,7 +6,7 @@ from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from typing import Any, Dict, List, Optional, Set, Tuple
|
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 import func, or_, text, tuple_
|
||||||
from sqlalchemy.dialects.postgresql import insert
|
from sqlalchemy.dialects.postgresql import insert
|
||||||
from sqlalchemy.engine import Row
|
from sqlalchemy.engine import Row
|
||||||
|
@ -23,6 +23,7 @@ from .models import (
|
||||||
RegisteredContract,
|
RegisteredContract,
|
||||||
)
|
)
|
||||||
from .settings import (
|
from .settings import (
|
||||||
|
METATX_REQUESTER_TYPE,
|
||||||
MOONSTREAM_ADMIN_ACCESS_TOKEN,
|
MOONSTREAM_ADMIN_ACCESS_TOKEN,
|
||||||
MOONSTREAM_APPLICATION_ID,
|
MOONSTREAM_APPLICATION_ID,
|
||||||
bugout_client,
|
bugout_client,
|
||||||
|
@ -186,7 +187,7 @@ def validate_method_and_params(
|
||||||
|
|
||||||
|
|
||||||
def create_resource_for_registered_contract(user_id: uuid.UUID) -> uuid.UUID:
|
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"]
|
creator_permissions = ["create", "read", "update", "delete"]
|
||||||
|
|
||||||
resource = bugout_client.create_resource(
|
resource = bugout_client.create_resource(
|
||||||
|
@ -847,6 +848,66 @@ def fetch_metatx_requester_ids(token: uuid.UUID) -> List[uuid.UUID]:
|
||||||
return metatx_requester_ids
|
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:
|
def handle_register(args: argparse.Namespace) -> None:
|
||||||
"""
|
"""
|
||||||
Handles the register command.
|
Handles the register command.
|
||||||
|
|
|
@ -278,6 +278,12 @@ class RegisteredContractWithHoldersResponse(RegisteredContractResponse):
|
||||||
holders: List[RegisteredContractHolderResponse] = Field(default_factory=list)
|
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):
|
class CallSpecification(BaseModel):
|
||||||
caller: str
|
caller: str
|
||||||
method: str
|
method: str
|
||||||
|
|
|
@ -11,7 +11,7 @@ from typing import Dict, List, Optional, Set, Tuple
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
from bugout.data import BugoutResourceHolder, BugoutUser
|
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.exc import NoResultFound
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
from web3 import Web3
|
from web3 import Web3
|
||||||
|
@ -40,6 +40,10 @@ tags_metadata = [
|
||||||
"description": DESCRIPTION,
|
"description": DESCRIPTION,
|
||||||
},
|
},
|
||||||
{"name": "requests", "description": "Call requests for registered contracts."},
|
{"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
|
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(
|
@app.get(
|
||||||
"/contracts/{contract_id}/holders",
|
"/contracts/{contract_id}/holders",
|
||||||
tags=["contracts"],
|
tags=["contracts"],
|
||||||
|
|
|
@ -3,16 +3,10 @@ import sys
|
||||||
import time
|
import time
|
||||||
from typing import Any, Dict, List, Optional
|
from typing import Any, Dict, List, Optional
|
||||||
|
|
||||||
from bugout.data import BugoutResourceHolder
|
|
||||||
from sqlalchemy.sql import delete, distinct, func, insert, update
|
from sqlalchemy.sql import delete, distinct, func, insert, update
|
||||||
|
|
||||||
from .. import db, models
|
from .. import db, models
|
||||||
from ..contracts_actions import create_resource_for_registered_contract
|
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):
|
def generate_handler(args: argparse.Namespace):
|
||||||
|
|
|
@ -21,6 +21,8 @@ bugout_client = Bugout(brood_api_url=BUGOUT_BROOD_URL, spire_api_url=BUGOUT_SPIR
|
||||||
BUGOUT_MAX_CONCURRENT_REQUESTS = 4
|
BUGOUT_MAX_CONCURRENT_REQUESTS = 4
|
||||||
bugout_client_semaphore = threading.Semaphore(BUGOUT_MAX_CONCURRENT_REQUESTS)
|
bugout_client_semaphore = threading.Semaphore(BUGOUT_MAX_CONCURRENT_REQUESTS)
|
||||||
|
|
||||||
|
METATX_REQUESTER_TYPE = "metatx_requester"
|
||||||
|
|
||||||
ENGINE_DEV_RAW = os.environ.get("ENGINE_DEV", "")
|
ENGINE_DEV_RAW = os.environ.get("ENGINE_DEV", "")
|
||||||
ENGINE_DEV = True if ENGINE_DEV_RAW in {"1", "true", "yes", "t", "y"} else False
|
ENGINE_DEV = True if ENGINE_DEV_RAW in {"1", "true", "yes", "t", "y"} else False
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue