Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 46 additions & 4 deletions inpost/api.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import logging
from typing import List

from aiohttp import ClientSession, ClientResponse
from aiohttp.typedefs import StrOrURL
from typing import List
import logging
from arrow import utcnow

from inpost.static import *


Expand Down Expand Up @@ -77,6 +78,9 @@ async def request(

if autorefresh and resp.status == 401:
await self.refresh_token()
headers_.update(
{'Authorization': self.auth_token}
)
resp = await self.sess.request(method, url, headers=headers_, json=data, **kwargs)

match resp.status:
Expand Down Expand Up @@ -107,6 +111,17 @@ async def from_phone_number(cls, phone_number: str | int):
inp._log.info(f'initialized by from_phone_number')
return inp

@classmethod
async def from_dict(cls, data: dict):
inp = cls()
await inp.set_phone_number(data['phone_number'])
inp.sms_code = data['sms_code']
inp.auth_token = data['auth_token']
inp.refr_token = data['refr_token']

inp._log.info(f'initialized by from_dict')
return inp

async def set_phone_number(self, phone_number: str | int) -> bool:
"""Set :class:`Inpost` phone number required for verification

Expand Down Expand Up @@ -502,7 +517,7 @@ async def open_compartment(self) -> bool:
self._log.debug(f'authorization token missing')
raise NotAuthenticatedError(reason='Not logged in')

resp = await self.request(method='get',
resp = await self.request(method='post',
action=f"open compartment for {self.parcel.shipment_number}",
url=compartment_open,
auth=True,
Expand Down Expand Up @@ -634,6 +649,33 @@ async def close_compartment(self) -> bool:

return False

async def reopen_compartment(self) -> bool:
"""Reopens compartment for `Inpost.parcel` object

:return: True if compartment gets reopened
:rtype: bool
:raises NotAuthenticatedError: User not authenticated in inpost service
:raises UnauthorizedError: Unauthorized access to inpost services,
:raises NotFoundError: Phone number not found
:raises UnidentifiedAPIError: Unexpected thing happened"""
self._log.info(f'reopening compartment for {self.parcel.shipment_number}')

if not self.auth_token:
self._log.debug(f'authorization token missing')
raise NotAuthenticatedError(reason='Not logged in')

resp = await self.request(method='post',
action=f"reopen compartment for {self.parcel.shipment_number}",
url=compartment_open,
auth=True,
headers=None,
data={'sessionUuid': self.parcel.compartment_properties.session_uuid},
autorefresh=True)

if resp.status == 200:
self._log.debug(f'opened compartment for {self.parcel.shipment_number}')
return True

async def get_prices(self) -> dict:
"""Fetches prices for inpost services

Expand Down
1 change: 1 addition & 0 deletions inpost/static/endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
parcel: str = 'https://api-inmobile-pl.easypack24.net/v3/parcels/tracked/' # get
multi: str = 'https://api-inmobile-pl.easypack24.net/v3/parcels/multi/' # get
collect: str = 'https://api-inmobile-pl.easypack24.net/v1/collect/validate' # post
reopen: str = 'https://api-inmobile-pl.easypack24.net/v1/collect/compartment/reopen' # post
compartment_open: str = 'https://api-inmobile-pl.easypack24.net/v1/collect/compartment/open' # post
compartment_status: str = 'https://api-inmobile-pl.easypack24.net/v1/collect/compartment/status' # post
terminate_collect_session: str = 'https://api-inmobile-pl.easypack24.net/v1/collect/terminate' # post
Expand Down
49 changes: 33 additions & 16 deletions inpost/static/parcels.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,9 @@

class BaseParcel:
def __init__(self, parcel_data: dict, logger: logging.Logger):
self.shipment_number: str = parcel_data['shipmentNumber']
self.shipment_number: str = parcel_data.get('shipmentNumber')
self._log: logging.Logger = logger.getChild(f'{__class__.__name__}.{self.shipment_number}')
self.status: ParcelStatus = ParcelStatus[parcel_data['status']]
# self.parcel_size: ParcelLockerSize | ParcelCarrierSize = ParcelLockerSize[parcel_data['parcelSize']] \
# if self.shipment_type == ParcelShipmentType.parcel else ParcelCarrierSize[parcel_data['parcelSize']]
self.expiry_date: arrow | None = get(parcel_data['expiryDate']) if 'expiryDate' in parcel_data else None
self.operations: Operations = Operations(operations_data=parcel_data['operations'], logger=self._log)
self.event_log: List[EventLog] = [EventLog(eventlog_data=event, logger=self._log)
Expand All @@ -33,32 +31,28 @@ class Parcel(BaseParcel):
def __init__(self, parcel_data: dict, logger: logging.Logger):
"""Constructor method"""
super().__init__(parcel_data, logger)
# self.shipment_number: str = parcel_data['shipmentNumber']
self._log: logging.Logger = logger.getChild(f'{__class__.__name__}.{self.shipment_number}')
self.shipment_type: ParcelShipmentType = ParcelShipmentType[parcel_data['shipmentType']]
self._open_code: str | None = parcel_data['openCode'] if 'openCode' in parcel_data else None
self._open_code: str | None = parcel_data.get('openCode', None)
self._qr_code: QRCode | None = QRCode(qrcode_data=parcel_data['qrCode'], logger=self._log) \
if 'qrCode' in parcel_data else None
self.stored_date: arrow | None = get(parcel_data['storedDate']) if 'storedDate' in parcel_data else None
self.pickup_date: arrow | None = get(parcel_data['pickUpDate']) if 'pickUpDate' in parcel_data else None
# self.expiry_date: arrow | None = get(parcel_data['expiryDate']) if 'expiryDate' in parcel_data else None
self.parcel_size: ParcelLockerSize | ParcelCarrierSize = ParcelLockerSize[parcel_data['parcelSize']] \
if self.shipment_type == ParcelShipmentType.parcel else ParcelCarrierSize[parcel_data['parcelSize']]
self.receiver: Receiver = Receiver(receiver_data=parcel_data['receiver'], logger=self._log)
self.sender: Sender = Sender(sender_data=parcel_data['sender'], logger=self._log)
self.receiver: Receiver = Receiver(receiver_data=parcel_data['receiver'], logger=self._log) if 'receiver' in parcel_data else None
self.sender: Sender = Sender(sender_data=parcel_data['sender'], logger=self._log) if 'sender' in parcel_data else None
self.pickup_point: PickupPoint = PickupPoint(pickuppoint_data=parcel_data['pickUpPoint'], logger=self._log) \
if 'pickUpPoint' in parcel_data else None
self.multi_compartment: MultiCompartment | None = MultiCompartment(
parcel_data['multiCompartment'], logger=self._log) if 'multiCompartment' in parcel_data else None
self.is_end_off_week_collection: bool = parcel_data['endOfWeekCollection']
# self.operations: Operations = Operations(operations_data=parcel_data['operations'], logger=self._log)
self.status: ParcelStatus = ParcelStatus[parcel_data['status']]
# self.event_log: List[EventLog] = [EventLog(eventlog_data=event, logger=self._log)
# for event in parcel_data['eventLog']]
self.avizo_transaction_status: str = parcel_data['avizoTransactionStatus']
self.is_end_off_week_collection: bool | None = parcel_data.get('endOfWeekCollection', None)
self.status: ParcelStatus = ParcelStatus[parcel_data['status']] if 'status' in parcel_data else None
self.avizo_transaction_status: str | None = parcel_data.get('avizoTransactionStatus', None)
self.shared_to: List[SharedTo] = [SharedTo(sharedto_data=person, logger=self._log)
for person in parcel_data['sharedTo']]
self.ownership_status: ParcelOwnership = ParcelOwnership[parcel_data['ownershipStatus']]
for person in parcel_data['sharedTo']] if 'sharedTo' in parcel_data else None
self.ownership_status: ParcelOwnership = ParcelOwnership[parcel_data['ownershipStatus']] if 'ownershipStatus' in parcel_data else None
self.economy_parcel: bool | None = parcel_data.get('economyParcel', None)
self._compartment_properties: CompartmentProperties | None = None

self._log.debug(f'created parcel with shipment number {self.shipment_number}')
Expand Down Expand Up @@ -338,6 +332,7 @@ def __init__(self, pickuppoint_data: dict, logger: logging.Logger):
self.image_url: str = pickuppoint_data['imageUrl']
self.easy_access_zone: bool = pickuppoint_data['easyAccessZone']
self.air_sensor: bool = pickuppoint_data['airSensor']
self.air_sensor_data: AirSensorData | None = AirSensorData(pickuppoint_data['airSensorData']) if 'airSensorData' in pickuppoint_data else None

self._log: logging.Logger = logger.getChild(__class__.__name__)
self._log.debug('created')
Expand Down Expand Up @@ -604,3 +599,25 @@ def status(self, status_data: str | CompartmentActualStatus):

if self._status == CompartmentActualStatus.UNKNOWN and isinstance(status_data, str):
self._log.debug(f'unexpected compartment actual status: {status_data}')


class AirSensorData:
"""Object representation of :class:`Parcel` air sensor data

:param airsensor_data: :class:`dict` containing air sensor data for :class:`Parcel`
:type airsensor_data: dict
:param logger: :class:`logging.Logger` parent instance
:type logger: logging.Logger"""
def __init__(self, airsensor_data: dict, logger: logging.Logger):
self.updated_until: arrow = airsensor_data['updatedUntil']
self.air_quality: str = airsensor_data['airQuality']
self.temperature: float = airsensor_data['temperature']
self.humidity: float = airsensor_data['humidity']
self.pressure: float = airsensor_data['pressure']
self.pm25_value: float = airsensor_data['pollutants']['pm25']['value']
self.pm25_percent: float = airsensor_data['pollutants']['pm25']['percent']
self.pm10_value: float = airsensor_data['pollutants']['pm10']['value']
self.pm10_percent: float = airsensor_data['pollutants']['pm10']['percent']

self._log: logging.Logger = logger.getChild(__class__.__name__)
self._log.debug('created')
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "inpost"
version = "0.0.10"
version = "0.1.2"
description = "Asynchronous InPost package allowing you to manage existing incoming parcels without mobile app"
authors = ["loboda4450 <[email protected]>", "MrKazik99 <[email protected]>"]
maintainers = ["loboda4450 <[email protected]>"]
Expand All @@ -13,6 +13,7 @@ packages = [
]
classifiers = [
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Framework :: aiohttp",
"Intended Audience :: Developers",
"Operating System :: Microsoft :: Windows",
Expand Down