Skip to content
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Zappa Changelog

## next
## 0.52.0
* Remove dateutil version restriction
* Fix failed downloads of wheel packages with non-alphanumeric characters
* Last release from Miserlou/Zappa
* Removed references to zappa.io

## 0.51.0
Expand Down
2 changes: 1 addition & 1 deletion zappa/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@
'Zappa (and AWS Lambda) support the following versions of Python: {}'.format(formatted_supported_versions))
raise RuntimeError(err_msg)

__version__ = '0.51.0'
__version__ = '0.52.0'
3 changes: 2 additions & 1 deletion zappa/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2122,7 +2122,8 @@ def load_settings(self, settings_file=None, session=None):
runtime=self.runtime,
tags=self.tags,
endpoint_urls=self.stage_config.get('aws_endpoint_urls',{}),
xray_tracing=self.xray_tracing
xray_tracing=self.xray_tracing,
no_venv=self.vargs.get("no_venv") if self.vargs else None
)

for setting in CUSTOM_SETTINGS:
Expand Down
47 changes: 26 additions & 21 deletions zappa/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,8 @@ def __init__(self,
runtime='python3.6', # Detected at runtime in CLI
tags=(),
endpoint_urls={},
xray_tracing=False
xray_tracing=False,
no_venv=False
):
"""
Instantiate this new Zappa instance, loading any custom credentials if necessary.
Expand Down Expand Up @@ -289,6 +290,7 @@ def __init__(self,
self.endpoint_urls = endpoint_urls
self.xray_tracing = xray_tracing

self.no_venv = no_venv
# Some common invocations, such as DB migrations,
# can take longer than the default.

Expand Down Expand Up @@ -522,34 +524,37 @@ def create_lambda_zip( self,
if not 'concurrent' in exclude:
exclude.append('concurrent')

def splitpath(path):
parts = []
(path, tail) = os.path.split(path)
while path and tail:
parts.append(tail)
to_exclude = []
if not self.no_venv:
def splitpath(path):
parts = []
(path, tail) = os.path.split(path)
parts.append(os.path.join(path, tail))
return list(map(os.path.normpath, parts))[::-1]
split_venv = splitpath(venv)
split_cwd = splitpath(cwd)

# Ideally this should be avoided automatically,
# but this serves as an okay stop-gap measure.
if split_venv[-1] == split_cwd[-1]: # pragma: no cover
print(
"Warning! Your project and virtualenv have the same name! You may want "
"to re-create your venv with a new name, or explicitly define a "
"'project_name', as this may cause errors."
)
while path and tail:
parts.append(tail)
(path, tail) = os.path.split(path)
parts.append(os.path.join(path, tail))
return list(map(os.path.normpath, parts))[::-1]
split_venv = splitpath(venv)
split_cwd = splitpath(cwd)

# Ideally this should be avoided automatically,
# but this serves as an okay stop-gap measure.
if split_venv[-1] == split_cwd[-1]: # pragma: no cover
print(
"Warning! Your project and virtualenv have the same name! You may want "
"to re-create your venv with a new name, or explicitly define a "
"'project_name', as this may cause errors."
)
to_exclude = [split_venv[-1]]

# First, do the project..
temp_project_path = tempfile.mkdtemp(prefix='zappa-project')
temp_project_path = tempfile.mkdtemp(prefix='zappa-project')

if not slim_handler:
# Slim handler does not take the project files.
if minify:
# Related: https://github.com/Miserlou/Zappa/issues/744
excludes = ZIP_EXCLUDES + exclude + [split_venv[-1]]
excludes = ZIP_EXCLUDES + exclude + to_exclude
copytree(cwd, temp_project_path, metadata=False, symlinks=False, ignore=shutil.ignore_patterns(*excludes))
else:
copytree(cwd, temp_project_path, metadata=False, symlinks=False)
Expand Down
27 changes: 21 additions & 6 deletions zappa/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -549,13 +549,28 @@ def handler(self, event, context):
zappa_returndict.setdefault('statusDescription', response.status)

if response.data:
if settings.BINARY_SUPPORT and \
not response.mimetype.startswith("text/") \
and response.mimetype != "application/json":
zappa_returndict['body'] = base64.b64encode(response.data).decode('utf-8')
zappa_returndict["isBase64Encoded"] = True
content_encoding = response.headers.get("Content-Encoding", None)
binary_encodings = ("gzip", "compress", "deflate", "br")
if settings.BINARY_SUPPORT and content_encoding in binary_encodings:
try:
zappa_returndict["body"] = base64.b64encode(response.data).decode("utf8")
zappa_returndict["isBase64Encoded"] = True
except UnicodeDecodeError as e:
logger.exception(e)
logger.error(f"Unable to decode resulting base64 encoded response.data as 'utf8': response.data={response.data}")
logger.warning("Using response.get_data(as_text=True)")
zappa_returndict["body"] = response.get_data(as_text=True)
else:
zappa_returndict['body'] = response.get_data(as_text=True)
try:
zappa_returndict["body"] = response.get_data(as_text=True)
except UnicodeDecodeError:
# If data can't be decoded as utf-8, try processing as binary
logger.warning(
"UnicodeDecodeError on response.get_data(as_text=True), "
"unable to decode response.data as 'utf8': encoding as base64 isBase64Encoded=True"
)
zappa_returndict["body"] = base64.b64encode(response.data).decode("utf8")
zappa_returndict["isBase64Encoded"] = True

zappa_returndict['statusCode'] = response.status_code
if 'headers' in event:
Expand Down