Skip to content

Commit 28776b8

Browse files
authored
Merge pull request #164 from lokalise/feature/PERF-1401_add_too_big_request_warning
PERF-1401 Add too big response warning
2 parents 315c771 + 8e7bda0 commit 28776b8

File tree

9 files changed

+137
-26
lines changed

9 files changed

+137
-26
lines changed

docs/additional_info/changelog.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
Changelog
44
=========
55

6+
3.5.1 (14-May-2025)
7+
-------------------
8+
9+
* Added `_response_too_big` param in the `download_files` method for `Current contributor <https://developers.lokalise.com/reference/download-files>`_ endpoint
10+
611
3.5.0 (08-May-2025)
712
-------------------
813

lokalise/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44
This module contains plugin metadata.
55
"""
66

7-
__version__: str = "3.5.0"
7+
__version__: str = "3.5.1"

lokalise/client_methods/glossary_terms.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ class GlossaryTermsMethods(EndpointProviderMixin):
1313
"""Glossary term client methods.
1414
"""
1515

16-
def glossary_terms(self, project_id: str,
17-
params: Optional[Dict] = None) -> GlossaryTermsCollection:
16+
def glossary_terms(
17+
self,
18+
project_id: str,
19+
params: Optional[Dict] = None) -> GlossaryTermsCollection:
1820
"""Fetches all glossary terms for the given project.
1921
2022
:param str project_id: ID of the project
@@ -56,7 +58,8 @@ def create_glossary_terms(self,
5658

5759
def update_glossary_terms(self,
5860
project_id: str,
59-
params: Dict[str, Any]) -> GlossaryTermsCollection:
61+
params: Dict[str,
62+
Any]) -> GlossaryTermsCollection:
6063
"""Updates one or more glossary terms.
6164
6265
:param str project_id: ID of the project

lokalise/endpoints/files_endpoint.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@
33
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
44
Module containing files endpoint.
55
"""
6+
import warnings
67
from typing import Dict, Union, Any, Optional
78
from .base_endpoint import BaseEndpoint
89
from .. import request
910

11+
warnings.formatwarning = lambda msg, *args, **kwargs: f"{msg}\n"
12+
1013

1114
class FilesEndpoint(BaseEndpoint):
1215
"""Describes files endpoint.
@@ -33,7 +36,15 @@ def download(self, params: Dict[str, Any],
3336
:rtype dict:
3437
"""
3538
path = self.path_with_params(**ids)
36-
return request.post(self.client, path + 'download', params)
39+
40+
response = request.post(self.client, path + 'download', params)
41+
42+
if '_response_too_big' in response:
43+
warnings.warn(
44+
'Warning: Project is too big for sync export. Please use our async export function '
45+
'instead (download_files_async)', UserWarning)
46+
47+
return response
3748

3849
def download_async(self, params: Dict[str, Any],
3950
**ids: Optional[Union[str, int]]) -> Dict:

lokalise/request.py

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
:attribute str BASE_URL: path to the Lokalise APIv2.
99
:attribute list PAGINATION_HEADERS: list of response headers that contain pagination data.
1010
"""
11-
from typing import Optional, Dict
11+
from typing import Optional, Dict, Any
1212
import requests
1313
from lokalise.request_utils import raise_on_error, path_to_endpoint, __format_params
1414
import lokalise.client
@@ -124,18 +124,29 @@ def respond_with(response: requests.models.Response) -> Dict:
124124
return {**data, **extract_headers_from(response)}
125125

126126

127-
def extract_headers_from(response: requests.models.Response) -> Dict:
128-
"""Fetches pagination-related data from the response headers
129-
130-
:param response: Response from the API
131-
:rtype dict:
127+
def extract_headers_from(response: requests.models.Response) -> Dict[str, Any]:
132128
"""
133-
return {
134-
"_pagination": {
135-
k.lower(): v for k,
136-
v in response.headers.items() if k.lower() in PAGINATION_HEADERS
137-
}
129+
Pull pagination metadata (and the oversized flag) out of an HTTP response.
130+
131+
Returns a dict like:
132+
{
133+
"_pagination": { "x-pagination-page": "3", ... },
134+
"_response_too_big": True # only when x-response-too-big header is present
138135
}
136+
"""
137+
138+
headers_lower = {k.lower(): v for k, v in response.headers.items()}
139+
140+
pagination = {
141+
k: v for k,
142+
v in headers_lower.items() if k in PAGINATION_HEADERS}
143+
144+
result: Dict[str, Any] = {"_pagination": pagination}
145+
146+
if "x-response-too-big" in headers_lower:
147+
result["_response_too_big"] = True
148+
149+
return result
139150

140151

141152
def options(client: lokalise.client.Client) -> Dict:

poetry.lock

Lines changed: 13 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "python-lokalise-api"
3-
version = "3.5.0"
3+
version = "3.5.1"
44
description = "Official Python interface for the Lokalise API v2"
55
authors = [
66
{name = "Ilya Krukowski", email = "golosizpru@gmail.com"}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
interactions:
2+
- request:
3+
body: '{"format": "json", "original_filenames": true, "replace_breaks": false}'
4+
headers:
5+
Accept:
6+
- application/json
7+
Accept-Encoding:
8+
- gzip, deflate
9+
Connection:
10+
- keep-alive
11+
Content-Length:
12+
- '71'
13+
User-Agent:
14+
- python-lokalise-api plugin/0.0.1
15+
x-api-token:
16+
- FILTERED
17+
method: POST
18+
uri: https://api.lokalise.com/api2/projects/454087345e09f3e7e7eae3.57891254/files/download
19+
response:
20+
body:
21+
string: '{"project_id":"454087345e09f3e7e7eae3.57891254","branch":"master","bundle_url":"https:\/\/s3-eu-west-1.amazonaws.com\/lokalise-assets\/files\/export\/454087345e09f3e7e7eae3.57891254\/aa2ea5d3b48a15f2069305b5e91c3e6c\/OnBoarding-locale.zip"}'
22+
headers:
23+
Access-Control-Allow-Headers:
24+
- Content-Type
25+
Access-Control-Allow-Origin:
26+
- '*'
27+
Cache-Control:
28+
- max-age=0, must-revalidate, no-cache, no-store, private
29+
Connection:
30+
- keep-alive
31+
Content-Type:
32+
- application/json
33+
Date:
34+
- Fri, 19 Jun 2020 12:32:33 GMT
35+
Expires:
36+
- Fri, 19 Jun 2020 12:32:33 GMT
37+
Pragma:
38+
- no-cache
39+
Server:
40+
- nginx
41+
Strict-Transport-Security:
42+
- max-age=31536000
43+
Transfer-Encoding:
44+
- chunked
45+
Vary:
46+
- Accept-Encoding
47+
X-Content-Type-Options:
48+
- nosniff
49+
X-Frame-Options:
50+
- deny
51+
X-XSS-Protection:
52+
- 1; mode=block
53+
X-Response-Too-Big:
54+
- 'true'
55+
content-length:
56+
- '240'
57+
status:
58+
code: 200
59+
message: OK
60+
version: 1

tests/client/files_test.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,23 @@ def test_download_files(client):
6565
})
6666
assert response['project_id'] == PROJECT_ID
6767
assert r"amazonaws.com" in response['bundle_url']
68+
assert '_response_too_big' not in response
69+
70+
71+
@pytest.mark.vcr
72+
def test_download_files_too_big(client):
73+
"""Tests files downloading with X-Response-Too-Big header
74+
"""
75+
with pytest.warns(UserWarning, match="Project is too big for sync export"):
76+
response = client.download_files(PROJECT_ID, {
77+
"format": "json",
78+
"original_filenames": True,
79+
"replace_breaks": False
80+
})
81+
82+
assert response['project_id'] == PROJECT_ID
83+
assert r"amazonaws.com" in response['bundle_url']
84+
assert '_response_too_big' in response
6885

6986

7087
@pytest.mark.vcr

0 commit comments

Comments
 (0)