<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rafael Rotiroti</title>
    <description>The latest articles on DEV Community by Rafael Rotiroti (@rotirotirafa).</description>
    <link>https://dev.to/rotirotirafa</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F403211%2Fb3651527-596a-476e-9b9a-5a9410cfae55.JPG</url>
      <title>DEV Community: Rafael Rotiroti</title>
      <link>https://dev.to/rotirotirafa</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rotirotirafa"/>
    <language>en</language>
    <item>
      <title>Como Limitar e Proteger suas APIs com Rate Limit?</title>
      <dc:creator>Rafael Rotiroti</dc:creator>
      <pubDate>Mon, 31 Mar 2025 16:31:17 +0000</pubDate>
      <link>https://dev.to/rotirotirafa/como-limitar-e-proteger-suas-apis-com-rate-limit-2n5p</link>
      <guid>https://dev.to/rotirotirafa/como-limitar-e-proteger-suas-apis-com-rate-limit-2n5p</guid>
      <description>&lt;p&gt;As APIs são a espinha dorsal das aplicações modernas, permitindo a comunicação eficiente entre clientes e servidores. No entanto, uma API sem proteção contra requisições excessivas pode ser vítimas de ataques, levando à degradação do desempenho, aumento dos custos de infraestrutura ou até mesmo à indisponibilidade do serviço.&lt;/p&gt;

&lt;h2&gt;
  
  
  Por que o Rate Limiting é importante?
&lt;/h2&gt;

&lt;p&gt;O Rate Limiting é um mecanismo essencial para garantir a estabilidade, segurança e uso justo de uma API. Ele ajuda a:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prevenir abusos – Usuários mal-intencionados ou bots podem sobrecarregar uma API com requisições, tentando explorar vulnerabilidades ou derrubar o serviço.&lt;/li&gt;
&lt;li&gt;Reduzir custos de infraestrutura – Um tráfego descontrolado pode aumentar os custos com servidores e impactar a escalabilidade da aplicação.&lt;/li&gt;
&lt;li&gt;Garantir uso justo – As limitações evitam que um único cliente monopolize os recursos da API, distribuindo melhor a carga.&lt;/li&gt;
&lt;li&gt;Mitigar ataques DDoS – Ao restringir o número de requisições por usuário ou IP, a API fica mais resistente a ataques de negação de serviço.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Onde o Rate Limiting é utilizado?
&lt;/h2&gt;

&lt;p&gt;O Rate Limiting é amplamente aplicado em diversos setores, como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Redes Sociais – Para evitar spam e abuso de bots (exemplo: o Twitter limita a quantidade de tweets postados por hora).&lt;/li&gt;
&lt;li&gt;E-commerce – Para impedir que robôs sobrecarreguem páginas de produtos ou ferramentas de rastreamento de preços.&lt;/li&gt;
&lt;li&gt;Serviços Financeiros – Para proteger APIs bancárias contra transações automatizadas excessivas.&lt;/li&gt;
&lt;li&gt;Aplicações SaaS – Para diferenciar planos gratuitos e pagos, limitando o número de requisições por usuário.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Hands on!
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Implementando Rate Limiting no FastAPI com Redis
&lt;/h2&gt;

&lt;p&gt;Uma abordagem comum para implementar rate limiting é utilizar o Redis como um armazenamento em memória para rastrear requisições por usuário, token ou IP. O FastAPI permite a fácil integração de middlewares para aplicar essas restrições de forma eficiente. A ideia é interceptar a request antes que ela passe para sua funcionalidade principal, o Middleware vai verificar se há espaço para uma nova requisição, se tiver ela permite seguir, se não retorna imediatamente um Status Code 429 "Too Many Requests". &lt;/p&gt;

&lt;h3&gt;
  
  
  Supondo que já possua o FastApi up &amp;amp; running:
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;pip install redis&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Vamos criar a classe RateLimiter:
&lt;/h3&gt;

&lt;p&gt;Nesse caso optei por colocar um limite de 10 requests a cada 1 minuto. No final mostrarei os resultados...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class RateLimiter:
    """
    Rate Limiter para APIs.
    Limita o número de requisições por usuário em um determinado intervalo de tempo
    redis_client: Cliente Redis para armazenar os dados de rate limiting
    max_requests: Número máximo de requisições permitidas
    window: Intervalo de tempo em segundos
    """

    def __init__(self, redis_client, max_requests=10, window=60):
        self.redis = redis_client
        self.max_requests = max_requests
        self.window = window

    def allow_request(self, user_id) -&amp;gt; bool:
        """Verifica se a requisição pode ser processada dentro do limite."""
        now = time.time()
        key = f"rate_limit:{user_id}"

        pipe = self.redis.pipeline()
        pipe.zadd(key, {now: now})
        pipe.zremrangebyscore(key, 0, now - self.window)
        pipe.zcard(key)
        pipe.expire(key, self.window * 2)

        _, _, request_count, _ = pipe.execute()

        result = request_count &amp;lt;= self.max_requests

        return result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configurando a aplicação (normalmente no seu main.py ou app.py):
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;redis_client = redis.Redis(host='redis', port=6379, db=0)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Criando o Middleware
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@app.middleware("http")
async def rate_limit_middleware(request: Request, call_next):
    """Middleware de rate limiting para todas as rotas"""
    user_id = request.headers.get('X-User-ID', 'anonymous')

    if not limiter.allow_request(user_id):
        return JSONResponse(
            status_code=429,
            content={"message": "Limite de requisições excedido"}
        )

    response = await call_next(request)
    return response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para testar, basta configurar o Insomnia, Postman ou qualquer ferramenta que possa simular cargas!&lt;/p&gt;

&lt;p&gt;No nosso caso aqui, utilizei o Insomnia! Segue as evidências:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhb9lwrkpfrzv2dq8b06p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhb9lwrkpfrzv2dq8b06p.png" alt="Evidência Too Many Requests" width="800" height="609"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O código fonte está no seguinte &lt;a href="https://github.com/rotirotirafa/rate_limiter" rel="noopener noreferrer"&gt;repo&lt;/a&gt;. Podem utilizar para estudos e afins! Há um uso do Locust como teste de carga dentro da pasta &lt;code&gt;load_test/&lt;/code&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusão
&lt;/h1&gt;

&lt;p&gt;O Rate Limiting é uma estratégia fundamental para proteger APIs e garantir um uso equilibrado e manter a performance. Integrando Redis com FastAPI, os desenvolvedores podem aplicar essas restrições de forma eficiente, tornando suas APIs mais robustas e escaláveis.&lt;/p&gt;

&lt;p&gt;Links úteis e inspirações:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://redis.io/glossary/rate-limiting/" rel="noopener noreferrer"&gt;https://redis.io/glossary/rate-limiting/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@m-elbably/rate-limiting-a-dynamic-distributed-rate-limiting-with-redis-339f9504200f" rel="noopener noreferrer"&gt;https://medium.com/@m-elbably/rate-limiting-a-dynamic-distributed-rate-limiting-with-redis-339f9504200f&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=YV4ePyW3DO8" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=YV4ePyW3DO8&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>fastapi</category>
      <category>redis</category>
      <category>microservices</category>
    </item>
    <item>
      <title>Simple and Functional PHP Environment Setup with Windows</title>
      <dc:creator>Rafael Rotiroti</dc:creator>
      <pubDate>Thu, 20 Feb 2025 12:07:58 +0000</pubDate>
      <link>https://dev.to/rotirotirafa/simple-and-functional-php-environment-setup-with-windows-4a10</link>
      <guid>https://dev.to/rotirotirafa/simple-and-functional-php-environment-setup-with-windows-4a10</guid>
      <description>&lt;p&gt;PHP was my first programming language that i worked, but in the past 8 years i've been working with another technologies such as Python, Java, Javascript. I never forgot PHP because this language helped me bills paid.&lt;/p&gt;

&lt;p&gt;In the past, most of the time i used XAMPP, MAMP or any {x}AMP stack to setup my environment... so after i worked with many other languages and learned how to setup many kind of environments i thought how do that in PHP in the right way (at least for me).&lt;/p&gt;

&lt;h2&gt;
  
  
  So let's get started.
&lt;/h2&gt;

&lt;p&gt;My proposal is use PHP, Composer and MySQL as database.&lt;/p&gt;

&lt;p&gt;Lets go to &lt;a href="https://windows.php.net/download/" rel="noopener noreferrer"&gt;PHP website and download&lt;/a&gt; any top version as Non Thread Safe zip.&lt;/p&gt;

&lt;p&gt;Extract to your root &lt;code&gt;C:/&lt;/code&gt; in path &lt;code&gt;php&lt;/code&gt; so everything should be inside &lt;code&gt;C:/php&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;Now download &lt;a href="https://getcomposer.org/download/" rel="noopener noreferrer"&gt;Composer&lt;/a&gt;, run your Composer-Setup.exe and probably he will identify your PHP in your Root C:/ folder.&lt;/p&gt;

&lt;p&gt;Finishing Composer Setup and Running Laravel with Docker Compose&lt;/p&gt;

&lt;p&gt;After installing Composer, open your terminal and verify the installation by running:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;composer --version&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you see the version number, Composer is ready. Cause not, try do restart your Windows.&lt;/p&gt;

&lt;p&gt;Now let's set up a Laravel project&lt;/p&gt;

&lt;p&gt;Open your terminal and run the following command to create a new Laravel application:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;composer create-project --prefer-dist laravel/laravel my-laravel-app&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Navigate to the project folder:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cd my-laravel-app&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Install Laravel dependencies:&lt;br&gt;
&lt;code&gt;composer install&lt;/code&gt; or &lt;code&gt;composer i&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Copy the .env.example to .env:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cp .env.example .env&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Generate the application key:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;php artisan key:generate&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We should need a Database.. lets configure an Docker Compose for MySQL and phpMyAdmin for managing it&lt;/p&gt;

&lt;p&gt;Inside your Laravel root directory, create a docker-compose.yml file and paste the following configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: '3.8'
services:
  db:
    image: mysql/mysql-server:latest
    container_name: mysql-db-container
    restart: always
    environment:
      - MYSQL_DATABASE=database
      - MYSQL_USER=admin
      - MYSQL_PASSWORD=password
      - MYSQL_ROOT_PASSWORD=password
    ports:
      - '3306:3306'
    volumes:
      - mysql-volume:/var/lib/mysql
    command: --sql_require_primary_key=0
    networks:
      - mysql-phpmyadmin

  phpmyadmin:
    depends_on:
      - db
    image: phpmyadmin
    restart: always
    ports:
      - "8090:80"
    environment:
      - PMA_HOST=db
      - MYSQL_USER=admin
      - MYSQL_ROOT_PASSWORD=password
    networks:
      - mysql-phpmyadmin

networks:
  mysql-phpmyadmin:

volumes:
  mysql-volume:
    driver: local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update Laravel's .env to connect to MySQL&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=database
DB_USERNAME=admin
DB_PASSWORD=password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Starting Docker Containers
&lt;/h2&gt;

&lt;p&gt;Run the following command to start MySQL and phpMyAdmin:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker compose up -d&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Access phpMyAdmin at &lt;a href="http://localhost:8090" rel="noopener noreferrer"&gt;http://localhost:8090&lt;/a&gt;. You can use the username and password given at docker-compose.yml&lt;/p&gt;

&lt;p&gt;Now, you can start Laravel's local development server by running:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;php artisan serve&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Access your Laravel application at &lt;a href="http://127.0.0.1:8000" rel="noopener noreferrer"&gt;http://127.0.0.1:8000&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And that’s it! You've successfully set up a PHP environment with an Laravel project with MySQL using Docker Compose. Happy coding!&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>php</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Rodando Modelos LLM Localmente com Ollama</title>
      <dc:creator>Rafael Rotiroti</dc:creator>
      <pubDate>Wed, 29 Jan 2025 13:23:32 +0000</pubDate>
      <link>https://dev.to/rotirotirafa/rodando-modelos-llm-localmente-com-ollama-273d</link>
      <guid>https://dev.to/rotirotirafa/rodando-modelos-llm-localmente-com-ollama-273d</guid>
      <description>&lt;p&gt;A IA tem dominado os palcos nos últimos anos e, cada vez mais, tem ganhado espaço com empresas, profissionais, estudantes... na verdade, em quase tudo.&lt;/p&gt;

&lt;p&gt;Desde então, a IA Generativa tem sido assunto em todos os lugares. Ao utilizarmos &lt;a href="https://chatgpt.com/" rel="noopener noreferrer"&gt;ChatGPT&lt;/a&gt;, &lt;a href="https://gemini.google.com" rel="noopener noreferrer"&gt;Gemini&lt;/a&gt; e &lt;a href="https://www.deepseek.com/" rel="noopener noreferrer"&gt;DeepSeek&lt;/a&gt;, estamos usufruindo de LLMs. Um LLM (Large Language Model), que em português significa Modelo de Linguagem em Larga Escala, é um tipo de IA Generativa treinada com um volume imenso de dados. Para entender e se aprofundar mais sobre as diferenças entre alguns tipos de IA, este excelente artigo do &lt;a href="https://medium.com/@hugojose1602/a-diferen%C3%A7a-entre-ia-generativa-llms-e-machine-learning-f6a068cba7fa" rel="noopener noreferrer"&gt;Hugo Cardoso&lt;/a&gt; pode ajudar.&lt;/p&gt;

&lt;p&gt;Quem utiliza no dia a dia as versões gratuitas do ChatGPT ou Gemini sabe que, em determinado momento, é necessário esperar algumas horas, trocar de modelo (ex: GPT-4o, mini) ou assinar o "premium". Isso acontece porque, obviamente, nem tudo é de graça (faz parte do modelo de negócio) mas também porque a execução desses modelos é custosa. O processo exige alto consumo de hardware e tráfego de rede para atender à demanda, principalmente em larga escala, como estamos vendo no mundo inteiro.&lt;/p&gt;

&lt;p&gt;Uma solução para utilizar modelos atualizados e com muitos parâmetros é rodá-los localmente. Além de reduzir custos (evitando pagar por uma versão premium), essa abordagem pode oferecer mais desempenho (dependendo do seu hardware) e, com certeza, mais privacidade. E é isso que vamos aprender a fazer a seguir.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Instalando o Ollama&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Para rodarmos LLMs localmente, precisamos de uma ferramenta que as execute. Neste caso, vamos usar o Ollama. Basicamente, o Ollama funciona como um gerenciador e runtime de modelos LLM.&lt;/p&gt;

&lt;p&gt;No meu caso, estou usando Linux, então a instalação pode ser feita com:&lt;/p&gt;

&lt;p&gt;No meu caso estou usando Linux entao:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -fsSL https://ollama.com/install.sh | sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;1.1 Configurando o Ollama&lt;/p&gt;

&lt;p&gt;Para rodarmos LLMs localmente, precisamos de uma ferramenta que as execute. Neste caso, vamos usar o Ollama. Basicamente, o Ollama funciona como um gerenciador e runtime de modelos LLM.&lt;/p&gt;

&lt;p&gt;No meu caso, estou usando Linux, então a instalação pode ser feita com:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ollama pull deepseek-r1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ou se escolher outro modelo..&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ollama pull [nome-modelo]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste caso, optei pelo modelo DeepSeek, a febre do momento. Mas você pode encontrar todos os modelos disponíveis aqui: &lt;a href="https://ollama.com/library." rel="noopener noreferrer"&gt;Ollama LIbrary&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aguarde o download finalizar e o modelo estará pronto para uso.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Utilizando o Ollama&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Temos algumas opções para rodar os modelos localmente. Podemos fazer isso de três formas, e vou ser direto em cada uma delas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rodar via CLI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs34669ai19c314s259u8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs34669ai19c314s259u8.gif" alt="Exemplo Ollama com CLI" width="854" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Conectar via Software (ex: LM Studio)&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0wok7hllpbkub5qk1kcy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0wok7hllpbkub5qk1kcy.png" alt="Print LM Studio" width="800" height="269"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Usar via REST API&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftnbfxgb9qhgrcryk31ml.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftnbfxgb9qhgrcryk31ml.png" alt="POST Insomnia" width="721" height="476"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Possibilidades, prós e contras.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Rodar um modelo LLM localmente abre um leque de possibilidades para desenvolvedores, pesquisadores e empresas. Dependendo do hardware disponível, é possível consumir modelos mais completos a um custo reduzido, treinar modelos personalizados e até integrá-los em aplicativos e serviços profissionais. No entanto, essa abordagem também traz desafios que precisam ser considerados.&lt;/p&gt;

&lt;p&gt;✅ O que eu gostei&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Baixo custo: Sem taxas recorrentes de nuvem, basta ter o hardware certo.&lt;/li&gt;
&lt;li&gt;Modelos mais robustos: Acesso a LLMs avançados sem restrições de provedores.&lt;/li&gt;
&lt;li&gt;Privacidade: Os dados ficam locais, garantindo maior segurança.&lt;/li&gt;
&lt;li&gt;Personalização: Possibilidade de fine-tuning para necessidades específicas.&lt;/li&gt;
&lt;li&gt;Aplicações comerciais: Uso offline em apps, chatbots e automação.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;⚠️ O que eu percebi&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Alto consumo de recursos: Requer GPUs potentes e muita RAM.&lt;/li&gt;
&lt;li&gt;Configuração complexa: Instalação e otimização podem ser trabalhosas.&lt;/li&gt;
&lt;li&gt;Manutenção constante: Atualizações e melhorias precisam ser feitas manualmente.&lt;/li&gt;
&lt;li&gt;Treinamento exige investimento: Fine-tuning pode demandar hardware caro.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Rodar LLMs localmente pode ser uma solução econômica e eficiente, mas exige planejamento e infraestrutura adequada. 🚀&lt;/p&gt;

</description>
      <category>deepseek</category>
      <category>ai</category>
      <category>python</category>
      <category>openai</category>
    </item>
    <item>
      <title>Utilizando Dotenv para Gerenciamento de Variáveis de Ambiente e Alembic</title>
      <dc:creator>Rafael Rotiroti</dc:creator>
      <pubDate>Thu, 21 Dec 2023 17:56:06 +0000</pubDate>
      <link>https://dev.to/rotirotirafa/utilizando-dotenv-para-gerenciamento-de-variaveis-de-ambiente-e-alembic-ji8</link>
      <guid>https://dev.to/rotirotirafa/utilizando-dotenv-para-gerenciamento-de-variaveis-de-ambiente-e-alembic-ji8</guid>
      <description>&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;Em meus projetos, especialmente ao trabalhar em ambientes de desenvolvimento local, utilizo variáveis de ambiente como uma estratégia eficaz para separar configurações sensíveis, como chaves de API e credenciais de banco de dados. Neste artigo, aprofundaremos no conceito de Dotenv, destacando seus benefícios e explorando como posso integrá-lo ao Alembic, por exemplo, para facilitar o gerenciamento de migrações de banco de dados. Aqui também falarei sobre vantagens e algumas desvantagens ao usá-lo.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é Dotenv?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://pypi.org/project/python-dotenv/" rel="noopener noreferrer"&gt;Dotenv &lt;/a&gt;é uma biblioteca popular em várias linguagens de programação, incluindo Python, que permite carregar variáveis de ambiente de um arquivo &lt;code&gt;.env&lt;/code&gt; para o ambiente em que minha aplicação está sendo executada. Em vez de definir variáveis de ambiente diretamente no sistema operacional ou em um serviço de hospedagem, posso armazená-las em um arquivo &lt;code&gt;.env&lt;/code&gt; na raiz do meu projeto.&lt;/p&gt;

&lt;h1&gt;
  
  
  Vantagens ao usar &lt;code&gt;.env&lt;/code&gt;
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Isolamento e Segurança
&lt;/h3&gt;

&lt;p&gt;Ao usar um arquivo &lt;code&gt;.env&lt;/code&gt;, você mantém suas variáveis de ambiente em um local isolado, separado do código-fonte. Isso ajuda a garantir que informações sensíveis, como chaves de API e credenciais, não sejam expostas inadvertidamente.&lt;/p&gt;

&lt;h3&gt;
  
  
  Portabilidade
&lt;/h3&gt;

&lt;p&gt;Com o &lt;a href="https://pypi.org/project/python-dotenv/" rel="noopener noreferrer"&gt;Dotenv&lt;/a&gt;, é fácil mover seu projeto entre diferentes ambientes (dev, homol, prod) sem modificar as variáveis de ambiente. Basta ter um arquivo &lt;code&gt;.env&lt;/code&gt; correspondente para cada ambiente.&lt;/p&gt;

&lt;h3&gt;
  
  
  Facilidade de Configuração
&lt;/h3&gt;

&lt;p&gt;Gerenciar variáveis de ambiente através de um arquivo &lt;code&gt;.env&lt;/code&gt;simplifica a configuração e inicialização de seu projeto, especialmente quando você não está trabalhando sozinho.&lt;/p&gt;

&lt;h1&gt;
  
  
  Hands On!
&lt;/h1&gt;

&lt;p&gt;Caso queira ver o projeto, eu subi o &lt;a href="https://github.com/rotirotirafa/dotenv_use" rel="noopener noreferrer"&gt;repo no github&lt;/a&gt; :).&lt;/p&gt;

&lt;h1&gt;
  
  
  Configure o ambiente
&lt;/h1&gt;

&lt;p&gt;Com seu &lt;code&gt;venv&lt;/code&gt; criado instale o &lt;code&gt;python-dotenv&lt;/code&gt;, no exemplo vamos utilizar o &lt;code&gt;alembic&lt;/code&gt;, então:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pip install alembic python-dotenv&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Crie o seu arquivo &lt;code&gt;.env&lt;/code&gt; e insira a variavel de ambiente da seguinte forma:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;DATABASE_URL=postgresql://db_username:db_pw@localhost/db_name&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Observe que o DATABASE_URL está em CAPS e o valor após o &lt;code&gt;=&lt;/code&gt; está fora de aspas duplas (ou simples).&lt;/p&gt;

&lt;p&gt;OBS: no &lt;a href="https://github.com/rotirotirafa/dotenv_use" rel="noopener noreferrer"&gt;repositorio&lt;/a&gt; tem um exemplo subindo o postgres com o docker.&lt;/p&gt;

&lt;h1&gt;
  
  
  Configurando o Alembic
&lt;/h1&gt;

&lt;p&gt;Para iniciar o alembic rode o comando: &lt;code&gt;alembic init alembic&lt;/code&gt; (modulo -- comando -- pasta destino)&lt;/p&gt;

&lt;p&gt;Na raiz do projeto será criado uma pasta chamada &lt;code&gt;alembic&lt;/code&gt; e dentro dela tem um arquivo &lt;code&gt;Env.py&lt;/code&gt; que vamos edita-lo para usar o &lt;code&gt;python-dotenv&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl8we7yem40qq59i848w3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl8we7yem40qq59i848w3.png" alt="Env.py" width="652" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A função &lt;code&gt;load_dotenv()&lt;/code&gt; faz com que ela enxergue o arquivo &lt;code&gt;.env&lt;/code&gt; na raiz do seu projeto, carregando todas as variáveis que você criar para dentro do seu projeto.&lt;/p&gt;

&lt;p&gt;Para utilizar, basta chamar a sua variável da seguinte forma: &lt;code&gt;os.getenv("NOME_VAR")&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Voltando para configuração do Alembic, para que ele consiga enxergar a variável de conexão com o banco de dados basta ajudar o código da função &lt;code&gt;run_migrations_online&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fobb1q9f1vrsv0xdedjv9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fobb1q9f1vrsv0xdedjv9.png" alt="run_migrations_online" width="757" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OBS: Veja que na imagem há o &lt;code&gt;config&lt;/code&gt;, ele puxa a configuração do arquivo &lt;code&gt;alembic.ini&lt;/code&gt; da raiz, caso não utilize &lt;code&gt;.env&lt;/code&gt;, por padrão é necessário alterar lá. Essa é uma das vantagens de se usar o &lt;code&gt;python-dotenv&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Agora basta rodar a migration:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnbude2g0bsjs6ul3yaz2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnbude2g0bsjs6ul3yaz2.png" alt="Image description" width="800" height="98"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Utilizando o Dotenv, tenho uma maneira conveniente e segura de gerenciar variáveis de ambiente em meus projetos Python. Ao combinar essa prática com ferramentas como Alembic, posso manter um gerenciamento eficiente de configurações sensíveis e simplificar a migração de banco de dados em multiplos ambientes. &lt;/p&gt;

&lt;h2&gt;
  
  
  Mas nem tudo são flores...
&lt;/h2&gt;

&lt;p&gt;Há desvantagens em usar Dotenv.&lt;/p&gt;

&lt;h3&gt;
  
  
  Complexidade em Ambientes Distribuídos
&lt;/h3&gt;

&lt;p&gt;Em ambientes distribuídos ou em sistemas orquestrados como Kubernetes, gerenciar variáveis de ambiente com um arquivo &lt;code&gt;.env&lt;/code&gt; pode não ser a abordagem mais eficiente. Nestes casos, ferramentas específicas de gerenciamento de configuração ou serviços de segredos podem ser mais apropriados (Hashicorp Vault, AWS Secrets Manager).&lt;/p&gt;

&lt;h3&gt;
  
  
  Risco de Exposição
&lt;/h3&gt;

&lt;p&gt;Se o arquivo &lt;code&gt;.env&lt;/code&gt; contiver informações sensíveis e não for tratado corretamente (por exemplo, não sendo incluído no .gitignore), existe o risco de expor informações sensíveis, especialmente se o código-fonte for compartilhado ou versionado publicamente.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dependência Externa
&lt;/h3&gt;

&lt;p&gt;Embora o Dotenv seja uma ferramenta útil, introduzir uma dependência externa em seu projeto pode aumentar a complexidade, especialmente se você estiver trabalhando em um ambiente onde a gestão de dependências é crítica.&lt;/p&gt;

&lt;h3&gt;
  
  
  Desacoplamento com Outras Ferramentas
&lt;/h3&gt;

&lt;p&gt;Em alguns cenários, integrar o Dotenv com certas ferramentas ou serviços pode exigir configurações adicionais ou scripts personalizados, o que pode complicar o processo de desenvolvimento ou implantação.&lt;/p&gt;

&lt;h3&gt;
  
  
  Desempenho
&lt;/h3&gt;

&lt;p&gt;Em sistemas de alta carga ou aplicações onde cada milissegundo conta, ler variáveis de ambiente de um arquivo pode introduzir uma sobrecarga mínima em comparação com outras formas mais eficientes de gerenciamento de configurações.&lt;/p&gt;

&lt;p&gt;Embora o Dotenv ofereça uma maneira conveniente e segura de gerenciar variáveis de ambiente em projetos Python, é essencial avaliar cuidadosamente as necessidades e requisitos específicos do seu projeto. Em alguns cenários, outras abordagens ou ferramentas podem ser mais adequadas para garantir a segurança, eficiência e escalabilidade da sua aplicação.&lt;/p&gt;

</description>
      <category>python</category>
      <category>tutorial</category>
      <category>beginners</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Como usar Terraform + Localstack (com Docker)</title>
      <dc:creator>Rafael Rotiroti</dc:creator>
      <pubDate>Fri, 17 Mar 2023 21:03:34 +0000</pubDate>
      <link>https://dev.to/rotirotirafa/como-usar-terraform-localstack-com-docker-h44</link>
      <guid>https://dev.to/rotirotirafa/como-usar-terraform-localstack-com-docker-h44</guid>
      <description>&lt;p&gt;Vou separar esse artigo em 4 partes: &lt;em&gt;motivação&lt;/em&gt;, &lt;em&gt;teoria&lt;/em&gt;, &lt;em&gt;prática&lt;/em&gt;, &lt;em&gt;conclusão&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;A intenção é ser um conteúdo leve, introdutório e nada de terno e gravata, que atenda desde de pessoas iniciantes e até mesmo mais experientes.&lt;/p&gt;

&lt;p&gt;Estou voltando a escrever agora e pretendo voltar a produzir esse tipo de conteúdo ao longo desse ano. Sugestões e feedback são muito bem vindos!&lt;/p&gt;

&lt;h2&gt;
  
  
  Motivação
&lt;/h2&gt;

&lt;p&gt;No fim do ano passado eu estava um pouco incomodado com o fato de saber apenas sobre o Terraform teoricamente... queria aprender e ter a capacidade de usar diariamente de forma mais autonoma, só que eu queria estudar com calma, fazer uma aplicação prática para válidar o conhecimento e etc.&lt;/p&gt;

&lt;p&gt;Em Janeiro tirei uns dias de férias para descansar, fui viajar e quando voltei tinha uma semana livre, tempo perfeito para se atualizar e colocar minhas ideias em dia. &lt;/p&gt;

&lt;p&gt;Terraform foi o escolhido da vez!&lt;/p&gt;

&lt;h2&gt;
  
  
  Teoria
&lt;/h2&gt;

&lt;p&gt;Como vamos utilizar Terraform, Docker e Localstack vou fazer um pequeno resumo de cada um.&lt;/p&gt;

&lt;p&gt;O &lt;a href="https://www.terraform.io/" rel="noopener noreferrer"&gt;Terraform&lt;/a&gt; é uma tecnologia &lt;a href="https://learn.microsoft.com/en-us/devops/deliver/what-is-infrastructure-as-code" rel="noopener noreferrer"&gt;IaaC &lt;/a&gt;(Infrastructure as a Code ou Infraestrutura como código, como prefirir.), permite que você provisione sua infraestura em nuvem através de código, numa estrutura bem familiar ao &lt;a href="https://www.json.org/json-pt.html" rel="noopener noreferrer"&gt;JSON &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O &lt;a href="https://www.docker.com/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; é uma plataforma que faz a criação de administração de containers, ou seja, permite que você isole e esteja preparado para fazer deploy do seu ambiente para nuvem.&lt;/p&gt;

&lt;p&gt;O &lt;a href="https://localstack.cloud/" rel="noopener noreferrer"&gt;Localstack&lt;/a&gt; é uma ferramenta que permite que você desenvolva e teste suas aplicações localmente, ou seja, permite que você utilize e simule tecnologias como SNS, Lambda, SQS, Dynamo e etc no seu ambiente local.&lt;/p&gt;

&lt;p&gt;A ideia é basicamente usar o Terraform para provisionar a infraestrutura dentro da minha máquina local, para isso utilizei o Localstack que simula toda minha infraestrutura da AWS dentro dos containeres do Docker.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prática
&lt;/h2&gt;

&lt;p&gt;Presumo que o Docker, Terraform e &lt;a href="https://aws.amazon.com/pt/cli/" rel="noopener noreferrer"&gt;AWS CLI&lt;/a&gt; estejam configurados e instalados em sua máquina e então podemos iniciar a configuração do Localstack.&lt;/p&gt;

&lt;p&gt;Criaremos o arquivo &lt;code&gt;docker-compose.yml&lt;/code&gt; com a seguinte instrução:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: "3.8"

services:
  localstack:
    image: localstack/localstack:1.3.1
    environment: 
      - AWS_DEFAULT_REGION=sa-east-1
      - AWS_ACCESS_KEY_ID=teste
      - AWS_SECRET_ACCESS_KEY=teste
      - EDGE_PORT=4566
      - DATA_DIR=${DATA_DIR-}
      - HOST_TMP_FOLDER=${TMPDIR:-/tmp/}localstack
      - DOCKER_HOST=unix:///var/run/docker.sock
    ports:
      - '4566-4587:4566-4587'
    volumes:
      - localstack-data:/tmp/localstack
      - "/var/run/docker.sock:/var/run/docker.sock"
    networks:
      - dev_to

volumes:
  localstack-data:
    name: localstack-data

networks:
  dev_to:
    name: dev_to
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;De forma resumida, estamos pedindo para o Docker criar a partir da imagem Localstack(1.3.1) um container. &lt;em&gt;Detalhe na EDGE_PORT=4566 que falarei mais adiante sobre ela!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Com o comando &lt;code&gt;docker compose up -d&lt;/code&gt; o Docker vai criar e subir o container na sua máquina local e prover todos os recursos que o Localstack dispõe.&lt;/p&gt;

&lt;p&gt;Rode o comando &lt;code&gt;docker ps&lt;/code&gt; e veja se obtem um resultado parecido:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqxzhbyfgs4b1nsjodmhi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqxzhbyfgs4b1nsjodmhi.png" alt="Resultado do Docker PS, container ativo!" width="800" height="66"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Com nosso container no ar e com o Localstack provisionado já podemos partir para o que interessa: Terraform!&lt;/p&gt;

&lt;p&gt;No meio do caminho acabei recebendo uma dica de um amigo sobre o &lt;a href="https://github.com/localstack/terraform-local" rel="noopener noreferrer"&gt;TFLocal&lt;/a&gt; que foi muito útil, pois ao utilizar o Terraform, precisamos apontar pro ambiente local e o TFLocal foi desenvolvido justamente para o cenário com Localstack.&lt;/p&gt;

&lt;p&gt;Para instalar, basta ter o &lt;a href="https://www.python.org/doc/" rel="noopener noreferrer"&gt;Python&lt;/a&gt; e rodar &lt;code&gt;pip install terraform-local&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Com isso, vamos escrever nosso arquivo &lt;code&gt;main.tf&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;provider "aws" {
  region                     = "sa-east-1"
  access_key                 = "teste"
  secret_key                 = "teste"
  skip_credentials_validation = true
  skip_requesting_account_id = true
  skip_metadata_api_check    = true
}


resource "aws_dynamodb_table" "basic-dynamodb-table" {
  name           = "GameScores"
  billing_mode   = "PROVISIONED"
  read_capacity  = 20
  write_capacity = 20
  hash_key       = "UserId"
  range_key      = "GameTitle"

  attribute {
    name = "UserId"
    type = "S"
  }

  attribute {
    name = "GameTitle"
    type = "S"
  }

  attribute {
    name = "TopScore"
    type = "N"
  }

  ttl {
    attribute_name = "TimeToExist"
    enabled        = false
  }

  global_secondary_index {
    name               = "GameTitleIndex"
    hash_key           = "GameTitle"
    range_key          = "TopScore"
    write_capacity     = 10
    read_capacity      = 10
    projection_type    = "INCLUDE"
    non_key_attributes = ["UserId"]
  }

  tags = {
    Name        = "dynamodb-table-1"
    Environment = "production"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O arquivo &lt;code&gt;main.tf&lt;/code&gt; é responsável por entender qual será o Provider(AWS, GCP, Azure) a ser utilizado e quais serviços serão criados, no exemplo acima eu quis utilizar o mesmo &lt;a href="https://dev.toprovider"&gt;exemplo&lt;/a&gt; no site do Terraform que é criar uma tabela no DynamoDB.&lt;/p&gt;

&lt;p&gt;Com o arquivo finalizado, podemos iniciar os comandos que vão realmente criar tudo lá dentro para nós, então abra seu terminal e digite: &lt;code&gt;tflocal init&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;O comando &lt;code&gt;tflocal init&lt;/code&gt; faz exatamente o mesmo que o &lt;code&gt;terraform init&lt;/code&gt; faz, inicia a configuração do terraform de acordo com o que temos de instrução no &lt;code&gt;main.tf&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Em seguida, &lt;code&gt;tflocal plan&lt;/code&gt;. Que por sua vez, vai carregar as suas configurações e te mostrar o que tem para ser feito como planejado.&lt;/p&gt;

&lt;p&gt;E por final, &lt;code&gt;tflocal apply -auto-approve&lt;/code&gt;, esse comando Apply realmente vai fazer a criação (nesse caso DynamoDB) dos serviços que foram planejados e a flag &lt;code&gt;-auto-approve&lt;/code&gt; faz com que não haja a necessidade de confirmar com um "yes" na linha de comando.&lt;/p&gt;

&lt;p&gt;Pronto, temos tudo criado e a mensagem que apareceu no terminal deve ter sido algo assim:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7tt3ai3nrc9y1p73vvyp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7tt3ai3nrc9y1p73vvyp.png" alt="Resultado do TFlocal apply" width="800" height="130"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para ver se sua table criou, basta rodar &lt;code&gt;aws dynamodb list-tables --endpoint-url http://localhost:4566&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F76hk72o1h7h86z571sqy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F76hk72o1h7h86z571sqy.png" alt="Lista de tabelas via AWS Cli" width="800" height="87"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A partir daqui, pode inserir registros na tabela e até mesmo usar o &lt;a href="https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/workbench.html" rel="noopener noreferrer"&gt;NoSQL Workbench&lt;/a&gt; para ter uma GUI de visualização.&lt;/p&gt;

&lt;p&gt;Lembra que eu falei sobre o a EDGE_PORT=4566 ?&lt;/p&gt;

&lt;p&gt;Veja que eu utilizei ela na minha consulta via CLI, ou seja todos os comandos que eu for fazer de consulta ou apontamentos via código localmente eu devo fazer na porta 4566, pois o localstack está roteando internamente e inteligentemente para os serviços solicitados. Se eu fosse consultar um SQS ou SNS eu apontaria para essa mesma porta 4566 e etc. Obviamente é algo configurável, pode ser utilizado as portas que consta nas docs do Localstack mas eu acho que é algo facilita nossa vida em meio tantas POCs (&lt;em&gt;Prove of concept&lt;/em&gt;) que fazemos por ai. &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Na minha opnião, desenvolver e testar local é melhor forma de você desenvolver antes de subir para um ambiente de DEV. Por ser um ambiente controlado as ferramentas como Docker, Localstack, Terraform fazem com que tenhamos um ganho absurdo de produtividade e testabilidade.&lt;/p&gt;

&lt;p&gt;Além de conseguir testar muitas features sem gastar $ é uma ótima forma de válidar e testar as coisas!&lt;/p&gt;

&lt;p&gt;Eu recomendo fortemente combinar essas ferramentas para o uso no dia a dia, fazendo com que nossas entregas além de validadas sejam mais consistentes.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;O amigo que mencionei é o &lt;a href="https://www.linkedin.com/in/renato-r/" rel="noopener noreferrer"&gt;Renato Rodrigues&lt;/a&gt;, ele que deu a dica de usar o tflocal para iniciar meus estudos com o Terraform usando Localstack. Fica aqui meu agradecimento!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Links que utilizei de inspiração:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.docker.com/blog/develop-your-cloud-app-locally-with-the-localstack-extension/" rel="noopener noreferrer"&gt;https://www.docker.com/blog/develop-your-cloud-app-locally-with-the-localstack-extension/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/pulse/develop-test-aws-apps-free-using-localstack-adtech-corp/?trk=organization-update-content_share-article" rel="noopener noreferrer"&gt;https://www.linkedin.com/pulse/develop-test-aws-apps-free-using-localstack-adtech-corp/?trk=organization-update-content_share-article&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>docker</category>
      <category>aws</category>
      <category>terraform</category>
      <category>python</category>
    </item>
    <item>
      <title>How run &amp; use DynamoDB locally</title>
      <dc:creator>Rafael Rotiroti</dc:creator>
      <pubDate>Wed, 19 Oct 2022 16:58:21 +0000</pubDate>
      <link>https://dev.to/rotirotirafa/how-run-use-dynamodb-locally-7do</link>
      <guid>https://dev.to/rotirotirafa/how-run-use-dynamodb-locally-7do</guid>
      <description>&lt;p&gt;This post intent to be simple and direct.&lt;/p&gt;

&lt;p&gt;We are going to run &lt;a href="https://aws.amazon.com/pt/dynamodb/" rel="noopener noreferrer"&gt;DynamoDB&lt;/a&gt; locally and connect with him using &lt;a href="https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/workbench.html" rel="noopener noreferrer"&gt;NoSQL Workbench&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Before we start, check if you have &lt;a href="https://www.docker.com/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; running on your machine. Else not, install &lt;a href="https://docs.docker.com/engine/install/" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Choose an folder or create a new one, inside this folder create a file &lt;code&gt;docker-compose.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: '3.8'
services:
  dynamodb-local:
    command: "-jar DynamoDBLocal.jar -sharedDb -dbPath ./data"
    image: "amazon/dynamodb-local:latest"
    container_name: dynamodb-local
    ports:
      - "8000:8000"
    volumes:
      - "./docker/dynamodb:/home/dynamodblocal/data"
    working_dir: /home/dynamodblocal
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In your terminal, inside the folder you created the file run following command:&lt;br&gt;
&lt;code&gt;docker-compose up&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If everything is well, this should be the result of your terminal:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F35omhp6nyquwh43emx8o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F35omhp6nyquwh43emx8o.png" alt="Command Finished" width="573" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lets connect with DynamoDB using NoSQL Workbench.&lt;/p&gt;

&lt;p&gt;Download and install using &lt;a href="https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/workbench.settingup.html" rel="noopener noreferrer"&gt;AWS NoSQL Workbench&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open the NoSQL Workbench Software.&lt;/p&gt;

&lt;p&gt;Choose &lt;strong&gt;Amazon DynamoDB&lt;/strong&gt;:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fadym2sv35zqvpgf525hs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fadym2sv35zqvpgf525hs.png" alt="Amazon DynamoDB " width="800" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click in Operation Builder and &lt;strong&gt;Add Connection&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcx6t1swtotncusxb3nnz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcx6t1swtotncusxb3nnz.png" alt="Add Connection" width="761" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Setup your connection:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7gj1k3tx9szgn45kng14.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7gj1k3tx9szgn45kng14.png" alt="Fill all fields" width="700" height="613"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And everything should be okay if you see this screen:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdbo8s2ryrxzn357nm1xj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdbo8s2ryrxzn357nm1xj.png" alt="Connection Estabilished" width="800" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hope this article helped you.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>dynamodb</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
