Skip to content

Commit 716aaeb

Browse files
Chocapikkdannywillems
authored andcommitted
Feat: Add AsyncClient, search API, and Pro detection
1 parent 3d12566 commit 716aaeb

File tree

5 files changed

+583
-7
lines changed

5 files changed

+583
-7
lines changed

README.md

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,48 @@ pip install leakix
1313

1414
To run tests, use `poetry run pytest`.
1515

16+
## Quick Start
17+
18+
```python
19+
from leakix import Client
20+
21+
client = Client(api_key="your-api-key")
22+
23+
# Simple search - same syntax as the website
24+
results = client.search("+plugin:GitConfigHttpPlugin", scope="leak")
25+
for event in results.json():
26+
print(event.ip, event.host)
27+
28+
# Search services
29+
results = client.search("+country:FR +port:22", scope="service")
30+
```
31+
32+
## Async Client
33+
34+
For async applications, use `AsyncClient`:
35+
36+
```python
37+
import asyncio
38+
from leakix import AsyncClient
39+
40+
async def main():
41+
async with AsyncClient(api_key="your-api-key") as client:
42+
# Simple search
43+
results = await client.search("+plugin:GitConfigHttpPlugin", scope="leak")
44+
for event in results:
45+
print(event.ip, event.host)
46+
47+
# Host lookup
48+
host = await client.get_host("8.8.8.8")
49+
print(host["services"])
50+
51+
# Streaming bulk export
52+
async for aggregation in client.bulk_export_stream(queries):
53+
print(aggregation.events[0].ip)
54+
55+
asyncio.run(main())
56+
```
57+
1658
## Documentation
1759

1860
Docstrings are used to document the library.
@@ -156,6 +198,46 @@ def example_get_plugins():
156198
print(p.description)
157199

158200

201+
def example_search_simple():
202+
"""
203+
Simple search using query string syntax (same as the website).
204+
No need to build Query objects manually.
205+
"""
206+
response = CLIENT.search("+plugin:GitConfigHttpPlugin", scope="leak")
207+
for event in response.json():
208+
print(event.ip)
209+
210+
211+
def example_search_service():
212+
"""
213+
Search for services with multiple filters.
214+
"""
215+
response = CLIENT.search("+country:FR +port:22", scope="service")
216+
for event in response.json():
217+
print(event.ip, event.port)
218+
219+
220+
def example_get_domain():
221+
"""
222+
Get services and leaks for a domain.
223+
"""
224+
response = CLIENT.get_domain("example.com")
225+
if response.is_success():
226+
print("Services:", response.json()["services"])
227+
print("Leaks:", response.json()["leaks"])
228+
229+
230+
def example_bulk_stream():
231+
"""
232+
Streaming bulk export - memory efficient for large datasets.
233+
Results are yielded one by one instead of loading all into memory.
234+
"""
235+
query = MustQuery(field=PluginField(Plugin.GitConfigHttpPlugin))
236+
for aggregation in CLIENT.bulk_export_stream(queries=[query]):
237+
for event in aggregation.events:
238+
print(event.ip)
239+
240+
159241
if __name__ == "__main__":
160242
example_get_host_filter_plugin()
161243
example_get_service_filter_plugin()
@@ -165,4 +247,8 @@ if __name__ == "__main__":
165247
example_get_leak_plugins_with_time()
166248
example_get_leak_raw_query()
167249
example_get_plugins()
250+
example_search_simple()
251+
example_search_service()
252+
example_get_domain()
253+
example_bulk_stream()
168254
```

leakix/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from importlib.metadata import version
22

3+
from leakix.async_client import AsyncClient as AsyncClient
34
from leakix.client import Client as Client
45
from leakix.client import HostResult as HostResult
56
from leakix.client import Scope as Scope
@@ -71,6 +72,7 @@
7172

7273
__all__ = [
7374
"__version__",
75+
"AsyncClient",
7476
"Client",
7577
"HostResult",
7678
"L9Subdomain",

0 commit comments

Comments
 (0)