blocket-api 0.3.0__tar.gz → 0.3.3__tar.gz
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.
- {blocket_api-0.3.0 → blocket_api-0.3.3}/PKG-INFO +60 -3
- {blocket_api-0.3.0 → blocket_api-0.3.3}/README.md +58 -1
- {blocket_api-0.3.0 → blocket_api-0.3.3}/blocket_api/blocket.py +85 -38
- {blocket_api-0.3.0 → blocket_api-0.3.3}/blocket_api/models.py +74 -0
- {blocket_api-0.3.0 → blocket_api-0.3.3}/blocket_api.egg-info/PKG-INFO +60 -3
- {blocket_api-0.3.0 → blocket_api-0.3.3}/blocket_api.egg-info/requires.txt +1 -1
- {blocket_api-0.3.0 → blocket_api-0.3.3}/pyproject.toml +2 -2
- {blocket_api-0.3.0 → blocket_api-0.3.3}/LICENSE +0 -0
- {blocket_api-0.3.0 → blocket_api-0.3.3}/blocket_api/__init__.py +0 -0
- {blocket_api-0.3.0 → blocket_api-0.3.3}/blocket_api/qasa.py +0 -0
- {blocket_api-0.3.0 → blocket_api-0.3.3}/blocket_api.egg-info/SOURCES.txt +0 -0
- {blocket_api-0.3.0 → blocket_api-0.3.3}/blocket_api.egg-info/dependency_links.txt +0 -0
- {blocket_api-0.3.0 → blocket_api-0.3.3}/blocket_api.egg-info/top_level.txt +0 -0
- {blocket_api-0.3.0 → blocket_api-0.3.3}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: blocket_api
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Summary: A python API wrapper for blocket.se
|
|
5
5
|
Author-email: dunderrrrrr <emil.bjorkroth@gmail.com>
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -12,7 +12,7 @@ Requires-Dist: pytest>=8.2.2
|
|
|
12
12
|
Requires-Dist: respx>=0.21.1
|
|
13
13
|
Requires-Dist: mypy>=1.15.0
|
|
14
14
|
Requires-Dist: pydantic>=2.11.7
|
|
15
|
-
Requires-Dist: ruff>=0.13.
|
|
15
|
+
Requires-Dist: ruff>=0.13.2
|
|
16
16
|
Dynamic: license-file
|
|
17
17
|
|
|
18
18
|
# BlocketAPI
|
|
@@ -31,6 +31,7 @@ BlocketAPI allows users to query saved searches, known as "Bevakningar", on [blo
|
|
|
31
31
|
- Get vehicle information, price evaluation and search for vehicles with multiple filters.
|
|
32
32
|
- Search for homes with filters for city, home type and more.
|
|
33
33
|
- Search for stores and get a specific store's listings.
|
|
34
|
+
- ...and more!
|
|
34
35
|
|
|
35
36
|
## 🧑💻️ Install
|
|
36
37
|
|
|
@@ -60,7 +61,7 @@ Some calls require a `bearerToken`. However, some calls are public and don't req
|
|
|
60
61
|
|
|
61
62
|
| Function | Token required | `as_objects` | Description |
|
|
62
63
|
|---|---|---|---|
|
|
63
|
-
| [`api.saved_searches()`](#saved_searches) | 🔐 Yes |
|
|
64
|
+
| [`api.saved_searches()`](#saved_searches) | 🔐 Yes | Yes | List your saved searches (bevakningar) |
|
|
64
65
|
| [`api.get_listings()`](#get_listings) | 🔐 Yes | - | List items related to a saved search |
|
|
65
66
|
| [`api.custom_search()`](#custom_search) | 👏 No | Yes | Search for everything on Blocket and filter by region |
|
|
66
67
|
| [`api.motor_search()`](#motor_search) | 👏 No | Yes | Advanced search for car-listings. |
|
|
@@ -69,6 +70,9 @@ Some calls require a `bearerToken`. However, some calls are public and don't req
|
|
|
69
70
|
| [`api.store_search()`](#store_search) | 👏 No | Yes | Search for a store.
|
|
70
71
|
| [`api.get_store_listings()`](#get_store_listings) | 👏 No | Yes | Get listings from a specific store.
|
|
71
72
|
| [`api.get_ad_by_id()`](#get_ad_by_id) | 👏 No | Yes | Get ad data from id.
|
|
73
|
+
| [`api.get_user_by_id()`](#get_user_by_id) | 👏 No | Yes | Get user data from id.
|
|
74
|
+
| [`api.save_ad()`](#save_ad) | 🔐 Yes | - | Save ad to "Saved ads".
|
|
75
|
+
| [`api.get_saved_ads()`](#get_saved_ads) | 🔐 Yes | - | Save ad to "Saved ads".
|
|
72
76
|
|
|
73
77
|
|
|
74
78
|
## 🤓 Detailed usage
|
|
@@ -77,6 +81,9 @@ Some calls require a `bearerToken`. However, some calls are public and don't req
|
|
|
77
81
|
|
|
78
82
|
Saved searches are your so called "Bevakningar" and can be found [here](https://www.blocket.se/sparade/bevakningar). Each saved search has and unique `id` which can be used as a parameter to `get_listings()`, see below.
|
|
79
83
|
|
|
84
|
+
Parameters:
|
|
85
|
+
- `as_objects` (`bool`, optional) - Return results as pydantic models, default is `False`.
|
|
86
|
+
|
|
80
87
|
```py
|
|
81
88
|
>>> api.saved_searches()
|
|
82
89
|
[
|
|
@@ -302,6 +309,56 @@ Get ad data from a specific ad id.
|
|
|
302
309
|
}
|
|
303
310
|
```
|
|
304
311
|
|
|
312
|
+
### get_user_by_id
|
|
313
|
+
Get user data from a user id. User id can be found in ads, searches and in blocket url `https://www.blocket.se/profil/<user_id>`.
|
|
314
|
+
|
|
315
|
+
- `user_id` (`int`, required) - The blocket user id.
|
|
316
|
+
- `as_objects` (`bool`, optional) - Return results as pydantic models, default is `False`.
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
```py
|
|
320
|
+
>>> api.get_user_by_id(1234)
|
|
321
|
+
{
|
|
322
|
+
'account': {
|
|
323
|
+
'blocket_account_id': '1234',
|
|
324
|
+
'created_at': '2020-10-10T15:45:06.407660',
|
|
325
|
+
'is_verified': True,
|
|
326
|
+
'name': 'Janne',
|
|
327
|
+
...
|
|
328
|
+
},
|
|
329
|
+
'active_ads': {[
|
|
330
|
+
...
|
|
331
|
+
]}
|
|
332
|
+
}
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
### save_ad
|
|
336
|
+
This saves the ad to "Saved ads" which can be found here at `https://www.blocket.se/sparade/annonser`. When saving an ad, blocket always responds with 204, even if the ad is already saved or does not exist.
|
|
337
|
+
|
|
338
|
+
- `ad_id` (`int`, required) - The ad id. Can be found by calling any other method or from ad url.
|
|
339
|
+
|
|
340
|
+
```py
|
|
341
|
+
>>> api.save_ad(1234)
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### get_saved_ads
|
|
345
|
+
Returns all of your saved ads from `https://www.blocket.se/sparade/annonser`.
|
|
346
|
+
|
|
347
|
+
```py
|
|
348
|
+
>>> api.get_saved_ads()
|
|
349
|
+
{
|
|
350
|
+
'data': [{
|
|
351
|
+
'ad_id': '1213682185'
|
|
352
|
+
'list_id': '1213682185'
|
|
353
|
+
'subject': 'Jeans från Gina tricot 158'
|
|
354
|
+
'body': 'Moderna jeans från Gina Tricot!'
|
|
355
|
+
...
|
|
356
|
+
}]
|
|
357
|
+
...
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
```
|
|
361
|
+
|
|
305
362
|
## 🔐 Blocket API token
|
|
306
363
|
|
|
307
364
|
There are two ways to acquire your token:
|
|
@@ -14,6 +14,7 @@ BlocketAPI allows users to query saved searches, known as "Bevakningar", on [blo
|
|
|
14
14
|
- Get vehicle information, price evaluation and search for vehicles with multiple filters.
|
|
15
15
|
- Search for homes with filters for city, home type and more.
|
|
16
16
|
- Search for stores and get a specific store's listings.
|
|
17
|
+
- ...and more!
|
|
17
18
|
|
|
18
19
|
## 🧑💻️ Install
|
|
19
20
|
|
|
@@ -43,7 +44,7 @@ Some calls require a `bearerToken`. However, some calls are public and don't req
|
|
|
43
44
|
|
|
44
45
|
| Function | Token required | `as_objects` | Description |
|
|
45
46
|
|---|---|---|---|
|
|
46
|
-
| [`api.saved_searches()`](#saved_searches) | 🔐 Yes |
|
|
47
|
+
| [`api.saved_searches()`](#saved_searches) | 🔐 Yes | Yes | List your saved searches (bevakningar) |
|
|
47
48
|
| [`api.get_listings()`](#get_listings) | 🔐 Yes | - | List items related to a saved search |
|
|
48
49
|
| [`api.custom_search()`](#custom_search) | 👏 No | Yes | Search for everything on Blocket and filter by region |
|
|
49
50
|
| [`api.motor_search()`](#motor_search) | 👏 No | Yes | Advanced search for car-listings. |
|
|
@@ -52,6 +53,9 @@ Some calls require a `bearerToken`. However, some calls are public and don't req
|
|
|
52
53
|
| [`api.store_search()`](#store_search) | 👏 No | Yes | Search for a store.
|
|
53
54
|
| [`api.get_store_listings()`](#get_store_listings) | 👏 No | Yes | Get listings from a specific store.
|
|
54
55
|
| [`api.get_ad_by_id()`](#get_ad_by_id) | 👏 No | Yes | Get ad data from id.
|
|
56
|
+
| [`api.get_user_by_id()`](#get_user_by_id) | 👏 No | Yes | Get user data from id.
|
|
57
|
+
| [`api.save_ad()`](#save_ad) | 🔐 Yes | - | Save ad to "Saved ads".
|
|
58
|
+
| [`api.get_saved_ads()`](#get_saved_ads) | 🔐 Yes | - | Save ad to "Saved ads".
|
|
55
59
|
|
|
56
60
|
|
|
57
61
|
## 🤓 Detailed usage
|
|
@@ -60,6 +64,9 @@ Some calls require a `bearerToken`. However, some calls are public and don't req
|
|
|
60
64
|
|
|
61
65
|
Saved searches are your so called "Bevakningar" and can be found [here](https://www.blocket.se/sparade/bevakningar). Each saved search has and unique `id` which can be used as a parameter to `get_listings()`, see below.
|
|
62
66
|
|
|
67
|
+
Parameters:
|
|
68
|
+
- `as_objects` (`bool`, optional) - Return results as pydantic models, default is `False`.
|
|
69
|
+
|
|
63
70
|
```py
|
|
64
71
|
>>> api.saved_searches()
|
|
65
72
|
[
|
|
@@ -285,6 +292,56 @@ Get ad data from a specific ad id.
|
|
|
285
292
|
}
|
|
286
293
|
```
|
|
287
294
|
|
|
295
|
+
### get_user_by_id
|
|
296
|
+
Get user data from a user id. User id can be found in ads, searches and in blocket url `https://www.blocket.se/profil/<user_id>`.
|
|
297
|
+
|
|
298
|
+
- `user_id` (`int`, required) - The blocket user id.
|
|
299
|
+
- `as_objects` (`bool`, optional) - Return results as pydantic models, default is `False`.
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
```py
|
|
303
|
+
>>> api.get_user_by_id(1234)
|
|
304
|
+
{
|
|
305
|
+
'account': {
|
|
306
|
+
'blocket_account_id': '1234',
|
|
307
|
+
'created_at': '2020-10-10T15:45:06.407660',
|
|
308
|
+
'is_verified': True,
|
|
309
|
+
'name': 'Janne',
|
|
310
|
+
...
|
|
311
|
+
},
|
|
312
|
+
'active_ads': {[
|
|
313
|
+
...
|
|
314
|
+
]}
|
|
315
|
+
}
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### save_ad
|
|
319
|
+
This saves the ad to "Saved ads" which can be found here at `https://www.blocket.se/sparade/annonser`. When saving an ad, blocket always responds with 204, even if the ad is already saved or does not exist.
|
|
320
|
+
|
|
321
|
+
- `ad_id` (`int`, required) - The ad id. Can be found by calling any other method or from ad url.
|
|
322
|
+
|
|
323
|
+
```py
|
|
324
|
+
>>> api.save_ad(1234)
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### get_saved_ads
|
|
328
|
+
Returns all of your saved ads from `https://www.blocket.se/sparade/annonser`.
|
|
329
|
+
|
|
330
|
+
```py
|
|
331
|
+
>>> api.get_saved_ads()
|
|
332
|
+
{
|
|
333
|
+
'data': [{
|
|
334
|
+
'ad_id': '1213682185'
|
|
335
|
+
'list_id': '1213682185'
|
|
336
|
+
'subject': 'Jeans från Gina tricot 158'
|
|
337
|
+
'body': 'Moderna jeans från Gina Tricot!'
|
|
338
|
+
...
|
|
339
|
+
}]
|
|
340
|
+
...
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
```
|
|
344
|
+
|
|
288
345
|
## 🔐 Blocket API token
|
|
289
346
|
|
|
290
347
|
There are two ways to acquire your token:
|
|
@@ -11,9 +11,11 @@ import httpx
|
|
|
11
11
|
|
|
12
12
|
from blocket_api.models import (
|
|
13
13
|
AdByIdResults,
|
|
14
|
+
BlocketUser,
|
|
14
15
|
CustomSearchResults,
|
|
15
16
|
HomeSearchResults,
|
|
16
17
|
MotorSearchResults,
|
|
18
|
+
SavedSearchResponse,
|
|
17
19
|
StoreListings,
|
|
18
20
|
StoreSearchResults,
|
|
19
21
|
)
|
|
@@ -164,7 +166,11 @@ def public_token(method: Callable) -> Callable:
|
|
|
164
166
|
|
|
165
167
|
|
|
166
168
|
def _make_request(
|
|
167
|
-
*,
|
|
169
|
+
*,
|
|
170
|
+
method: Callable[..., Response] = httpx.get,
|
|
171
|
+
url: str,
|
|
172
|
+
token: str | None,
|
|
173
|
+
raise_for_status: bool = True,
|
|
168
174
|
) -> Response:
|
|
169
175
|
headers = {
|
|
170
176
|
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0"
|
|
@@ -172,11 +178,11 @@ def _make_request(
|
|
|
172
178
|
if token:
|
|
173
179
|
headers["Authorization"] = f"Bearer {token}"
|
|
174
180
|
try:
|
|
175
|
-
response =
|
|
181
|
+
response = method(url, headers=headers)
|
|
176
182
|
if raise_for_status:
|
|
177
183
|
response.raise_for_status()
|
|
178
|
-
except Exception as
|
|
179
|
-
raise APIError(
|
|
184
|
+
except Exception as e:
|
|
185
|
+
raise APIError(e)
|
|
180
186
|
return response
|
|
181
187
|
|
|
182
188
|
|
|
@@ -184,8 +190,28 @@ def _make_request(
|
|
|
184
190
|
class BlocketAPI:
|
|
185
191
|
token: str | None = None
|
|
186
192
|
|
|
193
|
+
@overload
|
|
194
|
+
def saved_searches(
|
|
195
|
+
self,
|
|
196
|
+
limit: int = 99,
|
|
197
|
+
*,
|
|
198
|
+
as_objects: Literal[True],
|
|
199
|
+
) -> SavedSearchResponse: ...
|
|
200
|
+
|
|
201
|
+
@overload
|
|
202
|
+
def saved_searches(
|
|
203
|
+
self,
|
|
204
|
+
limit: int = 99,
|
|
205
|
+
*,
|
|
206
|
+
as_objects: Literal[False] = False,
|
|
207
|
+
) -> list[dict]: ...
|
|
208
|
+
|
|
187
209
|
@auth_token
|
|
188
|
-
def saved_searches(
|
|
210
|
+
def saved_searches(
|
|
211
|
+
self,
|
|
212
|
+
*,
|
|
213
|
+
as_objects: bool = False,
|
|
214
|
+
) -> list[dict] | SavedSearchResponse:
|
|
189
215
|
"""
|
|
190
216
|
Retrieves saved searches data, also known as "Bevakningar".
|
|
191
217
|
"""
|
|
@@ -204,7 +230,8 @@ class BlocketAPI:
|
|
|
204
230
|
.get("data", [])
|
|
205
231
|
)
|
|
206
232
|
|
|
207
|
-
|
|
233
|
+
result = searches + mobility_searches
|
|
234
|
+
return SavedSearchResponse(searches=result) if as_objects else result
|
|
208
235
|
|
|
209
236
|
def _for_search_id(self, search_id: int, limit: int) -> dict:
|
|
210
237
|
assert self.token
|
|
@@ -456,20 +483,12 @@ class BlocketAPI:
|
|
|
456
483
|
|
|
457
484
|
@overload
|
|
458
485
|
def search_store(
|
|
459
|
-
self,
|
|
460
|
-
search_query: str,
|
|
461
|
-
page: int = 0,
|
|
462
|
-
*,
|
|
463
|
-
as_objects: Literal[True],
|
|
486
|
+
self, search_query: str, page: int = 0, *, as_objects: Literal[True]
|
|
464
487
|
) -> StoreSearchResults: ...
|
|
465
488
|
|
|
466
489
|
@overload
|
|
467
490
|
def search_store(
|
|
468
|
-
self,
|
|
469
|
-
search_query: str,
|
|
470
|
-
page: int = 0,
|
|
471
|
-
*,
|
|
472
|
-
as_objects: Literal[False] = False,
|
|
491
|
+
self, search_query: str, page: int = 0, *, as_objects: Literal[False] = False
|
|
473
492
|
) -> dict: ...
|
|
474
493
|
|
|
475
494
|
@overload
|
|
@@ -505,20 +524,12 @@ class BlocketAPI:
|
|
|
505
524
|
|
|
506
525
|
@overload
|
|
507
526
|
def get_store_listings(
|
|
508
|
-
self,
|
|
509
|
-
store_id: int,
|
|
510
|
-
page: int = 0,
|
|
511
|
-
*,
|
|
512
|
-
as_objects: Literal[True],
|
|
527
|
+
self, store_id: int, page: int = 0, *, as_objects: Literal[True]
|
|
513
528
|
) -> StoreListings: ...
|
|
514
529
|
|
|
515
530
|
@overload
|
|
516
531
|
def get_store_listings(
|
|
517
|
-
self,
|
|
518
|
-
store_id: int,
|
|
519
|
-
page: int = 0,
|
|
520
|
-
*,
|
|
521
|
-
as_objects: Literal[False] = False,
|
|
532
|
+
self, store_id: int, page: int = 0, *, as_objects: Literal[False] = False
|
|
522
533
|
) -> dict: ...
|
|
523
534
|
|
|
524
535
|
@public_token
|
|
@@ -542,27 +553,63 @@ class BlocketAPI:
|
|
|
542
553
|
|
|
543
554
|
@overload
|
|
544
555
|
def get_ad_by_id(
|
|
545
|
-
self,
|
|
546
|
-
ad_id: int,
|
|
547
|
-
*,
|
|
548
|
-
as_objects: Literal[True],
|
|
556
|
+
self, ad_id: int, *, as_objects: Literal[True]
|
|
549
557
|
) -> AdByIdResults: ...
|
|
550
558
|
|
|
551
559
|
@overload
|
|
552
560
|
def get_ad_by_id(
|
|
553
|
-
self,
|
|
554
|
-
ad_id: int,
|
|
555
|
-
*,
|
|
556
|
-
as_objects: Literal[False] = False,
|
|
561
|
+
self, ad_id: int, *, as_objects: Literal[False] = False
|
|
557
562
|
) -> dict: ...
|
|
558
563
|
|
|
559
564
|
@public_token
|
|
560
565
|
def get_ad_by_id(
|
|
561
|
-
self,
|
|
562
|
-
ad_id: int,
|
|
563
|
-
*,
|
|
564
|
-
as_objects: bool = False,
|
|
566
|
+
self, ad_id: int, *, as_objects: bool = False
|
|
565
567
|
) -> dict | AdByIdResults:
|
|
568
|
+
"""
|
|
569
|
+
Return an ad with it's content. The ad_id can be found by searching or
|
|
570
|
+
from the blocket ad url.
|
|
571
|
+
"""
|
|
566
572
|
url = f"{BASE_URL}/search_bff/v2/content/{ad_id}"
|
|
567
573
|
response = _make_request(url=f"{url}", token=self.token).json()
|
|
568
574
|
return AdByIdResults.model_validate(response) if as_objects else response
|
|
575
|
+
|
|
576
|
+
@overload
|
|
577
|
+
def get_user_by_id(
|
|
578
|
+
self, user_id: int, *, as_objects: Literal[True]
|
|
579
|
+
) -> BlocketUser: ...
|
|
580
|
+
|
|
581
|
+
@overload
|
|
582
|
+
def get_user_by_id(
|
|
583
|
+
self, user_id: int, *, as_objects: Literal[False] = False
|
|
584
|
+
) -> dict: ...
|
|
585
|
+
|
|
586
|
+
@public_token
|
|
587
|
+
def get_user_by_id(
|
|
588
|
+
self, user_id: int, *, as_objects: bool = False
|
|
589
|
+
) -> dict | BlocketUser:
|
|
590
|
+
"""
|
|
591
|
+
Returns a user's profile data. Contains account information, ads and more.
|
|
592
|
+
Blocket url is https://www.blocket.se/profil/<user_id>.
|
|
593
|
+
"""
|
|
594
|
+
url = f"{BASE_URL}/profile-be/v1/public-profiles/{user_id}"
|
|
595
|
+
response = _make_request(url=f"{url}", token=self.token).json()
|
|
596
|
+
return BlocketUser.model_validate(response) if as_objects else response
|
|
597
|
+
|
|
598
|
+
@auth_token
|
|
599
|
+
def save_ad(self, ad_id: int) -> dict:
|
|
600
|
+
"""
|
|
601
|
+
Save an ad to "Saved ads" which can be found here:
|
|
602
|
+
https://www.blocket.se/sparade/annonser
|
|
603
|
+
"""
|
|
604
|
+
url = f"{BASE_URL}/search_bff/v1/saved_content/{ad_id}"
|
|
605
|
+
response = _make_request(method=httpx.put, url=f"{url}", token=self.token)
|
|
606
|
+
return {"status_code": response.status_code}
|
|
607
|
+
|
|
608
|
+
@auth_token
|
|
609
|
+
def get_saved_ads(self, limit: int = 100) -> dict:
|
|
610
|
+
"""
|
|
611
|
+
Returns all of your saved ads from https://www.blocket.se/sparade/annonser.
|
|
612
|
+
"""
|
|
613
|
+
url = f"{BASE_URL}/search_bff/v1/saved_content?lim={limit}"
|
|
614
|
+
response = _make_request(url=f"{url}", token=self.token).json()
|
|
615
|
+
return response
|
|
@@ -534,3 +534,77 @@ class AdByIdResults(BaseModel):
|
|
|
534
534
|
data: AdByIdData
|
|
535
535
|
inventory: AdByIdInventory
|
|
536
536
|
placements: list[AdByIdPlacement] | None = None
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
### GetUserById ###
|
|
540
|
+
|
|
541
|
+
|
|
542
|
+
class BlocketUserAccount(BaseModel):
|
|
543
|
+
blocket_account_id: str
|
|
544
|
+
created_at: datetime.datetime
|
|
545
|
+
is_verified: bool
|
|
546
|
+
name: str
|
|
547
|
+
on_blocket_since: str
|
|
548
|
+
verified_with: str
|
|
549
|
+
|
|
550
|
+
|
|
551
|
+
class BlocketUserAd(BaseModel):
|
|
552
|
+
ad_id: str
|
|
553
|
+
ad_url: str
|
|
554
|
+
image_url: str
|
|
555
|
+
price: str
|
|
556
|
+
region: str
|
|
557
|
+
subject: str
|
|
558
|
+
|
|
559
|
+
|
|
560
|
+
class BlocketUserActiveAds(BaseModel):
|
|
561
|
+
ads: list[BlocketUserAd]
|
|
562
|
+
label_primary: str
|
|
563
|
+
label_secondary: str
|
|
564
|
+
|
|
565
|
+
|
|
566
|
+
class BlocketUserBadge(BaseModel):
|
|
567
|
+
description: str
|
|
568
|
+
icon: str
|
|
569
|
+
icon_blocket_ui: str
|
|
570
|
+
id: str
|
|
571
|
+
label: str
|
|
572
|
+
|
|
573
|
+
|
|
574
|
+
class BlocketUserCO2Savings(BaseModel):
|
|
575
|
+
date_range: str
|
|
576
|
+
equivalent: str
|
|
577
|
+
text: str
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
class BlocketUserProfileInfo(BaseModel):
|
|
581
|
+
description: str | None = None
|
|
582
|
+
has_reviews: bool
|
|
583
|
+
name: str
|
|
584
|
+
|
|
585
|
+
|
|
586
|
+
class BlocketUser(BaseModel):
|
|
587
|
+
account: BlocketUserAccount
|
|
588
|
+
active_ads: BlocketUserActiveAds
|
|
589
|
+
badges: list[BlocketUserBadge]
|
|
590
|
+
co2_savings: BlocketUserCO2Savings
|
|
591
|
+
profile_info: BlocketUserProfileInfo
|
|
592
|
+
review_scores: dict | None = None
|
|
593
|
+
|
|
594
|
+
|
|
595
|
+
### SavedSearchesResult ###
|
|
596
|
+
|
|
597
|
+
|
|
598
|
+
class SavedSearch(BaseModel):
|
|
599
|
+
id: str
|
|
600
|
+
name: str
|
|
601
|
+
query: str
|
|
602
|
+
total_count: int
|
|
603
|
+
new_count: int
|
|
604
|
+
push_enabled: bool
|
|
605
|
+
push_available: bool
|
|
606
|
+
email_enabled: bool | None = None
|
|
607
|
+
|
|
608
|
+
|
|
609
|
+
class SavedSearchResponse(BaseModel):
|
|
610
|
+
searches: list[SavedSearch]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: blocket_api
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Summary: A python API wrapper for blocket.se
|
|
5
5
|
Author-email: dunderrrrrr <emil.bjorkroth@gmail.com>
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -12,7 +12,7 @@ Requires-Dist: pytest>=8.2.2
|
|
|
12
12
|
Requires-Dist: respx>=0.21.1
|
|
13
13
|
Requires-Dist: mypy>=1.15.0
|
|
14
14
|
Requires-Dist: pydantic>=2.11.7
|
|
15
|
-
Requires-Dist: ruff>=0.13.
|
|
15
|
+
Requires-Dist: ruff>=0.13.2
|
|
16
16
|
Dynamic: license-file
|
|
17
17
|
|
|
18
18
|
# BlocketAPI
|
|
@@ -31,6 +31,7 @@ BlocketAPI allows users to query saved searches, known as "Bevakningar", on [blo
|
|
|
31
31
|
- Get vehicle information, price evaluation and search for vehicles with multiple filters.
|
|
32
32
|
- Search for homes with filters for city, home type and more.
|
|
33
33
|
- Search for stores and get a specific store's listings.
|
|
34
|
+
- ...and more!
|
|
34
35
|
|
|
35
36
|
## 🧑💻️ Install
|
|
36
37
|
|
|
@@ -60,7 +61,7 @@ Some calls require a `bearerToken`. However, some calls are public and don't req
|
|
|
60
61
|
|
|
61
62
|
| Function | Token required | `as_objects` | Description |
|
|
62
63
|
|---|---|---|---|
|
|
63
|
-
| [`api.saved_searches()`](#saved_searches) | 🔐 Yes |
|
|
64
|
+
| [`api.saved_searches()`](#saved_searches) | 🔐 Yes | Yes | List your saved searches (bevakningar) |
|
|
64
65
|
| [`api.get_listings()`](#get_listings) | 🔐 Yes | - | List items related to a saved search |
|
|
65
66
|
| [`api.custom_search()`](#custom_search) | 👏 No | Yes | Search for everything on Blocket and filter by region |
|
|
66
67
|
| [`api.motor_search()`](#motor_search) | 👏 No | Yes | Advanced search for car-listings. |
|
|
@@ -69,6 +70,9 @@ Some calls require a `bearerToken`. However, some calls are public and don't req
|
|
|
69
70
|
| [`api.store_search()`](#store_search) | 👏 No | Yes | Search for a store.
|
|
70
71
|
| [`api.get_store_listings()`](#get_store_listings) | 👏 No | Yes | Get listings from a specific store.
|
|
71
72
|
| [`api.get_ad_by_id()`](#get_ad_by_id) | 👏 No | Yes | Get ad data from id.
|
|
73
|
+
| [`api.get_user_by_id()`](#get_user_by_id) | 👏 No | Yes | Get user data from id.
|
|
74
|
+
| [`api.save_ad()`](#save_ad) | 🔐 Yes | - | Save ad to "Saved ads".
|
|
75
|
+
| [`api.get_saved_ads()`](#get_saved_ads) | 🔐 Yes | - | Save ad to "Saved ads".
|
|
72
76
|
|
|
73
77
|
|
|
74
78
|
## 🤓 Detailed usage
|
|
@@ -77,6 +81,9 @@ Some calls require a `bearerToken`. However, some calls are public and don't req
|
|
|
77
81
|
|
|
78
82
|
Saved searches are your so called "Bevakningar" and can be found [here](https://www.blocket.se/sparade/bevakningar). Each saved search has and unique `id` which can be used as a parameter to `get_listings()`, see below.
|
|
79
83
|
|
|
84
|
+
Parameters:
|
|
85
|
+
- `as_objects` (`bool`, optional) - Return results as pydantic models, default is `False`.
|
|
86
|
+
|
|
80
87
|
```py
|
|
81
88
|
>>> api.saved_searches()
|
|
82
89
|
[
|
|
@@ -302,6 +309,56 @@ Get ad data from a specific ad id.
|
|
|
302
309
|
}
|
|
303
310
|
```
|
|
304
311
|
|
|
312
|
+
### get_user_by_id
|
|
313
|
+
Get user data from a user id. User id can be found in ads, searches and in blocket url `https://www.blocket.se/profil/<user_id>`.
|
|
314
|
+
|
|
315
|
+
- `user_id` (`int`, required) - The blocket user id.
|
|
316
|
+
- `as_objects` (`bool`, optional) - Return results as pydantic models, default is `False`.
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
```py
|
|
320
|
+
>>> api.get_user_by_id(1234)
|
|
321
|
+
{
|
|
322
|
+
'account': {
|
|
323
|
+
'blocket_account_id': '1234',
|
|
324
|
+
'created_at': '2020-10-10T15:45:06.407660',
|
|
325
|
+
'is_verified': True,
|
|
326
|
+
'name': 'Janne',
|
|
327
|
+
...
|
|
328
|
+
},
|
|
329
|
+
'active_ads': {[
|
|
330
|
+
...
|
|
331
|
+
]}
|
|
332
|
+
}
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
### save_ad
|
|
336
|
+
This saves the ad to "Saved ads" which can be found here at `https://www.blocket.se/sparade/annonser`. When saving an ad, blocket always responds with 204, even if the ad is already saved or does not exist.
|
|
337
|
+
|
|
338
|
+
- `ad_id` (`int`, required) - The ad id. Can be found by calling any other method or from ad url.
|
|
339
|
+
|
|
340
|
+
```py
|
|
341
|
+
>>> api.save_ad(1234)
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### get_saved_ads
|
|
345
|
+
Returns all of your saved ads from `https://www.blocket.se/sparade/annonser`.
|
|
346
|
+
|
|
347
|
+
```py
|
|
348
|
+
>>> api.get_saved_ads()
|
|
349
|
+
{
|
|
350
|
+
'data': [{
|
|
351
|
+
'ad_id': '1213682185'
|
|
352
|
+
'list_id': '1213682185'
|
|
353
|
+
'subject': 'Jeans från Gina tricot 158'
|
|
354
|
+
'body': 'Moderna jeans från Gina Tricot!'
|
|
355
|
+
...
|
|
356
|
+
}]
|
|
357
|
+
...
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
```
|
|
361
|
+
|
|
305
362
|
## 🔐 Blocket API token
|
|
306
363
|
|
|
307
364
|
There are two ways to acquire your token:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "blocket_api"
|
|
3
|
-
version = "0.3.
|
|
3
|
+
version = "0.3.3"
|
|
4
4
|
description = "A python API wrapper for blocket.se"
|
|
5
5
|
authors = [{name = "dunderrrrrr", email = "emil.bjorkroth@gmail.com"}]
|
|
6
6
|
readme = "README.md"
|
|
@@ -12,7 +12,7 @@ dependencies = [
|
|
|
12
12
|
"respx>=0.21.1",
|
|
13
13
|
"mypy>=1.15.0",
|
|
14
14
|
"pydantic>=2.11.7",
|
|
15
|
-
"ruff>=0.13.
|
|
15
|
+
"ruff>=0.13.2",
|
|
16
16
|
]
|
|
17
17
|
|
|
18
18
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|