blocket-api 0.3.1__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: blocket_api
3
- Version: 0.3.1
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.1
15
+ Requires-Dist: ruff>=0.13.2
16
16
  Dynamic: license-file
17
17
 
18
18
  # BlocketAPI
@@ -61,7 +61,7 @@ Some calls require a `bearerToken`. However, some calls are public and don't req
61
61
 
62
62
  | Function | Token required | `as_objects` | Description |
63
63
  |---|---|---|---|
64
- | [`api.saved_searches()`](#saved_searches) | 🔐 Yes | - | List your saved searches (bevakningar) |
64
+ | [`api.saved_searches()`](#saved_searches) | 🔐 Yes | Yes | List your saved searches (bevakningar) |
65
65
  | [`api.get_listings()`](#get_listings) | 🔐 Yes | - | List items related to a saved search |
66
66
  | [`api.custom_search()`](#custom_search) | 👏 No | Yes | Search for everything on Blocket and filter by region |
67
67
  | [`api.motor_search()`](#motor_search) | 👏 No | Yes | Advanced search for car-listings. |
@@ -71,6 +71,8 @@ Some calls require a `bearerToken`. However, some calls are public and don't req
71
71
  | [`api.get_store_listings()`](#get_store_listings) | 👏 No | Yes | Get listings from a specific store.
72
72
  | [`api.get_ad_by_id()`](#get_ad_by_id) | 👏 No | Yes | Get ad data from id.
73
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".
74
76
 
75
77
 
76
78
  ## 🤓 Detailed usage
@@ -79,6 +81,9 @@ Some calls require a `bearerToken`. However, some calls are public and don't req
79
81
 
80
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.
81
83
 
84
+ Parameters:
85
+ - `as_objects` (`bool`, optional) - Return results as pydantic models, default is `False`.
86
+
82
87
  ```py
83
88
  >>> api.saved_searches()
84
89
  [
@@ -327,6 +332,33 @@ Get user data from a user id. User id can be found in ads, searches and in block
327
332
  }
328
333
  ```
329
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
+
330
362
  ## 🔐 Blocket API token
331
363
 
332
364
  There are two ways to acquire your token:
@@ -1,20 +1,3 @@
1
- Metadata-Version: 2.4
2
- Name: blocket_api
3
- Version: 0.3.1
4
- Summary: A python API wrapper for blocket.se
5
- Author-email: dunderrrrrr <emil.bjorkroth@gmail.com>
6
- Requires-Python: >=3.10
7
- Description-Content-Type: text/markdown
8
- License-File: LICENSE
9
- Requires-Dist: httpx>=0.27.0
10
- Requires-Dist: pre-commit>=3.7.1
11
- Requires-Dist: pytest>=8.2.2
12
- Requires-Dist: respx>=0.21.1
13
- Requires-Dist: mypy>=1.15.0
14
- Requires-Dist: pydantic>=2.11.7
15
- Requires-Dist: ruff>=0.13.1
16
- Dynamic: license-file
17
-
18
1
  # BlocketAPI
19
2
 
20
3
  [![PyPI version](https://img.shields.io/pypi/v/blocket_api?style=for-the-badge)](https://pypi.org/project/blocket_api/) [![License](https://img.shields.io/badge/license-WTFPL-green?style=for-the-badge)](https://github.com/dunderrrrrr/blocket_api/blob/main/LICENSE) ![Python](https://img.shields.io/badge/Python-3.10-blue?style=for-the-badge) ![PyPI - Downloads](https://img.shields.io/pypi/dm/blocket_api?style=for-the-badge&color=%23dbce58)
@@ -61,7 +44,7 @@ Some calls require a `bearerToken`. However, some calls are public and don't req
61
44
 
62
45
  | Function | Token required | `as_objects` | Description |
63
46
  |---|---|---|---|
64
- | [`api.saved_searches()`](#saved_searches) | 🔐 Yes | - | List your saved searches (bevakningar) |
47
+ | [`api.saved_searches()`](#saved_searches) | 🔐 Yes | Yes | List your saved searches (bevakningar) |
65
48
  | [`api.get_listings()`](#get_listings) | 🔐 Yes | - | List items related to a saved search |
66
49
  | [`api.custom_search()`](#custom_search) | 👏 No | Yes | Search for everything on Blocket and filter by region |
67
50
  | [`api.motor_search()`](#motor_search) | 👏 No | Yes | Advanced search for car-listings. |
@@ -71,6 +54,8 @@ Some calls require a `bearerToken`. However, some calls are public and don't req
71
54
  | [`api.get_store_listings()`](#get_store_listings) | 👏 No | Yes | Get listings from a specific store.
72
55
  | [`api.get_ad_by_id()`](#get_ad_by_id) | 👏 No | Yes | Get ad data from id.
73
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".
74
59
 
75
60
 
76
61
  ## 🤓 Detailed usage
@@ -79,6 +64,9 @@ Some calls require a `bearerToken`. However, some calls are public and don't req
79
64
 
80
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.
81
66
 
67
+ Parameters:
68
+ - `as_objects` (`bool`, optional) - Return results as pydantic models, default is `False`.
69
+
82
70
  ```py
83
71
  >>> api.saved_searches()
84
72
  [
@@ -327,6 +315,33 @@ Get user data from a user id. User id can be found in ads, searches and in block
327
315
  }
328
316
  ```
329
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
+
330
345
  ## 🔐 Blocket API token
331
346
 
332
347
  There are two ways to acquire your token:
@@ -15,6 +15,7 @@ from blocket_api.models import (
15
15
  CustomSearchResults,
16
16
  HomeSearchResults,
17
17
  MotorSearchResults,
18
+ SavedSearchResponse,
18
19
  StoreListings,
19
20
  StoreSearchResults,
20
21
  )
@@ -165,7 +166,11 @@ def public_token(method: Callable) -> Callable:
165
166
 
166
167
 
167
168
  def _make_request(
168
- *, url: str, token: str | None, raise_for_status: bool = True
169
+ *,
170
+ method: Callable[..., Response] = httpx.get,
171
+ url: str,
172
+ token: str | None,
173
+ raise_for_status: bool = True,
169
174
  ) -> Response:
170
175
  headers = {
171
176
  "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0"
@@ -173,11 +178,11 @@ def _make_request(
173
178
  if token:
174
179
  headers["Authorization"] = f"Bearer {token}"
175
180
  try:
176
- response = httpx.get(url, headers=headers)
181
+ response = method(url, headers=headers)
177
182
  if raise_for_status:
178
183
  response.raise_for_status()
179
- except Exception as E:
180
- raise APIError(E)
184
+ except Exception as e:
185
+ raise APIError(e)
181
186
  return response
182
187
 
183
188
 
@@ -185,8 +190,28 @@ def _make_request(
185
190
  class BlocketAPI:
186
191
  token: str | None = None
187
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
+
188
209
  @auth_token
189
- def saved_searches(self) -> list[dict]:
210
+ def saved_searches(
211
+ self,
212
+ *,
213
+ as_objects: bool = False,
214
+ ) -> list[dict] | SavedSearchResponse:
190
215
  """
191
216
  Retrieves saved searches data, also known as "Bevakningar".
192
217
  """
@@ -205,7 +230,8 @@ class BlocketAPI:
205
230
  .get("data", [])
206
231
  )
207
232
 
208
- return searches + mobility_searches
233
+ result = searches + mobility_searches
234
+ return SavedSearchResponse(searches=result) if as_objects else result
209
235
 
210
236
  def _for_search_id(self, search_id: int, limit: int) -> dict:
211
237
  assert self.token
@@ -568,3 +594,22 @@ class BlocketAPI:
568
594
  url = f"{BASE_URL}/profile-be/v1/public-profiles/{user_id}"
569
595
  response = _make_request(url=f"{url}", token=self.token).json()
570
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
@@ -590,3 +590,21 @@ class BlocketUser(BaseModel):
590
590
  co2_savings: BlocketUserCO2Savings
591
591
  profile_info: BlocketUserProfileInfo
592
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,3 +1,20 @@
1
+ Metadata-Version: 2.4
2
+ Name: blocket_api
3
+ Version: 0.3.3
4
+ Summary: A python API wrapper for blocket.se
5
+ Author-email: dunderrrrrr <emil.bjorkroth@gmail.com>
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Requires-Dist: httpx>=0.27.0
10
+ Requires-Dist: pre-commit>=3.7.1
11
+ Requires-Dist: pytest>=8.2.2
12
+ Requires-Dist: respx>=0.21.1
13
+ Requires-Dist: mypy>=1.15.0
14
+ Requires-Dist: pydantic>=2.11.7
15
+ Requires-Dist: ruff>=0.13.2
16
+ Dynamic: license-file
17
+
1
18
  # BlocketAPI
2
19
 
3
20
  [![PyPI version](https://img.shields.io/pypi/v/blocket_api?style=for-the-badge)](https://pypi.org/project/blocket_api/) [![License](https://img.shields.io/badge/license-WTFPL-green?style=for-the-badge)](https://github.com/dunderrrrrr/blocket_api/blob/main/LICENSE) ![Python](https://img.shields.io/badge/Python-3.10-blue?style=for-the-badge) ![PyPI - Downloads](https://img.shields.io/pypi/dm/blocket_api?style=for-the-badge&color=%23dbce58)
@@ -44,7 +61,7 @@ Some calls require a `bearerToken`. However, some calls are public and don't req
44
61
 
45
62
  | Function | Token required | `as_objects` | Description |
46
63
  |---|---|---|---|
47
- | [`api.saved_searches()`](#saved_searches) | 🔐 Yes | - | List your saved searches (bevakningar) |
64
+ | [`api.saved_searches()`](#saved_searches) | 🔐 Yes | Yes | List your saved searches (bevakningar) |
48
65
  | [`api.get_listings()`](#get_listings) | 🔐 Yes | - | List items related to a saved search |
49
66
  | [`api.custom_search()`](#custom_search) | 👏 No | Yes | Search for everything on Blocket and filter by region |
50
67
  | [`api.motor_search()`](#motor_search) | 👏 No | Yes | Advanced search for car-listings. |
@@ -54,6 +71,8 @@ Some calls require a `bearerToken`. However, some calls are public and don't req
54
71
  | [`api.get_store_listings()`](#get_store_listings) | 👏 No | Yes | Get listings from a specific store.
55
72
  | [`api.get_ad_by_id()`](#get_ad_by_id) | 👏 No | Yes | Get ad data from id.
56
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".
57
76
 
58
77
 
59
78
  ## 🤓 Detailed usage
@@ -62,6 +81,9 @@ Some calls require a `bearerToken`. However, some calls are public and don't req
62
81
 
63
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.
64
83
 
84
+ Parameters:
85
+ - `as_objects` (`bool`, optional) - Return results as pydantic models, default is `False`.
86
+
65
87
  ```py
66
88
  >>> api.saved_searches()
67
89
  [
@@ -310,6 +332,33 @@ Get user data from a user id. User id can be found in ads, searches and in block
310
332
  }
311
333
  ```
312
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
+
313
362
  ## 🔐 Blocket API token
314
363
 
315
364
  There are two ways to acquire your token:
@@ -4,4 +4,4 @@ pytest>=8.2.2
4
4
  respx>=0.21.1
5
5
  mypy>=1.15.0
6
6
  pydantic>=2.11.7
7
- ruff>=0.13.1
7
+ ruff>=0.13.2
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "blocket_api"
3
- version = "0.3.1"
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.1",
15
+ "ruff>=0.13.2",
16
16
  ]
17
17
 
18
18
 
File without changes
File without changes