pylookyloo 1.23.1__py3-none-any.whl → 1.24.0__py3-none-any.whl
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.
- pylookyloo/api.py +106 -90
- {pylookyloo-1.23.1.dist-info → pylookyloo-1.24.0.dist-info}/METADATA +1 -1
- pylookyloo-1.24.0.dist-info/RECORD +8 -0
- {pylookyloo-1.23.1.dist-info → pylookyloo-1.24.0.dist-info}/WHEEL +1 -1
- pylookyloo-1.23.1.dist-info/RECORD +0 -8
- {pylookyloo-1.23.1.dist-info → pylookyloo-1.24.0.dist-info}/LICENSE +0 -0
- {pylookyloo-1.23.1.dist-info → pylookyloo-1.24.0.dist-info}/entry_points.txt +0 -0
pylookyloo/api.py
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
3
4
|
|
|
4
5
|
import base64
|
|
5
6
|
import warnings
|
|
6
7
|
|
|
7
8
|
from importlib.metadata import version
|
|
8
9
|
from io import BytesIO, StringIO
|
|
9
|
-
from typing import
|
|
10
|
+
from typing import Any, TypedDict, overload
|
|
10
11
|
from urllib.parse import urljoin, urlparse
|
|
11
12
|
from pathlib import PurePosixPath, Path
|
|
12
13
|
|
|
@@ -24,39 +25,39 @@ class AuthError(PyLookylooError):
|
|
|
24
25
|
class CaptureSettings(TypedDict, total=False):
|
|
25
26
|
'''The capture settings that can be passed to Lookyloo.'''
|
|
26
27
|
|
|
27
|
-
url:
|
|
28
|
-
document_name:
|
|
29
|
-
document:
|
|
30
|
-
browser:
|
|
31
|
-
device_name:
|
|
32
|
-
user_agent:
|
|
33
|
-
proxy:
|
|
34
|
-
general_timeout_in_sec:
|
|
35
|
-
cookies:
|
|
36
|
-
headers:
|
|
37
|
-
http_credentials:
|
|
38
|
-
geolocation:
|
|
39
|
-
timezone_id:
|
|
40
|
-
locale:
|
|
41
|
-
color_scheme:
|
|
42
|
-
viewport:
|
|
43
|
-
referer:
|
|
44
|
-
|
|
45
|
-
listing:
|
|
46
|
-
auto_report:
|
|
28
|
+
url: str | None
|
|
29
|
+
document_name: str | None
|
|
30
|
+
document: str | None
|
|
31
|
+
browser: str | None
|
|
32
|
+
device_name: str | None
|
|
33
|
+
user_agent: str | None
|
|
34
|
+
proxy: str | dict[str, str] | None
|
|
35
|
+
general_timeout_in_sec: int | None
|
|
36
|
+
cookies: list[dict[str, Any]] | None
|
|
37
|
+
headers: str | dict[str, str] | None
|
|
38
|
+
http_credentials: dict[str, int] | None
|
|
39
|
+
geolocation: dict[str, float] | None
|
|
40
|
+
timezone_id: str | None
|
|
41
|
+
locale: str | None
|
|
42
|
+
color_scheme: str | None
|
|
43
|
+
viewport: dict[str, int] | None
|
|
44
|
+
referer: str | None
|
|
45
|
+
|
|
46
|
+
listing: bool | None
|
|
47
|
+
auto_report: bool | dict[str, str] | None
|
|
47
48
|
|
|
48
49
|
|
|
49
50
|
class CompareSettings(TypedDict, total=False):
|
|
50
51
|
'''The settings that can be passed to the compare method on lookyloo side to filter out some differences'''
|
|
51
52
|
|
|
52
|
-
ressources_ignore_domains:
|
|
53
|
-
ressources_ignore_regexes:
|
|
53
|
+
ressources_ignore_domains: list[str] | None
|
|
54
|
+
ressources_ignore_regexes: list[str] | None
|
|
54
55
|
|
|
55
56
|
|
|
56
57
|
class Lookyloo():
|
|
57
58
|
|
|
58
|
-
def __init__(self, root_url: str='https://lookyloo.circl.lu/', useragent:
|
|
59
|
-
*, proxies:
|
|
59
|
+
def __init__(self, root_url: str='https://lookyloo.circl.lu/', useragent: str | None=None,
|
|
60
|
+
*, proxies: dict[str, str] | None=None):
|
|
60
61
|
'''Query a specific lookyloo instance.
|
|
61
62
|
|
|
62
63
|
:param root_url: URL of the instance to query.
|
|
@@ -73,7 +74,7 @@ class Lookyloo():
|
|
|
73
74
|
self.session.headers['user-agent'] = useragent if useragent else f'PyLookyloo / {version("pylookyloo")}'
|
|
74
75
|
if proxies:
|
|
75
76
|
self.session.proxies.update(proxies)
|
|
76
|
-
self.apikey:
|
|
77
|
+
self.apikey: str | None = None
|
|
77
78
|
|
|
78
79
|
@property
|
|
79
80
|
def is_up(self) -> bool:
|
|
@@ -84,7 +85,7 @@ class Lookyloo():
|
|
|
84
85
|
return False
|
|
85
86
|
return r.status_code == 200
|
|
86
87
|
|
|
87
|
-
def get_status(self, tree_uuid: str) ->
|
|
88
|
+
def get_status(self, tree_uuid: str) -> dict[str, Any]:
|
|
88
89
|
'''Get the status of a capture:
|
|
89
90
|
* -1: Unknown capture.
|
|
90
91
|
* 0: The capture is queued up but not processed yet.
|
|
@@ -94,24 +95,24 @@ class Lookyloo():
|
|
|
94
95
|
r = self.session.get(urljoin(self.root_url, str(PurePosixPath('json', tree_uuid, 'status'))))
|
|
95
96
|
return r.json()
|
|
96
97
|
|
|
97
|
-
def get_capture_stats(self, tree_uuid: str) ->
|
|
98
|
+
def get_capture_stats(self, tree_uuid: str) -> dict[str, Any]:
|
|
98
99
|
'''Get statistics of the capture'''
|
|
99
100
|
r = self.session.get(urljoin(self.root_url, str(PurePosixPath('json', tree_uuid, 'stats'))))
|
|
100
101
|
return r.json()
|
|
101
102
|
|
|
102
|
-
def get_info(self, tree_uuid: str) ->
|
|
103
|
+
def get_info(self, tree_uuid: str) -> dict[str, Any]:
|
|
103
104
|
'''Get information about the capture (url, timestamp, user agent)'''
|
|
104
105
|
r = self.session.get(urljoin(self.root_url, str(PurePosixPath('json', tree_uuid, 'info'))))
|
|
105
106
|
return r.json()
|
|
106
107
|
|
|
107
|
-
def get_comparables(self, tree_uuid: str) ->
|
|
108
|
+
def get_comparables(self, tree_uuid: str) -> dict[str, Any]:
|
|
108
109
|
'''Get comparable information from the capture'''
|
|
109
110
|
r = self.session.get(urljoin(self.root_url, str(PurePosixPath('json', tree_uuid, 'comparables'))))
|
|
110
111
|
return r.json()
|
|
111
112
|
|
|
112
|
-
def enqueue(self, url:
|
|
113
|
-
document:
|
|
114
|
-
document_name:
|
|
113
|
+
def enqueue(self, url: str | None=None, quiet: bool=False, # type: ignore[no-untyped-def]
|
|
114
|
+
document: Path | BytesIO | None=None,
|
|
115
|
+
document_name: str | None=None, **kwargs) -> str:
|
|
115
116
|
'''Enqueue an URL.
|
|
116
117
|
|
|
117
118
|
:param url: URL to enqueue
|
|
@@ -126,50 +127,50 @@ class Lookyloo():
|
|
|
126
127
|
|
|
127
128
|
@overload
|
|
128
129
|
def submit(self, *, quiet: bool=False,
|
|
129
|
-
capture_settings:
|
|
130
|
+
capture_settings: CaptureSettings | None=None) -> str:
|
|
130
131
|
...
|
|
131
132
|
|
|
132
133
|
@overload
|
|
133
134
|
def submit(self, *, quiet: bool=False,
|
|
134
|
-
url:
|
|
135
|
-
document_name:
|
|
136
|
-
browser:
|
|
137
|
-
user_agent:
|
|
138
|
-
proxy:
|
|
139
|
-
general_timeout_in_sec:
|
|
140
|
-
cookies:
|
|
141
|
-
headers:
|
|
142
|
-
http_credentials:
|
|
143
|
-
geolocation:
|
|
144
|
-
timezone_id:
|
|
145
|
-
locale:
|
|
146
|
-
color_scheme:
|
|
147
|
-
viewport:
|
|
148
|
-
referer:
|
|
149
|
-
listing:
|
|
150
|
-
auto_report:
|
|
135
|
+
url: str | None=None,
|
|
136
|
+
document_name: str | None=None, document: Path | BytesIO | None=None,
|
|
137
|
+
browser: str | None=None, device_name: str | None=None,
|
|
138
|
+
user_agent: str | None=None,
|
|
139
|
+
proxy: str | dict[str, str] | None=None,
|
|
140
|
+
general_timeout_in_sec: int | None=None,
|
|
141
|
+
cookies: list[dict[str, Any]] | None=None,
|
|
142
|
+
headers: str | dict[str, str] | None=None,
|
|
143
|
+
http_credentials: dict[str, int] | None=None,
|
|
144
|
+
geolocation: dict[str, float] | None=None,
|
|
145
|
+
timezone_id: str | None=None,
|
|
146
|
+
locale: str | None=None,
|
|
147
|
+
color_scheme: str | None=None,
|
|
148
|
+
viewport: dict[str, int] | None=None,
|
|
149
|
+
referer: str | None=None,
|
|
150
|
+
listing: bool | None=None,
|
|
151
|
+
auto_report: bool | dict[str, str] | None=None
|
|
151
152
|
) -> str:
|
|
152
153
|
...
|
|
153
154
|
|
|
154
155
|
def submit(self, *, quiet: bool=False,
|
|
155
|
-
capture_settings:
|
|
156
|
-
url:
|
|
157
|
-
document_name:
|
|
158
|
-
browser:
|
|
159
|
-
user_agent:
|
|
160
|
-
proxy:
|
|
161
|
-
general_timeout_in_sec:
|
|
162
|
-
cookies:
|
|
163
|
-
headers:
|
|
164
|
-
http_credentials:
|
|
165
|
-
geolocation:
|
|
166
|
-
timezone_id:
|
|
167
|
-
locale:
|
|
168
|
-
color_scheme:
|
|
169
|
-
viewport:
|
|
170
|
-
referer:
|
|
171
|
-
listing:
|
|
172
|
-
auto_report:
|
|
156
|
+
capture_settings: CaptureSettings | None=None,
|
|
157
|
+
url: str | None=None,
|
|
158
|
+
document_name: str | None=None, document: Path | BytesIO | None=None,
|
|
159
|
+
browser: str | None=None, device_name: str | None=None,
|
|
160
|
+
user_agent: str | None=None,
|
|
161
|
+
proxy: str | dict[str, str] | None=None,
|
|
162
|
+
general_timeout_in_sec: int | None=None,
|
|
163
|
+
cookies: list[dict[str, Any]] | None=None,
|
|
164
|
+
headers: str | dict[str, str] | None=None,
|
|
165
|
+
http_credentials: dict[str, int] | None=None,
|
|
166
|
+
geolocation: dict[str, float] | None=None,
|
|
167
|
+
timezone_id: str | None=None,
|
|
168
|
+
locale: str | None=None,
|
|
169
|
+
color_scheme: str | None=None,
|
|
170
|
+
viewport: dict[str, int] | None=None,
|
|
171
|
+
referer: str | None=None,
|
|
172
|
+
listing: bool | None=None,
|
|
173
|
+
auto_report: bool | dict[str, str] | None=None
|
|
173
174
|
) -> str:
|
|
174
175
|
'''Submit a URL to a lookyloo instance.
|
|
175
176
|
|
|
@@ -261,13 +262,13 @@ class Lookyloo():
|
|
|
261
262
|
return uuid
|
|
262
263
|
return urljoin(self.root_url, f'tree/{uuid}')
|
|
263
264
|
|
|
264
|
-
def get_apikey(self, username: str, password: str) ->
|
|
265
|
+
def get_apikey(self, username: str, password: str) -> dict[str, str]:
|
|
265
266
|
'''Get the API key for the given user.'''
|
|
266
267
|
to_post = {'username': username, 'password': password}
|
|
267
268
|
r = self.session.post(urljoin(self.root_url, str(PurePosixPath('json', 'get_token'))), json=to_post)
|
|
268
269
|
return r.json()
|
|
269
270
|
|
|
270
|
-
def init_apikey(self, username:
|
|
271
|
+
def init_apikey(self, username: str | None=None, password: str | None=None, apikey: str | None=None) -> None:
|
|
271
272
|
'''Init the API key for the current session. All the requests against lookyloo after this call will be authenticated.'''
|
|
272
273
|
if apikey:
|
|
273
274
|
self.apikey = apikey
|
|
@@ -282,12 +283,12 @@ class Lookyloo():
|
|
|
282
283
|
else:
|
|
283
284
|
raise AuthError('Unable to initialize API key')
|
|
284
285
|
|
|
285
|
-
def misp_export(self, tree_uuid: str) ->
|
|
286
|
+
def misp_export(self, tree_uuid: str) -> dict[str, Any]:
|
|
286
287
|
'''Export the capture in MISP format'''
|
|
287
288
|
r = self.session.get(urljoin(self.root_url, str(PurePosixPath('json', tree_uuid, 'misp_export'))))
|
|
288
289
|
return r.json()
|
|
289
290
|
|
|
290
|
-
def misp_push(self, tree_uuid: str) ->
|
|
291
|
+
def misp_push(self, tree_uuid: str) -> dict[str, Any] | list[dict[str, Any]]:
|
|
291
292
|
'''Push the capture to a pre-configured MISP instance (requires an authenticated user, use init_apikey first)
|
|
292
293
|
Note: if the response is a dict, it is an error mesage. If it is a list, it's a list of MISP event.
|
|
293
294
|
'''
|
|
@@ -296,7 +297,7 @@ class Lookyloo():
|
|
|
296
297
|
r = self.session.get(urljoin(self.root_url, str(PurePosixPath('json', tree_uuid, 'misp_push'))))
|
|
297
298
|
return r.json()
|
|
298
299
|
|
|
299
|
-
def trigger_modules(self, tree_uuid: str, force: bool=False) ->
|
|
300
|
+
def trigger_modules(self, tree_uuid: str, force: bool=False) -> dict[str, Any]:
|
|
300
301
|
'''Trigger all the available 3rd party modules on the given capture.
|
|
301
302
|
:param force: Trigger the modules even if they were already triggered today.
|
|
302
303
|
'''
|
|
@@ -305,21 +306,21 @@ class Lookyloo():
|
|
|
305
306
|
json=to_send)
|
|
306
307
|
return r.json()
|
|
307
308
|
|
|
308
|
-
def rebuild_capture(self, tree_uuid: str) ->
|
|
309
|
+
def rebuild_capture(self, tree_uuid: str) -> dict[str, str]:
|
|
309
310
|
'''Force rebuild a capture (requires an authenticated user, use init_apikey first)'''
|
|
310
311
|
if not self.apikey:
|
|
311
312
|
raise AuthError('You need to initialize the apikey to use this method (see init_apikey)')
|
|
312
|
-
r = self.session.
|
|
313
|
+
r = self.session.post(urljoin(self.root_url, str(PurePosixPath('admin', tree_uuid, 'rebuild'))))
|
|
313
314
|
return r.json()
|
|
314
315
|
|
|
315
|
-
def hide_capture(self, tree_uuid: str) ->
|
|
316
|
+
def hide_capture(self, tree_uuid: str) -> dict[str, str]:
|
|
316
317
|
'''Hide a capture from the index page (requires an authenticated user, use init_apikey first)'''
|
|
317
318
|
if not self.apikey:
|
|
318
319
|
raise AuthError('You need to initialize the apikey to use this method (see init_apikey)')
|
|
319
|
-
r = self.session.
|
|
320
|
+
r = self.session.post(urljoin(self.root_url, str(PurePosixPath('admin', tree_uuid, 'hide'))))
|
|
320
321
|
return r.json()
|
|
321
322
|
|
|
322
|
-
def get_redirects(self, capture_uuid: str) ->
|
|
323
|
+
def get_redirects(self, capture_uuid: str) -> dict[str, Any]:
|
|
323
324
|
'''Returns the initial redirects.
|
|
324
325
|
|
|
325
326
|
:param capture_uuid: UUID of the capture
|
|
@@ -327,7 +328,7 @@ class Lookyloo():
|
|
|
327
328
|
r = self.session.get(urljoin(self.root_url, str(PurePosixPath('json', capture_uuid, 'redirects'))))
|
|
328
329
|
return r.json()
|
|
329
330
|
|
|
330
|
-
def get_urls(self, capture_uuid: str) ->
|
|
331
|
+
def get_urls(self, capture_uuid: str) -> dict[str, Any]:
|
|
331
332
|
'''Returns all the URLs seen during the capture.
|
|
332
333
|
|
|
333
334
|
:param capture_uuid: UUID of the capture
|
|
@@ -335,7 +336,7 @@ class Lookyloo():
|
|
|
335
336
|
r = self.session.get(urljoin(self.root_url, str(PurePosixPath('json', capture_uuid, 'urls'))))
|
|
336
337
|
return r.json()
|
|
337
338
|
|
|
338
|
-
def get_hostnames(self, capture_uuid: str) ->
|
|
339
|
+
def get_hostnames(self, capture_uuid: str) -> dict[str, Any]:
|
|
339
340
|
'''Returns all the hostnames seen during the capture.
|
|
340
341
|
|
|
341
342
|
:param capture_uuid: UUID of the capture
|
|
@@ -359,7 +360,7 @@ class Lookyloo():
|
|
|
359
360
|
r = self.session.get(urljoin(self.root_url, str(PurePosixPath('bin', capture_uuid, 'data'))))
|
|
360
361
|
return BytesIO(r.content)
|
|
361
362
|
|
|
362
|
-
def get_cookies(self, capture_uuid: str) ->
|
|
363
|
+
def get_cookies(self, capture_uuid: str) -> list[dict[str, str]]:
|
|
363
364
|
'''Returns the complete cookies jar.
|
|
364
365
|
|
|
365
366
|
:param capture_uuid: UUID of the capture
|
|
@@ -382,7 +383,7 @@ class Lookyloo():
|
|
|
382
383
|
:param algorithm: The algorithm of the hashes
|
|
383
384
|
:param hashes_only: If False, will also return the URLs related to the hashes
|
|
384
385
|
'''
|
|
385
|
-
params:
|
|
386
|
+
params: dict[str, str | int] = {'algorithm': algorithm, 'hashes_only': int(hashes_only)}
|
|
386
387
|
|
|
387
388
|
r = self.session.get(urljoin(self.root_url, str(PurePosixPath('json', capture_uuid, 'hashes'))), params=params)
|
|
388
389
|
return r.json()
|
|
@@ -395,7 +396,7 @@ class Lookyloo():
|
|
|
395
396
|
r = self.session.get(urljoin(self.root_url, str(PurePosixPath('bin', capture_uuid, 'export'))))
|
|
396
397
|
return BytesIO(r.content)
|
|
397
398
|
|
|
398
|
-
def get_hash_occurrences(self, h: str) ->
|
|
399
|
+
def get_hash_occurrences(self, h: str) -> dict[str, Any]:
|
|
399
400
|
'''Returns the base 64 body related the the hash, and a list of all the captures containing that hash.
|
|
400
401
|
|
|
401
402
|
:param h: sha512 to search
|
|
@@ -403,7 +404,7 @@ class Lookyloo():
|
|
|
403
404
|
r = self.session.get(urljoin(self.root_url, str(PurePosixPath('json', 'hash_info', h))))
|
|
404
405
|
return r.json()
|
|
405
406
|
|
|
406
|
-
def get_url_occurrences(self, url: str, limit: int=20, cached_captures_only: bool=True) ->
|
|
407
|
+
def get_url_occurrences(self, url: str, limit: int=20, cached_captures_only: bool=True) -> dict[str, Any]:
|
|
407
408
|
'''Returns all the captures contining the URL
|
|
408
409
|
|
|
409
410
|
:param url: URL to lookup
|
|
@@ -414,7 +415,7 @@ class Lookyloo():
|
|
|
414
415
|
json={'url': url, 'limit': limit})
|
|
415
416
|
return r.json()
|
|
416
417
|
|
|
417
|
-
def get_hostname_occurrences(self, hostname: str, with_urls_occurrences: bool=False, limit: int=20, cached_captures_only: bool=True) ->
|
|
418
|
+
def get_hostname_occurrences(self, hostname: str, with_urls_occurrences: bool=False, limit: int=20, cached_captures_only: bool=True) -> dict[str, Any]:
|
|
418
419
|
'''Returns all the captures contining the hostname. It will be pretty slow on very common domains.
|
|
419
420
|
|
|
420
421
|
:param hostname: Hostname to lookup
|
|
@@ -426,13 +427,13 @@ class Lookyloo():
|
|
|
426
427
|
json={'hostname': hostname, 'with_urls_occurrences': with_urls_occurrences, 'limit': limit})
|
|
427
428
|
return r.json()
|
|
428
429
|
|
|
429
|
-
def get_stats(self) ->
|
|
430
|
+
def get_stats(self) -> dict[str, Any]:
|
|
430
431
|
'''Returns all the captures contining the URL'''
|
|
431
432
|
|
|
432
433
|
r = self.session.get(urljoin(self.root_url, str(PurePosixPath('json', 'stats'))))
|
|
433
434
|
return r.json()
|
|
434
435
|
|
|
435
|
-
def get_takedown_information(self, capture_uuid: str) ->
|
|
436
|
+
def get_takedown_information(self, capture_uuid: str) -> dict[str, Any]:
|
|
436
437
|
'''Returns information required to request a takedown for a capture
|
|
437
438
|
|
|
438
439
|
:param capture_uuid: UUID of the capture
|
|
@@ -441,7 +442,7 @@ class Lookyloo():
|
|
|
441
442
|
json={'capture_uuid': capture_uuid})
|
|
442
443
|
return r.json()
|
|
443
444
|
|
|
444
|
-
def compare_captures(self, capture_left: str, capture_right: str, /, *, compare_settings:
|
|
445
|
+
def compare_captures(self, capture_left: str, capture_right: str, /, *, compare_settings: CompareSettings | None=None) -> dict[str, Any]:
|
|
445
446
|
'''Compares two captures
|
|
446
447
|
|
|
447
448
|
:param capture_left: UUID of the capture to compare from
|
|
@@ -453,3 +454,18 @@ class Lookyloo():
|
|
|
453
454
|
'capture_right': capture_right,
|
|
454
455
|
'compare_settings': compare_settings})
|
|
455
456
|
return r.json()
|
|
457
|
+
|
|
458
|
+
def get_modules_responses(self, tree_uuid: str) -> dict[str, Any]:
|
|
459
|
+
'''Returns information from the 3rd party modules
|
|
460
|
+
|
|
461
|
+
:param capture_uuid: UUID of the capture
|
|
462
|
+
'''
|
|
463
|
+
r = self.session.get(urljoin(self.root_url, str(PurePosixPath('json', tree_uuid, 'modules'))))
|
|
464
|
+
return r.json()
|
|
465
|
+
|
|
466
|
+
def send_mail(self, tree_uuid: str, email: str = '', comment: str | None = None) -> bool | dict[str, Any]:
|
|
467
|
+
to_send = {'email': email}
|
|
468
|
+
if comment:
|
|
469
|
+
to_send['comment'] = comment
|
|
470
|
+
r = self.session.post(urljoin(self.root_url, str(PurePosixPath('json', tree_uuid, 'report'))), json=to_send)
|
|
471
|
+
return r.json()
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
pylookyloo/__init__.py,sha256=_JYXwXHL7ShZkeruvGd8qDTpxNRfuDjvV65SOMMU6yc,1922
|
|
2
|
+
pylookyloo/api.py,sha256=nbuCJmeGy34ZCFH5kZeVwJlysgmn_h6ZiQrqYAmA5iM,21748
|
|
3
|
+
pylookyloo/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
pylookyloo-1.24.0.dist-info/LICENSE,sha256=4C4hLYrIkUD96Ggk-y_Go1Qf7PBZrEm9PSeTGe2nd4s,1516
|
|
5
|
+
pylookyloo-1.24.0.dist-info/METADATA,sha256=GV8FRY1VU92q8jN8-Ko5Tohul-Vf0J0a7AM_S0Vsrvw,2340
|
|
6
|
+
pylookyloo-1.24.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
7
|
+
pylookyloo-1.24.0.dist-info/entry_points.txt,sha256=y2c0Ujg8co6Xyf7MoxStVU-fLQMZBSGAg-KFidmsha4,44
|
|
8
|
+
pylookyloo-1.24.0.dist-info/RECORD,,
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
pylookyloo/__init__.py,sha256=_JYXwXHL7ShZkeruvGd8qDTpxNRfuDjvV65SOMMU6yc,1922
|
|
2
|
-
pylookyloo/api.py,sha256=pUNC0DoaxYlvhOkDKHF4bSqRwABiCv1UkZgPz8zRIBM,21392
|
|
3
|
-
pylookyloo/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
-
pylookyloo-1.23.1.dist-info/LICENSE,sha256=4C4hLYrIkUD96Ggk-y_Go1Qf7PBZrEm9PSeTGe2nd4s,1516
|
|
5
|
-
pylookyloo-1.23.1.dist-info/METADATA,sha256=qltwCMFtvxCE5IO22c5uEaAukdc1l0h_hSEFVdoRI6Q,2340
|
|
6
|
-
pylookyloo-1.23.1.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
|
7
|
-
pylookyloo-1.23.1.dist-info/entry_points.txt,sha256=y2c0Ujg8co6Xyf7MoxStVU-fLQMZBSGAg-KFidmsha4,44
|
|
8
|
-
pylookyloo-1.23.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|