Skip to content

Commit

Permalink
Merge release candidate #233 from emnify/development
Browse files Browse the repository at this point in the history
  • Loading branch information
Th3Un1q3 authored Sep 16, 2024
2 parents 0b57dcb + adcbec7 commit 7338215
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 44 deletions.
2 changes: 1 addition & 1 deletion DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ To set up your sandbox, modify the code in this file as needed.
Once your sandbox is set up, you can launch the file and view the results.
```shell
docker run -t -e EMNIFY_SDK_APPLICATION_TOKEN=<your_token_here> -e EMINFY_SDK_API_ENDPOINT_URL=<your_debug_API_endpoint> -v $(pwd):/sdk emnify/python-sdk python docs/examples/local_debug.py
docker run -t -e EMNIFY_SDK_APPLICATION_TOKEN=<your_token_here> -e EMNIFY_SDK_API_ENDPOINT_URL=<your_debug_API_endpoint> -v $(pwd):/sdk emnify/python-sdk python docs/examples/local_debug.py
```

## Version Bump
Expand Down
4 changes: 2 additions & 2 deletions emnify/api_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from emnify.modules.api.models import AuthenticationResponse
from emnify import constants as emnify_constants

MAIN_URL = os.environ.get('EMINFY_SDK_API_ENDPOINT_URL', 'https://cdn.emnify.net/api')
MAIN_URL = os.environ.get('EMNIFY_SDK_API_ENDPOINT_URL', 'https://cdn.emnify.net/api')

MAX_PAGES_IN_PAGINATOR = 1000 # with regular page size 1000...2000 gives max 2_000_000 records

Expand Down Expand Up @@ -46,7 +46,7 @@ def process_exception(self, response: requests.Response, client, data: dict = No
raise emnify_errors.ValidationErrorException(f'{response.json()}')

def return_paginator(
self, response: requests.Response, client, data, files, query_params, path_params
self, response: requests.Response, client, data: dict = None, files=None, path_params: dict = None, query_params: dict = None
) -> typing.Generator:
query_params = query_params or {}
page = query_params.get('page', 1) if query_params else 1
Expand Down
76 changes: 53 additions & 23 deletions emnify/modules/device/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
class DeviceManager:
"""
Manager that allows to get/retrieve/create/update/send_sms to device
Args:
client: An instance of the EMnify class used for making API requests.
"""
def __init__(self, client):
self.client = client
Expand Down Expand Up @@ -63,6 +66,12 @@ def get_device_filter_model(self) -> typing.Type[device_models.FilterDeviceModel
return device_models.FilterDeviceModel

def get_device_sms_list(self, *, device: typing.Union[device_models.Device, int]) -> device_models.ListSms:
"""
Returns a list of SMS from the device.
:param device: device model or id of device
:return: list of devices
"""
device_id = self.validate_device(device)
sms_response = device_call_managers.GetAllSmsFromDevice().call_api(
client=self.client, path_params={'endpoint_id': device_id}
Expand All @@ -76,7 +85,8 @@ def send_sms(
sms: device_models.SmsCreateModel
) -> bool:
"""
Method sends sms to device
Sends an SMS to the device.
:param device: device model or id of device
:param sms: SmsCreateModel
:return: True if sms was sent
Expand All @@ -90,7 +100,8 @@ def send_sms(

def update_device(self, *, device_id: int, device: device_models.UpdateDevice) -> device_models.Device:
"""
Method updates device
Updates the device.
:param device_id: id of device
:param device: device update model
:return: True if device was updated
Expand All @@ -101,7 +112,8 @@ def update_device(self, *, device_id: int, device: device_models.UpdateDevice) -

def reset_connectivity_network(self, device_id: int) -> True:
"""
Method resets device connectivity network
Resets the device's connectivity network.
:param device_id: id of device
:return: True if reset of network was successful
"""
Expand All @@ -111,7 +123,8 @@ def reset_connectivity_network(self, device_id: int) -> True:

def reset_connectivity_data(self, device_id: int) -> True:
"""
Method resets device connectivity data
Resets the device's connectivity data.
:param device_id: id of device
:return: True if reset of data was successful
"""
Expand All @@ -121,7 +134,8 @@ def reset_connectivity_data(self, device_id: int) -> True:

def get_device_connectivity_status(self, device_id: int) -> device_models.DeviceConnectivityStatus:
"""
Method returns device connectivity status
Returns the device's connectivity status.
:param device_id: id of device
:return: DeviceConnectivityStatus model
"""
Expand All @@ -135,9 +149,10 @@ def get_devices_list(
filter_model: device_models.FilterDeviceModel = None,
sort_enum: device_models.DeviceSortModel = None,
**kwargs
) -> typing.Generator[device_models.RetrieveDevice, None, None]:
) -> typing.Generator[device_models.Device, None, None]:
"""
Method returns list of devices
Returns a list of devices.
:param filter_model: device filter model
:param sort_enum: device sort enum
:return: list of devices
Expand All @@ -151,6 +166,8 @@ def get_devices_list(

def delete_device(self, device_id: int) -> True:
"""
Deletes the device.
:param device_id: id of device
:return: True if device was deleted
"""
Expand All @@ -161,6 +178,8 @@ def delete_device(self, device_id: int) -> True:

def add_device_blacklist_operator(self, device_id: int, operator_id: int) -> True:
"""
Adds an operator to the blacklist.
:param device_id: id of device
:param operator_id: id of operator
:return: True if operator was added to blacklist
Expand All @@ -171,6 +190,8 @@ def add_device_blacklist_operator(self, device_id: int, operator_id: int) -> Tru

def delete_device_blacklist_operator(self, device_id: int, operator_id: int):
"""
Removes an operator from the blacklist.
:param device_id: id of device
:param operator_id: id of operator
:return: True if operator was deleted from blacklist
Expand All @@ -181,6 +202,8 @@ def delete_device_blacklist_operator(self, device_id: int, operator_id: int):

def get_device_operator_blacklist(self, device_id: int):
"""
Returns a list of blacklisted operators.
:param device_id: id of device
:return: list of operators
"""
Expand All @@ -192,6 +215,8 @@ def get_device_operator_blacklist(self, device_id: int):

def get_device_events_list(self, device: typing.Union[device_models.Device, int]):
"""
Returns a list of events for the device.
:param device: Device pydantic-model or int
:return: Generator with Device objects
"""
Expand All @@ -207,16 +232,13 @@ def change_status(
device_models.UpdateDevice, device_models.Device, device_models.RetrieveDevice, int
],
enable: bool = None, disable: bool = None
) -> None:
) -> bool:
"""
Change the status of a device and assigned SIM to enabled or disabled.
Changes the status of a device and its assigned SIM to enabled or disabled.
:param device: The ID or device model to update.
:type device: Union[UpdateDevice, Device, RetrieveDevice, int]
:param enable: Whether to enable the device.
:type enable: bool
:param disable: Whether to disable the device.
:type disable: bool
:raises ValidationErrorException: If neither `enable` nor `disable` is provided, or if both are provided.
"""
if not (enable or disable) or (enable and disable):
Expand All @@ -231,7 +253,8 @@ def change_status(

def disable_device(self, device_id: int):
"""
Method for changing a device status to 'disabled'
Changes a device status to 'disabled'.
:param device_id: id of device
:return: True if device was disabled
"""
Expand All @@ -240,7 +263,10 @@ def disable_device(self, device_id: int):

def release_sim(self, device_id: int):
"""
This method allows to release the assigned SIM from device by device_id
Releases the assigned SIM from the device.
:param device_id: id of device
:return: True if sim was released
"""
device = self.retrieve_device(device_id=device_id)
if not device.sim:
Expand All @@ -253,7 +279,11 @@ def release_sim(self, device_id: int):

def assign_sim(self, device_id: int, sim_id: int, enable: bool = False) -> None:
"""
this method allow to assign a SIM to the device
Assigns a SIM to the device
:param device_id: id of device
:param sim_id: id of SIM
:param enable: boolean value/activate to enable or disable the device
"""
device = self.retrieve_device(device_id=device_id)
sim = self.client.sim.retrieve_sim(sim_id=sim_id)
Expand All @@ -270,7 +300,8 @@ def assign_sim(self, device_id: int, sim_id: int, enable: bool = False) -> None:

def create_device(self, device: device_models.Device) -> bool:
"""
Method for creating a device
Creates a device
:param device: device model
:return: True if device was created
"""
Expand All @@ -279,6 +310,12 @@ def create_device(self, device: device_models.Device) -> bool:
return device_call_managers.CreateDevice().call_api(client=self.client, data=device.dict(exclude_none=True))

def retrieve_device(self, device_id: int) -> device_models.RetrieveDevice:
"""
Retrieves endpoint details for a given ID.
:param device_id: id of the device.
:return: Endpoint details associated with the given ID.
"""
if not isinstance(device_id, int) or device_id <= 0:
raise UnexpectedArgumentException('Device id must be positive integer')
response = device_call_managers.RetrieveDevice().call_api(
Expand All @@ -297,18 +334,11 @@ def validate_device(device: device_models.Device) -> int:

@staticmethod
def __check_device_status(device, status: dict):
"""
Hidden method for checking device for status update
devices to activate must have activated sim
"""
if status == emnify_constants.SimStatusesDict.ACTIVATED_DICT:
if not device.sim:
raise emnify_errors.ValidationErrorException('Devices for activation must have sim`s')

def __change_device_status(self, action: str, device):
"""
Hidden method for changing status of the device
"""
status_dict = {
'enable': {
'sim_status': emnify_constants.SimStatusesDict.ACTIVATED_DICT.value,
Expand Down
33 changes: 15 additions & 18 deletions emnify/modules/sim/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,35 +12,24 @@ class SimManager:
Args:
client: An instance of the EMnify class used for making API requests.
"""

def __init__(self, client):
self.client = client

@property
def get_sim_list_model(self):
"""
Returns the model for the SIM list.
"""
return sim_models.SimList

@property
def get_sim_update_model(self):
"""
Returns the model for updating SIM cards.
"""
return sim_models.SimUpdate

@property
def get_sim_filter_model(self):
"""
Returns the model for filtering SIM cards.
"""
return sim_models.SimFilter

@property
def get_sim_sort_enum(self):
"""
Returns sim sorting options.
"""
return emnify_const.SimSort

def get_sim_list(
Expand All @@ -50,7 +39,8 @@ def get_sim_list(
sort_enum: emnify_const.SimSort = None
) -> typing.Generator[sim_models.SimList, None, None]:
"""
Retrieve iterable list of SIM`s.
Retrieves an iterable list of SIM`s.
:param without_device: Allows to add a filter for request to find all SIM`s without device
:param filter_model: Model for request`s filtering
:param sort_enum: Model for request`s sorting
Expand All @@ -65,13 +55,17 @@ def get_sim_list(

def retrieve_sim(self, sim_id: int):
"""
Method for retrieving details of single sim by id
Retrieves details of single SIM by ID.
:param sim_id: id of sim to retrieve
"""
return sim_models.SimList(**SimRetrieveApi().call_api(client=self.client, path_params={'sim': sim_id}))

def register_sim(self, bic: str) -> typing.Union[typing.List[sim_models.SimList], sim_models.SimList]:
"""
:param bic: BIC number of sim/batch sims for registration
Registers SIM/batch SIMs.
:param bic: BIC number of SIM/batch SIMs for registration.
"""
data = emnify_const.SimStatusesDict.ACTIVATED_DICT.value
sim_response = SimActivateApi().call_api(client=self.client, data=data, path_params={'bic': bic})
Expand All @@ -83,18 +77,20 @@ def register_sim(self, bic: str) -> typing.Union[typing.List[sim_models.SimList]

def update_sim(self, sim_id: int, sim: sim_models.SimUpdate) -> bool:
"""
Method for updating sim`s
Updates SIM.
:param sim_id: int of sim to update
:param sim: filled sim update model
"""
return SimUpdateApi()\
return SimUpdateApi() \
.call_api(client=self.client, data=sim.dict(exclude_none=True), path_params={'sim': sim_id})

def activate_sim(self, sim_id: int):
"""
Activates `suspended` or `issued` SIM.
If you want to control both the device and SIM as a whole, it's recommended to use the :class:`DeviceManager.change_status` method if the SIM is assigned to a device.
Learn more about SIM Lifecycle: https://docs.emnify.com/services/sim-lifecycle-management
:param sim_id: int of sim to update
"""
return SimUpdateApi() \
Expand All @@ -108,6 +104,7 @@ def suspend_sim(self, sim_id: int):
Puts the `active` SIM to `suspended` state.
If you want to control both the device and SIM as a whole, it's recommended to use the :class:`DeviceManager.change_status` method if the SIM is assigned to a device.
Learn more about SIM Lifecycle: https://docs.emnify.com/services/sim-lifecycle-management
:param sim_id: id of sim to update
"""
return SimUpdateApi() \
Expand All @@ -131,7 +128,7 @@ def __transform_sim_filter_params(
query_filter['sort'] = sort_enum
if without_device is not None and without_device:
if query_filter.get('q'):
query_filter['q'] = query_filter['q']+'endpoint:null'
query_filter['q'] = query_filter['q'] + 'endpoint:null'
else:
query_filter['q'] = 'endpoint:null'
return query_filter

0 comments on commit 7338215

Please sign in to comment.