Skip to content

Commit 7207188

Browse files
authored
Merge pull request #21 from crowdsecurity/update-sdk-1.119.7-1db0676
Update python SDK version: 1.119.7
2 parents 1db0676 + 1b6c274 commit 7207188

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+19427
-517
lines changed

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2025 Crowdsec
3+
Copyright (c) 2026 Crowdsec
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# crowdsec_service_api
22

3-
**crowdsec_service_api** is a Python SDK for the [CrowdSec Service API](https://docs.crowdsec.net/u/service_api/intro/).
3+
**crowdsec_service_api** is a Python SDK for the [CrowdSec Service API](https://docs.crowdsec.net/u/console/service_api/getting_started).
44
This library enables you to manage CrowdSec resources such as blocklists, integrations in your python applications.
55

66
## Installation
@@ -11,10 +11,11 @@ pip install crowdsec_service_api
1111

1212
## Usage
1313

14-
You can follow this [documentation](https://docs.crowdsec.net/u/service_api/quickstart/blocklists) to see the basic usage of the SDK.
14+
You can follow this [documentation](https://docs.crowdsec.net/u/console/service_api/sdks/python) to see the basic usage of the SDK.
1515

1616
## Documentation
17-
You can access the full usage documentation [here](https://github.com/crowdsecurity/crowdsec-service-api-sdk-python/tree/main/doc).
17+
You can access [the quickstart guide here](https://docs.crowdsec.net/u/console/service_api/quickstart/authentication).
18+
Or you have the full usage documentation [here](https://github.com/crowdsecurity/crowdsec-service-api-sdk-python/tree/main/doc).
1819

1920
## Contributing
2021

crowdsec_service_api/__init__.py

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,35 @@
44
from .services.allowlists import Allowlists
55
from .services.blocklists import Blocklists
66
from .services.integrations import Integrations
7+
from .services.decisions import Decisions
78
from .services.info import Info
89
from .services.metrics import Metrics
910
from .services.hub import Hub
1011
from .services.cves import Cves
12+
from .services.vendors import Vendors
13+
from .services.products import Products
14+
from .services.tracker_tags import TrackerTags
15+
from .services.fingerprints import Fingerprints
16+
from .services.tracker_events import TrackerEvents
1117
from .http_client import ApiKeyAuth
1218

1319
class Server(Enum):
14-
production_server = 'https://admin.api.crowdsec.net/v1/'
20+
production_server = 'https://admin.api.crowdsec.net/v1'
1521

1622
__all__ = [
1723
'Allowlists',
1824
'Blocklists',
1925
'Integrations',
26+
'Decisions',
2027
'Info',
2128
'Metrics',
2229
'Hub',
2330
'Cves',
31+
'Vendors',
32+
'Products',
33+
'TrackerTags',
34+
'Fingerprints',
35+
'TrackerEvents',
2436
'AllowlistCreateRequest',
2537
'AllowlistCreateResponse',
2638
'AllowlistGetItemsResponse',
@@ -61,6 +73,7 @@ class Server(Enum):
6173
'BlocklistUpdateRequest',
6274
'BlocklistUsageStats',
6375
'Body_uploadBlocklistContent',
76+
'CVESubscription',
6477
'ComputedMetrics',
6578
'ComputedSavedMetrics',
6679
'CtiAs',
@@ -69,7 +82,16 @@ class Server(Enum):
6982
'CtiCountry',
7083
'CtiIp',
7184
'CtiScenario',
85+
'DecisionCreateRequest',
86+
'DecisionCreateResponse',
87+
'DecisionResponse',
88+
'DecisionTargetModel',
89+
'DecisionTargetType',
90+
'DecisionsGetResponsePage',
91+
'DecisionsSortBy',
92+
'DecisionsSortOrder',
7293
'EntityType',
94+
'FingerprintSubscription',
7395
'GetRemediationMetricsResponse',
7496
'HTTPValidationError',
7597
'InfoResponse',
@@ -97,6 +119,7 @@ class Server(Enum):
97119
'Stats',
98120
'SubscriberEntityType',
99121
'ValidationError',
122+
'VendorSubscription',
100123
'AppsecConfigIndex',
101124
'AppsecRuleIndex',
102125
'CollectionIndex',
@@ -106,21 +129,64 @@ class Server(Enum):
106129
'PostoverflowIndex',
107130
'ScenarioIndex',
108131
'VersionDetail',
132+
'AdjustmentScore',
109133
'AffectedComponent',
134+
'AllowlistSubscription',
110135
'AttackDetail',
111136
'Behavior',
137+
'CVEEventOutput',
138+
'CVEExploitationPhase',
139+
'CVEResponseBase',
140+
'CVEsubscription',
141+
'CWE',
112142
'Classification',
113143
'Classifications',
144+
'ExploitationPhase',
145+
'ExploitationPhaseChangeEventItem',
146+
'ExploitationPhaseChangeEventsResponsePage',
147+
'FacetBucket',
148+
'FingerprintEventOutput',
149+
'FingerprintRuleResponse',
150+
'FingerprintRuleSummary',
151+
'FingerprintTimelineItem',
114152
'GetCVEIPsResponsePage',
153+
'GetCVEProtectRulesResponse',
115154
'GetCVEResponse',
155+
'GetCVESubscribedIntegrationsResponsePage',
156+
'GetCVEsResponsePage',
157+
'GetCVEsSortBy',
158+
'GetCVEsSortOrder',
159+
'GetFingerprintIPsResponsePage',
160+
'GetFingerprintRulesResponsePage',
161+
'GetFingerprintSubscribedIntegrationsResponsePage',
162+
'GetVendorIPsResponsePage',
163+
'GetVendorSubscribedIntegrationsResponsePage',
116164
'History',
117165
'IPItem',
166+
'IntegrationResponse',
167+
'IntervalOptions',
168+
'IpsDetailsStats',
118169
'Location',
170+
'LookupImpactCVEItem',
171+
'LookupImpactFingerprintItem',
172+
'LookupImpactResponsePage',
173+
'LookupListItemWithStats',
174+
'LookupListWithStatsResponsePage',
119175
'MitreTechnique',
176+
'ProtectRule',
177+
'ProtectRuleTag',
120178
'Reference',
121179
'ScoreBreakdown',
122180
'Scores',
181+
'SinceOptions',
123182
'SubscribeCVEIntegrationRequest',
183+
'SubscribeFingerprintIntegrationRequest',
184+
'SubscribeVendorIntegrationRequest',
185+
'ThreatContext',
186+
'TimelineItem',
187+
'TopProductItem',
188+
'VendorSortBy',
189+
'VendorStatsResponse',
124190
'ApiKeyAuth',
125191
'Server',
126192
'Page'
4.79 KB
Binary file not shown.
710 Bytes
Binary file not shown.
137 Bytes
Binary file not shown.
144 KB
Binary file not shown.

crowdsec_service_api/base_model.py

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from urllib.parse import urlparse
2-
from pydantic import BaseModel, ConfigDict
3-
from typing import Generic, Sequence, Optional, TypeVar
2+
from pydantic import BaseModel, ConfigDict, PrivateAttr, RootModel
3+
from typing import Generic, Sequence, Optional, TypeVar, Any
44
from httpx import Auth
55
from .http_client import HttpClient
66

@@ -9,42 +9,52 @@ class BaseModelSdk(BaseModel):
99
model_config = ConfigDict(
1010
extra="ignore",
1111
)
12+
_client: Optional["Service"] = PrivateAttr(default=None)
13+
14+
def __init__(self, /, _client: "Service" = None, **data):
15+
super().__init__(**data)
16+
self._client = _client
17+
18+
def next(self, client: "Service" = None) -> Optional["BaseModelSdk"]:
19+
return (client if client is not None else self._client).next_page(self)
20+
21+
22+
class RootModelSdk(RootModel):
23+
def __getattr__(self, item: str) -> Any:
24+
return getattr(self.root, item)
1225

1326

1427
T = TypeVar("T")
1528

1629

1730
class Page(BaseModelSdk, Generic[T]):
18-
_client: "Service"
1931
items: Sequence[T]
2032
total: Optional[int]
2133
page: Optional[int]
2234
size: Optional[int]
2335
pages: Optional[int] = None
2436
links: Optional[dict] = None
2537

26-
def __init__(self, _client: "Service", **data):
27-
super().__init__(**data)
28-
self._client = _client
29-
30-
def next(self, client: "Service" = None) -> "Page[T]":
31-
return (client if client is not None else self._client).next_page(self)
32-
3338

3439
class Service:
35-
def __init__(self, base_url: str, auth: Auth) -> None:
36-
self.http_client = HttpClient(base_url=base_url, auth=auth)
40+
def __init__(self, base_url: str, auth: Auth, user_agent: str = None) -> None:
41+
self.http_client = HttpClient(
42+
base_url=base_url, auth=auth, user_agent=user_agent
43+
)
3744

38-
def next_page(self, page: Page[T]) -> Page[T]:
39-
if not page.links:
45+
def next_page(self, page: BaseModelSdk) -> Optional[BaseModelSdk]:
46+
if not hasattr(page, "links") or not page.links:
4047
raise ValueError(
4148
"No links found in the response, this is not a paginated response."
4249
)
43-
if page.links.get("next"):
50+
if page.links.next:
4451
# links are relative to host not to full base url. We need to pass a full formatted url here
4552
parsed_url = urlparse(self.http_client.base_url)
4653
response = self.http_client.get(
47-
f"{parsed_url.scheme}://{parsed_url.netloc}{page.links['next']}", path_params=None, params=None, headers=None
54+
f"{parsed_url.scheme}://{parsed_url.netloc}{page.links.next}",
55+
path_params=None,
56+
params=None,
57+
headers=None,
4858
)
4959
return page.__class__(_client=self, **response.json())
5060
return None

crowdsec_service_api/http_client.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,20 @@ def auth_flow(self, request):
4545

4646

4747
class HttpClient:
48-
def __init__(self, base_url: str, auth: httpx.Auth, aws_region="eu-west-1") -> None:
48+
def __init__(
49+
self,
50+
base_url: str,
51+
auth: httpx.Auth,
52+
user_agent: str = None,
53+
aws_region="eu-west-1",
54+
) -> None:
4955
self.aws_region = aws_region
5056
self.base_url = base_url
5157
self.auth = auth
52-
self.client = httpx.Client()
58+
headers = {"Accept-Encoding": "gzip"}
59+
if user_agent:
60+
headers["User-Agent"] = user_agent
61+
self.client = httpx.Client(headers=headers)
5362
self.timeout = 30
5463

5564
def _replace_path_params(self, url: str, path_params: dict):

0 commit comments

Comments
 (0)