Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
include:
- project: 'externalci/ci-image'
- project: '$CI_TEMPLATE'
ref: master
file: '.gitlab-ci-default.yaml'

Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "polyswarm"
version = "4.2.0"
version = "4.2.1"
description = "CLI for using the PolySwarm Customer APIs"
readme = "README.md"
authors = [{ name = "PolySwarm Developers", email = "info@polyswarm.io" }]
Expand Down Expand Up @@ -51,7 +51,7 @@ include-package-data = true
where = ["src"]

[tool.bumpversion]
current_version = "4.2.0"
current_version = "4.2.1"
commit = true
tag = false
sign_tags = true
Expand Down
2 changes: 1 addition & 1 deletion src/polyswarm/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '4.2.0'
__version__ = '4.2.1'
10 changes: 5 additions & 5 deletions src/polyswarm/client/polyswarm.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@
PROD_API_URI = 'https://api.polyswarm.network/v3'

# Convenience environment shortcuts so callers can write `--stage` instead of
# `--api-uri https://api.stage-v3.polyswarm.network/v3`. Keys are the click
# `--api-uri https://api.stage-blue.polyswarm.network/v3`. Keys are the click
# parameter names (click maps `--prod-eu` -> `prod_eu`).
API_URI_SHORTCUTS = {
'prod': PROD_API_URI,
'stage': 'https://api.stage-v3.polyswarm.network/v3',
'stage': 'https://api.stage-blue.polyswarm.network/v3',
'local': 'http://localhost:9696/v3',
'prod_eu': 'https://api.prod-eu-v3.polyswarm.network/v3',
'stage_eu': 'https://api.stage-eu-v3.polyswarm.network/v3',
'stage_eu': 'https://api.stage-eu-blue.polyswarm.network/v3',
}

_SHORTCUT_FLAGS = {
Expand Down Expand Up @@ -184,13 +184,13 @@ def invoke(self, ctx):
@click.option('--prod', is_flag=True, default=False,
help='Target the production API (https://api.polyswarm.network/v3) — same as the default.')
@click.option('--stage', is_flag=True, default=False,
help='Target the US staging API (https://api.stage-v3.polyswarm.network/v3).')
help='Target the US staging API (https://api.stage-blue.polyswarm.network/v3).')
@click.option('--local', is_flag=True, default=False,
help='Target a local API (http://localhost:9696/v3).')
@click.option('--prod-eu', 'prod_eu', is_flag=True, default=False,
help='Target the EU production API (https://api.prod-eu-v3.polyswarm.network/v3).')
@click.option('--stage-eu', 'stage_eu', is_flag=True, default=False,
help='Target the EU staging API (https://api.stage-eu-v3.polyswarm.network/v3).')
help='Target the EU staging API (https://api.stage-eu-blue.polyswarm.network/v3).')
@click.option('-o', '--output-file', type=click.File('w', encoding='utf8'), help='Path to output file.')
@click.option('--output-format', '--fmt', default='text', type=click.Choice(formatters.keys()),
help='Output format. Human-readable text or JSON.')
Expand Down
8 changes: 4 additions & 4 deletions tests/api_uri_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ def test_env_api_uri_used_when_no_flag(self):
def test_each_shortcut_resolves(self):
expected = {
'prod': 'https://api.polyswarm.network/v3',
'stage': 'https://api.stage-v3.polyswarm.network/v3',
'stage': 'https://api.stage-blue.polyswarm.network/v3',
'local': 'http://localhost:9696/v3',
'prod_eu': 'https://api.prod-eu-v3.polyswarm.network/v3',
'stage_eu': 'https://api.stage-eu-v3.polyswarm.network/v3',
'stage_eu': 'https://api.stage-eu-blue.polyswarm.network/v3',
}
# guard against the constant drifting from the verified ingress hosts
assert API_URI_SHORTCUTS == expected
Expand Down Expand Up @@ -124,7 +124,7 @@ def test_shortcut_beats_env_var(self):

# --- each shortcut ---
def test_stage_shortcut(self):
assert self._resolved_base('--stage') == 'https://api.stage-v3.polyswarm.network/v3'
assert self._resolved_base('--stage') == 'https://api.stage-blue.polyswarm.network/v3'

def test_local_shortcut(self):
assert self._resolved_base('--local') == 'http://localhost:9696/v3'
Expand All @@ -133,7 +133,7 @@ def test_prod_eu_shortcut(self):
assert self._resolved_base('--prod-eu') == 'https://api.prod-eu-v3.polyswarm.network/v3'

def test_stage_eu_shortcut(self):
assert self._resolved_base('--stage-eu') == 'https://api.stage-eu-v3.polyswarm.network/v3'
assert self._resolved_base('--stage-eu') == 'https://api.stage-eu-blue.polyswarm.network/v3'

def test_prod_shortcut_matches_default(self):
assert self._resolved_base('--prod') == 'https://api.polyswarm.network/v3'
Expand Down
6 changes: 3 additions & 3 deletions tests/kgb_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,17 @@ def test_kgb_create_get_delete_text(self):

@vcr.use_cassette()
def test_kgb_create_get_json(self):
created = self._run_cli(['--fmt', 'json', 'kgb', 'create', 'winget', SHA_B])
created = self._run_cli(['--fmt', 'json', 'kgb', 'create', 'commercial', SHA_B])
self.assertEqual(0, created.exit_code, created.output)
payload = json.loads(created.output.strip().splitlines()[-1])
assert payload['sha256'] == SHA_B
assert 'winget' in payload.get('sources', [])
assert 'commercial' in payload.get('sources', [])

got = self._run_cli(['--fmt', 'json', 'kgb', 'get', SHA_B])
self.assertEqual(0, got.exit_code, got.output)
payload = json.loads(got.output.strip().splitlines()[-1])
assert payload['sha256'] == SHA_B
assert 'winget' in payload.get('sources', [])
assert 'commercial' in payload.get('sources', [])

@vcr.use_cassette()
def test_kgb_get_after_delete_not_found(self):
Expand Down
8 changes: 4 additions & 4 deletions tests/known_good_field_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ def _render(instance):
class TestKnownGoodTextRendering:
def test_known_good_instance_renders_feeds_and_status(self):
feeds = [
{'tool': 'winget', 'tool_metadata': {}, 'created': '2026-06-11T00:00:00',
{'tool': 'commercial', 'tool_metadata': {}, 'created': '2026-06-11T00:00:00',
'updated': '2026-06-11T00:00:00'},
{'tool': 'nsrl', 'tool_metadata': {}, 'created': '2026-06-11T00:00:00',
'updated': '2026-06-11T00:00:00'},
]
text = _render(_instance(known_good=feeds))
# Feeds are listed (sorted) and the status reflects known-good.
assert 'known-good binary (flagged by: nsrl, winget); it is not scanned.' in text
assert 'known-good binary (flagged by: commercial, nsrl); it is not scanned.' in text
assert 'Status: Known good' in text
# A known-good binary must NOT be told to rescan / that no engines responded.
assert 'trigger a rescan' not in text
Expand All @@ -67,11 +67,11 @@ def test_state_known_good_without_feeds(self):
assert 'No engines responded' not in text

def test_state_known_good_with_feeds_lists_them(self):
feeds = [{'tool': 'winget', 'tool_metadata': {},
feeds = [{'tool': 'commercial', 'tool_metadata': {},
'created': '2026-06-11T00:00:00', 'updated': '2026-06-11T00:00:00'}]
text = _render(_instance(state='KNOWN_GOOD', known_good=feeds))
# When feeds are present the richer message still lists them.
assert 'known-good binary (flagged by: winget); it is not scanned.' in text
assert 'known-good binary (flagged by: commercial); it is not scanned.' in text
assert 'Status: Known good' in text

def test_non_known_good_state_unchanged(self):
Expand Down
20 changes: 10 additions & 10 deletions tests/vcr/test_kgb_create_get_json.vcr
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
interactions:
- request:
body: '{"sha256":"b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2","source":"winget","community":"gamma"}'
body: '{"sha256":"b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2","source":"commercial","community":"gamma"}'
headers:
accept:
- '*/*'
Expand All @@ -11,18 +11,18 @@ interactions:
connection:
- keep-alive
content-length:
- '115'
- '119'
content-type:
- application/json
host:
- artifact-index-e2e:9696
user-agent:
- polyswarm_api/4.0.0 (x86_64-Linux-CPython-3.14.4)
- polyswarm_api/4.1.0 (x86_64-Linux-CPython-3.12.3)
method: POST
uri: http://artifact-index-e2e:9696/v3/known-good
response:
body:
string: '{"result":{"artifact_instance_id":"2369287781010758","created":"2026-06-15T18:51:09.785317+00:00","id":"28878017864712926","sha256":"b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2","sources":["winget"]},"status":"OK"}
string: '{"result":{"artifact_instance_id":"94148575775325033","created":"2026-06-29T18:31:04.436511+00:00","id":"94927448183592703","sha256":"b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2","sources":["commercial"]},"status":"OK"}

'
headers:
Expand All @@ -33,11 +33,11 @@ interactions:
Connection:
- keep-alive
Content-Length:
- '236'
- '241'
Content-Type:
- application/json
Date:
- Mon, 15 Jun 2026 19:14:34 GMT
- Mon, 29 Jun 2026 18:31:04 GMT
Server:
- gunicorn
X-Billing-ID:
Expand All @@ -59,12 +59,12 @@ interactions:
host:
- artifact-index-e2e:9696
user-agent:
- polyswarm_api/4.0.0 (x86_64-Linux-CPython-3.14.4)
- polyswarm_api/4.1.0 (x86_64-Linux-CPython-3.12.3)
method: GET
uri: http://artifact-index-e2e:9696/v3/known-good?sha256=b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2&community=gamma
response:
body:
string: '{"result":{"artifact_instance_id":"2369287781010758","created":"2026-06-15T18:51:09.785317+00:00","id":"28878017864712926","sha256":"b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2","sources":["winget"]},"status":"OK"}
string: '{"result":{"artifact_instance_id":"94148575775325033","created":"2026-06-29T18:31:04.436511+00:00","id":"94927448183592703","sha256":"b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2","sources":["commercial"]},"status":"OK"}

'
headers:
Expand All @@ -75,11 +75,11 @@ interactions:
Connection:
- keep-alive
Content-Length:
- '236'
- '241'
Content-Type:
- application/json
Date:
- Mon, 15 Jun 2026 19:14:34 GMT
- Mon, 29 Jun 2026 18:31:04 GMT
Server:
- gunicorn
X-Billing-ID:
Expand Down
Loading