Spaces:
Running
Running
File size: 5,743 Bytes
fc0b9f5 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | # Usage recipes
No API key or login is needed. All examples call the public REST API. Start with summaries, then retrieve the details you need.
## Python: summary search and full details
```bash
pip install requests
```
```python
import requests
base = "https://wuhp-bbconnectapi.hf.space/api/v1"
session = requests.Session()
def get(path, **params):
response = session.get(base + path, params=params, timeout=180)
response.raise_for_status()
result = response.json()
if not result["ok"]:
raise RuntimeError(result)
return result
page = get("/programs", platforms="hackerone,bugcrowd", search="", limit=10)
print(page["total"], page["next_offset"])
for program in page["programs"][:2]:
detail = get(f"/programs/{program['platform']}/{program['handle']}")
print(program["name"], detail["min_bounty"], detail["max_bounty"], detail["currency"])
print("partial:", detail["partial"], "fields:", detail["field_status"])
print(detail["targets"], detail["rules"])
```
Details may use a fallback. A successful HTTP response is not proof that every field is present; inspect `partial`/`field_status` before accessing optional values.
## Crawl directory pages and export JSON/CSV
Run the [complete example](../examples/export_programs.py):
```bash
python examples/export_programs.py --platforms hackerone,bugcrowd,intigriti,yeswehack --output programs.json --csv programs.csv
```
The script follows `next_offset`, deduplicates IDs, validates statuses, and retries a bounded number of 429/503 responses. It exports directory summaries, not every policy document. To point it at a local instance, add `--base-url http://localhost:7860/api/v1`.
Equivalent pagination pattern:
```python
programs = {}
offset = 0
while True:
page = get("/programs", platforms="hackerone,bugcrowd", limit=100, offset=offset)
if page["partial"]:
raise RuntimeError("A directory source is unavailable; inspect page['sources']")
programs.update({p["id"]: p for p in page["programs"]})
if page["next_offset"] is None:
break
offset = page["next_offset"]
```
For large collections, use summaries to discover IDs, then batch selected detail lookups. Offset pagination is not an atomic snapshot and can shift after cache expiration.
## Filter advertised rewards without mixing currencies
```python
page = get("/programs", platforms="hackerone", currency="USD",
reward_at_least=1000, sort_by="max_bounty", descending=True, limit=10)
```
This uses directory `max_bounty`. Unknown amounts/currencies are excluded. It does not convert EUR to USD, infer minimums, or crawl all live tables before filtering.
## Get normalized assets while retaining exclusions
```python
assets = get("/programs/hackerone/security/assets", asset_type="wildcard", limit=100)
for asset in assets["in_scope"]:
print(asset["identifier"], asset["type"], asset["instructions"])
print("All exclusions:", assets["out_of_scope"])
print("Program rules:", assets["rules"])
```
If `next_offset` is present, continue paging the included assets. All exclusions and rules remain in each response. Native target-group restrictions are in each asset's `raw` record; a normalized identifier alone is not sufficient authorization to test.
## Batch detail lookup
```python
response = session.post(base + "/programs/batch", json={"programs": [
{"platform": "hackerone", "handle": "security"},
{"platform": "yeswehack", "handle": "outscale"},
]}, timeout=180)
# Batch status 503 still contains individual results if all lookups failed.
if response.status_code not in (200, 503):
response.raise_for_status()
batch = response.json()
if "programs" not in batch:
raise RuntimeError(batch)
for detail in batch["programs"]:
print(detail["platform"], detail["handle"], detail["ok"], detail.get("partial"))
```
## JavaScript / browser fetch
```javascript
const base = "https://wuhp-bbconnectapi.hf.space/api/v1";
const query = new URLSearchParams({
platforms: "hackerone,bugcrowd", limit: "10", include_details: "false"
});
const response = await fetch(`${base}/programs?${query}`);
const page = await response.json();
if (!response.ok || !page.ok) throw new Error(JSON.stringify(page));
console.log(page.programs, page.next_offset);
```
CORS is enabled for public GET/POST requests. Do not add credentials, tokens, or an Authorization header. For batch requests use `method: "POST"`, `headers: {"Content-Type": "application/json"}`, and `body: JSON.stringify({programs: [...]})`.
## curl
```bash
# Is the application awake? (No upstream check.)
curl 'https://wuhp-bbconnectapi.hf.space/api/v1/health'
# Program counts and source status
curl 'https://wuhp-bbconnectapi.hf.space/api/v1/stats'
# A small page with full scopes and rules
curl 'https://wuhp-bbconnectapi.hf.space/api/v1/programs?platforms=hackerone&include_details=true&limit=5'
# Save a complete policy/scope response
curl 'https://wuhp-bbconnectapi.hf.space/api/v1/programs/yeswehack/outscale' -o outscale.json
```
In Windows PowerShell, use `curl.exe` if `curl` is an alias in your shell. For JSON POSTs, Python or a saved request-body file avoids shell-specific quote escaping.
## Existing Gradio integrations
```python
from gradio_client import Client
client = Client("wuhp/bbconnectapi")
# Original contract: exactly five positional values, always full details.
page = client.predict(["hackerone"], "", False, 10, 0, api_name="/collect")
# Six values only on collect_options; False selects summaries.
summary = client.predict(["hackerone"], "", False, 10, 0, False, api_name="/collect_options")
```
For direct REST examples, `requests` is the only client dependency. `gradio_client` is needed only for Gradio calls.
|