Repository: getmoto/moto

Issue:
Fails to install cryptography for `moto-1.3.15`
Inside a python:3.8-slim docker container, `pip install moto` does not install `cryptography` on the latest moto release (moto-1.3.15). This causes subsequent commands to fail with `ModuleNotFoundError: No module named 'cryptography'` when invoking `moto` mocks.

To see this, jump into a fresh docker:
`docker run --rm -it python:3.8-slim /bin/bash`

Then inside run:
```
pip install moto
pip list
```
And note that `cryptography` is not installed.

Now run:
```
pip install moto==1.3.14
pip list
```

And note that `cryptography` is now installed.

An example of the failures seen when using the new release (ie. having only run `pip install moto`):
```
/usr/local/lib/python3.8/site-packages/moto/iam/__init__.py:2: in <module>
    from .models import iam_backend
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

    from __future__ import unicode_literals
    import base64
    import hashlib
    import os
    import random
    import string
    import sys
    from datetime import datetime
    import json
    import re
    
>   from cryptography import x509
E   ModuleNotFoundError: No module named 'cryptography'

/usr/local/lib/python3.8/site-packages/moto/iam/models.py:12: ModuleNotFoundError
```


Discussion:
Yup, encountered this issue as well while running a GitHub Actions test pipeline.
Hi @jamesgunnfiveai, @ffe4, this is due to an attempt to reduce the number of dependencies in moto.
By default, moto only comes with the absolute basic set of dependencies. As `cryptography` is only required in acm, ec2 and iam, this dependency will only be installed explicitly when calling `pip install moto[ec2]`.

If you have multiple services and don't want to go through the trouble of specifying a list of services, you can use all dependencies:
`pip install moto[all]`

Relevant PR: https://github.com/spulec/moto/pull/3281/files
AFAICT trying to use S3 `create_bucket()` triggers this error, via `moto/core/responses.py:141: in _authenticate_and_authorize_s3_action`.

The linked PR adds some documentation on why this error occurs, and how to resolve it. Hopefully that clears things up - if not please let me know
Hi, just noting I ran into this earlier today when trying to mock just s3 and sqs. Based on the stack traces I was getting, I think I would have needed the awslambda dependency, and possibly the ec2 dep as well, which wasn't clear to me. My app doesn't use lambda or ec2. My temporary fix was to downgrade to 1.3.14, but I suspect that using moto[all] or moto[ec2,awslambda] in requirements.txt would have also worked.

I wonder if there's now a deeper issue here of an unclear relationship between the deps a developer using moto declares, and the services they use?
> 
> 
> AFAICT trying to use S3 `create_bucket()` triggers this error, via `moto/core/responses.py:141: in _authenticate_and_authorize_s3_action`.

True @jvtm - just did some testing in that area. There's a bug where, in order to get S3 to work, you'd have to install dependencies for IAM. (So either `pip install moto[iam]` or `pip install moto[all]`.)

Will propose a fix shortly.
Thanks all, can confirm it's the S3 issue that I'm hitting. The error in the bug report is triggered when trying to create a bucket (which I should have included on the original report, apologies).

Sounds like fixing the hidden S3 dependency on IAM will solve this bug for me.
I had the same error, `No module named 'cryptography'`. Switching from `pip install moto[server]` to `pip install moto[all]` made cryptography error gone, but now it raises `No module named 'flask'` :( 

UPD: switching to `pip install moto[server,all]` does the trick.

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -99,25 +99,27 @@ def get_version():
     _dep_sshpubkeys_py2,
     _dep_sshpubkeys_py3,
 ]
+all_server_deps = all_extra_deps + ['flask']
 
 # TODO: do we want to add ALL services here?
 # i.e. even those without extra dependencies.
 # Would be good for future-compatibility, I guess.
 extras_per_service = {
-    "ec2": [_dep_cryptography, _dep_sshpubkeys_py2, _dep_sshpubkeys_py3],
     'acm': [_dep_cryptography],
-    'iam': [_dep_cryptography],
-    'cloudformation': [_dep_PyYAML, _dep_cfn_lint],
-    'cognitoidp': [_dep_python_jose, _dep_python_jose_ecdsa_pin],
     'awslambda': [_dep_docker],
     'batch': [_dep_docker],
+    'cloudformation': [_dep_PyYAML, _dep_cfn_lint],
+    'cognitoidp': [_dep_python_jose, _dep_python_jose_ecdsa_pin],
+    "ec2": [_dep_cryptography, _dep_sshpubkeys_py2, _dep_sshpubkeys_py3],
+    'iam': [_dep_cryptography],
     'iotdata': [_dep_jsondiff],
+    's3': [_dep_cryptography],
     'xray': [_dep_aws_xray_sdk],
 }
 
 extras_require = {
     'all': all_extra_deps,
-    'server': ['flask'],
+    'server': all_server_deps,
 }
 
 extras_require.update(extras_per_service)


Test patch: