Skip to content

Commit 7424aff

Browse files
authored
Merge pull request #4 from lutraconsulting/content_length_fix
Used MultipartEncoder from requests_toolbelt to include Content-Length
2 parents 7bac50a + 332f794 commit 7424aff

File tree

4 files changed

+54
-15
lines changed

4 files changed

+54
-15
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@ __pycache__/
33
*.egg
44
*.egg-info
55
dist
6-
*build
6+
*build
7+
*.whl
8+
.idea

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11
# Mergin python client
22

3-
Repo for mergin client and basic utils.
3+
Repo for mergin client and basic utils.
4+
5+
For using mergin client with its dependencies locally run:
6+
7+
python3 setup.py sdist bdist_wheel
8+
mkdir -p mergin/deps
9+
pip wheel -r mergin_client.egg-info/requires.txt -w mergin/deps

mergin/client.py

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,33 @@
11
import os
22
import re
33
import json
4-
import pytz
54
import zlib
65
import base64
76
import shutil
87
import urllib.parse
98
import urllib.request
10-
import dateutil.parser
119
from datetime import datetime
1210

11+
this_dir = os.path.dirname(os.path.realpath(__file__))
12+
13+
try:
14+
from requests_toolbelt import MultipartEncode
15+
import pytz
16+
import dateutil.parser
17+
except ImportError:
18+
# this is to import all dependencies shipped with package (e.g. to use in qgis-plugin)
19+
deps_dir = os.path.join(this_dir, 'deps')
20+
if os.path.exists(deps_dir):
21+
import sys
22+
for f in os.listdir(os.path.join(deps_dir)):
23+
sys.path.append(os.path.join(deps_dir, f))
24+
25+
from requests_toolbelt import MultipartEncode
26+
import pytz
27+
import dateutil.parser
28+
1329
from .utils import save_to_file, generate_checksum, move_file
14-
from .multipart import MultipartReader, MultipartEncoder, Field, parse_boundary
30+
from .multipart import MultipartReader, parse_boundary
1531

1632

1733
class InvalidProject(Exception):
@@ -372,15 +388,26 @@ def push_project(self, directory):
372388
changes = project_changes(server_info["files"], files)
373389
count = sum(len(items) for items in changes.values())
374390
if count:
375-
def fields():
376-
yield Field("changes", json.dumps(changes).encode("utf-8"))
377-
for file in (changes["added"] + changes["updated"]):
378-
path = file["path"]
379-
with open(os.path.join(directory, path), "rb") as f:
380-
yield Field(path, f, filename=path, content_type="application/octet-stream")
381-
382-
encoder = MultipartEncoder(fields())
383-
resp = self.post("/v1/project/data_sync/{}".format(project_path), encoder, encoder.get_headers())
391+
# Custom MultipartEncoder doesn't compute Content-Length,
392+
# which is currently required by gunicorn.
393+
# def fields():
394+
# yield Field("changes", json.dumps(changes).encode("utf-8"))
395+
# for file in (changes["added"] + changes["updated"]):
396+
# path = file["path"]
397+
# with open(os.path.join(directory, path), "rb") as f:
398+
# yield Field(path, f, filename=path, content_type="application/octet-stream")
399+
# encoder = MultipartEncoder(fields())
400+
401+
fields = {"changes": json.dumps(changes).encode("utf-8")}
402+
for file in (changes["added"] + changes["updated"]):
403+
path = file["path"]
404+
fields[path] = (path, open(os.path.join(directory, path), 'rb'), "application/octet-stream")
405+
encoder = MultipartEncoder(fields=fields)
406+
headers = {
407+
"Content-Type": encoder.content_type,
408+
"Content-Length": encoder.len
409+
}
410+
resp = self.post("/v1/project/data_sync/{}".format(project_path), encoder, headers=headers)
384411
new_project_info = json.load(resp)
385412
local_info["files"] = new_project_info["files"]
386413
local_info["version"] = new_project_info["version"]

setup.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@
1616
packages=find_packages(),
1717

1818
platforms='any',
19-
install_requires=[],
19+
install_requires=[
20+
'pytz',
21+
'python-dateutil',
22+
'requests_toolbelt'
23+
],
2024

2125
test_suite='nose.collector',
2226
tests_require=['nose'],

0 commit comments

Comments
 (0)