2017-02-24 00:43:48 +00:00
# Moto - Mock AWS Services
2013-02-16 03:15:43 +00:00
2017-05-12 23:51:37 +00:00
[![Join the chat at https://gitter.im/awsmoto/Lobby ](https://badges.gitter.im/awsmoto/Lobby.svg )](https://gitter.im/awsmoto/Lobby?utm_source=badge& utm_medium=badge& utm_campaign=pr-badge& utm_content=badge)
2013-03-01 03:36:23 +00:00
[![Build Status ](https://travis-ci.org/spulec/moto.png?branch=master )](https://travis-ci.org/spulec/moto)
2013-03-11 04:13:28 +00:00
[![Coverage Status ](https://coveralls.io/repos/spulec/moto/badge.png?branch=master )](https://coveralls.io/r/spulec/moto)
2017-03-15 03:20:17 +00:00
[![Docs ](https://readthedocs.org/projects/pip/badge/?version=stable )](http://docs.getmoto.org)
2013-03-01 03:36:23 +00:00
2013-02-16 03:15:43 +00:00
# In a nutshell
2017-02-24 00:43:48 +00:00
Moto is a library that allows your tests to easily mock out AWS Services.
2013-02-16 03:15:43 +00:00
2017-02-24 00:43:48 +00:00
Imagine you have the following python code that you want to test:
2013-02-16 03:15:43 +00:00
```python
2017-02-24 00:43:48 +00:00
import boto3
2013-02-16 03:15:43 +00:00
class MyModel(object):
def __init__ (self, name, value):
self.name = name
self.value = value
def save(self):
2017-02-24 00:43:48 +00:00
s3 = boto3.client('s3', region_name='us-east-1')
s3.put_object(Bucket='mybucket', Key=self.name, Body=self.value)
2013-02-16 03:15:43 +00:00
```
Take a minute to think how you would have tested that in the past.
2013-03-01 03:45:41 +00:00
Now see how you could test it with Moto:
2013-02-16 03:15:43 +00:00
```python
2017-02-24 00:43:48 +00:00
import boto3
2013-02-16 03:15:43 +00:00
from moto import mock_s3
from mymodule import MyModel
2017-02-24 00:43:48 +00:00
2013-02-16 03:15:43 +00:00
@mock_s3
def test_my_model_save():
2017-02-24 00:43:48 +00:00
conn = boto3.resource('s3', region_name='us-east-1')
2013-09-24 14:44:25 +00:00
# We need to create the bucket since this is all in Moto's 'virtual' AWS account
2017-02-24 00:43:48 +00:00
conn.create_bucket(Bucket='mybucket')
2013-09-24 14:44:25 +00:00
2013-02-16 03:15:43 +00:00
model_instance = MyModel('steve', 'is awesome')
model_instance.save()
2017-02-24 00:43:48 +00:00
body = conn.Object('mybucket', 'steve').get()['Body'].read().decode("utf-8")
assert body == b'is awesome'
2013-02-16 03:15:43 +00:00
```
With the decorator wrapping the test, all the calls to s3 are automatically mocked out. The mock keeps the state of the buckets and keys.
2017-02-24 00:43:48 +00:00
It gets even better! Moto isn't just for Python code and it isn't just for S3. Look at the [standalone server mode ](https://github.com/spulec/moto#stand-alone-server-mode ) for more information about running Moto with other languages. Here's the status of the other AWS services implemented:
2013-02-16 03:15:43 +00:00
2013-03-07 04:08:29 +00:00
```gherkin
2013-07-27 20:29:47 +00:00
|------------------------------------------------------------------------------|
| Service Name | Decorator | Development Status |
|------------------------------------------------------------------------------|
2017-09-22 14:16:12 +00:00
| ACM | @mock_acm | all endpoints done |
|------------------------------------------------------------------------------|
2016-03-05 23:09:09 +00:00
| API Gateway | @mock_apigateway | core endpoints done |
|------------------------------------------------------------------------------|
2013-07-27 20:29:47 +00:00
| Autoscaling | @mock_autoscaling | core endpoints done |
|------------------------------------------------------------------------------|
2014-11-04 00:28:34 +00:00
| Cloudformation | @mock_cloudformation | core endpoints done |
|------------------------------------------------------------------------------|
| Cloudwatch | @mock_cloudwatch | basic endpoints done |
|------------------------------------------------------------------------------|
2017-10-28 19:17:34 +00:00
| CloudwatchEvents | @mock_events | all endpoints done |
|------------------------------------------------------------------------------|
2018-04-03 23:40:45 +00:00
| Cognito Identity | @mock_cognitoidentity | basic endpoints done |
|------------------------------------------------------------------------------|
2018-05-02 21:13:12 +00:00
| Cognito Identity Provider | @mock_cognitoidp | basic endpoints done |
|------------------------------------------------------------------------------|
2015-09-16 14:01:13 +00:00
| Data Pipeline | @mock_datapipeline | basic endpoints done |
|------------------------------------------------------------------------------|
2013-07-27 20:29:47 +00:00
| DynamoDB | @mock_dynamodb | core endpoints done |
2017-10-29 16:06:09 +00:00
| DynamoDB2 | @mock_dynamodb2 | all endpoints + partial indexes |
2013-07-27 20:29:47 +00:00
|------------------------------------------------------------------------------|
| EC2 | @mock_ec2 | core endpoints done |
| - AMI | | core endpoints done |
| - EBS | | core endpoints done |
| - Instances | | all endpoints done |
| - Security Groups | | core endpoints done |
| - Tags | | all endpoints done |
|------------------------------------------------------------------------------|
2017-09-07 18:26:28 +00:00
| ECR | @mock_ecr | basic endpoints done |
|------------------------------------------------------------------------------|
2015-12-17 17:13:00 +00:00
| ECS | @mock_ecs | basic endpoints done |
|------------------------------------------------------------------------------|
2013-07-27 20:29:47 +00:00
| ELB | @mock_elb | core endpoints done |
2014-01-12 01:29:59 +00:00
|------------------------------------------------------------------------------|
2017-10-29 14:14:17 +00:00
| ELBv2 | @mock_elbv2 | all endpoints done |
2017-08-16 07:41:58 +00:00
|------------------------------------------------------------------------------|
2014-11-04 00:28:34 +00:00
| EMR | @mock_emr | core endpoints done |
|------------------------------------------------------------------------------|
2015-06-30 01:02:41 +00:00
| Glacier | @mock_glacier | core endpoints done |
|------------------------------------------------------------------------------|
2014-08-05 19:03:39 +00:00
| IAM | @mock_iam | core endpoints done |
|------------------------------------------------------------------------------|
2017-11-10 09:44:02 +00:00
| IoT | @mock_iot | core endpoints done |
| | @mock_iotdata | core endpoints done |
|------------------------------------------------------------------------------|
2017-10-03 20:56:04 +00:00
| Lambda | @mock_lambda | basic endpoints done, requires |
| | | docker |
2016-02-17 21:33:32 +00:00
|------------------------------------------------------------------------------|
2017-09-27 23:04:58 +00:00
| Logs | @mock_logs | basic endpoints done |
|------------------------------------------------------------------------------|
2015-06-30 01:02:41 +00:00
| Kinesis | @mock_kinesis | core endpoints done |
|------------------------------------------------------------------------------|
2016-06-24 19:26:59 +00:00
| KMS | @mock_kms | basic endpoints done |
|------------------------------------------------------------------------------|
2018-07-14 19:28:19 +00:00
| Organizations | @mock_organizations | some endpoints done |
|------------------------------------------------------------------------------|
2017-09-26 15:46:18 +00:00
| Polly | @mock_polly | all endpoints done |
|------------------------------------------------------------------------------|
2015-01-11 21:42:58 +00:00
| RDS | @mock_rds | core endpoints done |
|------------------------------------------------------------------------------|
2015-01-26 21:21:48 +00:00
| RDS2 | @mock_rds2 | core endpoints done |
|------------------------------------------------------------------------------|
2015-06-30 01:02:41 +00:00
| Redshift | @mock_redshift | core endpoints done |
|------------------------------------------------------------------------------|
2014-01-12 01:29:59 +00:00
| Route53 | @mock_route53 | core endpoints done |
2013-07-27 20:29:47 +00:00
|------------------------------------------------------------------------------|
| S3 | @mock_s3 | core endpoints done |
|------------------------------------------------------------------------------|
2018-06-06 05:15:24 +00:00
| SecretsManager | @mock_secretsmanager | basic endpoints done
2018-06-06 05:11:00 +00:00
|------------------------------------------------------------------------------|
2017-10-29 18:59:40 +00:00
| SES | @mock_ses | all endpoints done |
2013-07-27 20:29:47 +00:00
|------------------------------------------------------------------------------|
2017-09-20 20:49:09 +00:00
| SNS | @mock_sns | all endpoints done |
2014-11-04 00:28:34 +00:00
|------------------------------------------------------------------------------|
2013-07-27 20:29:47 +00:00
| SQS | @mock_sqs | core endpoints done |
|------------------------------------------------------------------------------|
2017-05-17 04:09:43 +00:00
| SSM | @mock_ssm | core endpoints done |
|------------------------------------------------------------------------------|
2013-07-27 20:29:47 +00:00
| STS | @mock_sts | core endpoints done |
|------------------------------------------------------------------------------|
2017-08-04 01:57:48 +00:00
| SWF | @mock_swf | basic endpoints done |
2016-02-05 22:38:19 +00:00
|------------------------------------------------------------------------------|
2017-10-28 19:17:34 +00:00
| X-Ray | @mock_xray | all endpoints done |
2017-09-22 22:36:26 +00:00
|------------------------------------------------------------------------------|
2013-03-07 04:08:29 +00:00
```
2013-02-16 03:15:43 +00:00
2018-05-31 03:19:56 +00:00
For a full list of endpoint [implementation coverage ](https://github.com/spulec/moto/blob/master/IMPLEMENTATION_COVERAGE.md )
2013-03-05 13:16:54 +00:00
### Another Example
Imagine you have a function that you use to launch new ec2 instances:
2013-03-05 13:14:43 +00:00
```python
2017-07-27 05:57:55 +00:00
import boto3
2013-03-05 13:14:43 +00:00
def add_servers(ami_id, count):
2017-07-27 05:57:55 +00:00
client = boto3.client('ec2', region_name='us-west-1')
client.run_instances(ImageId=ami_id, MinCount=count, MaxCount=count)
2013-03-05 13:14:43 +00:00
```
To test it:
```python
from . import add_servers
2017-07-27 05:57:55 +00:00
from moto import mock_ec2
2013-03-05 13:14:43 +00:00
@mock_ec2
def test_add_servers():
add_servers('ami-1234abcd', 2)
2017-07-27 05:57:55 +00:00
client = boto3.client('ec2', region_name='us-west-1')
instances = client.describe_instances()['Reservations'][0]['Instances']
assert len(instances) == 2
instance1 = instances[0]
assert instance1['ImageId'] == 'ami-1234abcd'
2013-03-05 13:14:43 +00:00
```
2013-02-28 03:25:15 +00:00
2017-08-09 07:56:15 +00:00
#### Using moto 1.0.X with boto2
moto 1.0.X mock docorators are defined for boto3 and do not work with boto2. Use the @mock_AWSSVC_deprecated to work with boto2.
Using moto with boto2
```python
2017-09-07 18:26:28 +00:00
from moto import mock_ec2_deprecated
2017-08-09 07:56:15 +00:00
import boto
2017-09-07 18:26:28 +00:00
2017-08-09 07:56:15 +00:00
@mock_ec2_deprecated
def test_something_with_ec2():
ec2_conn = boto.ec2.connect_to_region('us-east-1')
ec2_conn.get_only_instances(instance_ids='i-123456')
```
When using both boto2 and boto3, one can do this to avoid confusion:
```python
from moto import mock_ec2_deprecated as mock_ec2_b2
from moto import mock_ec2
```
2013-02-28 03:25:15 +00:00
## Usage
All of the services can be used as a decorator, context manager, or in a raw form.
### Decorator
```python
@mock_s3
def test_my_model_save():
2017-07-27 05:57:55 +00:00
# Create Bucket so that test can run
conn = boto3.resource('s3', region_name='us-east-1')
conn.create_bucket(Bucket='mybucket')
2013-02-28 03:25:15 +00:00
model_instance = MyModel('steve', 'is awesome')
model_instance.save()
2017-07-27 05:57:55 +00:00
body = conn.Object('mybucket', 'steve').get()['Body'].read().decode()
2013-02-28 03:25:15 +00:00
2017-07-27 05:57:55 +00:00
assert body == 'is awesome'
2013-02-28 03:25:15 +00:00
```
### Context Manager
```python
def test_my_model_save():
with mock_s3():
2017-07-27 05:57:55 +00:00
conn = boto3.resource('s3', region_name='us-east-1')
conn.create_bucket(Bucket='mybucket')
2013-02-28 03:25:15 +00:00
model_instance = MyModel('steve', 'is awesome')
model_instance.save()
2017-07-27 05:57:55 +00:00
body = conn.Object('mybucket', 'steve').get()['Body'].read().decode()
2013-02-28 03:25:15 +00:00
2017-07-27 05:57:55 +00:00
assert body == 'is awesome'
2013-02-28 03:25:15 +00:00
```
### Raw use
```python
def test_my_model_save():
mock = mock_s3()
mock.start()
2017-07-27 05:57:55 +00:00
conn = boto3.resource('s3', region_name='us-east-1')
conn.create_bucket(Bucket='mybucket')
2014-06-20 21:47:16 +00:00
2013-02-28 03:25:15 +00:00
model_instance = MyModel('steve', 'is awesome')
model_instance.save()
2017-07-27 05:57:55 +00:00
assert conn.Object('mybucket', 'steve').get()['Body'].read().decode() == 'is awesome'
2013-02-28 03:25:15 +00:00
mock.stop()
```
2013-02-28 05:09:58 +00:00
2013-03-05 13:14:43 +00:00
## Stand-alone Server Mode
2016-09-26 12:44:05 +00:00
Moto also has a stand-alone server mode. This allows you to utilize
the backend structure of Moto even if you don't use Python.
2013-03-05 13:14:43 +00:00
2016-09-26 12:44:05 +00:00
It uses flask, which isn't a default dependency. You can install the
server 'extra' package with:
```python
pip install moto[server]
```
You can then start it running a service:
2013-03-05 13:14:43 +00:00
```console
$ moto_server ec2
2016-09-01 11:14:38 +00:00
* Running on http://127.0.0.1:5000/
2013-03-05 13:14:43 +00:00
```
2016-09-26 12:44:05 +00:00
You can also pass the port:
2013-06-25 16:42:24 +00:00
```console
2014-08-14 02:16:53 +00:00
$ moto_server ec2 -p3000
2016-09-01 11:14:38 +00:00
* Running on http://127.0.0.1:3000/
```
If you want to be able to use the server externally you can pass an IP
address to bind to as a hostname or allow any of your external
interfaces with 0.0.0.0:
```console
$ moto_server ec2 -H 0.0.0.0
* Running on http://0.0.0.0:5000/
2013-06-25 16:42:24 +00:00
```
2016-09-01 11:14:38 +00:00
Please be aware this might allow other network users to access your
server.
2013-06-25 16:42:24 +00:00
2013-03-05 13:14:43 +00:00
Then go to [localhost ](http://localhost:5000/?Action=DescribeInstances ) to see a list of running instances (it will be empty since you haven't added any yet).
2016-10-22 05:18:23 +00:00
If you want to use boto with this (using the simpler decorators above instead is strongly encouraged), the easiest way is to create a boto config file (`~/.boto`) with the following values:
2014-11-27 16:03:40 +00:00
```
[Boto]
is_secure = False
https_validate_certificates = False
proxy_port = 5000
proxy = 127.0.0.1
```
2017-01-12 02:21:42 +00:00
If you want to use boto3 with this, you can pass an `endpoint_url` to the resource
```python
boto3.resource(
service_name='s3',
region_name='us-west-1',
endpoint_url='http://localhost:5000',
)
```
2013-02-28 05:16:16 +00:00
## Install
2013-02-28 05:09:58 +00:00
2017-11-10 09:44:02 +00:00
2013-02-28 05:09:58 +00:00
```console
2013-02-28 05:15:46 +00:00
$ pip install moto
2013-02-28 05:09:58 +00:00
```