connect-client-py 4.3.3__tar.gz → 4.3.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: connect-client-py
3
- Version: 4.3.3
3
+ Version: 4.3.4
4
4
  Summary: The official Python HTTP client to interact with the Connect REST API. Developed and maintained by Trinity IoT.
5
5
  Author: Andries Niemandt
6
6
  Author-email: Andries Niemandt <andries.niemandt@trintel.co.za>
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "connect-client-py"
7
- version = "4.3.3"
7
+ version = "4.3.4"
8
8
  description = "The official Python HTTP client to interact with the Connect REST API. Developed and maintained by Trinity IoT."
9
9
  requires-python = ">=3.9"
10
10
  license = "MIT"
@@ -5325,10 +5325,11 @@ class AsyncConnectClient:
5325
5325
  return Response(status=__response.status, headers=__response.headers, parsed=__result)
5326
5326
 
5327
5327
 
5328
- async def sims_crossref_retrieve(self, cr_key: str, cr_value: str) -> CrossReferenceRecord:
5328
+ async def sims_crossref_retrieve(self, cr_key: str, cr_value: str, *, apn: Optional[str] = None) -> CrossReferenceRecord:
5329
5329
  """
5330
- Returns the cross reference information for a SIM.
5331
- This includes information about the SIMs:
5330
+ Returns the cross reference information for a SIM, addressed by
5331
+ one of the identifiers the network reports: `msisdn`, `imsi`, `imei`
5332
+ or `ip`. This includes information about the SIMs:
5332
5333
 
5333
5334
  - MSISND
5334
5335
 
@@ -5338,6 +5339,13 @@ class AsyncConnectClient:
5338
5339
 
5339
5340
  - IP
5340
5341
 
5342
+ A framed IP is only unique within its APN's pool, so an `ip` lookup
5343
+ must also name the APN via the `apn` query parameter and is refused
5344
+ with `400 Bad Request` without it. Where several attachments match
5345
+ (a SIM on two APNs, an IP reissued from the pool) the most recently
5346
+ seen one is returned. A SIM with no observed traffic has no
5347
+ cross-reference data and returns 404.
5348
+
5341
5349
 
5342
5350
  **Required Roles:**
5343
5351
  - No special roles required
@@ -5348,13 +5356,15 @@ class AsyncConnectClient:
5348
5356
  against the company and folder associated with the resource.
5349
5357
  - The member must have access to the Folder the SIM is in.
5350
5358
  """
5351
- return (await self.sims_crossref_retrieve_with_response(cr_key, cr_value)).parsed
5359
+ return (await self.sims_crossref_retrieve_with_response(cr_key, cr_value, apn=apn)).parsed
5352
5360
 
5353
- async def sims_crossref_retrieve_with_response(self, cr_key: str, cr_value: str) -> Response[CrossReferenceRecord]:
5361
+ async def sims_crossref_retrieve_with_response(self, cr_key: str, cr_value: str, *, apn: Optional[str] = None) -> Response[CrossReferenceRecord]:
5354
5362
  cr_key_enc = quote(cr_key, safe="")
5355
5363
  cr_value_enc = quote(cr_value, safe="")
5356
5364
  __path = f"/api/v4/sims/crossref/{cr_key_enc}/{cr_value_enc}/"
5357
5365
  __query: List[Tuple[str, str]] = []
5366
+ if apn is not None:
5367
+ __query.append(("apn", str(apn)))
5358
5368
  __headers: List[Tuple[str, str]] = []
5359
5369
  if self._token is None:
5360
5370
  raise MissingTokenError()
@@ -5335,10 +5335,11 @@ class ConnectClient:
5335
5335
  return Response(status=__response.status, headers=__response.headers, parsed=__result)
5336
5336
 
5337
5337
 
5338
- def sims_crossref_retrieve(self, cr_key: str, cr_value: str) -> CrossReferenceRecord:
5338
+ def sims_crossref_retrieve(self, cr_key: str, cr_value: str, *, apn: Optional[str] = None) -> CrossReferenceRecord:
5339
5339
  """
5340
- Returns the cross reference information for a SIM.
5341
- This includes information about the SIMs:
5340
+ Returns the cross reference information for a SIM, addressed by
5341
+ one of the identifiers the network reports: `msisdn`, `imsi`, `imei`
5342
+ or `ip`. This includes information about the SIMs:
5342
5343
 
5343
5344
  - MSISND
5344
5345
 
@@ -5348,6 +5349,13 @@ class ConnectClient:
5348
5349
 
5349
5350
  - IP
5350
5351
 
5352
+ A framed IP is only unique within its APN's pool, so an `ip` lookup
5353
+ must also name the APN via the `apn` query parameter and is refused
5354
+ with `400 Bad Request` without it. Where several attachments match
5355
+ (a SIM on two APNs, an IP reissued from the pool) the most recently
5356
+ seen one is returned. A SIM with no observed traffic has no
5357
+ cross-reference data and returns 404.
5358
+
5351
5359
 
5352
5360
  **Required Roles:**
5353
5361
  - No special roles required
@@ -5358,13 +5366,15 @@ class ConnectClient:
5358
5366
  against the company and folder associated with the resource.
5359
5367
  - The member must have access to the Folder the SIM is in.
5360
5368
  """
5361
- return self.sims_crossref_retrieve_with_response(cr_key, cr_value).parsed
5369
+ return self.sims_crossref_retrieve_with_response(cr_key, cr_value, apn=apn).parsed
5362
5370
 
5363
- def sims_crossref_retrieve_with_response(self, cr_key: str, cr_value: str) -> Response[CrossReferenceRecord]:
5371
+ def sims_crossref_retrieve_with_response(self, cr_key: str, cr_value: str, *, apn: Optional[str] = None) -> Response[CrossReferenceRecord]:
5364
5372
  cr_key_enc = quote(cr_key, safe="")
5365
5373
  cr_value_enc = quote(cr_value, safe="")
5366
5374
  __path = f"/api/v4/sims/crossref/{cr_key_enc}/{cr_value_enc}/"
5367
5375
  __query: List[Tuple[str, str]] = []
5376
+ if apn is not None:
5377
+ __query.append(("apn", str(apn)))
5368
5378
  __headers: List[Tuple[str, str]] = []
5369
5379
  if self._token is None:
5370
5380
  raise MissingTokenError()
@@ -4251,7 +4251,7 @@ class MonthData:
4251
4251
  class MqttCommandResult:
4252
4252
  cid: Optional[str]
4253
4253
  detail: str
4254
- err: Optional[bool]
4254
+ err: bool
4255
4255
  msg: Any
4256
4256
  pid: Optional[str]
4257
4257
  qos: Optional[int]
@@ -4267,7 +4267,7 @@ class MqttCommandResult:
4267
4267
  return cls(
4268
4268
  cid=(data["cid"] if data["cid"] is not None else None),
4269
4269
  detail=data["detail"],
4270
- err=(data["err"] if data["err"] is not None else None),
4270
+ err=data["err"],
4271
4271
  msg=data["msg"],
4272
4272
  pid=(data["pid"] if data["pid"] is not None else None),
4273
4273
  qos=(data["qos"] if data["qos"] is not None else None),
@@ -4283,7 +4283,7 @@ class MqttCommandResult:
4283
4283
  out: Dict[str, Any] = {}
4284
4284
  out["cid"] = (self.cid if self.cid is not None else None)
4285
4285
  out["detail"] = self.detail
4286
- out["err"] = (self.err if self.err is not None else None)
4286
+ out["err"] = self.err
4287
4287
  out["msg"] = self.msg
4288
4288
  out["pid"] = (self.pid if self.pid is not None else None)
4289
4289
  out["qos"] = (self.qos if self.qos is not None else None)
@@ -6508,20 +6508,20 @@ class PatchedSimRequest:
6508
6508
 
6509
6509
  @dataclass
6510
6510
  class PatchedTagRequest:
6511
- company_id: Optional[int] = None
6511
+ company: Optional[int] = None
6512
6512
  name: Optional[str] = None
6513
6513
 
6514
6514
  @classmethod
6515
6515
  def from_dict(cls, data: Dict[str, Any]) -> "PatchedTagRequest":
6516
6516
  return cls(
6517
- company_id=data.get("company_id"),
6517
+ company=data.get("company"),
6518
6518
  name=data.get("name"),
6519
6519
  )
6520
6520
 
6521
6521
  def to_dict(self) -> Dict[str, Any]:
6522
6522
  out: Dict[str, Any] = {}
6523
- if self.company_id is not None:
6524
- out["company_id"] = self.company_id
6523
+ if self.company is not None:
6524
+ out["company"] = self.company
6525
6525
  if self.name is not None:
6526
6526
  out["name"] = self.name
6527
6527
  return out
@@ -8275,7 +8275,7 @@ class StratChoices(Enum):
8275
8275
 
8276
8276
  @dataclass
8277
8277
  class Tag:
8278
- company_id: int
8278
+ company: int
8279
8279
  company_url: str
8280
8280
  id: int
8281
8281
  name: str
@@ -8284,7 +8284,7 @@ class Tag:
8284
8284
  @classmethod
8285
8285
  def from_dict(cls, data: Dict[str, Any]) -> "Tag":
8286
8286
  return cls(
8287
- company_id=data["company_id"],
8287
+ company=data["company"],
8288
8288
  company_url=data["company_url"],
8289
8289
  id=data["id"],
8290
8290
  name=data["name"],
@@ -8293,7 +8293,7 @@ class Tag:
8293
8293
 
8294
8294
  def to_dict(self) -> Dict[str, Any]:
8295
8295
  out: Dict[str, Any] = {}
8296
- out["company_id"] = self.company_id
8296
+ out["company"] = self.company
8297
8297
  out["company_url"] = self.company_url
8298
8298
  out["id"] = self.id
8299
8299
  out["name"] = self.name
@@ -8303,19 +8303,19 @@ class Tag:
8303
8303
 
8304
8304
  @dataclass
8305
8305
  class TagRequest:
8306
- company_id: int
8306
+ company: int
8307
8307
  name: str
8308
8308
 
8309
8309
  @classmethod
8310
8310
  def from_dict(cls, data: Dict[str, Any]) -> "TagRequest":
8311
8311
  return cls(
8312
- company_id=data["company_id"],
8312
+ company=data["company"],
8313
8313
  name=data["name"],
8314
8314
  )
8315
8315
 
8316
8316
  def to_dict(self) -> Dict[str, Any]:
8317
8317
  out: Dict[str, Any] = {}
8318
- out["company_id"] = self.company_id
8318
+ out["company"] = self.company
8319
8319
  out["name"] = self.name
8320
8320
  return out
8321
8321