From 7c66c6ccbc057c9b7cecd3c62288c558556e7850 Mon Sep 17 00:00:00 2001 From: Pavel Sinitsin Date: Sat, 22 Jun 2024 18:55:10 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A3=D0=B1=D1=80=D0=B0=D0=BB=20=D0=BB=D0=B8?= =?UTF-8?q?=D1=88=D0=BD=D0=B8=D0=B5=20=D0=B8=D0=BC=D0=BE=D1=80=D1=82=D1=8B?= =?UTF-8?q?=20=D0=B8=20=D0=B1=D0=B8=D0=B1=D0=BB=D0=B8=D0=BE=D1=82=D0=B5?= =?UTF-8?q?=D0=BA=D0=B8=20=D0=B8=D0=B7=20pyproject.toml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bpiek/api.py | 64 ++++++++--------------- bpiek/models.py | 136 +++++++++++++++++++++++------------------------- pyproject.toml | 1 - 3 files changed, 89 insertions(+), 112 deletions(-) diff --git a/bpiek/api.py b/bpiek/api.py index 5a2184d..dbb7ee4 100644 --- a/bpiek/api.py +++ b/bpiek/api.py @@ -1,10 +1,10 @@ - import requests from bpiek import models AUTH_URL = "https://bp.iek.ru/oauth/login" API_URL = "https://bp.iek.ru/api/catalog/v1/" + class BPIekApi: def __init__(self, username, password) -> None: self.session = requests.Session() @@ -16,25 +16,15 @@ class BPIekApi: def _login(self) -> None: auth = self.session.post( url=f"{AUTH_URL}", - headers={ - "Content-Type": "application/x-www-form-urlencoded" - }, - data={ - "username": self.username, - "password": self.password - } + headers={"Content-Type": "application/x-www-form-urlencoded"}, + data={"username": self.username, "password": self.password}, ) def _instance(self, endpoint, params: dict = {}): response = self.session.get( url=API_URL + endpoint, - headers={ - "Content-Type": "application/json" - }, - params={ - "format": "json", - **params - } + headers={"Content-Type": "application/json"}, + params={"format": "json", **params}, ) return response.json() @@ -43,9 +33,7 @@ class BPIekApi: try: result: models.ParentCategoriesResponse = ( - models - .ParentCategoriesResponse - .model_validate(response) + models.ParentCategoriesResponse.model_validate(response) ) return result.categories @@ -57,25 +45,23 @@ class BPIekApi: response = self._instance(f"client/products/{article}") try: - result: models.Product = ( - models - .Product - .model_validate(response) - ) + result: models.Product = models.Product.model_validate(response) return result except Exception as e: return models.Error(code=400, message=str(e)) - def get_categories_and_products_by_slug_parent_category(self, slug) -> models.CategoriesAndProductsBySlugParentCategory | models.Error: + def get_categories_and_products_by_slug_parent_category( + self, slug + ) -> models.CategoriesAndProductsBySlugParentCategory | models.Error: response = self._instance(f"client/category/{slug}/json") try: result: models.CategoriesAndProductsBySlugParentCategory = ( - models - .CategoriesAndProductsBySlugParentCategory - .model_validate(response) + models.CategoriesAndProductsBySlugParentCategory.model_validate( + response + ) ) return result @@ -88,20 +74,16 @@ class BPIekApi: sortBy: str = "article", sortOrder: str = "asc", pageSize: int = 10, - page: int = 1 + page: int = 1, ) -> models.NewProductsResponse | models.Error: - response = self._instance("new-products", { - sortBy: sortBy, - sortOrder: sortOrder, - pageSize: pageSize, - page: page - }) + response = self._instance( + "new-products", + {sortBy: sortBy, sortOrder: sortOrder, pageSize: pageSize, page: page}, + ) try: result: models.NewProductsResponse = ( - models - .NewProductsResponse - .model_validate(response) + models.NewProductsResponse.model_validate(response) ) return result @@ -109,14 +91,14 @@ class BPIekApi: except Exception as e: return models.Error(code=400, message=str(e)) - def get_remains_and_planresidues(self, slug) -> models.RemainsAndPlanresiduesResponse | models.Error: + def get_remains_and_planresidues( + self, slug + ) -> models.RemainsAndPlanresiduesResponse | models.Error: response = self._instance(f"client/category/{slug}/balances-json") try: result: models.RemainsAndPlanresiduesResponse = ( - models - .RemainsAndPlanresiduesResponse - .model_validate(response) + models.RemainsAndPlanresiduesResponse.model_validate(response) ) return result diff --git a/bpiek/models.py b/bpiek/models.py index 907f378..260572b 100644 --- a/bpiek/models.py +++ b/bpiek/models.py @@ -3,12 +3,12 @@ from pydantic import BaseModel, ConfigDict, Field from pydantic.types import UUID1 - class Category(BaseModel): - slug: str # Слаг категории - name: str # Название категории - url: str # Относительный адрес категории - apiUrl: str # Ссылка на скачивание файла с содержимым категории + slug: str # Слаг категории + name: str # Название категории + url: str # Относительный адрес категории + apiUrl: str # Ссылка на скачивание файла с содержимым категории + class ProductShort(BaseModel): class WarehouseData(BaseModel): @@ -16,55 +16,53 @@ class ProductShort(BaseModel): dateBegan: str | None dateEnd: str | None amount: int - type: str # Enum: "production" "shipping" Тип поступления, production - поступление после производства, shipping - доставка на склад + type: str # Enum: "production" "shipping" Тип поступления, production - поступление после производства, shipping - доставка на склад warehouseId: UUID1 warehouseName: str availableAmount: int incoming: list[Incoming] - - article: str # Артикул товара - name: str # Полное наименование товара - multiplicity: int | None # Кратность продажи - priceBase: float | None # Базовая цена с НДС - priceRrc: float | None # Рекомендованная розничная цена (РРЦ) с НДС - available: int | None # Значение остатка - units: str | None # Единицы измерения + article: str # Артикул товара + name: str # Полное наименование товара + multiplicity: int | None # Кратность продажи + priceBase: float | None # Базовая цена с НДС + priceRrc: float | None # Рекомендованная розничная цена (РРЦ) с НДС + available: int | None # Значение остатка + units: str | None # Единицы измерения warehouseData: list[WarehouseData] + class Product(ProductShort): class ImageVariant(BaseModel): - url: str # Ссылка - ext: str # Расширение - width: int # Ширина - + url: str # Ссылка + ext: str # Расширение + width: int # Ширина class Etim(BaseModel): class EtimClass(BaseModel): id: str - name: str # Название класса + name: str # Название класса class EtimFeatures(BaseModel): id: str - name: str # Название свойства - sort: int | None # Порядок сортировки по умолчанию - unit: str | None # Единицы измерения - value: str # Значение свойства - value_union: str # Код значения + name: str # Название свойства + sort: int | None # Порядок сортировки по умолчанию + unit: str | None # Единицы измерения + value: str # Значение свойства + value_union: str # Код значения etim_class: EtimClass = Field(alias="class") features: list[EtimFeatures] - class Complects(BaseModel): - article: str # Артикул - name: str # Наименование - quantity: int # Количество + article: str # Артикул + name: str # Наименование + quantity: int # Количество class LeftPeriod(BaseModel): - name: str # Название характеристики - value: str # Значение характеристики + name: str # Название характеристики + value: str # Значение характеристики class LeftPeriodRaw(BaseModel): class Lifespan(BaseModel): @@ -101,11 +99,10 @@ class Product(ProductShort): description: str class Videos(BaseModel): - name: str description: str url: str - type: str # Enum: "url" "file" + type: str # Enum: "url" "file" class Software(BaseModel): name: str @@ -113,54 +110,51 @@ class Product(ProductShort): url: str size: str - - - - shortName: str # Краткое название - description: str | None # Описание - categoryName: str | None # Название категории - category: str # Относительный путь до категории в каталоге - slug: str # Слаг товара - tm: str # Торговая марка - url: str # Ссылка на товар - isArchived: bool # Архивный или нет - imageUrl: str # Фото товара (основное) - imageUrls: list[str] # Все фото товара - imageVariants: list[ImageVariant] # Все вариации изображений - advantages: str | None # Преимущества - etim: Etim # EIM характеристики товара - complects: list[Complects] # Комплектация и сопутствующие товары - complectations: str | None # Комплектация - files: list[Any] # Список файлов, относящихся к товару (ГЧ, КД, CAD-модели и т.д.) - leftPeriod: list[LeftPeriod] | None # Характеристики срока службы - leftPeriodRaw: LeftPeriodRaw # Гарантийные показатели - logisticParams: list[LogisticParams] # Логистические характеристики - logisticParamsData: LogisticParamsData | None # Подробные логистические характеристики - novelty: bool # Новинка или нет - designFeatures: list[DesignFeatures] # Отличительные особенности - videos: list[Videos] # Видео по товару - software: list[Software] # ПО по товару - banner: str | None # Текст баннера - lastModified: str | None # Дата последнего изменения - countryOfProduction: str | None # Страна производства - firstSaleDate: str | None # Дата начала продаж - feacn: str | None # Код ТН ВЭД + shortName: str # Краткое название + description: str | None # Описание + categoryName: str | None # Название категории + category: str # Относительный путь до категории в каталоге + slug: str # Слаг товара + tm: str # Торговая марка + url: str # Ссылка на товар + isArchived: bool # Архивный или нет + imageUrl: str # Фото товара (основное) + imageUrls: list[str] # Все фото товара + imageVariants: list[ImageVariant] # Все вариации изображений + advantages: str | None # Преимущества + etim: Etim # EIM характеристики товара + complects: list[Complects] # Комплектация и сопутствующие товары + complectations: str | None # Комплектация + files: list[Any] # Список файлов, относящихся к товару (ГЧ, КД, CAD-модели и т.д.) + leftPeriod: list[LeftPeriod] | None # Характеристики срока службы + leftPeriodRaw: LeftPeriodRaw # Гарантийные показатели + logisticParams: list[LogisticParams] # Логистические характеристики + logisticParamsData: ( + LogisticParamsData | None + ) # Подробные логистические характеристики + novelty: bool # Новинка или нет + designFeatures: list[DesignFeatures] # Отличительные особенности + videos: list[Videos] # Видео по товару + software: list[Software] # ПО по товару + banner: str | None # Текст баннера + lastModified: str | None # Дата последнего изменения + countryOfProduction: str | None # Страна производства + firstSaleDate: str | None # Дата начала продаж + feacn: str | None # Код ТН ВЭД family: str | Any | None series: str | Any | None - indPacking: list[str] # Ссылки на фото упаковки - analogs: list["Product"] # Аналоги - related: list["Product"] # Совместно применяемые изделия + indPacking: list[str] # Ссылки на фото упаковки + analogs: list["Product"] # Аналоги + related: list["Product"] # Совместно применяемые изделия qrCode: str | None = Field(default=None) isOutOfAssortment: bool isOutOfProduction: bool - - - class ParentCategoriesResponse(BaseModel): categories: list[Category] + class CategoriesAndProductsBySlugParentCategory(BaseModel): date: str slug: str @@ -169,6 +163,7 @@ class CategoriesAndProductsBySlugParentCategory(BaseModel): categories: list[Category] products: list[Product] + class NewProductsResponse(BaseModel): class Data(BaseModel): products: list[Product] @@ -182,6 +177,7 @@ class NewProductsResponse(BaseModel): data: Data _meta: Meta + class RemainsAndPlanresiduesResponse(BaseModel): date: str products: list[ProductShort] diff --git a/pyproject.toml b/pyproject.toml index 98e4e5e..a983bc6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,6 @@ readme = "README.md" [tool.poetry.dependencies] python = "^3.12" requests = "^2.32.3" -loguru = "^0.7.2" pydantic = "^2.7.4"