Skip to content
This repository has been archived by the owner on Apr 23, 2024. It is now read-only.

Commit

Permalink
Merge branch 'develop' into improve_get_tasks
Browse files Browse the repository at this point in the history
  • Loading branch information
SebRut committed May 11, 2022
2 parents 4d47d29 + 654d70b commit b6b7aa2
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 12 deletions.
4 changes: 2 additions & 2 deletions README.md
Expand Up @@ -13,7 +13,7 @@
`pip install pygrocy`

## Usage
Import the package:
Import the package:
```python
from pygrocy import Grocy
```
Expand All @@ -38,4 +38,4 @@ for entry in grocy.stock():
If you need help using pygrocy check the [discussions](https://github.com/SebRut/pygrocy/issues) section. Feel free to create an issue for feature requests, bugs and errors in the library.

## Development testing
You need tox and Python 3.6/8/9 to run the tests. Navigate to the root dir of `pygrocy` and execute `tox` to run the tests.
You need tox and Python 3.8/9/10 to run the tests. Navigate to the root dir of `pygrocy` and execute `tox` to run the tests.
41 changes: 32 additions & 9 deletions pygrocy/grocy_api_client.py
Expand Up @@ -3,11 +3,11 @@
import logging
from datetime import datetime
from enum import Enum
from typing import Dict, List, Optional
from typing import Dict, List, Optional, Any
from urllib.parse import urljoin

import requests
from pydantic import BaseModel, Field
from pydantic import BaseModel, Field, validator
from pydantic.schema import date

from pygrocy import EntityType
Expand All @@ -21,6 +21,17 @@
_LOGGER.setLevel(logging.INFO)


def _field_not_empty_validator(field_name: str):
"""Reusable Pydantic field pre-validator to convert empty str to None."""
return validator(field_name, allow_reuse=True, pre=True)(_none_if_empty_str)


def _none_if_empty_str(value: Any):
if isinstance(value, str) and value == "":
return None
return value


class ShoppingListItem(BaseModel):
id: int
product_id: Optional[int] = None
Expand Down Expand Up @@ -76,7 +87,7 @@ class ProductData(BaseModel):
id: int
name: str
description: Optional[str] = None
location_id: int
location_id: Optional[int] = None
product_group_id: Optional[int] = None
qu_id_stock: int
qu_id_purchase: int
Expand All @@ -87,6 +98,9 @@ class ProductData(BaseModel):
min_stock_amount: Optional[float]
default_best_before_days: int

location_id_validator = _field_not_empty_validator("location_id")
product_group_id_validator = _field_not_empty_validator("product_group_id")


class ChoreData(BaseModel):
id: int
Expand All @@ -102,6 +116,10 @@ class ChoreData(BaseModel):
next_execution_assigned_to_user_id: Optional[int] = None
userfields: Optional[Dict]

next_execution_assigned_to_user_id_validator = _field_not_empty_validator(
"next_execution_assigned_to_user_id"
)


class UserDto(BaseModel):
id: int
Expand All @@ -113,8 +131,8 @@ class UserDto(BaseModel):

class CurrentChoreResponse(BaseModel):
chore_id: int
last_tracked_time: Optional[datetime]
next_estimated_execution_time: datetime
last_tracked_time: Optional[datetime] = None
next_estimated_execution_time: Optional[datetime] = None


class CurrentStockResponse(BaseModel):
Expand Down Expand Up @@ -160,7 +178,7 @@ class ProductDetailsResponse(BaseModel):
class ChoreDetailsResponse(BaseModel):
chore: ChoreData
last_tracked: Optional[datetime] = None
next_estimated_execution_time: datetime
next_estimated_execution_time: Optional[datetime] = None
track_count: int = 0
next_execution_assigned_user: Optional[UserDto] = None
last_done_by: Optional[UserDto] = None
Expand Down Expand Up @@ -193,11 +211,14 @@ class TaskResponse(BaseModel):
assigned_to_user: Optional[UserDto] = None
userfields: Optional[Dict] = None

category_id_validator = _field_not_empty_validator("category_id")
assigned_to_user_id_validator = _field_not_empty_validator("assigned_to_user_id")


class CurrentBatteryResponse(BaseModel):
id: int
last_tracked_time: Optional[datetime] = None
next_estimated_charge_time: datetime
next_estimated_charge_time: Optional[datetime] = None


class BatteryData(BaseModel):
Expand All @@ -214,7 +235,7 @@ class BatteryDetailsResponse(BaseModel):
battery: BatteryData
charge_cycles_count: int
last_charged: Optional[datetime] = None
next_estimated_charge_time: datetime
next_estimated_charge_time: Optional[datetime] = None


class MealPlanSectionResponse(BaseModel):
Expand All @@ -223,6 +244,8 @@ class MealPlanSectionResponse(BaseModel):
sort_number: Optional[int] = None
row_created_timestamp: datetime

sort_number_validator = _field_not_empty_validator("sort_number")


class StockLogResponse(BaseModel):
id: int
Expand Down Expand Up @@ -620,7 +643,7 @@ def get_recipe(self, object_id: int) -> RecipeDetailsResponse:
return RecipeDetailsResponse(**parsed_json)

def get_batteries(self) -> List[CurrentBatteryResponse]:
parsed_json = self._do_get_request(f"batteries")
parsed_json = self._do_get_request("batteries")
if parsed_json:
return [CurrentBatteryResponse(**data) for data in parsed_json]

Expand Down
2 changes: 1 addition & 1 deletion test/test_product.py
Expand Up @@ -26,7 +26,7 @@ def test_product_get_details_valid(self, grocy):
assert product.qu_factor_purchase_to_stock == 1.0
assert product.default_quantity_unit_purchase.id == 5
assert product.default_quantity_unit_purchase.name == "Tin"
assert product.default_quantity_unit_purchase.description == None
assert product.default_quantity_unit_purchase.description is None
assert product.default_quantity_unit_purchase.name_plural == "Tins"

assert len(product.product_barcodes) == 2
Expand Down

0 comments on commit b6b7aa2

Please sign in to comment.