Skip to content

Commit

Permalink
Add resources endpoint. #102
Browse files Browse the repository at this point in the history
  • Loading branch information
paul121 committed Mar 4, 2021
1 parent c2cf94a commit 871e33f
Show file tree
Hide file tree
Showing 3 changed files with 167 additions and 1 deletion.
11 changes: 10 additions & 1 deletion backend/app/app/routers/api_v2/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
from fastapi import APIRouter, Security

from app.routers.api_v2.endpoints import login, users, utils, api_key, farms
from app.routers.utils.security import get_current_active_superuser
from app.routers.api_v2.endpoints.resources import resources
from app.routers.utils.security import get_farm_access, get_current_active_superuser

logger = logging.getLogger(__name__)

Expand All @@ -25,4 +26,12 @@
farms.router,
prefix="/farms",
tags=["farms"],
)

# Include /farms/logs endpoints.
router.include_router(
resources.router,
prefix="/farms/resources",
tags=["Resources"],
dependencies=[Security(get_farm_access, scopes=['farm:read', 'farm.logs'])]
)
Empty file.
157 changes: 157 additions & 0 deletions backend/app/app/routers/api_v2/endpoints/resources/resources.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
from fastapi import APIRouter, Depends, Query
from starlette.requests import Request
from pydantic import BaseModel
from pydantic.typing import Dict, List, Optional, Union, Any
from sqlalchemy.orm import Session

from app.routers.utils.db import get_db
from app.routers.utils.farms import get_active_farms_url_or_list, get_farm_client, ClientError
from app.schemas.farm import Farm

router = APIRouter()

# /farms/resources endpoint.


# todo: Use pydantic.types.UUID4 instead of string for IDs once farmOS.py supports this.
class ResourceIdentifier(BaseModel):
id: Optional[str]
type: Optional[str]


class Relationship(BaseModel):
data: List[Optional[ResourceIdentifier]]


class Resource(BaseModel):
id: Optional[str]
type: Optional[str]
attributes: Optional[Dict[str, Union[Any]]]
relationships: Optional[Dict[str, Relationship]]


class ResourceUpdate(Resource):
id: str


@router.get("/{entity_type}/{bundle}")
def get_resource(
request: Request,
entity_type: str,
bundle: str,
farm_list: List[Farm] = Depends(get_active_farms_url_or_list),
db: Session = Depends(get_db),
):
query_params = {**request.query_params}
query_params.pop('farm_id', None)
query_params.pop('farm_url', None)

data = {}
for farm in farm_list:
data[farm.id] = None

# Get a farmOS client.
try:
farm_client = get_farm_client(db=db, farm=farm)
except ClientError as e:
data[farm.id] = str(e)
continue

# Make the request.
try:
response = farm_client.resource.get(entity_type, bundle, query_params)
data[farm.id] = response
except Exception as e:
data[farm.id] = str(e)
continue

return data


@router.post("/{entity_type}/{bundle}")
def create_resource(
resource: Resource,
entity_type: str,
bundle: str,
farm_list: List[Farm] = Depends(get_active_farms_url_or_list),
db: Session = Depends(get_db),
):
data = {}
for farm in farm_list:
data[farm.id] = []

# Get a farmOS client.
try:
farm_client = get_farm_client(db=db, farm=farm)
except ClientError as e:
data[farm.id] = str(e)
continue

# Make the request.
try:
data[farm.id] = farm_client.resource.send(entity_type, bundle, payload=resource.dict(exclude_unset=True))
except Exception as e:
data[farm.id] = str(e)
continue

return data


@router.put("/{entity_type}/{bundle}")
def update_resource(
resource: ResourceUpdate,
entity_type: str,
bundle: str,
farm_list: List[Farm] = Depends(get_active_farms_url_or_list),
db: Session = Depends(get_db),
):
data = {}
for farm in farm_list:
data[farm.id] = []

# Get a farmOS client.
try:
farm_client = get_farm_client(db=db, farm=farm)
except ClientError as e:
data[farm.id] = str(e)
continue

# Make the request.
try:
data[farm.id] = farm_client.resource.send(entity_type, bundle, payload=resource.dict(exclude_unset=True))
except Exception as e:
data[farm.id] = str(e)
continue

return data


@router.delete("/{entity_type}/{bundle}")
def delete_farm_assets(
entity_type: str,
bundle: str,
id: List[str] = Query(None),
farm_list: List[Farm] = Depends(get_active_farms_url_or_list),
db: Session = Depends(get_db),
):
data = {}
for farm in farm_list:
data[farm.id] = []

# Get a farmOS client.
try:
farm_client = get_farm_client(db=db, farm=farm)
except ClientError:
data[farm.id] = str(e)
continue

# Make the request.
for single_id in id:
try:
response = farm_client.resource.delete(entity_type, bundle, id=single_id)
data[farm.id].append({single_id: response})
except Exception as e:
data[farm.id].append({single_id: str(e)})
continue

return data

0 comments on commit 871e33f

Please sign in to comment.