vysion 2.0.2__tar.gz → 2.0.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.1
2
2
  Name: vysion
3
- Version: 2.0.2
3
+ Version: 2.0.4
4
4
  Summary: The official Python client library for Vysion
5
5
  Home-page: https://vysion.ai
6
6
  License: Apache-2.0
@@ -29,7 +29,7 @@ Welcome to the PyPi webpage for Vysion, our implementation as a Python library t
29
29
 
30
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).
31
31
 
32
- Latest version: [2.0.2](https://pypi.org/project/vysion/)
32
+ Latest version: [2.0.4](https://pypi.org/project/vysion/)
33
33
 
34
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.
35
35
 
@@ -4,7 +4,7 @@ Welcome to the PyPi webpage for Vysion, our implementation as a Python library t
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.2](https://pypi.org/project/vysion/)
7
+ Latest version: [2.0.4](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.2"
3
+ version = "2.0.4"
4
4
  description = "The official Python client library for Vysion"
5
5
  homepage = "https://vysion.ai"
6
6
  repository = "https://gitlab.com/byronlabs/vysion/vysion-py"
@@ -36,6 +36,7 @@ black = "^24.3.0"
36
36
 
37
37
  [tool.poetry.group.dev.dependencies]
38
38
  ruff = "^0.5.2"
39
+ pytest = "^8.3.2"
39
40
 
40
41
  [build-system]
41
42
  requires = ["poetry-core>=1.0.0"]
@@ -26,9 +26,19 @@ from urllib.parse import quote, urlencode, urljoin
26
26
  # from pydantic import validate_arguments
27
27
  import requests
28
28
 
29
- import vysion.dto as dto
30
29
  from vysion.client.error import APIError
31
- from vysion.dto import Error
30
+ from vysion.dto import (
31
+ Error,
32
+ DocumentHit,
33
+ VysionResponse,
34
+ RansomwareHit,
35
+ Stat,
36
+ Network,
37
+ Language,
38
+ ImChannelHit,
39
+ ImMessageHit,
40
+ ImProfileHit,
41
+ )
32
42
  from vysion.version import __version__ as vysion_version
33
43
 
34
44
  # All API endpoints start with this prefix, you don't need to include the
@@ -106,9 +116,8 @@ class BaseClient:
106
116
  query = "?" + urlencode(query_params_initialzed)
107
117
  return urljoin(base, query)
108
118
 
109
- def _make_request(self, url: str) -> dto.VysionResponse:
119
+ def _make_request(self, url: str) -> VysionResponse:
110
120
  session = self.__get_session__()
111
- print(url)
112
121
  r = session.get(url)
113
122
 
114
123
  # TODO Improve this
@@ -123,14 +132,12 @@ class BaseClient:
123
132
 
124
133
  raise APIError(code, message)
125
134
 
126
- payload = r.json()
127
-
128
- result = dto.VysionResponse.model_validate(payload)
135
+ result = r.json()
129
136
 
130
137
  return result
131
138
 
132
139
 
133
- def vysion_error_manager(method) -> Union[dto.VysionResponse, Error]:
140
+ def vysion_error_manager(method) -> Union[VysionResponse, Error]:
134
141
  def manage(*args, **kwargs):
135
142
  try:
136
143
  result = method(*args, **kwargs)
@@ -162,11 +169,11 @@ class Client(BaseClient):
162
169
  gte: datetime = None,
163
170
  page: int = 1,
164
171
  page_size: int = 10,
165
- network: dto.Network = None,
166
- language: dto.Language = None,
172
+ network: Network = None,
173
+ language: Language = None,
167
174
  include_tag: str = None,
168
175
  exclude_tag: str = None,
169
- ) -> dto.VysionResponse:
176
+ ) -> VysionResponse[DocumentHit]:
170
177
  url = self._build_api_url__(
171
178
  "document/search",
172
179
  q=q,
@@ -180,14 +187,14 @@ class Client(BaseClient):
180
187
  exclude_tag=exclude_tag,
181
188
  )
182
189
 
183
- result = self._make_request(url)
190
+ result = VysionResponse[DocumentHit].model_validate(self._make_request(url))
184
191
  return result.data
185
192
 
186
193
  @vysion_error_manager
187
- def get_document(self, document_id: str) -> dto.VysionResponse:
194
+ def get_document(self, document_id: str) -> VysionResponse[DocumentHit]:
188
195
  url = self._build_api_url__("document", document_id)
189
196
 
190
- result = self._make_request(url)
197
+ result = VysionResponse[DocumentHit].model_validate(self._make_request(url))
191
198
  return result.data
192
199
 
193
200
  @vysion_error_manager
@@ -197,28 +204,28 @@ class Client(BaseClient):
197
204
  page: int = 1,
198
205
  lte: datetime = None,
199
206
  gte: datetime = None,
200
- ) -> dto.VysionResponse:
207
+ ) -> VysionResponse[DocumentHit]:
201
208
  url = self._build_api_url__("document/url", url, page=page, lte=lte, gte=gte)
202
209
 
203
- result = self._make_request(url)
210
+ result = VysionResponse[DocumentHit].model_validate(self._make_request(url))
204
211
  return result.data
205
212
 
206
213
  @vysion_error_manager
207
- def get_tag(self, tag: str) -> dto.VysionResponse:
214
+ def get_tag(self, tag: str) -> VysionResponse[DocumentHit]:
208
215
  url = self._build_api_url__("document/tag", tag)
209
216
 
210
- result = self._make_request(url)
217
+ result = VysionResponse[DocumentHit].model_validate(self._make_request(url))
211
218
  return result.data
212
219
 
213
220
  @vysion_error_manager
214
221
  def find_email(
215
222
  self, email: str, page: int = 1, lte: datetime = None, gte: datetime = None
216
- ) -> dto.VysionResponse:
223
+ ) -> VysionResponse[DocumentHit]:
217
224
  url = self._build_api_url__(
218
225
  "document/email", email, page=page, lte=lte, gte=gte
219
226
  )
220
227
 
221
- result = self._make_request(url)
228
+ result = VysionResponse[DocumentHit].model_validate(self._make_request(url))
222
229
  return result.data
223
230
 
224
231
  @vysion_error_manager
@@ -229,7 +236,7 @@ class Client(BaseClient):
229
236
  page: int = 1,
230
237
  lte: datetime = None,
231
238
  gte: datetime = None,
232
- ) -> dto.VysionResponse:
239
+ ) -> VysionResponse[DocumentHit]:
233
240
  url = self._build_api_url__(
234
241
  "document/phone",
235
242
  country_code + "/" + phone_number,
@@ -238,7 +245,7 @@ class Client(BaseClient):
238
245
  gte=gte,
239
246
  )
240
247
 
241
- result = self._make_request(url)
248
+ result = VysionResponse[DocumentHit].model_validate(self._make_request(url))
242
249
  return result.data
243
250
 
244
251
  @vysion_error_manager
@@ -249,12 +256,12 @@ class Client(BaseClient):
249
256
  page: int = 1,
250
257
  lte: datetime = None,
251
258
  gte: datetime = None,
252
- ) -> dto.VysionResponse:
259
+ ) -> VysionResponse[DocumentHit]:
253
260
  url = self._build_api_url__(
254
261
  "document/wallet", chain + "/" + address, page=page, lte=lte, gte=gte
255
262
  )
256
263
 
257
- result = self._make_request(url)
264
+ result = VysionResponse[DocumentHit].model_validate(self._make_request(url))
258
265
  return result.data
259
266
 
260
267
  @vysion_error_manager
@@ -277,10 +284,10 @@ class Client(BaseClient):
277
284
  gte: datetime = None,
278
285
  page: int = 1,
279
286
  page_size: int = 10,
280
- network: dto.Network = None,
287
+ network: Network = None,
281
288
  country: str = None,
282
- language: dto.Language = None,
283
- ) -> dto.VysionResponse:
289
+ language: Language = None,
290
+ ) -> VysionResponse[RansomwareHit]:
284
291
  url = self._build_api_url__(
285
292
  "victim/search",
286
293
  q=q,
@@ -293,14 +300,14 @@ class Client(BaseClient):
293
300
  language=language,
294
301
  )
295
302
 
296
- result = self._make_request(url)
303
+ result = VysionResponse[RansomwareHit].model_validate(self._make_request(url))
297
304
  return result.data
298
305
 
299
306
  @vysion_error_manager
300
- def get_ransomware_victim(self, document_id: str) -> dto.VysionResponse:
307
+ def get_ransomware_victim(self, document_id: str) -> VysionResponse[RansomwareHit]:
301
308
  url = self._build_api_url__("victim", document_id)
302
309
 
303
- result = self._make_request(url)
310
+ result = VysionResponse[RansomwareHit].model_validate(self._make_request(url))
304
311
  return result.data
305
312
 
306
313
  #
@@ -313,10 +320,12 @@ class Client(BaseClient):
313
320
  countries: str = None,
314
321
  gte: datetime = None,
315
322
  lte: datetime = None,
316
- ) -> dto.VysionResponse[dto.Stat]:
317
- url = self._build_api_url__("stats/countries", countries=countries, gte=gte, lte=lte)
323
+ ) -> VysionResponse[Stat]:
324
+ url = self._build_api_url__(
325
+ "stats/countries", countries=countries, gte=gte, lte=lte
326
+ )
318
327
 
319
- result = self._make_request(url)
328
+ result = VysionResponse[Stat].model_validate(self._make_request(url))
320
329
  return result.data
321
330
 
322
331
  @vysion_error_manager
@@ -325,10 +334,12 @@ class Client(BaseClient):
325
334
  countries: str = None,
326
335
  gte: datetime = None,
327
336
  lte: datetime = None,
328
- ) -> dto.VysionResponse[dto.Stat]:
329
- url = self._build_api_url__("stats/groups", countries=countries, gte=gte, lte=lte)
337
+ ) -> VysionResponse[Stat]:
338
+ url = self._build_api_url__(
339
+ "stats/groups", countries=countries, gte=gte, lte=lte
340
+ )
330
341
 
331
- result = self._make_request(url)
342
+ result = VysionResponse[Stat].model_validate(self._make_request(url))
332
343
  return result.data
333
344
 
334
345
  #
@@ -344,7 +355,7 @@ class Client(BaseClient):
344
355
  lte: datetime = None,
345
356
  page: int = 1,
346
357
  username: str = None,
347
- ) -> dto.VysionResponse[dto.ImMessageHit]:
358
+ ) -> VysionResponse[ImMessageHit]:
348
359
  url = self._build_api_url__(
349
360
  "im/" + platform + "/search",
350
361
  q=q,
@@ -354,43 +365,45 @@ class Client(BaseClient):
354
365
  username=username,
355
366
  )
356
367
 
357
- result = self._make_request(url)
368
+ result = VysionResponse[ImMessageHit].model_validate(self._make_request(url))
358
369
  return result.data
359
370
 
360
371
  @vysion_error_manager
361
372
  def get_im_chat(
362
373
  self, platform: str, channelId: str, gte: datetime = None, lte: datetime = None
363
- ) -> dto.VysionResponse[dto.ImMessageHit]:
364
- url = self._build_api_url__("im/" + platform + "/chat/" + channelId, gte=gte, lte=lte)
374
+ ) -> VysionResponse[ImMessageHit]:
375
+ url = self._build_api_url__(
376
+ "im/" + platform + "/chat/" + channelId, gte=gte, lte=lte
377
+ )
365
378
 
366
- result = self._make_request(url)
379
+ result = VysionResponse[ImMessageHit].model_validate(self._make_request(url))
367
380
  return result.data
368
381
 
369
382
  @vysion_error_manager
370
383
  def get_im_profile(
371
384
  self, platform: str, userId: str
372
- ) -> dto.VysionResponse[dto.ImProfileHit]:
385
+ ) -> VysionResponse[ImProfileHit]:
373
386
  url = self._build_api_url__("im/" + platform + "/profile/", userId)
374
387
 
375
- result = self._make_request(url)
388
+ result = VysionResponse[ImProfileHit].model_validate(self._make_request(url))
376
389
  return result.data
377
390
 
378
391
  @vysion_error_manager
379
392
  def get_im_message(
380
393
  self, platform: str, messageId: str
381
- ) -> dto.VysionResponse[dto.ImMessageHit]:
394
+ ) -> VysionResponse[ImMessageHit]:
382
395
  url = self._build_api_url__("im/" + platform + "/message/", messageId)
383
396
 
384
- result = self._make_request(url)
397
+ result = VysionResponse[ImMessageHit].model_validate(self._make_request(url))
385
398
  return result.data
386
399
 
387
400
  @vysion_error_manager
388
401
  def get_im_channel(
389
402
  self, platform: str, channelId: str
390
- ) -> dto.VysionResponse[dto.ImChannelHit]:
403
+ ) -> VysionResponse[ImChannelHit]:
391
404
  url = self._build_api_url__("im/" + platform + "/channel/", channelId)
392
405
 
393
- result = self._make_request(url)
406
+ result = VysionResponse[ImChannelHit].model_validate(self._make_request(url))
394
407
  return result.data
395
408
 
396
409
  #
@@ -399,8 +399,7 @@ T = TypeVar("T")
399
399
 
400
400
  class Result(BaseModel, Generic[T]):
401
401
  total: int = 0
402
- hits: Union[List[DocumentHit],List[Stat],List[ImChannelHit],List[ImMessageHit],
403
- List[ImProfileHit]] = Field(default_factory=lambda: [])
402
+ hits: List[T] = Field(default_factory=lambda: [])
404
403
 
405
404
  def __init__(self, **kwargs):
406
405
  super().__init__(**kwargs)
@@ -58,4 +58,4 @@ class Tag(BaseModel):
58
58
  return f"Tag<{self}>"
59
59
 
60
60
  def __str__(self):
61
- return f'''{self.namespace}:{self.predicate}:"{self.value}"'''
61
+ return f'''{self.namespace}:{self.predicate}="{self.value}"'''
@@ -111,7 +111,7 @@ class MISPProcessor:
111
111
 
112
112
  self.misp_event.add_object(misp_object)
113
113
 
114
- def process(self, result: dto.Result, **kwargs) -> MISPEvent:
114
+ def process(self, result: dto.Result[DocumentHit|RansomFeedHit], **kwargs) -> MISPEvent:
115
115
 
116
116
  processor = {
117
117
  DocumentHit: self.parse_hit,
@@ -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.2"
18
+ __version__ = "2.0.4"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes