How to use AWS DynamoDB locally…

Chances are most of us have unique situations for wanting to interact with DynamoDB locally, maybe it’s to develop and test different data models, perhaps it’s to develop programmatic functions to interact with the database, perhaps you want to reduce development expenses, or perhaps you’re just doing research. Regardless of your reasons, I want to help you by showing you how to leverage DynamoDB locally. We will use the following tools.

We will walk through setting up the local environment, generating data, uploading data, interacting with the noSQL Workbench, and some neat tips to keep in mind. So with that being said, let’s dive into into it!

Note: If you get lost, simply visit to view the end solution. Also, feel free to fork this template project and use it as a starting point.

Setting up the environment

First thing first, ensure that you have Terraform (> v0.12.0), noSQL Workbench, and localstack ( > v0.11.3) installed and working on your system. If you need help installing these resources checkout the three links below. Due to the abundance of resources for getting started available, I will skip ahead and assume you have them installed.

(Alternative) if you don’t want to use localstack, DynamoDB offers a docker image, you may use this option as well.


First thing first, fire up localstack. If you installed it through pip then it’s as easy as issuing the command localstack start . Or if you used the localstack docker image then it’s as simple as docker run localstack/localstack . If everything starts up correctly then you should be seeing something similar to the screenshot below.

Note: localstack has plenty of parameters to pass in during startup. We are taking the defaults which starts majority of the mocked AWS services but there are plenty of other options worth checking out.

Image for post

WSL2 output through pip installation

#porgramming #golang #aws #terraform #dynamodb #amazon web services

What is GEEK

Buddha Community

How to use AWS DynamoDB locally…
Chloe  Butler

Chloe Butler


Pdf2gerb: Perl Script Converts PDF Files to Gerber format


Perl script converts PDF files to Gerber format

Pdf2Gerb generates Gerber 274X photoplotting and Excellon drill files from PDFs of a PCB. Up to three PDFs are used: the top copper layer, the bottom copper layer (for 2-sided PCBs), and an optional silk screen layer. The PDFs can be created directly from any PDF drawing software, or a PDF print driver can be used to capture the Print output if the drawing software does not directly support output to PDF.

The general workflow is as follows:

  1. Design the PCB using your favorite CAD or drawing software.
  2. Print the top and bottom copper and top silk screen layers to a PDF file.
  3. Run Pdf2Gerb on the PDFs to create Gerber and Excellon files.
  4. Use a Gerber viewer to double-check the output against the original PCB design.
  5. Make adjustments as needed.
  6. Submit the files to a PCB manufacturer.

Please note that Pdf2Gerb does NOT perform DRC (Design Rule Checks), as these will vary according to individual PCB manufacturer conventions and capabilities. Also note that Pdf2Gerb is not perfect, so the output files must always be checked before submitting them. As of version 1.6, Pdf2Gerb supports most PCB elements, such as round and square pads, round holes, traces, SMD pads, ground planes, no-fill areas, and panelization. However, because it interprets the graphical output of a Print function, there are limitations in what it can recognize (or there may be bugs).

See docs/Pdf2Gerb.pdf for install/setup, config, usage, and other info.

#Pdf2Gerb config settings:
#Put this file in same folder/directory as itself (global settings),
#or copy to another folder/directory with PDFs if you want PCB-specific settings.
#There is only one user of this file, so we don't need a custom package or namespace.
#NOTE: all constants defined in here will be added to main namespace.
#package pdf2gerb_cfg;

use strict; #trap undef vars (easier debug)
use warnings; #other useful info (easier debug)

#configurable settings:
#change values here instead of in main file

use constant WANT_COLORS => ($^O !~ m/Win/); #ANSI colors no worky on Windows? this must be set < first DebugPrint() call

#just a little warning; set realistic expectations:
#DebugPrint("${\(CYAN)} ${\(VERSION)}, $^O O/S\n${\(YELLOW)}${\(BOLD)}${\(ITALIC)}This is EXPERIMENTAL software.  \nGerber files MAY CONTAIN ERRORS.  Please CHECK them before fabrication!${\(RESET)}", 0); #if WANT_DEBUG

use constant METRIC => FALSE; #set to TRUE for metric units (only affect final numbers in output files, not internal arithmetic)
use constant APERTURE_LIMIT => 0; #34; #max #apertures to use; generate warnings if too many apertures are used (0 to not check)
use constant DRILL_FMT => '2.4'; #'2.3'; #'2.4' is the default for PCB fab; change to '2.3' for CNC

use constant WANT_DEBUG => 0; #10; #level of debug wanted; higher == more, lower == less, 0 == none
use constant GERBER_DEBUG => 0; #level of debug to include in Gerber file; DON'T USE FOR FABRICATION
use constant WANT_STREAMS => FALSE; #TRUE; #save decompressed streams to files (for debug)
use constant WANT_ALLINPUT => FALSE; #TRUE; #save entire input stream (for debug ONLY)

#DebugPrint(sprintf("${\(CYAN)}DEBUG: stdout %d, gerber %d, want streams? %d, all input? %d, O/S: $^O, Perl: $]${\(RESET)}\n", WANT_DEBUG, GERBER_DEBUG, WANT_STREAMS, WANT_ALLINPUT), 1);
#DebugPrint(sprintf("max int = %d, min int = %d\n", MAXINT, MININT), 1); 

#define standard trace and pad sizes to reduce scaling or PDF rendering errors:
#This avoids weird aperture settings and replaces them with more standardized values.
#(I'm not sure how photoplotters handle strange sizes).
#Fewer choices here gives more accurate mapping in the final Gerber files.
#units are in inches
use constant TOOL_SIZES => #add more as desired
#round or square pads (> 0) and drills (< 0):
    .010, -.001,  #tiny pads for SMD; dummy drill size (too small for practical use, but needed so StandardTool will use this entry)
    .031, -.014,  #used for vias
    .041, -.020,  #smallest non-filled plated hole
    .051, -.025,
    .056, -.029,  #useful for IC pins
    .070, -.033,
    .075, -.040,  #heavier leads
#    .090, -.043,  #NOTE: 600 dpi is not high enough resolution to reliably distinguish between .043" and .046", so choose 1 of the 2 here
    .100, -.046,
    .115, -.052,
    .130, -.061,
    .140, -.067,
    .150, -.079,
    .175, -.088,
    .190, -.093,
    .200, -.100,
    .220, -.110,
    .160, -.125,  #useful for mounting holes
#some additional pad sizes without holes (repeat a previous hole size if you just want the pad size):
    .090, -.040,  #want a .090 pad option, but use dummy hole size
    .065, -.040, #.065 x .065 rect pad
    .035, -.040, #.035 x .065 rect pad
    .001,  #too thin for real traces; use only for board outlines
    .006,  #minimum real trace width; mainly used for text
    .008,  #mainly used for mid-sized text, not traces
    .010,  #minimum recommended trace width for low-current signals
    .015,  #moderate low-voltage current
    .020,  #heavier trace for power, ground (even if a lighter one is adequate)
    .030,  #heavy-current traces; be careful with these ones!
#Areas larger than the values below will be filled with parallel lines:
#This cuts down on the number of aperture sizes used.
#Set to 0 to always use an aperture or drill, regardless of size.
use constant { MAX_APERTURE => max((TOOL_SIZES)) + .004, MAX_DRILL => -min((TOOL_SIZES)) + .004 }; #max aperture and drill sizes (plus a little tolerance)
#DebugPrint(sprintf("using %d standard tool sizes: %s, max aper %.3f, max drill %.3f\n", scalar((TOOL_SIZES)), join(", ", (TOOL_SIZES)), MAX_APERTURE, MAX_DRILL), 1);

#NOTE: Compare the PDF to the original CAD file to check the accuracy of the PDF rendering and parsing!
#for example, the CAD software I used generated the following circles for holes:
#CAD hole size:   parsed PDF diameter:      error:
#  .014                .016                +.002
#  .020                .02267              +.00267
#  .025                .026                +.001
#  .029                .03167              +.00267
#  .033                .036                +.003
#  .040                .04267              +.00267
#This was usually ~ .002" - .003" too big compared to the hole as displayed in the CAD software.
#To compensate for PDF rendering errors (either during CAD Print function or PDF parsing logic), adjust the values below as needed.
#units are pixels; for example, a value of 2.4 at 600 dpi = .0004 inch, 2 at 600 dpi = .0033"
use constant
    HOLE_ADJUST => -0.004 * 600, #-2.6, #holes seemed to be slightly oversized (by .002" - .004"), so shrink them a little
    RNDPAD_ADJUST => -0.003 * 600, #-2, #-2.4, #round pads seemed to be slightly oversized, so shrink them a little
    SQRPAD_ADJUST => +0.001 * 600, #+.5, #square pads are sometimes too small by .00067, so bump them up a little
    RECTPAD_ADJUST => 0, #(pixels) rectangular pads seem to be okay? (not tested much)
    TRACE_ADJUST => 0, #(pixels) traces seemed to be okay?
    REDUCE_TOLERANCE => .001, #(inches) allow this much variation when reducing circles and rects

#Also, my CAD's Print function or the PDF print driver I used was a little off for circles, so define some additional adjustment values here:
#Values are added to X/Y coordinates; units are pixels; for example, a value of 1 at 600 dpi would be ~= .002 inch
use constant
    CIRCLE_ADJUST_MINY => -0.001 * 600, #-1, #circles were a little too high, so nudge them a little lower
    CIRCLE_ADJUST_MAXX => +0.001 * 600, #+1, #circles were a little too far to the left, so nudge them a little to the right
    SUBST_CIRCLE_CLIPRECT => FALSE, #generate circle and substitute for clip rects (to compensate for the way some CAD software draws circles)
    WANT_CLIPRECT => TRUE, #FALSE, #AI doesn't need clip rect at all? should be on normally?
    RECT_COMPLETION => FALSE, #TRUE, #fill in 4th side of rect when 3 sides found

#allow .012 clearance around pads for solder mask:
#This value effectively adjusts pad sizes in the TOOL_SIZES list above (only for solder mask layers).
use constant SOLDER_MARGIN => +.012; #units are inches

#line join/cap styles:
use constant
    CAP_NONE => 0, #butt (none); line is exact length
    CAP_ROUND => 1, #round cap/join; line overhangs by a semi-circle at either end
    CAP_SQUARE => 2, #square cap/join; line overhangs by a half square on either end
    CAP_OVERRIDE => FALSE, #cap style overrides drawing logic
#number of elements in each shape type:
use constant
    RECT_SHAPELEN => 6, #x0, y0, x1, y1, count, "rect" (start, end corners)
    LINE_SHAPELEN => 6, #x0, y0, x1, y1, count, "line" (line seg)
    CURVE_SHAPELEN => 10, #xstart, ystart, x0, y0, x1, y1, xend, yend, count, "curve" (bezier 2 points)
    CIRCLE_SHAPELEN => 5, #x, y, 5, count, "circle" (center + radius)
#const my %SHAPELEN =
#Readonly my %SHAPELEN =>
    rect => RECT_SHAPELEN,
    line => LINE_SHAPELEN,
    curve => CURVE_SHAPELEN,
    circle => CIRCLE_SHAPELEN,

#This will repeat the entire body the number of times indicated along the X or Y axes (files grow accordingly).
#Display elements that overhang PCB boundary can be squashed or left as-is (typically text or other silk screen markings).
#Set "overhangs" TRUE to allow overhangs, FALSE to truncate them.
#xpad and ypad allow margins to be added around outer edge of panelized PCB.
use constant PANELIZE => {'x' => 1, 'y' => 1, 'xpad' => 0, 'ypad' => 0, 'overhangs' => TRUE}; #number of times to repeat in X and Y directions

# Set this to 1 if you need TurboCAD support.
#$turboCAD = FALSE; #is this still needed as an option?

#CIRCAD pad generation uses an appropriate aperture, then moves it (stroke) "a little" - we use this to find pads and distinguish them from PCB holes. 
use constant PAD_STROKE => 0.3; #0.0005 * 600; #units are pixels
#convert very short traces to pads or holes:
use constant TRACE_MINLEN => .001; #units are inches
#use constant ALWAYS_XY => TRUE; #FALSE; #force XY even if X or Y doesn't change; NOTE: needs to be TRUE for all pads to show in FlatCAM and ViewPlot
use constant REMOVE_POLARITY => FALSE; #TRUE; #set to remove subtractive (negative) polarity; NOTE: must be FALSE for ground planes

#PDF uses "points", each point = 1/72 inch
#combined with a PDF scale factor of .12, this gives 600 dpi resolution (1/72 * .12 = 600 dpi)
use constant INCHES_PER_POINT => 1/72; #0.0138888889; #multiply point-size by this to get inches

# The precision used when computing a bezier curve. Higher numbers are more precise but slower (and generate larger files).
#$bezierPrecision = 100;
use constant BEZIER_PRECISION => 36; #100; #use const; reduced for faster rendering (mainly used for silk screen and thermal pads)

# Ground planes and silk screen or larger copper rectangles or circles are filled line-by-line using this resolution.
use constant FILL_WIDTH => .01; #fill at most 0.01 inch at a time

# The max number of characters to read into memory
use constant MAX_BYTES => 10 * M; #bumped up to 10 MB, use const

use constant DUP_DRILL1 => TRUE; #FALSE; #kludge: ViewPlot doesn't load drill files that are too small so duplicate first tool

my $runtime = time(); #Time::HiRes::gettimeofday(); #measure my execution time

print STDERR "Loaded config settings from '${\(__FILE__)}'.\n";
1; #last value must be truthful to indicate successful load


#use Package::Constants;
#use Exporter qw(import); #

#my $caller = "pdf2gerb::";

#sub cfg
#    my $proto = shift;
#    my $class = ref($proto) || $proto;
#    my $settings =
#    {
#        $WANT_DEBUG => 990, #10; #level of debug wanted; higher == more, lower == less, 0 == none
#    };
#    bless($settings, $class);
#    return $settings;

#use constant HELLO => "hi there2"; #"main::HELLO" => "hi there";
#use constant GOODBYE => 14; #"main::GOODBYE" => 12;

#print STDERR "read cfg file\n";

#our @EXPORT_OK = Package::Constants->list(__PACKAGE__); #; NOTE: "_OK" skips short/common names

#print STDERR scalar(@EXPORT_OK) . " consts exported:\n";
#foreach(@EXPORT_OK) { print STDERR "$_\n"; }
#my $val = main::thing("xyz");
#print STDERR "caller gave me $val\n";
#foreach my $arg (@ARGV) { print STDERR "arg $arg\n"; }

Download Details:

Author: swannman
Source Code:

License: GPL-3.0 license


A GUI for Local DynamoDB- Dynamodb-Admin

Quick Start Guide

1. Install the package globally from npm.

$ npm install -g dynamodb-admin

2. Run DynamoDB locally inside a Docker container

Make sure you have Docker installed on your system. Instructions are here.

Now pull and run the Docker dynamodb-local image to spin up your very own DynamoDB instance running on port 8000.

$ docker pull amazon/dynamodb-local
$ docker run -p 8000:8000 amazon/dynamodb-local

3. Start dynamodb-admin (with defaults)


$ dynamodb-admin


> export DYNAMO_ENDPOINT=http://localhost:8000
> dynamodb-admin

After these steps you will have:

The next step is to create a table and start reading/writing to it!

Advanced Setup

You may need to override regions, endpoints and/or credentials to peek inside local DynamoDB instances you have spun up to replicate a production environment.

If so, just override the defaults when starting the service. You can override some, or all of these, as required.


Setting up your Tables

The easy way — for simple use cases

Here we are going to create your table using the dynamodb-admin GUI. This is most likely going to be appropriate for your use-case.

Clicking on ‘Create table’ takes us to a screen where we can define how our table should look. Remember that DynamoDB is effectively a key-value store, meaning to get started we only need to define a table name and a hash attribute (the primary key). If you expect that you’ll need to perform lookups based on another attribute of your data, you may want to add some Secondary Indices.

In this example, I’ve named the table ‘Cats’ and given it a primary index ‘name’ and a secondary index ‘owner’. Both indices are of type String and we must give the secondary index a name — which can be different from the name of the attribute.

‘name’ is not a good choice of primary index in practice, as it means only one cat with a given name can be present in the table. Instead, it would be better to give each cat a unique id and use that as the primary index.

Finally, add your first item to the table by clicking the ‘Create item’ link on the top right. This will take you to a new screen where you can enter the json which defines the record. The only requirement for each entry is that the primary key is included.

The Hard(er) Way — for more complex table structures

Using the GUI to set up tables is fine for simple tables, or when you’re just exploring how your data storage might be structured. However, if you are trying to mimic a complex table, or you want to stand-up tables quickly for testing you may want to use the command line to create the table(s) for you.

1. Install the AWS CLI

Instructions for installing (for Mac) via the command line are here. This is a very powerful utility tool. I’d recommend installing it if you work with AWS even if you don’t opt to use it here.

2. Create a table schema

If you already have a table schema you can skip this and move along to Step 3.

$ aws dynamodb create-table --generate-cli-skeleton > dynamo_table_def.json

This will create a basic table schema and pipe it into a file named dynamo_table_def.json.

You can now open the json file and edit it to fit your desired table schema. This is great because you can now use this same schema file when you need the table, rather than manually setting it up each time via the GUI.

If you’re just curious what the schema should look like, or you need some inspiration for your own — here is the schema for the Cats table.

  "AttributeDefinitions": [
      "AttributeName": "name",
      "AttributeType": "S"
      "AttributeName": "owner",
      "AttributeType": "S"
  "TableName": "Cats",
  "KeySchema": [
      "AttributeName": "name",
      "KeyType": "HASH"
  "ProvisionedThroughput": {
    "ReadCapacityUnits": 3,
    "WriteCapacityUnits": 3
  "GlobalSecondaryIndexes": [
      "IndexName": "idx_owner",
      "KeySchema": [
          "AttributeName": "owner",
          "KeyType": "HASH"
      "Projection": {
        "ProjectionType": "ALL"
      "ProvisionedThroughput": {
        "ReadCapacityUnits": 3,
        "WriteCapacityUnits": 3

3. Use the schema to create the table

Finally, create the table locally

$ aws dynamodb create-table --cli-input-json file://dynamo_table_def.json --endpoint-url http://localhost:8000

Remember the --endpoint-url parameter, otherwise a real table will be created in whatever region your AWS CLI defaults to.

After running this command, go back to dynamodb-admin in your browser. You’ll see your table has been created. Now it’s time to use it!

Use Cases

I’ve picked 3 examples to show how dynamodb-admin can help you develop and test your applications.

Running locally alongside an application

This example is super simple. Let’s say you’re developing a Python application which reads from a DynamoDB table of movies. You may want run a local DynamoDB instance for development and tests, to avoid standing up unnecessary infrastructure. Dynamodb-local is a godsend for this. However it can be fiddly to put data in the table, from the command line.

You could write code to put the correct items in the table. Indeed for tests this might be ideal, as you absolutely should test the logic you’re using to read and write from the table.

However to quickly test some code path or to build out a feature, when the remote infrastructure or data is not present, it’s typically much easier to put the data into the DynamoDB table manually.

You can set up your table and add some movies, using the GUI, as described above. Then read from the table like so:

from pprint import pprint
import boto3
from botocore.exceptions import ClientError

def get_movie(title, year, dynamodb=None):
    if not dynamodb:
        dynamodb = boto3.resource('dynamodb', endpoint_url="http://localhost:8000")

    table = dynamodb.Table('Movies')

        response = table.get_item(Key={'year': year, 'title': title})
    except ClientError as e:
        return response['Item']

if __name__ == '__main__':
    movie = get_movie("The Big New Movie", 2015,)
    if movie:
        print("Get movie succeeded:")
        pprint(movie, sort_dicts=False)

Creating the table and putting items in it, using dynamodb-admin, lets you focus on the business logic. When you’re happy with how your logic looks, you can focus on writing to the table.

Using dynamodb-admin as a library

Since dynamodb-admin is a Node library, we can use it inside our Node projects. This is again great for local development, as each time you run the service you have what is effectively the AWS console ready to view and manipulate the data.

const AWS = require('aws-sdk');
const {createServer} = require('dynamodb-admin');
const dynamodb = new AWS.DynamoDB();
const dynClient = new AWS.DynamoDB.DocumentClient({service: dynamodb});
const app = createServer(dynamodb, dynClient);
const port = 8001;
const server = app.listen(port);
server.on('listening', () => {
  const address = server.address();
  console.log(`  listening on${address.port}`);

Using dynamodb-admin with AWS Amplify

AWS Amplify is a development framework that deals with a lot of the common problems when building a mobile or web application, setting up the infrastructure required for you. Each part of the framework deserves a blog post of its own, but here we are going to be looking at mocking the DynamoDB tables Amplify creates based on your GraphQL API definition.

If you’d like to find out how to use Amplify to create a GraphQL API the documentation is here

Amplify let’s you mock services used by your app with the Amplify CLI tool by running

$ amplify mock <service>

If you have used Amplify to create a GraphQL API to serve as the backend for your project you can run

$ amplify mock api

This will do two things:

  1. Starts a mock Appsync API endpoint on port 20002
  2. Creates a DynamoDB instance on port 62224

We can now use dynamodb-admin to take a peek inside the tables Amplify has created, based on our API’s requirements by running

$ AWS_REGION=us-fake-1 AWS_ACCESS_KEY_ID=fake AWS_SECRET_ACCESS_KEY=fake DYNAMO_ENDPOINT=http://localhost:62224  dynamodb-admin

I’ve personally found this really useful to test locally, before committing to pushing my API changes.

Originally published by 

#dynamodb #aws #code #dynamodb-admin #dynamodb-local

Seamus  Quitzon

Seamus Quitzon


AWS Cost Allocation Tags and Cost Reduction

Bob had just arrived in the office for his first day of work as the newly hired chief technical officer when he was called into a conference room by the president, Martha, who immediately introduced him to the head of accounting, Amanda. They exchanged pleasantries, and then Martha got right down to business:

“Bob, we have several teams here developing software applications on Amazon and our bill is very high. We think it’s unnecessarily high, and we’d like you to look into it and bring it under control.”

Martha placed a screenshot of the Amazon Web Services (AWS) billing report on the table and pointed to it.

“This is a problem for us: We don’t know what we’re spending this money on, and we need to see more detail.”

Amanda chimed in, “Bob, look, we have financial dimensions that we use for reporting purposes, and I can provide you with some guidance regarding some information we’d really like to see such that the reports that are ultimately produced mirror these dimensions — if you can do this, it would really help us internally.”

“Bob, we can’t stress how important this is right now. These projects are becoming very expensive for our business,” Martha reiterated.

“How many projects do we have?” Bob inquired.

“We have four projects in total: two in the aviation division and two in the energy division. If it matters, the aviation division has 75 developers and the energy division has 25 developers,” the CEO responded.

Bob understood the problem and responded, “I’ll see what I can do and have some ideas. I might not be able to give you retrospective insight, but going forward, we should be able to get a better idea of what’s going on and start to bring the cost down.”

The meeting ended with Bob heading to find his desk. Cost allocation tags should help us, he thought to himself as he looked for someone who might know where his office is.

#aws #aws cloud #node js #cost optimization #aws cli #well architected framework #aws cost report #cost control #aws cost #aws tags

Hire AWS Developer

Looking to Hire Professional AWS Developers?

The technology inventions have demanded all businesses to use and manage cloud-based computing services and Amazon is dominating the cloud computing services provider in the world.

Hire AWS Developer from & Get the best amazon web services development. Take your business to excellence with our best AWS developer that will serve you the benefit of different cloud computing tools.

Consult with experts: Development services

#hire aws developer #aws developers #aws development company #aws development services #aws development #aws

Adem John


Collect, Visualize And Respond To Critical Metrics Using AWS Monitorin

Track events across your account with AWS monitoring services. It enables businesses to record critical event and activity logs for your services and stores the data in S3. The data collected usually consists of user identities, traffic origins IPs and timestamps. With AWS monitoring, you can also view event logs for upto 90 days for free. Additionally, data insights and events based on your data can also be accessed for an additional fee. 

Furthermore, with AWS monitoring services, you can cluster, visualize and proactively respond to critical metrics. You can set alarms and create alerts according to thresholds for metrics and events to automatically respond to metrics values or system changes. AWS monitoring services enable you to monitor, optimize and troubleshoot resources, both in public and private clouds and on-premises. With AWS monitoring, get conditional alerting, optimized recommendations, predictive analytics, anomaly detection based on machine learning, and compliance auditing.