basic image support
This commit is contained in:
parent
43b2e33551
commit
1a68c28802
2 changed files with 117 additions and 1 deletions
|
|
@ -35,7 +35,7 @@ EXPECTED_SCHEMAS = {
|
||||||
},
|
},
|
||||||
"items": {
|
"items": {
|
||||||
"required_fields": ["Name", "Type", "Level", "Rarity"],
|
"required_fields": ["Name", "Type", "Level", "Rarity"],
|
||||||
"optional_fields": ["Description", "Game Name (from Games)"],
|
"optional_fields": ["Description", "Game Name (from Games)", "Image"],
|
||||||
},
|
},
|
||||||
"item_instances": {
|
"item_instances": {
|
||||||
"required_fields": ["ID", "User", "Item"],
|
"required_fields": ["ID", "User", "Item"],
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,30 @@ class CreateItemResponse(BaseModel):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ItemImageAttachment(BaseModel):
|
||||||
|
"""Model for item image attachment details."""
|
||||||
|
|
||||||
|
url: str = Field(..., description="Direct URL to the PNG image file")
|
||||||
|
filename: Optional[str] = Field(None, description="Original filename of the uploaded image")
|
||||||
|
type: Optional[str] = Field(None, description="MIME type of the image file")
|
||||||
|
size: Optional[int] = Field(None, description="File size in bytes")
|
||||||
|
|
||||||
|
|
||||||
|
class DetailedItemResponse(BaseModel):
|
||||||
|
"""Response model for detailed item data including image."""
|
||||||
|
|
||||||
|
id: str = Field(..., description="Unique identifier for the item")
|
||||||
|
name: str = Field(..., description="Display name of the item")
|
||||||
|
type: str = Field(..., description="Category or type of the item")
|
||||||
|
level: int = Field(..., description="Required level to use this item")
|
||||||
|
rarity: str = Field(
|
||||||
|
..., description="Rarity classification (common, rare, epic, legendary, etc.)"
|
||||||
|
)
|
||||||
|
game_name: Optional[str] = Field(None, description="Name of the game this item belongs to")
|
||||||
|
description: Optional[str] = Field(None, description="Description of the item")
|
||||||
|
image: Optional[ItemImageAttachment] = Field(None, description="PNG image attachment details")
|
||||||
|
|
||||||
|
|
||||||
def create_items_router(
|
def create_items_router(
|
||||||
sessions_table, users_table, items_table, item_addons_table, item_instances_table
|
sessions_table, users_table, items_table, item_addons_table, item_instances_table
|
||||||
) -> APIRouter:
|
) -> APIRouter:
|
||||||
|
|
@ -245,6 +269,98 @@ The item will be added to the user's inventory and associated with their current
|
||||||
detail=error_response["detail"],
|
detail=error_response["detail"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@router.get(
|
||||||
|
"/{item_id}",
|
||||||
|
response_model=DetailedItemResponse,
|
||||||
|
summary="Get detailed information for a specific item",
|
||||||
|
description="""Get complete details for a specific item including image thumbnail.
|
||||||
|
|
||||||
|
Returns all available information about the item including name, type, level, rarity, game, description, and base64 encoded image thumbnail.
|
||||||
|
|
||||||
|
**Authentication:** None required""",
|
||||||
|
responses={
|
||||||
|
200: {
|
||||||
|
"description": "Item details retrieved successfully",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"example": {
|
||||||
|
"id": "rec123",
|
||||||
|
"name": "Iron Sword",
|
||||||
|
"type": "weapon",
|
||||||
|
"level": 5,
|
||||||
|
"rarity": "common",
|
||||||
|
"game_name": "Adventure Quest",
|
||||||
|
"description": "A sturdy iron sword perfect for beginning adventurers",
|
||||||
|
"image": {
|
||||||
|
"url": "https://v5.airtableusercontent.com/v1/15/15/1704067200000/xyz123/iron-sword.png",
|
||||||
|
"filename": "iron-sword.png",
|
||||||
|
"type": "image/png",
|
||||||
|
"size": 45321
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
404: {"description": "Item not found"},
|
||||||
|
429: {"description": "Rate limit exceeded"}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
@limiter.limit(f"{settings.rate_limit_requests}/minute")
|
||||||
|
async def get_item(request: Request, item_id: str):
|
||||||
|
"""Get detailed information for a specific item including image."""
|
||||||
|
try:
|
||||||
|
# Validate the item ID format
|
||||||
|
validate_airtable_id(item_id)
|
||||||
|
|
||||||
|
# Get the item
|
||||||
|
item = await get_item_by_id(item_id, items_table)
|
||||||
|
if not item:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail="Item not found"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Extract fields
|
||||||
|
fields = item.get("fields", {})
|
||||||
|
|
||||||
|
# Process image attachment if present
|
||||||
|
image_data = None
|
||||||
|
if "Image" in fields and fields["Image"]:
|
||||||
|
# Airtable attachments are arrays of attachment objects
|
||||||
|
attachments = fields["Image"]
|
||||||
|
if isinstance(attachments, list) and len(attachments) > 0:
|
||||||
|
# Take the first attachment
|
||||||
|
attachment = attachments[0]
|
||||||
|
image_data = ItemImageAttachment(
|
||||||
|
url=attachment.get("url", ""),
|
||||||
|
filename=attachment.get("filename"),
|
||||||
|
type=attachment.get("type"),
|
||||||
|
size=attachment.get("size")
|
||||||
|
)
|
||||||
|
|
||||||
|
# Build response with all available fields
|
||||||
|
response_data = {
|
||||||
|
"id": item["id"],
|
||||||
|
"name": fields.get("Name", ""),
|
||||||
|
"type": fields.get("Type", ""),
|
||||||
|
"level": fields.get("Level", 0),
|
||||||
|
"rarity": str(fields.get("Rarity", "")) if fields.get("Rarity") is not None else "",
|
||||||
|
"game_name": fields.get("Game Name (from Games)", [None])[0] if fields.get("Game Name (from Games)") else None,
|
||||||
|
"description": fields.get("Description"),
|
||||||
|
"image": image_data
|
||||||
|
}
|
||||||
|
|
||||||
|
return response_data
|
||||||
|
|
||||||
|
except HTTPException:
|
||||||
|
raise
|
||||||
|
except Exception as e:
|
||||||
|
error_response = create_safe_error_response(e, "Failed to retrieve item")
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||||
|
detail=error_response["detail"]
|
||||||
|
)
|
||||||
|
|
||||||
return router
|
return router
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue