Repository: terricain/aioboto3 (language: python)

Issue:
s3.upload_file with zero byte length fails with MalformedXML error
* Async AWS SDK for Python version: 8.3.0
* Python version: 3.8
* Operating System: Ubuntu 20.04

### Description

I'm using aioboto3 to upload various files. Some files occasionally have zero byte length.

### What I Did

```
await s3.upload_file(file_name, s3_bucket, object_name, 
      Callback=callback,
      ExtraArgs={ 
          'ACL': s3_acl,
          'Metadata': meta_data
      }
  )     

# The above fails when the file is zero length with the following error.

An error occurred (MalformedXML) when calling the CompleteMultipartUpload operation: Unknown

# Relevant Header sample (possibly missing ETag?)

'headers': {'User-Agent': 'Boto3/1.16.52 Python/3.8.5 Linux/5.11.0-7614-generic Botocore/1.19.52'}, 'body': b'<CompleteMultipartUpload xmlns="http://s3.amazonaws.com/doc/2006-03-01/" />'

```

### What I expected

I had to work around this by using s3.put_object() with an empty byte array. It would be great if the zero byte length files worked through upload_file().


Discussion / hints:

Fix patch:
diff --git a/HISTORY.rst b/HISTORY.rst
index 230f67a..3d62442 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -2,6 +2,19 @@
 History
 =======
 
+9.0.0 (2021-06-27)
+------------------
+
+* Removed default session
+* Bumped aiobotocore to 1.3.1 - thanks @slipovenko
+
+
+8.3.0 (2021-03-24)
+------------------
+
+* Fixed S3.Bucket injected load method
+* Updated CI
+
 8.2.1 (2021-03-02)
 ------------------
 
@@ -27,7 +40,6 @@ History
 
 * @u-ashish Fixed a bug where ExtraArgs was ignored when doing s3.copy
 
-
 8.0.4 (2020-07-07)
 ------------------
 
@@ -76,14 +88,11 @@ History
 * Asyncified the S3 resource Bucket().objects API and by extension, anything else in boto3 that uses the same object structure
 * Bumped aiobotocore version so that eventstreams would now work
 
-
-
 6.4.0 (2019-06-20)
 ------------------
 
 * Updated ```upload_fileobj``` to upload multiple parts concurrently to make best use of the available bandwidth
 
-
 6.2.0 (2019-05-07)
 ------------------
 
@@ -91,20 +100,17 @@ History
 * Added waiter support in resources
 * Made resource object properties coroutines and lazy load data when called
 
-
 6.2.0 (2019-02-27)
 ------------------
 
 * Added S3 Client side encryption functionality
 
-
 6.1.0 (2019-02-13)
 ------------------
 
 * nvllsvm cleaned up the packaging, requirements, travis, sphinx...
 * Unvendored aiobotocore
 
-
 6.0.1 (2018-11-22)
 ------------------
 
diff --git a/Pipfile b/Pipfile
index fba7949..d620bf5 100644
--- a/Pipfile
+++ b/Pipfile
@@ -20,5 +20,5 @@ requests = "*"
 aiofiles = "*"
 
 [packages]
-aiobotocore = {extras = ["boto3"],version = "==1.2.2"}
+aiobotocore = {extras = ["boto3"],version = "==1.3.1"}
 aioboto3 = {editable = true,path = "."}
diff --git a/Pipfile.lock b/Pipfile.lock
index 1071fa6..82364e4 100644
--- a/Pipfile.lock
+++ b/Pipfile.lock
@@ -1,7 +1,7 @@
 {
     "_meta": {
         "hash": {
-            "sha256": "bbc30ff0080501fc50be36c109c892fa00f93df8ceb98fe7d6478129e3513b7e"
+            "sha256": "f9bea12b10655091fdd57ec1a30ab7018f262aa123cac25e26451cf8fe1b0759"
         },
         "pipfile-spec": 6,
         "requires": {},
@@ -23,10 +23,10 @@
                 "boto3"
             ],
             "hashes": [
-                "sha256:37c23166603a3bd134e5f6fc22dbbf8c274d4d24c71418fba292ed2cd7a0bf43"
+                "sha256:8ecee55346651e0f4cbda883e3e16cfe11460b8d7adcc08d0017cbb867636ae1"
             ],
             "index": "pypi",
-            "version": "==1.2.2"
+            "version": "==1.3.1"
         },
         "aiohttp": {
             "hashes": [
@@ -86,24 +86,24 @@
         },
         "attrs": {
             "hashes": [
-                "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6",
-                "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700"
+                "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1",
+                "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"
             ],
-            "version": "==20.3.0"
+            "version": "==21.2.0"
         },
         "boto3": {
             "hashes": [
-                "sha256:360a9f805b11f2e468d48815193c55278765fb30b64350893ab63236a5034726",
-                "sha256:81c514185de8937ba75023a2466fae0cc6f170e6348fdac31c235c32ba9d58f3"
+                "sha256:a482135c30fa07eaf4370314dd0fb49117222a266d0423b2075aed3835ed1f04",
+                "sha256:d5ef160442925f5944e4cde88589f0f195f6c284f05613114fc6bbc35e342fa7"
             ],
-            "version": "==1.16.52"
+            "version": "==1.17.49"
         },
         "botocore": {
             "hashes": [
-                "sha256:d8f50e4162012ccfab64c2db4fcc99313d46d57789072251bab56013d66546e2",
-                "sha256:dc5ec23deadbe9327d3c81d03fddf80805c549059baabd80dea605941fe6a221"
+                "sha256:6a672ba41dd00e5c1c1824ca8143d180d88de8736d78c0b1f96b8d3cb0466561",
+                "sha256:f7f103fa0651c69dd360c7d0ecd874854303de5cc0869e0cbc2818a52baacc69"
             ],
-            "version": "==1.19.52"
+            "version": "==1.20.49"
         },
         "chardet": {
             "hashes": [
@@ -114,10 +114,10 @@
         },
         "idna": {
             "hashes": [
-                "sha256:5205d03e7bcbb919cc9c19885f9920d622ca52448306f2377daede5cf3faac16",
-                "sha256:c5b02147e01ea9920e6b0a3f1f7bb833612d507592c837a6c49552768f4054e1"
+                "sha256:14475042e284991034cb48e06f6851428fb14c4dc953acd9be9a5e95c7b6dd7a",
+                "sha256:467fbad99067910785144ce333826c71fb0e63a425657295239737f7ecd125f3"
             ],
-            "version": "==3.1"
+            "version": "==3.2"
         },
         "jmespath": {
             "hashes": [
@@ -177,33 +177,32 @@
         },
         "s3transfer": {
             "hashes": [
-                "sha256:5d48b1fd2232141a9d5fb279709117aaba506cacea7f86f11bc392f06bfa8fc2",
-                "sha256:c5dadf598762899d8cfaecf68eba649cd25b0ce93b6c954b156aaa3eed160547"
+                "sha256:35627b86af8ff97e7ac27975fe0a98a312814b46c6333d8a6b889627bcd80994",
+                "sha256:efa5bd92a897b6a8d5c1383828dca3d52d0790e0756d49740563a3fb6ed03246"
             ],
-            "version": "==0.3.6"
+            "version": "==0.3.7"
         },
         "six": {
             "hashes": [
-                "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259",
-                "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"
+                "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926",
+                "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"
             ],
-            "version": "==1.15.0"
+            "version": "==1.16.0"
         },
         "typing-extensions": {
             "hashes": [
-                "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918",
-                "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c",
-                "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f"
+                "sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497",
+                "sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342",
+                "sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84"
             ],
-            "version": "==3.7.4.3"
+            "version": "==3.10.0.0"
         },
         "urllib3": {
             "hashes": [
-                "sha256:2f4da4594db7e1e110a944bb1b551fdf4e6c136ad42e4234131391e21eb5b0df",
-                "sha256:e7b021f7241115872f92f43c6508082facffbd1c048e3c6e2bb9c2a157e28937"
+                "sha256:39fb8672126159acb139a7718dd10806104dec1e2f0f6c88aab05d17df10c8d4",
+                "sha256:f57b4c16c62fa2760b7e3d97c35b255512fb6b59a259730f36ba32ce9f8e342f"
             ],
-            "markers": "python_version != '3.4'",
-            "version": "==1.26.4"
+            "version": "==1.26.6"
         },
         "wrapt": {
             "hashes": [
@@ -257,11 +256,11 @@
     "develop": {
         "aiofiles": {
             "hashes": [
-                "sha256:bd3019af67f83b739f8e4053c6c0512a7f545b9a8d91aaeab55e6e0f9d123c27",
-                "sha256:e0281b157d3d5d59d803e3f4557dcc9a3dff28a4dd4829a9ff478adae50ca092"
+                "sha256:a1c4fc9b2ff81568c83e21392a82f344ea9d23da906e4f6a52662764545e19d4",
+                "sha256:c67a6823b5f23fcab0a2595a289cec7d8c863ffcb4322fb8cd6b90400aedfdbc"
             ],
             "index": "pypi",
-            "version": "==0.6.0"
+            "version": "==0.7.0"
         },
         "alabaster": {
             "hashes": [
@@ -279,46 +278,46 @@
         },
         "attrs": {
             "hashes": [
-                "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6",
-                "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700"
+                "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1",
+                "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"
             ],
-            "version": "==20.3.0"
+            "version": "==21.2.0"
         },
         "aws-sam-translator": {
             "hashes": [
-                "sha256:2f8904fd4a631752bc441a8fd928c444ed98ceb86b94d25ed7b84982e2eff1cd",
-                "sha256:5cf7faab3566843f3b44ef1a42a9c106ffb50809da4002faab818076dcc7bff8",
-                "sha256:c35075e7e804490d6025598ed4878ad3ab8668e37cafb7ae75120b1c37a6d212"
+                "sha256:4195ae8196f04803e7f0384a2b5ccd8c2b06ce0d8dc408aa1f1ce96c23bcf39d",
+                "sha256:f7d51b661fe1f5613a882f4733d1c92eff4dac36a076eafd18031d209b178695",
+                "sha256:fa1b990d9329d19052e7b91cf0b19371ed9d31a529054b616005884cd662b584"
             ],
-            "version": "==1.35.0"
+            "version": "==1.36.0"
         },
         "aws-xray-sdk": {
             "hashes": [
-                "sha256:697c9068e84dd5d2c1456def3fd0865f226046b5db4db56d738050e425960adf",
-                "sha256:e7b72959436471f0eb7b6757ffef289ecf16409954f1be7be7f49d57070e5994"
+                "sha256:487e44a2e0b2a5b994f7db5fad3a8115f1ea238249117a119bce8ca2750661bd",
+                "sha256:90c2fcc982a770e86d009a4c3d2b5c3e372da91cb8284d982bae458e2c0bb268"
             ],
-            "version": "==2.7.0"
+            "version": "==2.8.0"
         },
         "babel": {
             "hashes": [
-                "sha256:9d35c22fcc79893c3ecc85ac4a56cde1ecf3f19c540bba0922308a6c06ca6fa5",
-                "sha256:da031ab54472314f210b0adcff1588ee5d1d1d0ba4dbd07b94dba82bde791e05"
+                "sha256:ab49e12b91d937cd11f0b67cb259a57ab4ad2b59ac7a3b41d6c06c0ac5b0def9",
+                "sha256:bc0c176f9f6a994582230df350aa6e05ba2ebe4b3ac317eab29d9be5d2768da0"
             ],
-            "version": "==2.9.0"
+            "version": "==2.9.1"
         },
         "boto3": {
             "hashes": [
-                "sha256:360a9f805b11f2e468d48815193c55278765fb30b64350893ab63236a5034726",
-                "sha256:81c514185de8937ba75023a2466fae0cc6f170e6348fdac31c235c32ba9d58f3"
+                "sha256:a482135c30fa07eaf4370314dd0fb49117222a266d0423b2075aed3835ed1f04",
+                "sha256:d5ef160442925f5944e4cde88589f0f195f6c284f05613114fc6bbc35e342fa7"
             ],
-            "version": "==1.16.52"
+            "version": "==1.17.49"
         },
         "botocore": {
             "hashes": [
-                "sha256:d8f50e4162012ccfab64c2db4fcc99313d46d57789072251bab56013d66546e2",
-                "sha256:dc5ec23deadbe9327d3c81d03fddf80805c549059baabd80dea605941fe6a221"
+                "sha256:6a672ba41dd00e5c1c1824ca8143d180d88de8736d78c0b1f96b8d3cb0466561",
+                "sha256:f7f103fa0651c69dd360c7d0ecd874854303de5cc0869e0cbc2818a52baacc69"
             ],
-            "version": "==1.19.52"
+            "version": "==1.20.49"
         },
         "bump2version": {
             "hashes": [
@@ -337,22 +336,31 @@
         },
         "certifi": {
             "hashes": [
-                "sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c",
-                "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830"
+                "sha256:2bbf76fd432960138b3ef6dda3dde0544f27cbf8546c458e60baf371917ba9ee",
+                "sha256:50b1e4f8446b06f41be7dd6338db18e0990601dce795c2b1686458aa7e8fa7d8"
             ],
-            "version": "==2020.12.5"
+            "version": "==2021.5.30"
         },
         "cffi": {
             "hashes": [
                 "sha256:005a36f41773e148deac64b08f233873a4d0c18b053d37da83f6af4d9087b813",
+                "sha256:04c468b622ed31d408fea2346bec5bbffba2cc44226302a0de1ade9f5ea3d373",
+                "sha256:06d7cd1abac2ffd92e65c0609661866709b4b2d82dd15f611e602b9b188b0b69",
+                "sha256:06db6321b7a68b2bd6df96d08a5adadc1fa0e8f419226e25b2a5fbf6ccc7350f",
                 "sha256:0857f0ae312d855239a55c81ef453ee8fd24136eaba8e87a2eceba644c0d4c06",
+                "sha256:0f861a89e0043afec2a51fd177a567005847973be86f709bbb044d7f42fc4e05",
                 "sha256:1071534bbbf8cbb31b498d5d9db0f274f2f7a865adca4ae429e147ba40f73dea",
                 "sha256:158d0d15119b4b7ff6b926536763dc0714313aa59e320ddf787502c70c4d4bee",
+                "sha256:1bf1ac1984eaa7675ca8d5745a8cb87ef7abecb5592178406e55858d411eadc0",
                 "sha256:1f436816fc868b098b0d63b8920de7d208c90a67212546d02f84fe78a9c26396",
+                "sha256:24a570cd11895b60829e941f2613a4f79df1a27344cbbb82164ef2e0116f09c7",
+                "sha256:24ec4ff2c5c0c8f9c6b87d5bb53555bf267e1e6f70e52e5a9740d32861d36b6f",
                 "sha256:2894f2df484ff56d717bead0a5c2abb6b9d2bf26d6960c4604d5c48bbc30ee73",
                 "sha256:29314480e958fd8aab22e4a58b355b629c59bf5f2ac2492b61e3dc06d8c7a315",
+                "sha256:293e7ea41280cb28c6fcaaa0b1aa1f533b8ce060b9e701d78511e1e6c4a1de76",
                 "sha256:34eff4b97f3d982fb93e2831e6750127d1355a923ebaeeb565407b3d2f8d41a1",
                 "sha256:35f27e6eb43380fa080dccf676dece30bef72e4a67617ffda586641cd4508d49",
+                "sha256:3c3f39fa737542161d8b0d680df2ec249334cd70a8f420f71c9304bd83c3cbed",
                 "sha256:3d3dd4c9e559eb172ecf00a2a7517e97d1e96de2a5e610bd9b68cea3925b4892",
                 "sha256:43e0b9d9e2c9e5d152946b9c5fe062c151614b262fda2e7b201204de0b99e482",
                 "sha256:48e1c69bbacfc3d932221851b39d49e81567a4d4aac3b21258d9c24578280058",
@@ -360,6 +368,7 @@
                 "sha256:58e3f59d583d413809d60779492342801d6e82fefb89c86a38e040c16883be53",
                 "sha256:5de7970188bb46b7bf9858eb6890aad302577a5f6f75091fd7cdd3ef13ef3045",
                 "sha256:65fa59693c62cf06e45ddbb822165394a288edce9e276647f0046e1ec26920f3",
+                "sha256:681d07b0d1e3c462dd15585ef5e33cb021321588bebd910124ef4f4fb71aef55",
                 "sha256:69e395c24fc60aad6bb4fa7e583698ea6cc684648e1ffb7fe85e3c1ca131a7d5",
                 "sha256:6c97d7350133666fbb5cf4abdc1178c812cb205dc6f41d174a7b0f18fb93337e",
                 "sha256:6e4714cc64f474e4d6e37cfff31a814b509a35cb17de4fb1999907575684479c",
@@ -377,8 +386,10 @@
                 "sha256:b85eb46a81787c50650f2392b9b4ef23e1f126313b9e0e9013b35c15e4288e2e",
                 "sha256:bb89f306e5da99f4d922728ddcd6f7fcebb3241fc40edebcb7284d7514741991",
                 "sha256:cbde590d4faaa07c72bf979734738f328d239913ba3e043b1e98fe9a39f8b2b6",
+                "sha256:cc5a8e069b9ebfa22e26d0e6b97d6f9781302fe7f4f2b8776c3e1daea35f1adc",
                 "sha256:cd2868886d547469123fadc46eac7ea5253ea7fcb139f12e1dfc2bbd406427d1",
                 "sha256:d42b11d692e11b6634f7613ad8df5d6d5f8875f5d48939520d351007b3c13406",
+                "sha256:df5052c5d867c1ea0b311fb7c3cd28b19df469c056f7fdcfe88c7473aa63e333",
                 "sha256:f2d45f97ab6bb54753eab54fffe75aaf3de4ff2341c9daee1987ee1837636f1d",
                 "sha256:fd78e5fee591709f32ef6edb9a015b4aa1a5022598e36227500c8f4e02328d9c"
             ],
@@ -386,10 +397,10 @@
         },
         "cfn-lint": {
             "hashes": [
-                "sha256:2ffda6da0fe57d11c89cc0b44a9aa58e117ef8cb0cc30a8e543b14cdeaedeb39",
-                "sha256:6b8fdc1994ee814630d353be1a0a00e3ba13bb776ebf9b0d28479a441c157aeb"
+                "sha256:453c759de8372062174e40d3bce8f7e3472767074873429b2f2f6037b7f74b7d",
+                "sha256:80ece1e41057d0231a14c6100bbe9ebc9a26b755f860881dc6160d3bc28c0daa"
             ],
-            "version": "==0.48.0"
+            "version": "==0.51.0"
         },
         "chardet": {
             "hashes": [
@@ -400,10 +411,10 @@
         },
         "click": {
             "hashes": [
-                "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a",
-                "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"
+                "sha256:8c04c11192119b1ef78ea049e0a6f0463e4c48ef00a30160c704337586f3ad7a",
+                "sha256:fba402a4a47334742d782209a7c79bc448911afe1149d07bdabdf480b3e2f4b6"
             ],
-            "version": "==7.1.2"
+            "version": "==8.0.1"
         },
         "coverage": {
             "hashes": [
@@ -464,20 +475,20 @@
         },
         "cryptography": {
             "hashes": [
-                "sha256:066bc53f052dfeda2f2d7c195cf16fb3e5ff13e1b6b7415b468514b40b381a5b",
-                "sha256:0923ba600d00718d63a3976f23cab19aef10c1765038945628cd9be047ad0336",
-                "sha256:2d32223e5b0ee02943f32b19245b61a62db83a882f0e76cc564e1cec60d48f87",
-                "sha256:4169a27b818de4a1860720108b55a2801f32b6ae79e7f99c00d79f2a2822eeb7",
-                "sha256:57ad77d32917bc55299b16d3b996ffa42a1c73c6cfa829b14043c561288d2799",
-                "sha256:5ecf2bcb34d17415e89b546dbb44e73080f747e504273e4d4987630493cded1b",
-                "sha256:600cf9bfe75e96d965509a4c0b2b183f74a4fa6f5331dcb40fb7b77b7c2484df",
-                "sha256:66b57a9ca4b3221d51b237094b0303843b914b7d5afd4349970bb26518e350b0",
-                "sha256:93cfe5b7ff006de13e1e89830810ecbd014791b042cbe5eec253be11ac2b28f3",
-                "sha256:9e98b452132963678e3ac6c73f7010fe53adf72209a32854d55690acac3f6724",
-                "sha256:df186fcbf86dc1ce56305becb8434e4b6b7504bc724b71ad7a3239e0c9d14ef2",
-                "sha256:fec7fb46b10da10d9e1d078d1ff8ed9e05ae14f431fdbd11145edd0550b9a964"
-            ],
-            "version": "==3.4.6"
+                "sha256:0f1212a66329c80d68aeeb39b8a16d54ef57071bf22ff4e521657b27372e327d",
+                "sha256:1e056c28420c072c5e3cb36e2b23ee55e260cb04eee08f702e0edfec3fb51959",
+                "sha256:240f5c21aef0b73f40bb9f78d2caff73186700bf1bc6b94285699aff98cc16c6",
+                "sha256:26965837447f9c82f1855e0bc8bc4fb910240b6e0d16a664bb722df3b5b06873",
+                "sha256:37340614f8a5d2fb9aeea67fd159bfe4f5f4ed535b1090ce8ec428b2f15a11f2",
+                "sha256:3d10de8116d25649631977cb37da6cbdd2d6fa0e0281d014a5b7d337255ca713",
+                "sha256:3d8427734c781ea5f1b41d6589c293089704d4759e34597dce91014ac125aad1",
+                "sha256:7ec5d3b029f5fa2b179325908b9cd93db28ab7b85bb6c1db56b10e0b54235177",
+                "sha256:8e56e16617872b0957d1c9742a3f94b43533447fd78321514abbe7db216aa250",
+                "sha256:de4e5f7f68220d92b7637fc99847475b59154b7a1b3868fb7385337af54ac9ca",
+                "sha256:eb8cc2afe8b05acbd84a43905832ec78e7b3873fb124ca190f574dca7389a87d",
+                "sha256:ee77aa129f481be46f8d92a1a7db57269a2f23052d5f2433b4621bb457081cc9"
+            ],
+            "version": "==3.4.7"
         },
         "decorator": {
             "hashes": [
@@ -495,32 +506,32 @@
         },
         "dill": {
             "hashes": [
-                "sha256:78370261be6ea49037ace8c17e0b7dd06d0393af6513cc23f9b222d9367ce389",
-                "sha256:efb7f6cb65dba7087c1e111bb5390291ba3616741f96840bfc75792a1a9b5ded"
+                "sha256:7e40e4a70304fd9ceab3535d36e58791d9c4a776b38ec7f7ec9afc8d3dca4d4f",
+                "sha256:9f9734205146b2b353ab3fec9af0070237b6ddae78452af83d2fca84d739e675"
             ],
             "index": "pypi",
-            "version": "==0.3.3"
+            "version": "==0.3.4"
         },
         "distlib": {
             "hashes": [
-                "sha256:8c09de2c67b3e7deef7184574fc060ab8a793e7adbb183d942c389c8b13c52fb",
-                "sha256:edf6116872c863e1aa9d5bb7cb5e05a022c519a4594dc703843343a9ddd9bff1"
+                "sha256:106fef6dc37dd8c0e2c0a60d3fca3e77460a48907f335fa28420463a6f799736",
+                "sha256:23e223426b28491b1ced97dc3bbe183027419dfc7982b4fa2f05d5f3ff10711c"
             ],
-            "version": "==0.3.1"
+            "version": "==0.3.2"
         },
         "docker": {
             "hashes": [
-                "sha256:d3393c878f575d3a9ca3b94471a3c89a6d960b35feb92f033c0de36cc9d934db",
-                "sha256:f3607d5695be025fa405a12aca2e5df702a57db63790c73b927eb6a94aac60af"
+                "sha256:3e8bc47534e0ca9331d72c32f2881bb13b93ded0bcdeab3c833fb7cf61c0a9a5",
+                "sha256:fc961d622160e8021c10d1bcabc388c57d55fb1f917175afbe24af442e6879bd"
             ],
-            "version": "==4.4.4"
+            "version": "==5.0.0"
         },
         "docutils": {
             "hashes": [
-                "sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af",
-                "sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc"
+                "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125",
+                "sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61"
             ],
-            "version": "==0.16"
+            "version": "==0.17.1"
         },
         "ecdsa": {
             "hashes": [
@@ -538,18 +549,18 @@
         },
         "flake8": {
             "hashes": [
-                "sha256:12d05ab02614b6aee8df7c36b97d1a3b2372761222b19b58621355e82acddcff",
-                "sha256:78873e372b12b093da7b5e5ed302e8ad9e988b38b063b61ad937f26ca58fc5f0"
+                "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b",
+                "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"
             ],
             "index": "pypi",
-            "version": "==3.9.0"
+            "version": "==3.9.2"
         },
         "flask": {
             "hashes": [
-                "sha256:4efa1ae2d7c9865af48986de8aeb8504bf32c7f3d6fdc9353d34b21f4b127060",
-                "sha256:8a4fdd8936eba2512e9c85df320a37e694c93945b33ef33c89946a340a238557"
+                "sha256:1c4c257b1892aec1398784c63791cbaa43062f1f7aeb555c4da961b20ee68f55",
+                "sha256:a6209ca15eb63fc9385f38e452704113d679511d9574d09b2cf9183ae7d20dc9"
             ],
-            "version": "==1.1.2"
+            "version": "==2.0.1"
         },
         "flask-cors": {
             "hashes": [
@@ -566,10 +577,10 @@
         },
         "idna": {
             "hashes": [
-                "sha256:5205d03e7bcbb919cc9c19885f9920d622ca52448306f2377daede5cf3faac16",
-                "sha256:c5b02147e01ea9920e6b0a3f1f7bb833612d507592c837a6c49552768f4054e1"
+                "sha256:14475042e284991034cb48e06f6851428fb14c4dc953acd9be9a5e95c7b6dd7a",
+                "sha256:467fbad99067910785144ce333826c71fb0e63a425657295239737f7ecd125f3"
             ],
-            "version": "==3.1"
+            "version": "==3.2"
         },
         "imagesize": {
             "hashes": [
@@ -587,17 +598,17 @@
         },
         "itsdangerous": {
             "hashes": [
-                "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19",
-                "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749"
+                "sha256:5174094b9637652bdb841a3029700391451bd092ba3db90600dea710ba28e97c",
+                "sha256:9e724d68fc22902a1435351f84c3fb8623f303fffcc566a4cb952df8c572cff0"
             ],
-            "version": "==1.1.0"
+            "version": "==2.0.1"
         },
         "jinja2": {
             "hashes": [
-                "sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419",
-                "sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6"
+                "sha256:1f06f2da51e7b56b8f238affdd6b4e2c61e39598a378cc49345bc1bd42a978a4",
+                "sha256:703f484b47a6af502e743c9122595cc812b0271f661722403114f71a79d0f5a4"
             ],
-            "version": "==2.11.3"
+            "version": "==3.0.1"
         },
         "jmespath": {
             "hashes": [
@@ -608,9 +619,9 @@
         },
         "jsondiff": {
             "hashes": [
-                "sha256:34941bc431d10aa15828afe1cbb644977a114e75eef6cc74fb58951312326303"
+                "sha256:5122bf4708a031b02db029366184a87c5d0ddd5a327a5884ee6cf0193e599d71"
             ],
-            "version": "==1.2.0"
+            "version": "==1.3.0"
         },
         "jsonpatch": {
             "hashes": [
@@ -642,60 +653,42 @@
         },
         "markupsafe": {
             "hashes": [
-                "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473",
-                "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161",
-                "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235",
-                "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5",
-                "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42",
-                "sha256:195d7d2c4fbb0ee8139a6cf67194f3973a6b3042d742ebe0a9ed36d8b6f0c07f",
-                "sha256:22c178a091fc6630d0d045bdb5992d2dfe14e3259760e713c490da5323866c39",
-                "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff",
-                "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b",
-                "sha256:2beec1e0de6924ea551859edb9e7679da6e4870d32cb766240ce17e0a0ba2014",
-                "sha256:3b8a6499709d29c2e2399569d96719a1b21dcd94410a586a18526b143ec8470f",
-                "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1",
-                "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e",
-                "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183",
-                "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66",
-                "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b",
-                "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1",
-                "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15",
-                "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1",
-                "sha256:6f1e273a344928347c1290119b493a1f0303c52f5a5eae5f16d74f48c15d4a85",
-                "sha256:6fffc775d90dcc9aed1b89219549b329a9250d918fd0b8fa8d93d154918422e1",
-                "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e",
-                "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b",
-                "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905",
-                "sha256:7fed13866cf14bba33e7176717346713881f56d9d2bcebab207f7a036f41b850",
-                "sha256:84dee80c15f1b560d55bcfe6d47b27d070b4681c699c572af2e3c7cc90a3b8e0",
-                "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735",
-                "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d",
-                "sha256:98bae9582248d6cf62321dcb52aaf5d9adf0bad3b40582925ef7c7f0ed85fceb",
-                "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e",
-                "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d",
-                "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c",
-                "sha256:a6a744282b7718a2a62d2ed9d993cad6f5f585605ad352c11de459f4108df0a1",
-                "sha256:acf08ac40292838b3cbbb06cfe9b2cb9ec78fce8baca31ddb87aaac2e2dc3bc2",
-                "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21",
-                "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2",
-                "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5",
-                "sha256:b1dba4527182c95a0db8b6060cc98ac49b9e2f5e64320e2b56e47cb2831978c7",
-                "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b",
-                "sha256:b7d644ddb4dbd407d31ffb699f1d140bc35478da613b441c582aeb7c43838dd8",
-                "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6",
-                "sha256:bf5aa3cbcfdf57fa2ee9cd1822c862ef23037f5c832ad09cfea57fa846dec193",
-                "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f",
-                "sha256:caabedc8323f1e93231b52fc32bdcde6db817623d33e100708d9a68e1f53b26b",
-                "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f",
-                "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2",
-                "sha256:d53bc011414228441014aa71dbec320c66468c1030aae3a6e29778a3382d96e5",
-                "sha256:d73a845f227b0bfe8a7455ee623525ee656a9e2e749e4742706d80a6065d5e2c",
-                "sha256:d9be0ba6c527163cbed5e0857c451fcd092ce83947944d6c14bc95441203f032",
-                "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7",
-                "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be",
-                "sha256:feb7b34d6325451ef96bc0e36e1a6c0c1c64bc1fbec4b854f4529e51887b1621"
-            ],
-            "version": "==1.1.1"
+                "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298",
+                "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64",
+                "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b",
+                "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567",
+                "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff",
+                "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74",
+                "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35",
+                "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26",
+                "sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7",
+                "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75",
+                "sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f",
+                "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135",
+                "sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8",
+                "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a",
+                "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914",
+                "sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18",
+                "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8",
+                "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2",
+                "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d",
+                "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b",
+                "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f",
+                "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb",
+                "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833",
+                "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415",
+                "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902",
+                "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9",
+                "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d",
+                "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066",
+                "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f",
+                "sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5",
+                "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94",
+                "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509",
+                "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51",
+                "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872"
+            ],
+            "version": "==2.0.1"
         },
         "mccabe": {
             "hashes": [
@@ -704,38 +697,31 @@
             ],
             "version": "==0.6.1"
         },
-        "mock": {
-            "hashes": [
-                "sha256:122fcb64ee37cfad5b3f48d7a7d51875d7031aaf3d8be7c42e2bee25044eee62",
-                "sha256:7d3fbbde18228f4ff2f1f119a45cdffa458b4c0dee32eb4d2bb2f82554bac7bc"
-            ],
-            "version": "==4.0.3"
-        },
         "more-itertools": {
             "hashes": [
-                "sha256:5652a9ac72209ed7df8d9c15daf4e1aa0e3d2ccd3c87f8265a0673cd9cbc9ced",
-                "sha256:c5d6da9ca3ff65220c3bfd2a8db06d698f05d4d2b9be57e1deb2be5a45019713"
+                "sha256:2cf89ec599962f2ddc4d568a05defc40e0a587fbc10d5989713638864c36be4d",
+                "sha256:83f0308e05477c68f56ea3a888172c78ed5d5b3c282addb67508e7ba6c8f813a"
             ],
-            "version": "==8.7.0"
+            "version": "==8.8.0"
         },
         "moto": {
             "extras": [
                 "server"
             ],
             "hashes": [
-                "sha256:4610d27ead9124eaa84a78eca7dfa25a8ccb66cf6a7cb8a8889b5ca0c7796889",
-                "sha256:f5db62e50a5377da4457307675281198e9ffbe9425866a88f523bef0c6e8d463"
+                "sha256:f205da54d5e9442450a519dbe5bb49c31d9f496b551a84648afa01a360fd4b82",
+                "sha256:fe7b8b15b7dea9de56fa88a0e3f53ce54f8d584590161b210cce71d01cc97899"
             ],
             "index": "pypi",
-            "version": "==2.0.2"
+            "version": "==2.0.10"
         },
         "networkx": {
             "hashes": [
-                "sha256:7978955423fbc9639c10498878be59caf99b44dc304c2286162fd24b458c1602",
-                "sha256:8c5812e9f798d37c50570d15c4a69d5710a18d77bafc903ee9c5fba7454c616c"
+                "sha256:0635858ed7e989f4c574c2328380b452df892ae85084144c73d8cd819f0c4e06",
+                "sha256:109cd585cac41297f71103c3c42ac6ef7379f29788eb54cb751be5a663bb235a"
             ],
             "markers": "python_version >= '3.5'",
-            "version": "==2.5"
+            "version": "==2.5.1"
         },
         "packaging": {
             "hashes": [
@@ -788,25 +774,48 @@
         },
         "pygithub": {
             "hashes": [
-                "sha256:300bc16e62886ca6537b0830e8f516ea4bc3ef12d308e0c5aff8bdbd099173d4",
-                "sha256:87afd6a67ea582aa7533afdbf41635725f13d12581faed7e3e04b1579c0c0627"
+                "sha256:1bbfff9372047ff3f21d5cd8e07720f3dbfdaf6462fcaed9d815f528f1ba7283",
+                "sha256:2caf0054ea079b71e539741ae56c5a95e073b81fa472ce222e81667381b9601b"
             ],
             "index": "pypi",
-            "version": "==1.54.1"
+            "version": "==1.55"
         },
         "pygments": {
             "hashes": [
-                "sha256:2656e1a6edcdabf4275f9a3640db59fd5de107d88e8663c5d4e9a0fa62f77f94",
-                "sha256:534ef71d539ae97d4c3a4cf7d6f110f214b0e687e92f9cb9d2a3b0d3101289c8"
+                "sha256:a18f47b506a429f6f4b9df81bb02beab9ca21d0a5fee38ed15aef65f0545519f",
+                "sha256:d66e804411278594d764fc69ec36ec13d9ae9147193a1740cd34d272ca383b8e"
             ],
-            "version": "==2.8.1"
+            "version": "==2.9.0"
         },
         "pyjwt": {
             "hashes": [
-                "sha256:5c6eca3c2940464d106b99ba83b00c6add741c9becaec087fb7ccdefea71350e",
-                "sha256:8d59a976fb773f3e6a39c85636357c4f0e242707394cadadd9814f5cbaa20e96"
+                "sha256:934d73fbba91b0483d3857d1aff50e96b2a892384ee2c17417ed3203f173fca1",
+                "sha256:fba44e7898bbca160a2b2b501f492824fc8382485d3a6f11ba5d0c1937ce6130"
             ],
-            "version": "==1.7.1"
+            "version": "==2.1.0"
+        },
+        "pynacl": {
+            "hashes": [
+                "sha256:06cbb4d9b2c4bd3c8dc0d267416aaed79906e7b33f114ddbf0911969794b1cc4",
+                "sha256:11335f09060af52c97137d4ac54285bcb7df0cef29014a1a4efe64ac065434c4",
+                "sha256:2fe0fc5a2480361dcaf4e6e7cea00e078fcda07ba45f811b167e3f99e8cff574",
+                "sha256:30f9b96db44e09b3304f9ea95079b1b7316b2b4f3744fe3aaecccd95d547063d",
+                "sha256:4e10569f8cbed81cb7526ae137049759d2a8d57726d52c1a000a3ce366779634",
+                "sha256:511d269ee845037b95c9781aa702f90ccc36036f95d0f31373a6a79bd8242e25",
+                "sha256:537a7ccbea22905a0ab36ea58577b39d1fa9b1884869d173b5cf111f006f689f",
+                "sha256:54e9a2c849c742006516ad56a88f5c74bf2ce92c9f67435187c3c5953b346505",
+                "sha256:757250ddb3bff1eecd7e41e65f7f833a8405fede0194319f87899690624f2122",
+                "sha256:7757ae33dae81c300487591c68790dfb5145c7d03324000433d9a2c141f82af7",
+                "sha256:7c6092102219f59ff29788860ccb021e80fffd953920c4a8653889c029b2d420",
+                "sha256:8122ba5f2a2169ca5da936b2e5a511740ffb73979381b4229d9188f6dcb22f1f",
+                "sha256:9c4a7ea4fb81536c1b1f5cc44d54a296f96ae78c1ebd2311bd0b60be45a48d96",
+                "sha256:c914f78da4953b33d4685e3cdc7ce63401247a21425c16a39760e282075ac4a6",
+                "sha256:cd401ccbc2a249a47a3a1724c2918fcd04be1f7b54eb2a5a71ff915db0ac51c6",
+                "sha256:d452a6746f0a7e11121e64625109bc4468fc3100452817001dbe018bb8b08514",
+                "sha256:ea6841bc3a76fa4942ce00f3bda7d436fda21e2d91602b9e21b7ca9ecab8f3ff",
+                "sha256:f8851ab9041756003119368c1e6cd0b9c631f46d686b3904b18c0139f4419f80"
+            ],
+            "version": "==1.4.0"
         },
         "pyparsing": {
             "hashes": [
@@ -823,27 +832,27 @@
         },
         "pytest": {
             "hashes": [
-                "sha256:9d1edf9e7d0b84d72ea3dbcdfd22b35fb543a5e8f2a60092dd578936bf63d7f9",
-                "sha256:b574b57423e818210672e07ca1fa90aaf194a4f63f3ab909a2c67ebb22913839"
+                "sha256:50bcad0a0b9c5a72c8e4e7c9855a3ad496ca6a881a3641b4260605450772c54b",
+                "sha256:91ef2131a9bd6be8f76f1f08eac5c5317221d6ad1e143ae03894b862e8976890"
             ],
             "index": "pypi",
-            "version": "==6.2.2"
+            "version": "==6.2.4"
         },
         "pytest-asyncio": {
             "hashes": [
-                "sha256:2eae1e34f6c68fc0a9dc12d4bea190483843ff4708d24277c41568d6b6044f1d",
-                "sha256:9882c0c6b24429449f5f969a5158b528f39bde47dc32e85b9f0403965017e700"
+                "sha256:2564ceb9612bbd560d19ca4b41347b54e7835c2f792c504f698e05395ed63f6f",
+                "sha256:3042bcdf1c5d978f6b74d96a151c4cfb9dcece65006198389ccd7e6c60eb1eea"
             ],
             "index": "pypi",
-            "version": "==0.14.0"
+            "version": "==0.15.1"
         },
         "pytest-cov": {
             "hashes": [
-                "sha256:359952d9d39b9f822d9d29324483e7ba04a3a17dd7d05aa6beb7ea01e359e5f7",
-                "sha256:bdb9fdb0b85a7cc825269a4c56b48ccaa5c7e365054b6038772c32ddcdc969da"
+                "sha256:261bb9e47e65bd099c89c3edf92972865210c36813f80ede5277dceb77a4a62a",
+                "sha256:261ceeb8c227b726249b376b8526b600f38667ee314f910353fa318caa01f4d7"
             ],
             "index": "pypi",
-            "version": "==2.11.1"
+            "version": "==2.12.1"
         },
         "python-dateutil": {
             "hashes": [
@@ -857,10 +866,10 @@
                 "cryptography"
             ],
             "hashes": [
-                "sha256:4e4192402e100b5fb09de5a8ea6bcc39c36ad4526341c123d401e2561720335b",
-                "sha256:67d7dfff599df676b04a996520d9be90d6cdb7e6dd10b4c7cacc0c3e2e92f2be"
+                "sha256:55779b5e6ad599c6336191246e95eb2293a9ddebd555f796a65f838f07e5d78a",
+                "sha256:9b1376b023f8b298536eedd47ae1089bcdb848f1535ab30555cd92002d78923a"
             ],
-            "version": "==3.2.0"
+            "version": "==3.3.0"
         },
         "pytz": {
             "hashes": [
@@ -901,7 +910,6 @@
                 "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6",
                 "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0"
             ],
-            "markers": "python_version != '3.4'",
             "version": "==5.4.1"
         },
         "requests": {
@@ -914,10 +922,10 @@
         },
         "responses": {
             "hashes": [
-                "sha256:3b1ea9cf026edaaf25e853abc4d3b2687d25467e9d8d41e77ee525cad0673f3e",
-                "sha256:cf62ab0f4119b81d485521b2c950d8aa55a885c90126488450b7acb8ee3f77ac"
+                "sha256:18a5b88eb24143adbf2b4100f328a2f5bfa72fbdacf12d97d41f07c26c45553d",
+                "sha256:b54067596f331786f5ed094ff21e8d79e6a1c68ef625180a7d34808d6f36c11b"
             ],
-            "version": "==0.13.1"
+            "version": "==0.13.3"
         },
         "rsa": {
             "hashes": [
@@ -928,17 +936,17 @@
         },
         "s3transfer": {
             "hashes": [
-                "sha256:5d48b1fd2232141a9d5fb279709117aaba506cacea7f86f11bc392f06bfa8fc2",
-                "sha256:c5dadf598762899d8cfaecf68eba649cd25b0ce93b6c954b156aaa3eed160547"
+                "sha256:35627b86af8ff97e7ac27975fe0a98a312814b46c6333d8a6b889627bcd80994",
+                "sha256:efa5bd92a897b6a8d5c1383828dca3d52d0790e0756d49740563a3fb6ed03246"
             ],
-            "version": "==0.3.6"
+            "version": "==0.3.7"
         },
         "six": {
             "hashes": [
-                "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259",
-                "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"
+                "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926",
+                "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"
             ],
-            "version": "==1.15.0"
+            "version": "==1.16.0"
         },
         "snowballstemmer": {
             "hashes": [
@@ -949,19 +957,19 @@
         },
         "sphinx": {
             "hashes": [
-                "sha256:3f01732296465648da43dec8fb40dc451ba79eb3e2cc5c6d79005fd98197107d",
-                "sha256:ce9c228456131bab09a3d7d10ae58474de562a6f79abb3dc811ae401cf8c1abc"
+                "sha256:b5c2ae4120bf00c799ba9b3699bc895816d272d120080fbc967292f29b52b48c",
+                "sha256:d1cb10bee9c4231f1700ec2e24a91be3f3a3aba066ea4ca9f3bbe47e59d5a1d4"
             ],
             "index": "pypi",
-            "version": "==3.5.3"
+            "version": "==4.0.2"
         },
         "sphinx-autodoc-typehints": {
             "hashes": [
-                "sha256:244ba6d3e2fdb854622f643c7763d6f95b6886eba24bec28e86edf205e4ddb20",
-                "sha256:da049791d719f4c9813642496ee4764203e317f0697eb75446183fa2a68e3f77"
+                "sha256:193617d9dbe0847281b1399d369e74e34cd959c82e02c7efde077fca908a9f52",
+                "sha256:5e81776ec422dd168d688ab60f034fccfafbcd94329e9537712c93003bddc04a"
             ],
             "index": "pypi",
-            "version": "==1.11.1"
+            "version": "==1.12.0"
         },
         "sphinxcontrib-applehelp": {
             "hashes": [
@@ -979,10 +987,10 @@
         },
         "sphinxcontrib-htmlhelp": {
             "hashes": [
-                "sha256:3c0bc24a2c41e340ac37c85ced6dafc879ab485c095b1d65d2461ac2f7cca86f",
-                "sha256:e8f5bb7e31b2dbb25b9cc435c8ab7a79787ebf7f906155729338f3156d93659b"
+                "sha256:d412243dfb797ae3ec2b59eca0e52dac12e75a241bf0e4eb861e450d06c6ed07",
+                "sha256:f5f8bb2d0d629f398bf47d0d69c07bc13b65f75a81ad9e2f71a63d4b7a2f6db2"
             ],
-            "version": "==1.0.3"
+            "version": "==2.0.0"
         },
         "sphinxcontrib-jsmath": {
             "hashes": [
@@ -1000,10 +1008,10 @@
         },
         "sphinxcontrib-serializinghtml": {
             "hashes": [
-                "sha256:eaa0eccc86e982a9b939b2b82d12cc5d013385ba5eadcc7e4fed23f4405f77bc",
-                "sha256:f242a81d423f59617a8e5cf16f5d4d74e28ee9a66f9e5b637a18082991db5a9a"
+                "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd",
+                "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"
             ],
-            "version": "==1.1.4"
+            "version": "==1.1.5"
         },
         "sshpubkeys": {
             "hashes": [
@@ -1021,11 +1029,11 @@
         },
         "tox": {
             "hashes": [
-                "sha256:05a4dbd5e4d3d8269b72b55600f0b0303e2eb47ad5c6fe76d3576f4c58d93661",
-                "sha256:e007673f3595cede9b17a7c4962389e4305d4a3682a6c5a4159a1453b4f326aa"
+                "sha256:307a81ddb82bd463971a273f33e9533a24ed22185f27db8ce3386bff27d324e3",
+                "sha256:b0b5818049a1c1997599d42012a637a33f24c62ab8187223fdd318fa8522637b"
             ],
             "index": "pypi",
-            "version": "==3.23.0"
+            "version": "==3.23.1"
         },
         "tox-travis": {
             "hashes": [
@@ -1037,32 +1045,31 @@
         },
         "urllib3": {
             "hashes": [
-                "sha256:2f4da4594db7e1e110a944bb1b551fdf4e6c136ad42e4234131391e21eb5b0df",
-                "sha256:e7b021f7241115872f92f43c6508082facffbd1c048e3c6e2bb9c2a157e28937"
+                "sha256:39fb8672126159acb139a7718dd10806104dec1e2f0f6c88aab05d17df10c8d4",
+                "sha256:f57b4c16c62fa2760b7e3d97c35b255512fb6b59a259730f36ba32ce9f8e342f"
             ],
-            "markers": "python_version != '3.4'",
-            "version": "==1.26.4"
+            "version": "==1.26.6"
         },
         "virtualenv": {
             "hashes": [
-                "sha256:49ec4eb4c224c6f7dd81bb6d0a28a09ecae5894f4e593c89b0db0885f565a107",
-                "sha256:83f95875d382c7abafe06bd2a4cdd1b363e1bb77e02f155ebe8ac082a916b37c"
+                "sha256:14fdf849f80dbb29a4eb6caa9875d476ee2a5cf76a5f5415fa2f1606010ab467",
+                "sha256:2b0126166ea7c9c3661f5b8e06773d28f83322de7a3ff7d06f0aed18c9de6a76"
             ],
-            "version": "==20.4.3"
+            "version": "==20.4.7"
         },
         "websocket-client": {
             "hashes": [
-                "sha256:44b5df8f08c74c3d82d28100fdc81f4536809ce98a17f0757557813275fbb663",
-                "sha256:63509b41d158ae5b7f67eb4ad20fecbb4eee99434e73e140354dc3ff8e09716f"
+                "sha256:b68e4959d704768fa20e35c9d508c8dc2bbc041fd8d267c0d7345cffe2824568",
+                "sha256:e5c333bfa9fa739538b652b6f8c8fc2559f1d364243c8a689d7c0e1d41c2e611"
             ],
-            "version": "==0.58.0"
+            "version": "==1.1.0"
         },
         "werkzeug": {
             "hashes": [
-                "sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43",
-                "sha256:6c80b1e5ad3665290ea39320b91e1be1e0d5f60652b964a3070216de83d2e47c"
+                "sha256:1de1db30d010ff1af14a009224ec49ab2329ad2cde454c8a708130642d579c42",
+                "sha256:6c1ec500dcdba0baa27600f6a22f6333d8b662d22027ff9f6202e3367413caa8"
             ],
-            "version": "==1.0.1"
+            "version": "==2.0.1"
         },
         "wrapt": {
             "hashes": [
@@ -1076,13 +1083,6 @@
                 "sha256:8bbcb45cc982f48b2ca8fe7e7827c5d792f217ecf1792626f808bf41c3b86051"
             ],
             "version": "==0.12.0"
-        },
-        "zipp": {
-            "hashes": [
-                "sha256:3607921face881ba3e026887d8150cca609d517579abe052ac81fc5aeffdbd76",
-                "sha256:51cb66cc54621609dd593d1787f286ee42a5c0adbb4b29abea5a63edc3e03098"
-            ],
-            "version": "==3.4.1"
         }
     }
 }
diff --git a/README.rst b/README.rst
index 806905b..ad89c54 100644
--- a/README.rst
+++ b/README.rst
@@ -17,6 +17,8 @@ Async AWS SDK for Python
      :target: https://pyup.io/repos/github/terrycain/aioboto3/
      :alt: Updates
 
+**Breaking changes for v9, aioboto3.resource and aioboto3.client methods no longer exist, make a session then call session.client etc...**
+This was done for various reasons but mainly that it prevents the default session living longer than it should as that breaks situations where eventloops are replaced.
 
 **The .client and .resource functions must now be used as async context managers.**
 
diff --git a/aioboto3/__init__.py b/aioboto3/__init__.py
index 6b1a267..0ecfe8b 100644
--- a/aioboto3/__init__.py
+++ b/aioboto3/__init__.py
@@ -3,77 +3,11 @@
 """Top-level package for Async AWS SDK for Python."""
 import logging
 from aioboto3.session import Session
-from boto3.compat import _warn_deprecated_python
 
 __author__ = """Terry Cain"""
 __email__ = 'terry@terrys-home.co.uk'
 __version__ = '8.3.0'
 
-DEFAULT_SESSION = None
-
-
-def setup_default_session(**kwargs):
-    """
-    Set up a default session, passing through any parameters to the session
-    constructor. There is no need to call this unless you wish to pass custom
-    parameters, because a default session will be created for you.
-    """
-    global DEFAULT_SESSION
-    DEFAULT_SESSION = Session(**kwargs)
-
-
-def set_stream_logger(name='boto3', level=logging.DEBUG, format_string=None):
-    """
-    Add a stream handler for the given name and level to the logging module.
-    By default, this logs all boto3 messages to ``stdout``.
-
-    :type name: string
-    :param name: Log name
-    :type level: int
-    :param level: Logging level, e.g. ``logging.INFO``
-    :type format_string: str
-    :param format_string: Log message format
-    """
-    if format_string is None:
-        format_string = "%(asctime)s %(name)s [%(levelname)s] %(message)s"
-
-    logger = logging.getLogger(name)
-    logger.setLevel(level)
-    handler = logging.StreamHandler()
-    handler.setLevel(level)
-    formatter = logging.Formatter(format_string)
-    handler.setFormatter(formatter)
-    logger.addHandler(handler)
-
-
-def _get_default_session(**kwargs):
-    """
-    Get the default session, creating one if needed.
-    :rtype: :py:class:`~aioboto3.session.Session`
-    :return: The default session
-    """
-    if DEFAULT_SESSION is None:
-        setup_default_session(**kwargs)
-    _warn_deprecated_python()
-
-    return DEFAULT_SESSION
-
-
-def client(*args, **kwargs):
-    """
-    Create a low-level service client by name using the default session.
-    See :py:meth:`aioboto3.session.Session.client`.
-    """
-    return _get_default_session().client(*args, **kwargs)
-
-
-def resource(*args, **kwargs):
-    """
-    Create a resource service client by name using the default session.
-    See :py:meth:`aioboto3.session.Session.resource`.
-    """
-    return _get_default_session().resource(*args, **kwargs)
-
 
 # Set up logging to ``/dev/null`` like a library is supposed to.
 # http://docs.python.org/3.3/howto/logging.html#configuring-logging-for-a-library
diff --git a/aioboto3/s3/cse.py b/aioboto3/s3/cse.py
index 0442d7e..79ce88d 100644
--- a/aioboto3/s3/cse.py
+++ b/aioboto3/s3/cse.py
@@ -235,9 +235,11 @@ def __init__(self, keyid: Optional[str] = None, kms_client_args: Optional[dict]
         # Store the client instead of creating one every time, performance wins when doing many files
         self._kms_client = None
         self._kms_client_args = kms_client_args if kms_client_args else {}
+        self._session = None
 
     async def setup(self):
-        self._kms_client = await aioboto3.client('kms', **self._kms_client_args).__aenter__()
+        self._session = aioboto3.Session()
+        self._kms_client = await self._session.client('kms', **self._kms_client_args).__aenter__()
 
     async def close(self):
         await self._kms_client.close()
@@ -303,6 +305,7 @@ def __init__(self, crypto_context: CryptoContext, s3_client_args: Optional[dict]
         self._backend = default_backend()
 
         self._crypto_context = crypto_context
+        self._session = None
         self._s3_client = None
         self._s3_client_args = s3_client_args if s3_client_args else {}
 
@@ -312,7 +315,8 @@ async def setup(self):
         else:
             self._loop = asyncio.get_running_loop()
 
-        self._s3_client = await aioboto3.client('s3', **self._s3_client_args).__aenter__()
+        self._session = aioboto3.Session()
+        self._s3_client = await self._session.client('s3', **self._s3_client_args).__aenter__()
         await self._crypto_context.setup()
 
     async def close(self):
diff --git a/aioboto3/s3/inject.py b/aioboto3/s3/inject.py
index 0430626..1d402e0 100644
--- a/aioboto3/s3/inject.py
+++ b/aioboto3/s3/inject.py
@@ -243,6 +243,7 @@ async def file_reader() -> None:
         while not eof:
             part += 1
             multipart_payload = b''
+            loop_counter = 0
             while len(multipart_payload) < multipart_chunksize:
                 try:
                     # Handles if .read() returns anything that can be awaited
@@ -263,14 +264,17 @@ async def file_reader() -> None:
                     multipart_payload = b''
                     break
 
-                if data == b'':  # End of file
+                if data == b'' and loop_counter > 0:  # End of file, handles uploading empty files
                     eof = True
                     break
                 multipart_payload += data
+                loop_counter += 1
 
             # If file has ended but chunk has some data in it, upload it,
             # else if file ended just after a chunk then exit
-            if not multipart_payload:
+            # if the first part is b'' then upload it as we're uploading an empty
+            # file
+            if not multipart_payload and part != 1:
                 break
 
             if Processing:
diff --git a/setup.py b/setup.py
index 4e78b46..70e552b 100755
--- a/setup.py
+++ b/setup.py
@@ -12,7 +12,7 @@
     history = history_file.read()
 
 requirements = [
-    'aiobotocore[boto3]==1.2.2'
+    'aiobotocore[boto3]==1.3.1'
 ]
 
 setup_requirements = [


Test patch:
diff --git a/tests/conftest.py b/tests/conftest.py
index d52d9a1..ce21578 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -3,6 +3,7 @@
 import string
 import uuid
 import mock
+from typing import Dict, Type
 
 from aiobotocore.config import AioConfig
 from aioboto3.session import Session
@@ -15,7 +16,7 @@ def debug(request):
     return request.param
 
 
-def moto_config():
+def moto_config() -> Dict[str, str]:
     return {
         'aws_secret_access_key': 'xxx',
         'aws_access_key_id': 'xxx'
@@ -23,17 +24,17 @@ def moto_config():
 
 
 @pytest.fixture
-def region():
+def region() -> str:
     return 'eu-central-1'
 
 
 @pytest.fixture
-def signature_version():
+def signature_version() -> str:
     return 'v4'
 
 
 @pytest.fixture
-def config(signature_version):
+def config(signature_version: str) -> AioConfig:
     return AioConfig(
         signature_version=signature_version,
         read_timeout=5,
@@ -42,27 +43,27 @@ def config(signature_version):
 
 
 @pytest.fixture
-def random_table_name():
+def random_table_name() -> str:
     return 'test_' + ''.join([random.choice(string.hexdigits) for _ in range(0, 8)])
 
 
 @pytest.fixture
-def bucket_name():
+def bucket_name() -> str:
     return 'test-bucket-' + str(uuid.uuid4())
 
 
 @pytest.fixture
-def kms_key_alias():
+def kms_key_alias() -> str:
     return 'alias/test-' + uuid.uuid4().hex
 
 
 @pytest.fixture
-def s3_key_name():
+def s3_key_name() -> str:
     return uuid.uuid4().hex
 
 
 @pytest.fixture
-async def dynamodb_resource(request, region, config, event_loop, dynamodb2_server):
+async def dynamodb_resource(request, region: str, config: AioConfig, event_loop, dynamodb2_server: str) -> "ServiceResource":
     session = Session(region_name=region, **moto_config())
 
     async with session.resource('dynamodb', region_name=region, endpoint_url=dynamodb2_server, config=config) as resource:
@@ -70,7 +71,7 @@ async def dynamodb_resource(request, region, config, event_loop, dynamodb2_serve
 
 
 @pytest.fixture
-async def s3_client(request, region, config, event_loop, s3_server, bucket_name):
+async def s3_client(request, region: str, config: AioConfig, event_loop, s3_server: str, bucket_name: str) -> "S3":
     session = Session(region_name=region, **moto_config())
 
     async with session.client('s3', region_name=region, endpoint_url=s3_server, config=config) as client:
@@ -78,69 +79,61 @@ async def s3_client(request, region, config, event_loop, s3_server, bucket_name)
 
 
 @pytest.fixture
-async def s3_resource(request, region, config, event_loop, s3_server, bucket_name):
+async def s3_resource(request, region: str, config: AioConfig, event_loop, s3_server: str, bucket_name: str) -> "ServiceResource":
     session = Session(region_name=region, **moto_config())
 
     async with session.resource('s3', region_name=region, endpoint_url=s3_server, config=config) as resource:
         yield resource
 
 
-@pytest.fixture(scope='function')
-def s3_moto_patch(request, region, config, event_loop, s3_server):
-    from aioboto3 import client as orig_client, resource as orig_resource
+def create_fake_session(url_overrides: Dict[str, str]) -> Type[Session]:
+    class FakeSession(Session):
+        def __init__(self, *args, **kwargs):
+            super(FakeSession, self).__init__(*args, **kwargs)
 
-    s3_url = s3_server
+            self.__url_overrides = url_overrides
+            self.__secret_key = 'ABCDEFGABCDEFGABCDEF'
+            self.__access_key = 'YTYHRSshtrsTRHSrsTHRSTrthSRThsrTHsr'
 
-    def fake_client(*args, **kwargs):
-        nonlocal s3_url
-        if 'endpoint_url' not in kwargs and args[0] == 's3':
-            kwargs['endpoint_url'] = s3_url
-            kwargs['aws_access_key_id'] = 'ABCDEFGABCDEFGABCDEF'
-            kwargs['aws_secret_access_key'] = 'YTYHRSshtrsTRHSrsTHRSTrthSRThsrTHsr'
+        def client(self, *args, **kwargs):
 
-        return orig_client(*args, **kwargs)
+            if 'endpoint_url' not in kwargs and args[0] in self.__url_overrides:
+                kwargs['endpoint_url'] = self.__url_overrides[args[0]]
 
-    def fake_res(*args, **kwargs):
-        nonlocal s3_url
-        if 'endpoint_url' not in kwargs and args[0] == 's3':
-            kwargs['endpoint_url'] = s3_url
-            kwargs['aws_access_key_id'] = 'ABCDEFGABCDEFGABCDEF'
-            kwargs['aws_secret_access_key'] = 'YTYHRSshtrsTRHSrsTHRSTrthSRThsrTHsr'
-        return orig_resource(*args, **kwargs)
+            kwargs['aws_access_key_id'] = self.__secret_key
+            kwargs['aws_secret_access_key'] = self.__access_key
 
-    client_patcher = mock.patch('aioboto3.client', fake_client)
-    resource_patcher = mock.patch('aioboto3.resource', fake_res)
+            return super(FakeSession, self).client(*args, **kwargs)
 
-    client_patcher.start()
-    resource_patcher.start()
+        def resource(self, *args, **kwargs):
 
-    yield fake_client, fake_res
+            if 'endpoint_url' not in kwargs and args[0] in self.__url_overrides:
+                kwargs['endpoint_url'] = self.__url_overrides[args[0]]
 
-    client_patcher.stop()
-    resource_patcher.stop()
-    aioboto3.DEFAULT_SESSION = None
+            kwargs['aws_access_key_id'] = self.__secret_key
+            kwargs['aws_secret_access_key'] = self.__access_key
 
+            return super(FakeSession, self).resource(*args, **kwargs)
+    return FakeSession
 
-@pytest.fixture
-def kms_moto_patch(request, region, config, event_loop, kms_server):
-    from aioboto3 import client as orig_client
 
-    kms_url = kms_server
+@pytest.fixture(scope='function')
+def moto_patch(request, region, config, event_loop, s3_server, kms_server):
+    FakeSession = create_fake_session({
+        's3': s3_server,
+        'kms': kms_server
+    })
 
-    def fake_client(*args, **kwargs):
-        nonlocal kms_url
-        if 'endpoint_url' not in kwargs and args[0] == 'kms':
-            kwargs['endpoint_url'] = kms_url
-            kwargs['aws_access_key_id'] = 'ABCDEFGABCDEFGABCDEF'
-            kwargs['aws_secret_access_key'] = 'YTYHRSshtrsTRHSrsTHRSTrthSRThsrTHsr'
-        return orig_client(*args, **kwargs)
+    session_patcher1 = mock.patch('aioboto3.Session', FakeSession)
+    session_patcher2 = mock.patch('aioboto3.session.Session', FakeSession)
 
-    client_patcher = mock.patch('aioboto3.client', fake_client)
-    client_patcher.start()
+    session_patcher1.start()
+    session_patcher2.start()
 
-    yield fake_client
+    yield
 
-    client_patcher.stop()
+    session_patcher1.stop()
+    session_patcher2.stop()
 
 
 pytest_plugins = ['mock_server']
diff --git a/tests/test_basic.py b/tests/test_basic.py
index 445b1b1..c99f7cb 100644
--- a/tests/test_basic.py
+++ b/tests/test_basic.py
@@ -12,16 +12,16 @@
 @pytest.mark.asyncio
 async def test_getting_client(event_loop):
     """Simple getting of client."""
-    aioboto3.DEFAULT_SESSION = None
+    session = aioboto3.Session()
 
-    async with aioboto3.client('ssm', region_name='eu-central-1') as client:
+    async with session.client('ssm', region_name='eu-central-1') as client:
         assert isinstance(client, AioBaseClient)
 
 
 @pytest.mark.asyncio
 async def test_getting_resource_cm(event_loop):
     """Simple getting of resource."""
-    aioboto3.DEFAULT_SESSION = None
+    session = aioboto3.Session()
 
-    async with aioboto3.resource('dynamodb', region_name='eu-central-1') as resource:
+    async with session.resource('dynamodb', region_name='eu-central-1') as resource:
         assert isinstance(resource.meta.client, AioBaseClient)
diff --git a/tests/test_patches.py b/tests/test_patches.py
index 19a18b1..5f7df81 100644
--- a/tests/test_patches.py
+++ b/tests/test_patches.py
@@ -74,15 +74,13 @@
 
 
 def test_patches():
-    print("Boto3 version: {} aiobotocore version: {}".format(
-        boto3.__version__, aiobotocore.__version__))
+    print("Boto3 version: {} aiobotocore version: {}".format(boto3.__version__, aiobotocore.__version__))
 
     success = True
     for obj, digests in _API_DIGESTS.items():
         digest = hashlib.sha1(getsource(obj).encode('utf-8')).hexdigest()
         if digest not in digests:
-            print("Digest of {}:{} not found in: {}".format(
-                obj.__qualname__, digest, digests))
+            print("Digest of {}:{} not found in: {}".format(obj.__qualname__, digest, digests))
             success = False
 
     assert success
diff --git a/tests/test_s3.py b/tests/test_s3.py
index bc7017f..fa1c524 100644
--- a/tests/test_s3.py
+++ b/tests/test_s3.py
@@ -85,6 +85,28 @@ def callback(bytes_sent):
     assert (await resp['Body'].read()) == data
 
 
+@pytest.mark.asyncio
+async def test_s3_upload_empty_fileobj(event_loop, s3_client, bucket_name):
+    await s3_client.create_bucket(Bucket=bucket_name)
+
+    fh = BytesIO(b'')
+    fh.seek(0)
+
+    callbacks = []
+
+    def callback(bytes_sent):
+        callbacks.append(bytes_sent)
+
+    await s3_client.upload_fileobj(fh, bucket_name, 'test_file', Callback=callback)
+
+    # We should of got 1 callback saying its written 12 bytes
+    assert len(callbacks) == 1
+    assert callbacks[0] == 0
+
+    resp = await s3_client.get_object(Bucket=bucket_name, Key='test_file')
+    assert len(await resp['Body'].read()) == 0
+
+
 @pytest.mark.asyncio
 async def test_s3_upload_fileobj_async(event_loop, s3_client, bucket_name):
     await s3_client.create_bucket(Bucket=bucket_name)
diff --git a/tests/test_s3_cse.py b/tests/test_s3_cse.py
index b6c7d22..3d561b9 100644
--- a/tests/test_s3_cse.py
+++ b/tests/test_s3_cse.py
@@ -3,6 +3,7 @@
 
 import pytest
 
+import aioboto3
 import aioboto3.s3.cse as cse
 
 # Need big chunk of data for range test
@@ -30,7 +31,7 @@
 
 # @pytest.mark.skip(reason="no way of currently testing this")
 # @pytest.mark.asyncio
-# async def test_cse1(event_loop, s3_moto_patch, kms_moto_patch, region, bucket_name, kms_key_alias):
+# async def test_cse1(event_loop, moto_patch, region, bucket_name, kms_key_alias):
 #     kms_client = kms_moto_patch('kms', region_name=region)
 #     s3_client, s3_resource = s3_moto_patch
 #     s3_client = s3_client('s3', region_name=region)
@@ -65,33 +66,35 @@
 
 @pytest.mark.xfail(reason="Waiting for moto to accept PR and release")
 @pytest.mark.asyncio
-async def test_kms_crypto_context_success(event_loop, s3_moto_patch, kms_moto_patch, region, bucket_name, kms_key_alias):
-    kms_client = kms_moto_patch('kms', region_name=region)
-    resp = await kms_client.create_key(KeyUsage='ENCRYPT_DECRYPT', Origin='AWS_KMS')
-    key_id = resp['KeyMetadata']['KeyId']
+async def test_kms_crypto_context_success(event_loop, moto_patch, region, bucket_name, kms_key_alias):
+    session = aioboto3.Session()
 
-    await kms_client.create_alias(AliasName=kms_key_alias, TargetKeyId=key_id)
+    async with session.client('kms', region_name=region) as kms_client:
+        resp = await kms_client.create_key(KeyUsage='ENCRYPT_DECRYPT', Origin='AWS_KMS')
+        key_id = resp['KeyMetadata']['KeyId']
 
-    # Create context
-    kms_context = cse.KMSCryptoContext(kms_key_alias, kms_client_args={'region_name': region})
-    assert kms_context.kms_key == kms_key_alias
+        await kms_client.create_alias(AliasName=kms_key_alias, TargetKeyId=key_id)
 
-    await kms_context.setup()
-    assert kms_context._kms_client is not None
+        # Create context
+        kms_context = cse.KMSCryptoContext(kms_key_alias, kms_client_args={'region_name': region})
+        assert kms_context.kms_key == kms_key_alias
 
-    aes_key, material_description, encrypted_aes_key = await kms_context.get_encryption_aes_key()
+        await kms_context.setup()
+        assert kms_context._kms_client is not None
 
-    # Material description should denote what key is used
-    assert material_description['kms_cmk_id'] == kms_key_alias
+        aes_key, material_description, encrypted_aes_key = await kms_context.get_encryption_aes_key()
 
-    resp = await kms_client.decrypt(CiphertextBlob=encrypted_aes_key, EncryptionContext=material_description)
-    assert aes_key == resp['Plaintext']
+        # Material description should denote what key is used
+        assert material_description['kms_cmk_id'] == kms_key_alias
 
-    await kms_context.close()
+        resp = await kms_client.decrypt(CiphertextBlob=encrypted_aes_key, EncryptionContext=material_description)
+        assert aes_key == resp['Plaintext']
+
+        await kms_context.close()
 
 
 @pytest.mark.asyncio
-async def test_kms_crypto_context_decrypt_no_key(event_loop, s3_moto_patch, kms_moto_patch, region, bucket_name, kms_key_alias):
+async def test_kms_crypto_context_decrypt_no_key(event_loop, moto_patch, region, bucket_name, kms_key_alias):
     # Create context
     kms_context = cse.KMSCryptoContext(kms_client_args={'region_name': region})
     await kms_context.setup()
@@ -104,9 +107,10 @@ async def test_kms_crypto_context_decrypt_no_key(event_loop, s3_moto_patch, kms_
 
 
 @pytest.mark.asyncio
-async def test_kms_cse_encrypt_decrypt_aes_gcm(event_loop, s3_moto_patch, region, bucket_name, s3_key_name):
-    s3_client, s3_resource = s3_moto_patch
-    async with s3_client('s3', region_name=region) as s3_client:
+async def test_kms_cse_encrypt_decrypt_aes_gcm(event_loop, moto_patch, region, bucket_name, s3_key_name):
+    session = aioboto3.Session()
+
+    async with session.client('s3', region_name=region) as s3_client:
         await s3_client.create_bucket(Bucket=bucket_name, CreateBucketConfiguration={'LocationConstraint': region})
 
         aes_key = b'O\x8b\xdc\x92\x87k\x9aJ{m\x82\xb3\x96\xf7\x93]\xa1\xb2Cl\x86<5\xbe\x13\xaf\xa8\x94\xa2O3\xef'
@@ -151,9 +155,10 @@ async def test_kms_cse_encrypt_decrypt_aes_gcm(event_loop, s3_moto_patch, region
 
 
 @pytest.mark.asyncio
-async def test_symmetric_cse_encrypt_decrypt_aes_cbc(event_loop, s3_moto_patch, region, bucket_name, s3_key_name):
-    s3_client, s3_resource = s3_moto_patch
-    async with s3_client('s3', region_name=region) as s3_client:
+async def test_symmetric_cse_encrypt_decrypt_aes_cbc(event_loop, moto_patch, region, bucket_name, s3_key_name):
+    session = aioboto3.Session()
+
+    async with session.client('s3', region_name=region) as s3_client:
         await s3_client.create_bucket(Bucket=bucket_name, CreateBucketConfiguration={'LocationConstraint': region})
 
         aes_key = b'O\x8b\xdc\x92\x87k\x9aJ{m\x82\xb3\x96\xf7\x93]\xa1\xb2Cl\x86<5\xbe\x13\xaf\xa8\x94\xa2O3\xef'
@@ -195,9 +200,10 @@ async def test_symmetric_cse_encrypt_decrypt_aes_cbc(event_loop, s3_moto_patch,
 
 
 @pytest.mark.asyncio
-async def test_asymmetric_cse_encrypt_decrypt_aes_cbc(event_loop, s3_moto_patch, region, bucket_name, s3_key_name):
-    s3_client, s3_resource = s3_moto_patch
-    async with s3_client('s3', region_name=region) as s3_client:
+async def test_asymmetric_cse_encrypt_decrypt_aes_cbc(event_loop, moto_patch, region, bucket_name, s3_key_name):
+    session = aioboto3.Session()
+
+    async with session.client('s3', region_name=region) as s3_client:
         await s3_client.create_bucket(Bucket=bucket_name, CreateBucketConfiguration={'LocationConstraint': region})
 
         private_key = b'0\x82\x02w\x02\x01\x000\r\x06\t*\x86H\x86\xf7\r\x01\x01\x01\x05\x00\x04\x82\x02a0\x82\x02]\x02\x01\x00\x02\x81\x81\x00\xbb x \x88x\xa6\x1b\x94\r\x93\x82\x9bU4j\x90//4\x97\xfd\x0c\xdf\xd3\x10\xab}\x99\x19\xe4\xfe\xf1=\x8aM\xca\x06\xa6\xf3\xa5\xce8\x19Q\xcc\x12\x1a\xc2\xc4\xd9w\xeex\xf6\xbc\x1f\xb2u\xb3Z\x0e!fsLJ>\x7fi\xdcc\xb9:\xee2\xf8h5h\x1f\x96\xab\xa4\xfc\x02\x12=D\xde\xde}i~\xe8\xe1y\x16\xc0\xe1\xeb\xca\x16\xbde@+\x00\x9e\xbf\x12\xe7\x0c\xa7#\x88\x80\xa04\xe2M\xc2\x1f\xc2\x8a\xfc\x08M\x02\x03\x01\x00\x01\x02\x81\x81\x00\x92\x1d\x0fO\xaf\xe0-+\xd9\x96$9VZ\xd8\x9b\xe0\xcb\xc7\x1bU\x16UH,\x01\x976r&\xa3\x05b\x8f?\xff\xef\xa0\xf4\x19\xc9\xbc\xd5W\x07\xe4\xc5\xba9\x9d\x05\x85\xbd"\x9c\xdeV\r\xbe\x13\xf6\\\x94<\x99\xa0/\xa8\x8f\xd8\x14\xa3\x88\x88\x1b\xdf\xee\xbb\xaf\xcd\xc7k{\xb2\x9e\x90B\x05)\x7f\xedo\x95\xb9[\xf4\x8fQ\xc0\xee\xd0\xc9\xb9\x1e\xbfP\xe7\x8c\x87\xab\x87\n\xfd\xcb\x04\xe5\x9bEv\x0f)8\x94R;\xf8B\xc1\x02A\x00\xe8D\x96\xdd\x1f\xd4\xd1\xbc\xd2p\xd0\x11\x99pkp\xa9\xb5\xdd:\xa7\xdfn\xd6%\x82\xaeK\xb20\xd2\x03\xf2\r\x06\x1as\xc3_\x95\xf3\xab`>\xaa\x1c\xc1\x19]\xa3\xf2]Q+\xf9\xebi\x9feQ\xd6\xf4\xe3\x11\x02A\x00\xce? \xe6=\xad\x14\xf5\x96PY\xf8\xc1\xaa\xb8y\x9f{\xd8\xf4\x94\x8b}\x9c\\\xec\x10\x7f\xfbD"\xbbd\xa3g\x85\xbd\x97\x18\xd7\xde\x99\xb7\x1dw\xbfwb\xbb\xaa\x01\xaf~\x8aW K\xed;{\xf6t\x99}\x02A\x00\x9b\x13\xf8\x9a\x89?B\x0eM\x7fo\x1c\xe1\x12\xd3Yt\xa6m\xa0U\'tL\\\xdd$\xdc{\x8b\xe7\x1d%F\x96\xd5\xa0\x87H\xd1\xc8\xd0\x9a\xc1\x1c9x\xa0$\nk\xae\xec\x9cm\x10F\x04[\xd4\xc9\xad\xd5\xd1\x02@I\xf9V\x81~I\xa0$\xdd\xbf\x00&:\xc0R\xde<\x97\x9d\x1fLP#\xc3{\x88\xa7\xfa_R\xf6\xea#\x94\x80B\xf5\xd7E\xef\xd7Ef\xeaH\xd3\x01\xad\x06\x06Z\x08i\xe8\x90\x8bb\xf09\xcf\xa2{\xfb\xb9\x02@D\xbaAV\x03\x94,\xc7\xf3/\xbd\xf3I\xc2\x0fAI\xcd\x9e\xa1\xce\xdf\xa7\x19S\x86\xf3\xc2\x854]\xac\xab\xc8\x8f@\x03_-?{>\x1f\xcc\x1a@\xdb\n\xf0v5\xe4tL\xf3\x16kD\xb5\x83L(3\xd2'