vysion 2.0.20__tar.gz → 2.1.1__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,7 +1,8 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.1
2
2
  Name: vysion
3
- Version: 2.0.20
3
+ Version: 2.1.1
4
4
  Summary: The official Python client library for Vysion
5
+ Home-page: https://vysion.ai
5
6
  License: Apache-2.0
6
7
  Author: Javier Junquera-Sánchez
7
8
  Author-email: javier.junquera@byronlabs.io
@@ -14,23 +15,21 @@ Classifier: Programming Language :: Python :: 3.9
14
15
  Classifier: Programming Language :: Python :: 3.10
15
16
  Classifier: Programming Language :: Python :: 3.11
16
17
  Classifier: Programming Language :: Python :: 3.12
17
- Classifier: Programming Language :: Python :: 3.13
18
18
  Requires-Dist: pydantic (>=2.0.1,<3.0.0)
19
19
  Requires-Dist: pymisp (>=2.4.194,<3.0.0)
20
20
  Requires-Dist: requests (>=2.28.1,<3.0.0)
21
21
  Requires-Dist: softenum (==1.0.1)
22
22
  Project-URL: Documentation, https://developers.vysion.ai
23
- Project-URL: Homepage, https://vysion.ai
24
23
  Project-URL: Repository, https://github.com/ByronLabs/vysion-py
25
24
  Description-Content-Type: text/markdown
26
25
 
27
26
  # Vysion-PY
28
27
 
29
- Welcome to the open source repository for vysion-py, our implementation as a Python library to use the Vysion tool. Vysion is a dark web intelligence tool that provides information collected from web pages from Tor, I2P, cybercrime forums on the clearnet, etc. Vysion API also provides a feed of information on ransomware attacks published by the various ransomware groups currently active.
28
+ Welcome to the PyPi webpage for Vysion, our implementation as a Python library to use the Vysion tool. Vysion is a dark web intelligence tool that provides information collected from web pages from Tor, I2P, cybercrime forums on the clearnet, etc. Vysion API also provides a feed of information on ransomware attacks published by the various ransomware groups currently active.
30
29
 
31
30
  You can request a demo for the web app or an API-key to use in this library at [vysion.ai](https://vysion.ai).
32
31
 
33
- Latest version: [2.0.20](https://pypi.org/project/vysion/)
32
+ Latest version: [2.1.1](https://pypi.org/project/vysion/)
34
33
 
35
34
  You can visit [the documentation](https://developers.vysion.ai/?python) for more information on the searches and requests performed with the library or directly on the API.
36
35
 
@@ -1,10 +1,10 @@
1
1
  # Vysion-PY
2
2
 
3
- Welcome to the open source repository for vysion-py, our implementation as a Python library to use the Vysion tool. Vysion is a dark web intelligence tool that provides information collected from web pages from Tor, I2P, cybercrime forums on the clearnet, etc. Vysion API also provides a feed of information on ransomware attacks published by the various ransomware groups currently active.
3
+ Welcome to the PyPi webpage for Vysion, our implementation as a Python library to use the Vysion tool. Vysion is a dark web intelligence tool that provides information collected from web pages from Tor, I2P, cybercrime forums on the clearnet, etc. Vysion API also provides a feed of information on ransomware attacks published by the various ransomware groups currently active.
4
4
 
5
5
  You can request a demo for the web app or an API-key to use in this library at [vysion.ai](https://vysion.ai).
6
6
 
7
- Latest version: [2.0.20](https://pypi.org/project/vysion/)
7
+ Latest version: [2.1.1](https://pypi.org/project/vysion/)
8
8
 
9
9
  You can visit [the documentation](https://developers.vysion.ai/?python) for more information on the searches and requests performed with the library or directly on the API.
10
10
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "vysion"
3
- version = "2.0.20"
3
+ version = "2.1.1"
4
4
  description = "The official Python client library for Vysion"
5
5
  homepage = "https://vysion.ai"
6
6
  repository = "https://github.com/ByronLabs/vysion-py"
@@ -15,8 +15,6 @@ See the License for the specific language governing permissions and
15
15
  limitations under the License.
16
16
  """
17
17
 
18
- # TODO Referenciar vt-py
19
-
20
18
  import logging
21
19
  import os
22
20
  from datetime import datetime, timedelta
@@ -419,6 +417,51 @@ class Client(BaseClient):
419
417
  result = VysionResponse[ImMessageHit].model_validate(self._make_request(url))
420
418
  return result.data
421
419
 
420
+
421
+ @vysion_error_manager
422
+ def im_find_email(
423
+ self,
424
+ email: str,
425
+ page: int = 1,
426
+ page_size: int = 10,
427
+ lte: datetime = None,
428
+ gte: datetime = None
429
+ ) -> VysionResponse[DocumentHit]:
430
+ url = self._build_api_url__(
431
+ "im/email",
432
+ email,
433
+ page=page,
434
+ page_size=page_size,
435
+ lte=lte,
436
+ gte=gte
437
+ )
438
+
439
+ result = VysionResponse[ImProfileHit].model_validate(self._make_request(url))
440
+ return result.data
441
+
442
+ @vysion_error_manager
443
+ def im_find_wallet(
444
+ self,
445
+ chain: str,
446
+ address: str,
447
+ page: int = 1,
448
+ page_size: int = 10,
449
+ lte: datetime = None,
450
+ gte: datetime = None,
451
+ ) -> VysionResponse[DocumentHit]:
452
+ url = self._build_api_url__(
453
+ "im/wallet/" + chain,
454
+ address,
455
+ page=page,
456
+ page_size=page_size,
457
+ lte=lte,
458
+ gte=gte
459
+ )
460
+
461
+ result = VysionResponse[ImProfileHit].model_validate(self._make_request(url))
462
+ return result.data
463
+
464
+
422
465
  @vysion_error_manager
423
466
  def get_im_chat(
424
467
  self, platform: str, channelId: str, gte: datetime = None, lte: datetime = None
@@ -465,6 +508,7 @@ class Client(BaseClient):
465
508
 
466
509
  result = VysionResponse[ImServerHit].model_validate(self._make_request(url))
467
510
  return result.data
511
+
468
512
 
469
513
  #
470
514
  # FEEDS
@@ -472,6 +516,7 @@ class Client(BaseClient):
472
516
 
473
517
  @vysion_error_manager
474
518
  def consume_feed_ransomware(self, batch_day: datetime = datetime.today()):
519
+ #TODO implement client feed logic
475
520
  pass
476
521
 
477
522
 
@@ -494,7 +539,4 @@ class RansomwareFeed(DaylyFeed):
494
539
 
495
540
  for page in range(pages):
496
541
  url = self._build_api_url__("feed", "ransomware", days=days, page=page + 1)
497
- yield self._make_request(url)
498
-
499
-
500
- # TODO /api/v1/feeds
542
+ yield self._make_request(url)
@@ -303,7 +303,25 @@ class ImMessageHit(BaseModel):
303
303
  detectionDate: datetime
304
304
  serverId: Optional[Union[int, str]] = Field(default_factory=lambda: None) #Discord Exclusive
305
305
  serverTitle: Optional[str] = Field(default_factory=lambda: None) #Discord Exclusive
306
- platform: Optional[str] = Field(default_factory=lambda: None) #Discord Exclusive
306
+ platform: Optional[str] = Field(default_factory=lambda: None)
307
+
308
+ @model_validator(mode="after")
309
+ def validate_platform_specific_fields(cls, values):
310
+ """
311
+ Conditionally include platform-specific fields:
312
+ - Include Discord-specific fields only for Discord platform
313
+ - Exclude Discord-specific fields for Telegram platform
314
+ """
315
+ platform = getattr(values, "platform", None)
316
+
317
+ # For Telegram platform, remove Discord-specific fields
318
+ if platform is None or (isinstance(platform, str) and platform.lower() == "telegram"):
319
+ # Delete attributes instead of setting to None
320
+ for attr in ["serverId", "serverTitle"]:
321
+ if hasattr(values, attr):
322
+ delattr(values, attr)
323
+
324
+ return values
307
325
 
308
326
  class ImMessageCardHit(BaseModel):
309
327
  userId: Optional[Union[int, str]] = Field(default_factory=lambda: None)
@@ -318,6 +336,24 @@ class ImMessageCardHit(BaseModel):
318
336
  serverTitle: Optional[str] = Field(default_factory=lambda: None) #Discord Exclusive
319
337
  platform: Optional[str] = Field(default_factory=lambda: None)
320
338
 
339
+ @model_validator(mode="after")
340
+ def validate_platform_specific_fields(cls, values):
341
+ """
342
+ Conditionally include platform-specific fields:
343
+ - Include Discord-specific fields only for Discord platform
344
+ - Exclude Discord-specific fields for Telegram platform
345
+ """
346
+ platform = getattr(values, "platform", None)
347
+
348
+ # For Telegram platform, remove Discord-specific fields
349
+ if platform is None or (isinstance(platform, str) and platform.lower() == "telegram"):
350
+ # Delete attributes instead of setting to None
351
+ for attr in ["serverId", "serverTitle"]:
352
+ if hasattr(values, attr):
353
+ delattr(values, attr)
354
+
355
+ return values
356
+
321
357
  class ImProfileHit(BaseModel):
322
358
  userId: Union[int, str]
323
359
  usernames: Optional[List[str]] = Field(default_factory=lambda: None)
@@ -328,8 +364,41 @@ class ImProfileHit(BaseModel):
328
364
  bot: Optional[bool] = Field(default_factory=lambda: None) #Discord Exclusive
329
365
  discordLink: Optional[List[str]] = Field(default_factory=lambda: None) #Discord Exclusive
330
366
  discriminator: Optional[List[int]] = Field(default_factory=lambda: None) #Discord Exclusive
367
+ # TODO platform should be mandatory
331
368
  platform: Optional[str] = Field(default_factory=lambda: None)
369
+ email: List[Email] = Field(default_factory=lambda: [])
370
+ paste: List[Paste] = Field(default_factory=lambda: [])
371
+ skype: List[Skype] = Field(default_factory=lambda: [])
372
+ telegram: List[Telegram] = Field(default_factory=lambda: [])
373
+ whatsapp: List[WhatsApp] = Field(default_factory=lambda: [])
374
+ bitcoin_address: List[BitcoinAddress] = Field(default_factory=lambda: [])
375
+ polkadot_address: List[PolkadotAddress] = Field(default_factory=lambda: [])
376
+ ethereum_address: List[EthereumAddress] = Field(default_factory=lambda: [])
377
+ monero_address: List[MoneroAddress] = Field(default_factory=lambda: [])
378
+ ripple_address: List[RippleAddress] = Field(default_factory=lambda: [])
379
+ zcash_address: List[ZcashAddress] = Field(default_factory=lambda: [])
380
+
332
381
 
382
+ model_config = ConfigDict(exclude_defaults=True)
383
+
384
+ @model_validator(mode="after")
385
+ def validate_platform_specific_fields(cls, values):
386
+ """
387
+ Conditionally include platform-specific fields:
388
+ - Include Discord-specific fields only for Discord platform
389
+ - Exclude Discord-specific fields for Telegram platform
390
+ """
391
+ platform = getattr(values, "platform", None)
392
+
393
+ # For Telegram platform, remove Discord-specific fields
394
+ if platform is None or (isinstance(platform, str) and platform.lower() == "telegram"):
395
+ # Delete attributes instead of setting to None
396
+ for attr in ["discordLink", "bot", "discriminator"]:
397
+ if hasattr(values, attr):
398
+ delattr(values, attr)
399
+
400
+ return values
401
+
333
402
  @field_validator("userId")
334
403
  def validate_userId(cls, v: int) -> int:
335
404
  if not v:
@@ -353,6 +422,29 @@ class ImChannelHit(BaseModel):
353
422
  serverTitle: Optional[List[str]] = Field(default_factory=lambda: None) #Discord Exclusive
354
423
  platform: Optional[str] = Field(default_factory=lambda: None)
355
424
 
425
+ @model_validator(mode="after")
426
+ def validate_platform_specific_fields(cls, values):
427
+ """
428
+ Conditionally include platform-specific fields:
429
+ - Include Discord-specific fields only for Discord platform
430
+ - Exclude Discord-specific fields for Telegram platform
431
+ """
432
+ platform = getattr(values, "platform", None)
433
+
434
+ # For Telegram platform, remove Discord-specific fields
435
+ if platform is None or (isinstance(platform, str) and platform.lower() == "telegram"):
436
+ # Delete attributes instead of setting to None
437
+ for attr in ["serverId", "serverTitle"]:
438
+ if hasattr(values, attr):
439
+ delattr(values, attr)
440
+ else:
441
+ # For Discord platform, remove Telegram-specific fields
442
+ for attr in ["channelPhoto"]:
443
+ if hasattr(values, attr):
444
+ delattr(values, attr)
445
+
446
+ return values
447
+
356
448
  @field_validator("detectionDate")
357
449
  def validate_detectionDate(cls, v: datetime) -> datetime:
358
450
  if not v:
@@ -401,7 +493,7 @@ class CryptoFeedHit(BaseModel):
401
493
  detectionDate: datetime
402
494
  url: str
403
495
  network: str
404
- title: str
496
+ title: Optional[str] = Field(default_factory=lambda: None)
405
497
  tag: List[Tag] = Field(default_factory=lambda: [])
406
498
  bitcoin_address: Optional[List[BitcoinAddress]] = Field(default_factory=lambda: [])
407
499
  polkadot_address: Optional[List[PolkadotAddress]] = Field(default_factory=lambda: [])
@@ -79,7 +79,7 @@ class MISPProcessor:
79
79
  self.misp_event.add_attribute("xmr", value=xmr.value)
80
80
 
81
81
  for xrp in hit.ripple_address:
82
- self.misp_event.add_attribute("xrp", value=xmr.value)
82
+ self.misp_event.add_attribute("xrp", value=xrp.value)
83
83
 
84
84
  for zec in hit.zcash_address:
85
85
  self.misp_event.add_attribute("zec", value=zec.value)
@@ -15,4 +15,4 @@ See the License for the specific language governing permissions and
15
15
  limitations under the License.
16
16
  """
17
17
 
18
- __version__ = "2.0.20"
18
+ __version__ = "2.1.1"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes