

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

# Python e ElastiCache
<a name="ElastiCache-Getting-Started-Tutorials-Python"></a>

In questo tutorial, usi l'AWS SDK for Python (Boto3) per scrivere programmi semplici per eseguire le seguenti operazioni: ElastiCache 
+ Crea ElastiCache cluster Redis OSS (modalità cluster abilitata e modalità cluster disabilitata)
+ Controlla se esistono utenti o gruppi di utenti, altrimenti creali. (Questa funzionalità è disponibile con Valkey 7.2 e versioni successive e con Redis OSS da 6.0 a 7.1.)
+ Connect a ElastiCache
+ Esegui operazioni come impostare e ricevere stringhe, leggere e scrivere su Steam e pubblicare e iscriverti dal canale. Pub/Sub 

Mentre segui questo tutorial, puoi fare riferimento alla documentazione di AWS SDK for Python (Boto). [La sezione seguente è specifica per ElastiCache: client di basso livello ElastiCache ](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/elasticache.html)

## Prerequisiti dei tutorial
<a name="ElastiCache-Getting-Started-Tutorials-Prerquisites"></a>
+ Imposta una chiave di AWS accesso per utilizzare.AWS SDKs Per ulteriori informazioni, consulta [Configurazione ElastiCache](set-up.md).
+ Installare Python 3.0 o versione successiva. Per maggiori informazioni, consulta [https://www.python.org/downloads](https://www.python.org/downloads). Per istruzioni, consulta [Quickstart](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/quickstart.html) nella documentazione di Boto 3.

**Topics**
+ [Prerequisiti dei tutorial](#ElastiCache-Getting-Started-Tutorials-Prerquisites)
+ [Tutorial: creazione di cluster e utenti ElastiCache](#ElastiCache-Getting-Started-Tutorials-Create-Cluster-and-Users)
+ [Tutorial: Connessione a ElastiCache](#ElastiCache-Getting-Started-Tutorials-Connecting)
+ [Esempi di utilizzo](#ElastiCache-Getting-Started-Tutorials-Usage)

## Tutorial: creazione di cluster e utenti ElastiCache
<a name="ElastiCache-Getting-Started-Tutorials-Create-Cluster-and-Users"></a>

Gli esempi seguenti utilizzano l'SDK boto3 ElastiCache per le operazioni di gestione Redis OSS (creazione di cluster o utenti) e redis-py/ per la gestione dei dati. redis-py-cluster 

**Topics**
+ [Creare un cluster in modalità cluster disabilitata](#ElastiCache-Getting-Started-Tutorials-Create-Cluster)
+ [Creare un cluster in modalità cluster disabilitata con TLS e RBAC](#ElastiCache-Getting-Started-Tutorials-RBAC)
+ [Creare un cluster in modalità cluster abilitata](#ElastiCache-Getting-Started-Tutorials-Cluster-Enabled)
+ [Creare un cluster in modalità cluster abilitata con TLS e RBAC](#ElastiCache-Getting-Started-Tutorials-Cluster-RBAC)
+ [Controlla se users/usergroup esiste, altrimenti creali](#ElastiCache-Getting-Started-Tutorials-Users)

### Creare un cluster in modalità cluster disabilitata
<a name="ElastiCache-Getting-Started-Tutorials-Create-Cluster"></a>

*Copia il seguente programma e incollalo in un file denominato .py. CreateClusterModeDisabledCluster*

```
import boto3
import logging

logging.basicConfig(level=logging.INFO)
client = boto3.client('elasticache')

def create_cluster_mode_disabled(CacheNodeType='cache.t3.small',EngineVersion='6.0',NumCacheClusters=2,ReplicationGroupDescription='Sample cluster',ReplicationGroupId=None):
    """Creates an ElastiCache Cluster with cluster mode disabled

    Returns a dictionary with the API response

    :param CacheNodeType: Node type used on the cluster. If not specified, cache.t3.small will be used
    Refer to https://docs.aws.amazon.com/AmazonElastiCache/latest/dg/CacheNodes.SupportedTypes.html for supported node types
    :param EngineVersion: Engine version to be used. If not specified, latest will be used.
    :param NumCacheClusters: Number of nodes in the cluster. Minimum 1 (just a primary node) and maximun 6 (1 primary and 5 replicas).
    If not specified, cluster will be created with 1 primary and 1 replica.
    :param ReplicationGroupDescription: Description for the cluster.
    :param ReplicationGroupId: Name for the cluster
    :return: dictionary with the API results

    """
    if not ReplicationGroupId:
        return 'ReplicationGroupId parameter is required'

    response = client.create_replication_group(
        AutomaticFailoverEnabled=True,
        CacheNodeType=CacheNodeType,
        Engine='valkey',
        EngineVersion=EngineVersion,
        NumCacheClusters=NumCacheClusters,
        ReplicationGroupDescription=ReplicationGroupDescription,
        ReplicationGroupId=ReplicationGroupId,
        SnapshotRetentionLimit=30,
    )
    return response


if __name__ == '__main__':
    
    # Creates an ElastiCache Cluster mode disabled cluster, based on cache.m6g.large nodes, Valkey 8.0, one primary and two replicas
    elasticacheResponse = create_cluster_mode_disabled(
        #CacheNodeType='cache.m6g.large', 
        EngineVersion='8.0',
        NumCacheClusters=3,
        ReplicationGroupDescription='Valkey cluster mode disabled with replicas',
        ReplicationGroupId='valkey202104053'
        )
    
    logging.info(elasticacheResponse)
```

Per eseguire il programma, immetti il comando seguente:

 `python CreateClusterModeDisabledCluster.py`

Per ulteriori informazioni, consulta [Gestione dei cluster in ElastiCache](Clusters.md).

### Creare un cluster in modalità cluster disabilitata con TLS e RBAC
<a name="ElastiCache-Getting-Started-Tutorials-RBAC"></a>

Per garantire la sicurezza, è possibile utilizzare Transport Layer Security (TLS) e Controllo di accesso basato sul ruolo (RBAC) quando si crea un cluster disabilitato in modalità cluster. A differenza di Valkey o Redis OSS AUTH, in cui tutti i client autenticati hanno accesso completo al gruppo di replica se il token è autenticato, RBAC consente di controllare l'accesso al cluster tramite gruppi di utenti. Questi gruppi di utenti sono progettati come un modo per organizzare l'accesso ai gruppi di replica. Per ulteriori informazioni, consulta [Controllo accessi basato sui ruoli (RBAC)](Clusters.RBAC.md).

*Copia il seguente programma e incollalo in un file denominato RBAC.py. ClusterModeDisabledWith*

```
import boto3
import logging

logging.basicConfig(level=logging.INFO)
client = boto3.client('elasticache')

def create_cluster_mode_disabled_rbac(CacheNodeType='cache.t3.small',EngineVersion='6.0',NumCacheClusters=2,ReplicationGroupDescription='Sample cluster',ReplicationGroupId=None, UserGroupIds=None, SecurityGroupIds=None,CacheSubnetGroupName=None):
    """Creates an ElastiCache Cluster with cluster mode disabled and RBAC

    Returns a dictionary with the API response

    :param CacheNodeType: Node type used on the cluster. If not specified, cache.t3.small will be used
    Refer to https://docs.aws.amazon.com/AmazonElastiCache/latest/dg/CacheNodes.SupportedTypes.html for supported node types
    :param EngineVersion: Engine version to be used. If not specified, latest will be used.
    :param NumCacheClusters: Number of nodes in the cluster. Minimum 1 (just a primary node) and maximun 6 (1 primary and 5 replicas).
    If not specified, cluster will be created with 1 primary and 1 replica.
    :param ReplicationGroupDescription: Description for the cluster.
    :param ReplicationGroupId: Mandatory name for the cluster.
    :param UserGroupIds: The ID of the user group to be assigned to the cluster.
    :param SecurityGroupIds: List of security groups to be assigned. If not defined, default will be used
    :param CacheSubnetGroupName: subnet group where the cluster will be placed. If not defined, default will be used.
    :return: dictionary with the API results

    """
    if not ReplicationGroupId:
        return {'Error': 'ReplicationGroupId parameter is required'}
    elif not isinstance(UserGroupIds,(list)):
        return {'Error': 'UserGroupIds parameter is required and must be a list'}

    params={'AutomaticFailoverEnabled': True, 
            'CacheNodeType': CacheNodeType, 
            'Engine': 'valkey', 
            'EngineVersion': EngineVersion, 
            'NumCacheClusters': NumCacheClusters, 
            'ReplicationGroupDescription': ReplicationGroupDescription, 
            'ReplicationGroupId': ReplicationGroupId, 
            'SnapshotRetentionLimit': 30, 
            'TransitEncryptionEnabled': True, 
            'UserGroupIds':UserGroupIds
        }

    # defaults will be used if CacheSubnetGroupName or SecurityGroups are not explicit.
    if isinstance(SecurityGroupIds,(list)):
        params.update({'SecurityGroupIds':SecurityGroupIds})
    if CacheSubnetGroupName:
        params.update({'CacheSubnetGroupName':CacheSubnetGroupName})

    response = client.create_replication_group(**params)
    return response

if __name__ == '__main__':

    # Creates an ElastiCache Cluster mode disabled cluster, based on cache.m6g.large nodes, Valkey 8.0, one primary and two replicas.
    # Assigns the existent user group "mygroup" for RBAC authentication
   
    response=create_cluster_mode_disabled_rbac(
        CacheNodeType='cache.m6g.large',
        EngineVersion='8.0',
        NumCacheClusters=3,
        ReplicationGroupDescription='Valkey cluster mode disabled with replicas',
        ReplicationGroupId='valkey202104',
        UserGroupIds=[
            'mygroup'
        ],
        SecurityGroupIds=[
            'sg-7cc73803'
        ],
        CacheSubnetGroupName='default'
    )

    logging.info(response)
```

Per eseguire il programma, immetti il comando seguente:

 `python ClusterModeDisabledWithRBAC.py`

Per ulteriori informazioni, consulta [Gestione dei cluster in ElastiCache](Clusters.md).

### Creare un cluster in modalità cluster abilitata
<a name="ElastiCache-Getting-Started-Tutorials-Cluster-Enabled"></a>

Copiare il seguente programma e incollarlo in un file denominato *ClusterModeEnabled.py.*

```
import boto3
import logging

logging.basicConfig(level=logging.INFO)
client = boto3.client('elasticache')

def create_cluster_mode_enabled(CacheNodeType='cache.t3.small',EngineVersion='6.0',NumNodeGroups=1,ReplicasPerNodeGroup=1, ReplicationGroupDescription='Sample cache with cluster mode enabled',ReplicationGroupId=None):
    """Creates an ElastiCache Cluster with cluster mode enabled

    Returns a dictionary with the API response

    :param CacheNodeType: Node type used on the cluster. If not specified, cache.t3.small will be used
    Refer to https://docs.aws.amazon.com/AmazonElastiCache/latest/dg/CacheNodes.SupportedTypes.html for supported node types
    :param EngineVersion: Engine version to be used. If not specified, latest will be used.
    :param NumNodeGroups: Number of shards in the cluster. Minimum 1 and maximun 90.
    If not specified, cluster will be created with 1 shard.
    :param ReplicasPerNodeGroup: Number of replicas per shard. If not specified 1 replica per shard will be created.
    :param ReplicationGroupDescription: Description for the cluster.
    :param ReplicationGroupId: Name for the cluster
    :return: dictionary with the API results

    """
    if not ReplicationGroupId:
        return 'ReplicationGroupId parameter is required'
    
    response = client.create_replication_group(
        AutomaticFailoverEnabled=True,
        CacheNodeType=CacheNodeType,
        Engine='valkey',
        EngineVersion=EngineVersion,
        ReplicationGroupDescription=ReplicationGroupDescription,
        ReplicationGroupId=ReplicationGroupId,
    #   Creates a cluster mode enabled cluster with 1 shard(NumNodeGroups), 1 primary node (implicit) and 2 replicas (replicasPerNodeGroup)
        NumNodeGroups=NumNodeGroups,
        ReplicasPerNodeGroup=ReplicasPerNodeGroup,
        CacheParameterGroupName='default.valkey7.2.cluster.on'
    )

    return response


# Creates a cluster mode enabled 
response = create_cluster_mode_enabled(
    CacheNodeType='cache.m6g.large',
    EngineVersion='6.0',
    ReplicationGroupDescription='Valkey cluster mode enabled with replicas',
    ReplicationGroupId='valkey20210',
#   Creates a cluster mode enabled cluster with 1 shard(NumNodeGroups), 1 primary (implicit) and 2 replicas (replicasPerNodeGroup)
    NumNodeGroups=2,
    ReplicasPerNodeGroup=1,
)

logging.info(response)
```

Per eseguire il programma, immetti il comando seguente:

 `python ClusterModeEnabled.py`

Per ulteriori informazioni, consulta [Gestione dei cluster in ElastiCache](Clusters.md).

### Creare un cluster in modalità cluster abilitata con TLS e RBAC
<a name="ElastiCache-Getting-Started-Tutorials-Cluster-RBAC"></a>

Per garantire la sicurezza, è possibile utilizzare Transport Layer Security (TLS) e Controllo di accesso basato sul ruolo (RBAC) durante la creazione di un cluster in modalità cluster abilitata. A differenza di Valkey o Redis OSS AUTH, in cui tutti i client autenticati hanno accesso completo al gruppo di replica se il token è autenticato, RBAC consente di controllare l'accesso al cluster tramite gruppi di utenti. Questi gruppi di utenti sono progettati come un modo per organizzare l'accesso ai gruppi di replica. Per ulteriori informazioni, consulta [Controllo accessi basato sui ruoli (RBAC)](Clusters.RBAC.md).

*Copia il seguente programma e incollalo in un file denominato RBAC.py. ClusterModeEnabledWith*

```
import boto3
import logging

logging.basicConfig(level=logging.INFO)
client = boto3.client('elasticache')

def create_cluster_mode_enabled(CacheNodeType='cache.t3.small',EngineVersion='6.0',NumNodeGroups=1,ReplicasPerNodeGroup=1, ReplicationGroupDescription='Sample cache with cluster mode enabled',ReplicationGroupId=None,UserGroupIds=None, SecurityGroupIds=None,CacheSubnetGroupName=None,CacheParameterGroupName='default.valkey7.2.cluster.on'):
    """Creates an ElastiCache Cluster with cluster mode enabled and RBAC

    Returns a dictionary with the API response

    :param CacheNodeType: Node type used on the cluster. If not specified, cache.t3.small will be used
    Refer to https://docs.aws.amazon.com/AmazonElastiCache/latest/dg/CacheNodes.SupportedTypes.html for supported node types
    :param EngineVersion: Engine version to be used. If not specified, latest will be used.
    :param NumNodeGroups: Number of shards in the cluster. Minimum 1 and maximun 90.
    If not specified, cluster will be created with 1 shard.
    :param ReplicasPerNodeGroup: Number of replicas per shard. If not specified 1 replica per shard will be created.
    :param ReplicationGroupDescription: Description for the cluster.
    :param ReplicationGroupId: Name for the cluster.
    :param CacheParameterGroupName: Parameter group to be used. Must be compatible with the engine version and cluster mode enabled.
    :return: dictionary with the API results

    """
    if not ReplicationGroupId:
        return 'ReplicationGroupId parameter is required'
    elif not isinstance(UserGroupIds,(list)):
        return {'Error': 'UserGroupIds parameter is required and must be a list'}

    params={'AutomaticFailoverEnabled': True, 
            'CacheNodeType': CacheNodeType, 
            'Engine': 'valkey', 
            'EngineVersion': EngineVersion, 
            'ReplicationGroupDescription': ReplicationGroupDescription, 
            'ReplicationGroupId': ReplicationGroupId, 
            'SnapshotRetentionLimit': 30, 
            'TransitEncryptionEnabled': True, 
            'UserGroupIds':UserGroupIds,
            'NumNodeGroups': NumNodeGroups,
            'ReplicasPerNodeGroup': ReplicasPerNodeGroup,
            'CacheParameterGroupName': CacheParameterGroupName
        }

    # defaults will be used if CacheSubnetGroupName or SecurityGroups are not explicit.
    if isinstance(SecurityGroupIds,(list)):
        params.update({'SecurityGroupIds':SecurityGroupIds})
    if CacheSubnetGroupName:
        params.update({'CacheSubnetGroupName':CacheSubnetGroupName})

    response = client.create_replication_group(**params)
    return response

if __name__ == '__main__':
    # Creates a cluster mode enabled cluster
    response = create_cluster_mode_enabled(
        CacheNodeType='cache.m6g.large',
        EngineVersion='7.2',
        ReplicationGroupDescription='Valkey cluster mode enabled with replicas',
        ReplicationGroupId='valkey2021',
    #   Creates a cluster mode enabled cluster with 1 shard(NumNodeGroups), 1 primary (implicit) and 2 replicas (replicasPerNodeGroup)
        NumNodeGroups=2,
        ReplicasPerNodeGroup=1,
        UserGroupIds=[
            'mygroup'
        ],
        SecurityGroupIds=[
            'sg-7cc73803'
        ],
        CacheSubnetGroupName='default'

    )
    
    logging.info(response)
```

Per eseguire il programma, immetti il comando seguente:

 `python ClusterModeEnabledWithRBAC.py`

Per ulteriori informazioni, consulta [Gestione dei cluster in ElastiCache](Clusters.md).

### Controlla se users/usergroup esiste, altrimenti creali
<a name="ElastiCache-Getting-Started-Tutorials-Users"></a>

Con RBAC, è possibile creare utenti e assegnare loro autorizzazioni specifiche utilizzando una stringa di accesso. Gli utenti vengono assegnati a gruppi di utenti allineati con un ruolo specifico (amministratori, risorse umane) che vengono quindi distribuiti a uno o più ElastiCache gruppi di replica Redis OSS. In questo modo, è possibile stabilire limiti di sicurezza tra i client che utilizzano lo stesso gruppo o gruppi di replica Valkey o Redis OSS e impedire ai client di accedere ai dati degli altri. Per ulteriori informazioni, consulta [Controllo accessi basato sui ruoli (RBAC)](Clusters.RBAC.md).

*Copia il seguente programma e incollalo in un file denominato .py. UserAndUserGroups* Aggiorna il meccanismo per fornire le credenziali. Le credenziali in questo esempio vengono mostrate come sostituibili e assegnate a un elemento non dichiarato. Evita le credenziali a codifica fissa.

Questo esempio utilizza una stringa di accesso con le autorizzazioni per l'utente. Per ulteriori informazioni sulle stringhe di accesso, vedere. [Specifica delle autorizzazioni mediante una stringa di accesso](Clusters.RBAC.md#Access-string)

```
import boto3
import logging

logging.basicConfig(level=logging.INFO)
client = boto3.client('elasticache')

def check_user_exists(UserId):
    """Checks if UserId exists

    Returns True if UserId exists, otherwise False
    :param UserId: ElastiCache User ID
    :return: True|False
    """
    try:
        response = client.describe_users(
            UserId=UserId,
        )
        if response['Users'][0]['UserId'].lower() == UserId.lower():
            return True
    except Exception as e:
        if e.response['Error']['Code'] == 'UserNotFound':
            logging.info(e.response['Error'])
            return False
        else:
            raise

def check_group_exists(UserGroupId):
    """Checks if UserGroupID exists

    Returns True if Group ID exists, otherwise False
    :param UserGroupId: ElastiCache User ID
    :return: True|False
    """

    try:
        response = client.describe_user_groups(
            UserGroupId=UserGroupId
        )
        if response['UserGroups'][0]['UserGroupId'].lower() == UserGroupId.lower():
            return True
    except Exception as e:
        if e.response['Error']['Code'] == 'UserGroupNotFound':
            logging.info(e.response['Error'])
            return False
        else:
            raise

def create_user(UserId=None,UserName=None,Password=None,AccessString=None):
    """Creates a new user

    Returns the ARN for the newly created user or the error message
    :param UserId: ElastiCache user ID. User IDs must be unique
    :param UserName: ElastiCache user name. ElastiCache allows multiple users with the same name as long as the associated user ID is unique.
    :param Password: Password for user. Must have at least 16 chars.
    :param AccessString: Access string with the permissions for the user. 
    :return: user ARN
    """
    try:
        response = client.create_user(
            UserId=UserId,
            UserName=UserName,
            Engine='Redis',
            Passwords=[Password],
            AccessString=AccessString,
            NoPasswordRequired=False
        )
        return response['ARN']
    except Exception as e:
        logging.info(e.response['Error'])
        return e.response['Error']

def create_group(UserGroupId=None, UserIds=None):
    """Creates a new group.
    A default user is required (mandatory) and should be specified in the UserIds list

    Return: Group ARN
    :param UserIds: List with user IDs to be associated with the new group. A default user is required
    :param UserGroupId: The ID (name) for the group
    :return: Group ARN
    """
    try:
        response = client.create_user_group(
            UserGroupId=UserGroupId,
            Engine='Redis',
            UserIds=UserIds
        )
        return response['ARN']
    except Exception as e:
        logging.info(e.response['Error'])


if __name__ == '__main__':
    
    groupName='mygroup2'
    userName = 'myuser2'
    userId=groupName+'-'+userName

    # Creates a new user if the user ID does not exist.
    for tmpUserId,tmpUserName in [ (userId,userName), (groupName+'-default','default')]:
        if not check_user_exists(tmpUserId):
            response=create_user(UserId=tmpUserId, UserName=EXAMPLE,Password=EXAMPLE,AccessString='on ~* +@all')
            logging.info(response)
        # assigns the new user ID to the user group
    if not check_group_exists(groupName):
        UserIds = [ userId , groupName+'-default']
        response=create_group(UserGroupId=groupName,UserIds=UserIds)
        logging.info(response)
```

Per eseguire il programma, immetti il comando seguente:

 `python UserAndUserGroups.py`

## Tutorial: Connessione a ElastiCache
<a name="ElastiCache-Getting-Started-Tutorials-Connecting"></a>

I seguenti esempi utilizzano il client Valkey o Redis OSS a cui connettersi. ElastiCache

**Topics**
+ [Connessione a un cluster non crittografato in modalità cluster disabilitata](#ElastiCache-Getting-Started-Tutorials-Connecting-cluster-mode-disabled)
+ [Connessione a un cluster abilitato in modalità cluster](#ElastiCache-Getting-Started-Tutorials-Connecting-cluster-mode-enabled)

### Connessione a un cluster non crittografato in modalità cluster disabilitata
<a name="ElastiCache-Getting-Started-Tutorials-Connecting-cluster-mode-disabled"></a>

Copia il seguente programma e incollalo in un file denominato *ConnectClusterModeDisabled.py.* Aggiorna il meccanismo per fornire le credenziali. Le credenziali in questo esempio vengono mostrate come sostituibili e assegnate a un elemento non dichiarato. Evita le credenziali a codifica fissa.

```
from redis import Redis
import logging

logging.basicConfig(level=logging.INFO)
redis = Redis(host='primary.xxx.yyyyyy.zzz1.cache.amazonaws.com', port=6379, decode_responses=True, ssl=True, username=example, password=EXAMPLE)

if redis.ping():
    logging.info("Connected to Redis")
```

Per eseguire il programma, immetti il comando seguente:

 `python ConnectClusterModeDisabled.py`

### Connessione a un cluster abilitato in modalità cluster
<a name="ElastiCache-Getting-Started-Tutorials-Connecting-cluster-mode-enabled"></a>

Copiare il seguente programma e incollarlo in un file denominato *ConnectClusterModeEnabled.py.*

```
from rediscluster import RedisCluster
import logging

logging.basicConfig(level=logging.INFO)
redis = RedisCluster(startup_nodes=[{"host": "xxx.yyy.clustercfg.zzz1.cache.amazonaws.com","port": "6379"}], decode_responses=True,skip_full_coverage_check=True)

if redis.ping():
    logging.info("Connected to Redis")
```

Per eseguire il programma, immetti il comando seguente:

 `python ConnectClusterModeEnabled.py`

## Esempi di utilizzo
<a name="ElastiCache-Getting-Started-Tutorials-Usage"></a>

I seguenti esempi utilizzano l'SDK boto3 per ElastiCache lavorare con ElastiCache Redis OSS.

**Topics**
+ [Imposta e ottieni stringhe](#ElastiCache-Getting-Started-Tutorials-set-strings)
+ [Imposta e ottieni un hash con più elementi](#ElastiCache-Getting-Started-Tutorials-set-hash)
+ [Pubblica (scrivi) e iscriviti (leggi) da un canale Pub/Sub](#ElastiCache-Getting-Started-Tutorials-pub-sub)
+ [Scrivere e leggere da un flusso](#ElastiCache-Getting-Started-Tutorials-read-write-stream)

### Imposta e ottieni stringhe
<a name="ElastiCache-Getting-Started-Tutorials-set-strings"></a>

*Copia il seguente programma e incollalo in un file denominato .py. SetAndGetStrings*

```
import time
import logging
logging.basicConfig(level=logging.INFO,format='%(asctime)s: %(message)s')

keyName='mykey'
currTime=time.ctime(time.time())

# Set the key 'mykey' with the current date and time as value. 
# The Key will expire and removed from cache in 60 seconds.
redis.set(keyName, currTime, ex=60)

# Sleep just for better illustration of TTL (expiration) value
time.sleep(5)

# Retrieve the key value and current TTL
keyValue=redis.get(keyName)
keyTTL=redis.ttl(keyName)

logging.info("Key {} was set at {} and has {} seconds until expired".format(keyName, keyValue, keyTTL))
```

Per eseguire il programma, immetti il comando seguente:

 `python SetAndGetStrings.py`

### Imposta e ottieni un hash con più elementi
<a name="ElastiCache-Getting-Started-Tutorials-set-hash"></a>

Copia il seguente programma e incollalo in un file denominato *SetAndGetHash.py.*

```
import logging
import time

logging.basicConfig(level=logging.INFO,format='%(asctime)s: %(message)s')

keyName='mykey'
keyValues={'datetime': time.ctime(time.time()), 'epochtime': time.time()}

# Set the hash 'mykey' with the current date and time in human readable format (datetime field) and epoch number (epochtime field). 
redis.hset(keyName, mapping=keyValues)

# Set the key to expire and removed from cache in 60 seconds.
redis.expire(keyName, 60)

# Sleep just for better illustration of TTL (expiration) value
time.sleep(5)

# Retrieves all the fields and current TTL
keyValues=redis.hgetall(keyName)
keyTTL=redis.ttl(keyName)

logging.info("Key {} was set at {} and has {} seconds until expired".format(keyName, keyValues, keyTTL))
```

Per eseguire il programma, immetti il comando seguente:

 `python SetAndGetHash.py`

### Pubblica (scrivi) e iscriviti (leggi) da un canale Pub/Sub
<a name="ElastiCache-Getting-Started-Tutorials-pub-sub"></a>

Copia il seguente programma e incollalo in un file chiamato *PubAndSub.py.*

```
import logging
import time

def handlerFunction(message):
    """Prints message got from PubSub channel to the log output

    Return None
    :param message: message to log
    """
    logging.info(message)

logging.basicConfig(level=logging.INFO)
redis = Redis(host="redis202104053.tihewd.ng.0001.use1.cache.amazonaws.com", port=6379, decode_responses=True)


# Creates the subscriber connection on "mychannel"
subscriber = redis.pubsub()
subscriber.subscribe(**{'mychannel': handlerFunction})

# Creates a new thread to watch for messages while the main process continues with its routines
thread = subscriber.run_in_thread(sleep_time=0.01)

# Creates publisher connection on "mychannel"
redis.publish('mychannel', 'My message')

# Publishes several messages. Subscriber thread will read and print on log.
while True:
    redis.publish('mychannel',time.ctime(time.time()))
    time.sleep(1)
```

Per eseguire il programma, immetti il comando seguente:

 `python PubAndSub.py`

### Scrivere e leggere da un flusso
<a name="ElastiCache-Getting-Started-Tutorials-read-write-stream"></a>

Copia il seguente programma e incollalo in un file denominato *ReadWriteStream.py.*

```
from redis import Redis
import redis.exceptions as exceptions
import logging
import time
import threading

logging.basicConfig(level=logging.INFO)

def writeMessage(streamName):
    """Starts a loop writting the current time and thread name to 'streamName'

    :param streamName: Stream (key) name to write messages.
    """
    fieldsDict={'writerId':threading.currentThread().getName(),'myvalue':None}
    while True:
        fieldsDict['myvalue'] = time.ctime(time.time())
        redis.xadd(streamName,fieldsDict)
        time.sleep(1)

def readMessage(groupName=None,streamName=None):
    """Starts a loop reading from 'streamName'
    Multiple threads will read from the same stream consumer group. Consumer group is used to coordinate data distribution.
    Once a thread acknowleges the message, it won't be provided again. If message wasn't acknowledged, it can be served to another thread.

    :param groupName: stream group were multiple threads will read.
    :param streamName: Stream (key) name where messages will be read.
    """

    readerID=threading.currentThread().getName()
    while True:
        try:
            # Check if the stream has any message
            if redis.xlen(streamName)>0:
                # Check if if the messages are new (not acknowledged) or not (already processed)
                streamData=redis.xreadgroup(groupName,readerID,{streamName:'>'},count=1)
                if len(streamData) > 0:
                    msgId,message = streamData[0][1][0]
                    logging.info("{}: Got {} from ID {}".format(readerID,message,msgId))
                    #Do some processing here. If the message has been processed sucessfuly, acknowledge it and (optional) delete the message.
                    redis.xack(streamName,groupName,msgId)
                    logging.info("Stream message ID {} read and processed successfuly by {}".format(msgId,readerID))
                    redis.xdel(streamName,msgId)
            else:
                pass
        except:
            raise
            
        time.sleep(0.5)

# Creates the stream 'mystream' and consumer group 'myworkergroup' where multiple threads will write/read.
try:
    redis.xgroup_create('mystream','myworkergroup',mkstream=True)
except exceptions.ResponseError as e:
    logging.info("Consumer group already exists. Will continue despite the error: {}".format(e))
except:
    raise

# Starts 5 writer threads.
for writer_no in range(5):
    writerThread = threading.Thread(target=writeMessage, name='writer-'+str(writer_no), args=('mystream',),daemon=True)
    writerThread.start()

# Starts 10 reader threads
for reader_no in range(10):
    readerThread = threading.Thread(target=readMessage, name='reader-'+str(reader_no), args=('myworkergroup','mystream',),daemon=True)
    readerThread.daemon = True
    readerThread.start()

# Keep the code running for 30 seconds
time.sleep(30)
```

Per eseguire il programma, immetti il comando seguente:

 `python ReadWriteStream.py`