Giter VIP home page Giter VIP logo

geolambda's Introduction

GeoLambda: geospatial AWS Lambda Layer

The GeoLambda project provides public Docker images and AWS Lambda Layers containing common geospatial native libraries. GeoLambda contains the libraries for GDAL, Proj, GEOS, GeoTIFF, HDF4/5, SZIP, NetCDF, OpenJPEG, WEBP, ZSTD, and others. For some applications you may wish to minimize the size of the libraries by excluding unused libraries, or you may wish to add other libraries. In this case this repository can be used as a template to create your own Docker image or Lambda Layer following the instructions in this README.

This repository also contains additional images and layers for specific runtimes. Using them as a Layer assumes the use of the base GeoLambda layer.

Usage

While GeoLambda was initially intended for AWS Lambda it is also useful as a base geospatial Docker image. For detailed info on what is included in each image, see the Dockerfile for that version or the CHANGELOG. A version summary is provided here:

geolambda GDAL Notes
1.0.0 2.3.1
1.1.0 2.4.1
1.2.0 2.4.2 Separate Python (3.7.4) image and Lambda Layer added
2.0.0 3.0.1 libgeotiff 1.5.1, proj 6.2.0
2.1.0 3.2.1 libgeotiff 1.6.0, proj 7.2.1, openjpeg 2.4.0, Python layer 3.7.9

Environment variables

When using GeoLambda some environment variables need to be set. These are set in the Docker image, but if using the Lambda Layer they will need to be set:

  • GDAL_DATA=/opt/share/gdal
  • PROJ_LIB=/opt/share/proj (only needed for GeoLambda 2.0.0+)

Lambda Layers

If you just wish to use the publicly available Lambda layers you will need the ARN for the layer in the same region as your Lambda function. Currently, the latest GeoLambda layers are deployed in us-east-1, us-west-2, eu-central-1, eu-west-2, and eu-north-1. If you want to use it in another region please file an issue or you can also create your own layer using this repository (see instructions below on 'Create a new version').

v2.1.0

Region ARN
us-east-1 arn:aws:lambda:us-east-1:552188055668:layer:geolambda:4
us-west-2 arn:aws:lambda:us-west-2:552188055668:layer:geolambda:4
eu-central-1 arn:aws:lambda:eu-central-1:552188055668:layer:geolambda:4
eu-west-2
eu-north-1

v2.1.0-python

See the GeoLambda Python README. The Python Lambda Layer includes the libraries numpy, rasterio, GDAL, pyproj, and shapely, plus everything in the standard GeoLambda layer. Note this is a change from v2.0.0 where both Layers needed to be included in a Lambda.

Region ARN
us-east-1 arn:aws:lambda:us-east-1:552188055668:layer:geolambda-python:3
us-west-2 arn:aws:lambda:us-west-2:552188055668:layer:geolambda-python:3
eu-central-1 arn:aws:lambda:eu-central-1:552188055668:layer:geolambda-python:3
eu-west-2
eu-north-1

v2.0.0

Region ARN
us-east-1 arn:aws:lambda:us-east-1:552188055668:layer:geolambda:4
us-west-2 arn:aws:lambda:us-west-2:552188055668:layer:geolambda:4
eu-central-1 arn:aws:lambda:eu-central-1:552188055668:layer:geolambda:4

v2.0.0-python

See the GeoLambda Python README. The Python Lambda Layer includes the libraries numpy, rasterio, GDAL, pyproj, and shapely. This is an addition to the standard GeoLambda layer; if you wish to use GeoLambda-Python, both layers must be included.

Region ARN
us-east-1 arn:aws:lambda:us-east-1:552188055668:layer:geolambda-python:3
us-west-2 arn:aws:lambda:us-west-2:552188055668:layer:geolambda-python:3
eu-central-1 arn:aws:lambda:eu-central-1:552188055668:layer:geolambda-python:3

v1.2.0

Region ARN
us-east-1 arn:aws:lambda:us-east-1:552188055668:layer:geolambda:2
us-west-2 arn:aws:lambda:us-west-2:552188055668:layer:geolambda:2
eu-central-1 arn:aws:lambda:eu-central-1:552188055668:layer:geolambda:2

v1.2.0-python

See the GeoLambda Python README. The Python Lambda Layer includes the libraries numpy, rasterio, GDAL, pyproj, and shapely. This is an addition to the standard GeoLambda layer; if you wish to use GeoLambda-Python, both layers must be included.

Region ARN
us-east-1 arn:aws:lambda:us-east-1:552188055668:layer:geolambda-python:1
us-west-2 arn:aws:lambda:us-west-2:552188055668:layer:geolambda-python:1
eu-central-1 arn:aws:lambda:eu-central-1:552188055668:layer:geolambda-python:1

v1.1.0

Region ARN
us-east-1 arn:aws:lambda:us-east-1:552188055668:layer:geolambda:1
us-west-2 arn:aws:lambda:us-west-2:552188055668:layer:geolambda:1
eu-central-1 arn:aws:lambda:eu-central-1:552188055668:layer:geolambda:1

Docker images

The Docker images used to create the Lambda layer are also published to Docker Hub, and thus are also suitable for general use as a base image for geospatial applications.

The developmentseed/geolambda image in Docker Hub is tagged by version.

$ docker pull developmentseed/geolambda:<version>

Or just include it in your own Dockerfile as the base image.

FROM developmentseed/geolambda:<version>

The GeoLambda image does not have an entrypoint defined, so a command must be provided when you run it. This example will mount the current directory to /work and run the container interactively.

$ docker run --rm -v $PWD:/home/geolambda -it developmentseed/geolambda:latest /bin/bash

All of the GDAL CLI tools are installed so could be run on images in the current directory.

Development

Contributions to the geolambda project are encouraged. The goal is to provide a turnkey method for developing and deploying geospatial applications to AWS. The 'master' branch in this repository contains the current state as deployed to the Docker Hub images developmentseed/geolambda:latest and devlopmentseed/geolambda-python:latest, along with a tag of the version. The 'develop' branch is the development version and is not deployed to Docker Hub.

When making a merge to the master branch be sure to increment the VERSION file. Circle will push the new version as a tag to GitHub and build and push the image to Docker Hub. If a GitHub tag already exists with that version the process will fail.

Create a new version

Use the Dockerfile here as a template for your own version of GeoLambda. Simply edit it to remove or add additional libraries, then build and tag with your own name. The steps below are used to create a new official version of GeoLambda, replace developmentseed/geolambda with your own name.

To create a new version of GeoLambda follow these steps. Note that this is the manual process of what is currently done in CircleCI, so it is not necessary to perform them but they are useful as an example for deploying your own versions.

  1. update the version in the VERSION file

The version in the VERSION file will be used to tag the Docker images and create a GitHub tag.

  1. build the image:
$ VERSION=$(cat VERSION)
$ docker build . -t developmentseed/geolambda:${VERSION}
  1. Push the image to Docker Hub:
$ docker push developmentseed/geolambda:${VERSION}
  1. Create deployment package using the built-in packaging script
$ docker run --rm -v $PWD:/home/geolambda \
	-it developmentseed/geolambda:${VERSION} package.sh

This will create a lambda/ directory containing the native libraries and related files, along with a lambda-deploy.zip file that can be deployed as a Lambda layer.

  1. Push as Lambda layer (if layer already exists a new version will be created)
$ aws lambda publish-layer-version \
	--layer-name geolambda \
	--license-info "MIT" \
	--description "Native geospatial libaries for all runtimes" \
	--zip-file fileb://lambda-deploy.zip
  1. Make layer public (needs to be done each time a new version is published)
$ aws lambda add-layer-version-permission --layer-name geolambda \
	--statement-id public --version-number 1 --principal '*' \
	--action lambda:GetLayerVersion

geolambda's People

Contributors

bluetyson avatar kylebarron avatar matthewhanson avatar robertd avatar seilerman avatar vincentsarago avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

geolambda's Issues

Problem with projections (EPSG), unable to read 'gcs.csv'

Having this error in Logging:
Unable to open EPSG support file gcs.csv. Try setting the GDAL_DATA environment variable to point to the directory containing EPSG csv files.

Corresponding code parts:

# imports used for the example code below
import logging
from osgeo import gdal
from osgeo import ogr
from osgeo import osr
epsg_in = 4326
osr_in = osr.SpatialReference()
osr_in.ImportFromEPSG(epsg_in)

But if check the geolambda layer, I can find the gcs.csv file in share/gdal folder.
Already tried with the setting of Environmental variable at Lambda function (key: GDAL_DATA, value: /usr/local/share/gdal) but nothing changed :S
What can be the reason of this? Any idea how to fix it?

Additional: Tried with these as well, didn't work:
"GDAL_DATA": "/opt/share/gdal",
"PROJ_LIB": "/opt/share/proj",

Support for PostgreSQL drive

example:

Running this command: 👇

docker run --rm -v ${PWD}:/home/geolambda developmentseed/geolambda:latest ogr2ogr \
  -f "PostgreSQL" \
  PG:"host=localhost port=15432 dbname=db user=postgres password=1234 " \
  data/admin-areas/states/Admin2.shp \
  -overwrite \
  -nln states \
  -nlt MULTIPOLYGON \
  -lco GEOMETRY_NAME=geom

The error: There is not included PostgreSQL in gdal.

Unzipped size must be smaller than 132586253 bytes

When using the layer

arn:aws:lambda:us-east-1:552188055668:layer:geolambda-python:3

I cannot deploy to Lambda because I will get this error:

An error occurred: MyLambdaFunction - Unzipped size must be smaller than 132586253 bytes (Service: AWSLambdaInternal; Status Code: 400; Error Code: InvalidParameterValueException; Request ID: c9e35258-e012-4ca1-a70f-05037bb70aef).

How can I use the layer on python 3 without having a limit problem?

Packaging script only works with :full

I updated my Dockerfile to use :min and then tried packaging with docker-compose run package and got the following error:

cp: cannot stat ‘/usr/local/lib/libdf.so.0’: No such file or directory
cp: cannot stat ‘/usr/local/lib/libsz.so.2’: No such file or directory
cp: cannot stat ‘/usr/local/lib/libhdf5.so.101’: No such file or directory
cp: cannot stat ‘/usr/local/lib/libmfhdf.so.0’: No such file or directory

I think those libs aren't installed in this tag so the cp fails. Probably should be made conditional but I couldn't think of a quick fix

Installation instruction fails on GDAL installation.

Summary of the bug/issue.

Python GeoLambda Readme Installation fails while installing GDAL. The GDAL version it is trying to install is 3.0.1

Steps to reproduce the bug.

Following the installation instructions from the README.
VERSION=1.2.0
docker build . --build-arg VERSION=${VERSION} --build-arg PYVERSION=3.6.8 -t geo-lambda:latest

Buggy behaviour and/or error message

Sending build context to Docker daemon  15.87kB
Step 1/10 : ARG VERSION=1.2.0
Step 2/10 : FROM developmentseed/geolambda:${VERSION}
 ---> 7e5ae746c387
Step 3/10 : LABEL maintainer="Development Seed <[email protected]>"
 ---> Using cache
 ---> d561fa6c0519
Step 4/10 : LABEL authors="Matthew Hanson  <[email protected]>"
 ---> Using cache
 ---> c140aea93a85
Step 5/10 : ARG PYVERSION=3.7.4
 ---> Using cache
 ---> e1feebc7d86d
Step 6/10 : ENV     PYENV_ROOT=/root/.pyenv     PATH=/root/.pyenv/shims:/root/.pyenv/bin:$PATH
 ---> Using cache
 ---> 97846c82a747
Step 7/10 : RUN     curl https://pyenv.run | bash;     CONFIGURE_OPTS="--with-openssl=${PREFIX}/openssl"         LD_RUN_PATH="${PREFIX}/openssl/lib"         pyenv install ${PYVERSION};     pyenv global ${PYVERSION};     pip install --upgrade pip
 ---> Using cache
 ---> 1fa92623f65f
Step 8/10 : COPY requirements*.txt ./
 ---> cc3f7cd7092e
Step 9/10 : RUN     pip install -r requirements-pre.txt;     pip install -r requirements.txt
 ---> Running in 7476483364fa
Collecting numpy
  Downloading https://files.pythonhosted.org/packages/d2/ab/43e678759326f728de861edbef34b8e2ad1b1490505f20e0d1f0716c3bf4/numpy-1.17.4-cp36-cp36m-manylinux1_x86_64.whl (20.0MB)
Installing collected packages: numpy
Successfully installed numpy-1.17.4
Collecting GDAL==3.0.1
  Downloading https://files.pythonhosted.org/packages/26/c6/f8846ba726b37f9a1099acb5bff43c309fb913577674c1ba491f6fc60598/GDAL-3.0.1.tar.gz (576kB)
Collecting rasterio==1.1.0
  Downloading https://files.pythonhosted.org/packages/1a/6d/ee8b15e0d45dd7e9e7f2559e37f91915a19155cf8403948ff2082903ee30/rasterio-1.1.0.tar.gz (2.1MB)
  Installing build dependencies: started
  Installing build dependencies: finished with status 'done'
  Getting requirements to build wheel: started
  Getting requirements to build wheel: finished with status 'done'
    Preparing wheel metadata: started
    Preparing wheel metadata: finished with status 'done'
Collecting shapely==1.6.4.post2
  Downloading https://files.pythonhosted.org/packages/38/b6/b53f19062afd49bb5abd049aeed36f13bf8d57ef8f3fa07a5203531a0252/Shapely-1.6.4.post2-cp36-cp36m-manylinux1_x86_64.whl (1.5MB)
Collecting pyproj==2.4.0
  Downloading https://files.pythonhosted.org/packages/7a/b1/ab67ad924770e1c1432fa0953a665b8ea193b60c7494457b69da052d6e83/pyproj-2.4.0-cp36-cp36m-manylinux1_x86_64.whl (10.1MB)
Collecting cligj>=0.5
  Downloading https://files.pythonhosted.org/packages/e4/be/30a58b4b0733850280d01f8bd132591b4668ed5c7046761098d665ac2174/cligj-0.5.0-py3-none-any.whl
Requirement already satisfied: numpy in /root/.pyenv/versions/3.6.8/lib/python3.6/site-packages (from rasterio==1.1.0->-r requirements.txt (line 2)) (1.17.4)
Collecting snuggs>=1.4.1
  Downloading https://files.pythonhosted.org/packages/cc/0e/d27d6e806d6c0d1a2cfdc5d1f088e42339a0a54a09c3343f7f81ec8947ea/snuggs-1.4.7-py3-none-any.whl
Collecting attrs
  Downloading https://files.pythonhosted.org/packages/a2/db/4313ab3be961f7a763066401fb77f7748373b6094076ae2bda2806988af6/attrs-19.3.0-py2.py3-none-any.whl
Collecting click-plugins
  Downloading https://files.pythonhosted.org/packages/e9/da/824b92d9942f4e472702488857914bdd50f73021efea15b4cad9aca8ecef/click_plugins-1.1.1-py2.py3-none-any.whl
Collecting click<8,>=4.0
  Downloading https://files.pythonhosted.org/packages/fa/37/45185cb5abbc30d7257104c434fe0b07e5a195a6847506c074527aa599ec/Click-7.0-py2.py3-none-any.whl (81kB)
Collecting affine
  Downloading https://files.pythonhosted.org/packages/ac/a6/1a39a1ede71210e3ddaf623982b06ecfc5c5c03741ae659073159184cd3e/affine-2.3.0-py2.py3-none-any.whl
Collecting pyparsing>=2.1.6
  Downloading https://files.pythonhosted.org/packages/c0/0c/fc2e007d9a992d997f04a80125b0f183da7fb554f1de701bbb70a8e7d479/pyparsing-2.4.5-py2.py3-none-any.whl (67kB)
Building wheels for collected packages: rasterio
  Building wheel for rasterio (PEP 517): started
  Building wheel for rasterio (PEP 517): still running...
  Building wheel for rasterio (PEP 517): finished with status 'done'
  Created wheel for rasterio: filename=rasterio-1.1.0-cp36-cp36m-linux_x86_64.whl size=4943674 sha256=21999fcf1f9bd1f1f0d6d4c82925a52b9f4630539de92409f813320c08f83e83
  Stored in directory: /root/.cache/pip/wheels/6c/44/28/18fca8582827f0a8594284474ad863e806ceb28d9fbcc948c4
Successfully built rasterio
Installing collected packages: GDAL, click, cligj, pyparsing, snuggs, attrs, click-plugins, affine, rasterio, shapely, pyproj
    Running setup.py install for GDAL: started
    Running setup.py install for GDAL: finished with status 'error'
    ERROR: Command errored out with exit status 1:
     command: /root/.pyenv/versions/3.6.8/bin/python3.6 -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-j2lowkfe/GDAL/setup.py'"'"'; __file__='"'"'/tmp/pip-install-j2lowkfe/GDAL/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-w4f0b8w0/install-record.txt --single-version-externally-managed --compile
         cwd: /tmp/pip-install-j2lowkfe/GDAL/
    Complete output (50 lines):
    running install
    running build
    running build_py
    creating build
    creating build/lib.linux-x86_64-3.6
    copying gdal.py -> build/lib.linux-x86_64-3.6
    copying ogr.py -> build/lib.linux-x86_64-3.6
    copying osr.py -> build/lib.linux-x86_64-3.6
    copying gdalconst.py -> build/lib.linux-x86_64-3.6
    copying gdalnumeric.py -> build/lib.linux-x86_64-3.6
    creating build/lib.linux-x86_64-3.6/osgeo
    copying osgeo/ogr.py -> build/lib.linux-x86_64-3.6/osgeo
    copying osgeo/__init__.py -> build/lib.linux-x86_64-3.6/osgeo
    copying osgeo/gnm.py -> build/lib.linux-x86_64-3.6/osgeo
    copying osgeo/gdal.py -> build/lib.linux-x86_64-3.6/osgeo
    copying osgeo/osr.py -> build/lib.linux-x86_64-3.6/osgeo
    copying osgeo/gdal_array.py -> build/lib.linux-x86_64-3.6/osgeo
    copying osgeo/gdalnumeric.py -> build/lib.linux-x86_64-3.6/osgeo
    copying osgeo/gdalconst.py -> build/lib.linux-x86_64-3.6/osgeo
    Fixing build/lib.linux-x86_64-3.6/gdal.py build/lib.linux-x86_64-3.6/ogr.py build/lib.linux-x86_64-3.6/osr.py build/lib.linux-x86_64-3.6/gdalconst.py build/lib.linux-x86_64-3.6/gdalnumeric.py build/lib.linux-x86_64-3.6/osgeo/ogr.py build/lib.linux-x86_64-3.6/osgeo/__init__.py build/lib.linux-x86_64-3.6/osgeo/gnm.py build/lib.linux-x86_64-3.6/osgeo/gdal.py build/lib.linux-x86_64-3.6/osgeo/osr.py build/lib.linux-x86_64-3.6/osgeo/gdal_array.py build/lib.linux-x86_64-3.6/osgeo/gdalnumeric.py build/lib.linux-x86_64-3.6/osgeo/gdalconst.py
    Skipping optional fixer: ws_comma
    Fixing build/lib.linux-x86_64-3.6/gdal.py build/lib.linux-x86_64-3.6/ogr.py build/lib.linux-x86_64-3.6/osr.py build/lib.linux-x86_64-3.6/gdalconst.py build/lib.linux-x86_64-3.6/gdalnumeric.py build/lib.linux-x86_64-3.6/osgeo/ogr.py build/lib.linux-x86_64-3.6/osgeo/__init__.py build/lib.linux-x86_64-3.6/osgeo/gnm.py build/lib.linux-x86_64-3.6/osgeo/gdal.py build/lib.linux-x86_64-3.6/osgeo/osr.py build/lib.linux-x86_64-3.6/osgeo/gdal_array.py build/lib.linux-x86_64-3.6/osgeo/gdalnumeric.py build/lib.linux-x86_64-3.6/osgeo/gdalconst.py
    Skipping optional fixer: ws_comma
    running build_ext
    gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I../../port -I../../gcore -I../../alg -I../../ogr/ -I../../ogr/ogrsf_frmts -I../../gnm -I../../apps -I/root/.pyenv/versions/3.6.8/include/python3.6m -I/root/.pyenv/versions/3.6.8/lib/python3.6/site-packages/numpy/core/include -I/usr/local/include -c gdal_python_cxx11_test.cpp -o gdal_python_cxx11_test.o
    gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I../../port -I../../gcore -I../../alg -I../../ogr/ -I../../ogr/ogrsf_frmts -I../../gnm -I../../apps -I/root/.pyenv/versions/3.6.8/include/python3.6m -I/root/.pyenv/versions/3.6.8/lib/python3.6/site-packages/numpy/core/include -I/usr/local/include -c gdal_python_cxx11_test.cpp -o gdal_python_cxx11_test.o -std=c++11
    building 'osgeo._gdal' extension
    creating build/temp.linux-x86_64-3.6
    creating build/temp.linux-x86_64-3.6/extensions
    gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I../../port -I../../gcore -I../../alg -I../../ogr/ -I../../ogr/ogrsf_frmts -I../../gnm -I../../apps -I/root/.pyenv/versions/3.6.8/include/python3.6m -I/root/.pyenv/versions/3.6.8/lib/python3.6/site-packages/numpy/core/include -I/usr/local/include -c extensions/gdal_wrap.cpp -o build/temp.linux-x86_64-3.6/extensions/gdal_wrap.o -std=c++11 -I/usr/local/include
    extensions/gdal_wrap.cpp: In function ‘OSRSpatialReferenceShadow* GDALDatasetShadow_GetSpatialRef(GDALDatasetShadow*)’:
    extensions/gdal_wrap.cpp:4672:54: error: ‘GDALGetSpatialRef’ was not declared in this scope
         OGRSpatialReferenceH ref = GDALGetSpatialRef(self);
                                                          ^
    extensions/gdal_wrap.cpp: In function ‘void GDALDatasetShadow_SetSpatialRef(GDALDatasetShadow*, OSRSpatialReferenceShadow*)’:
    extensions/gdal_wrap.cpp:4681:57: error: ‘GDALSetSpatialRef’ was not declared in this scope
          GDALSetSpatialRef( self, (OGRSpatialReferenceH)srs );
                                                             ^
    extensions/gdal_wrap.cpp: In function ‘OSRSpatialReferenceShadow* GDALDatasetShadow_GetGCPSpatialRef(GDALDatasetShadow*)’:
    extensions/gdal_wrap.cpp:4722:57: error: ‘GDALGetGCPSpatialRef’ was not declared in this scope
         OGRSpatialReferenceH ref = GDALGetGCPSpatialRef(self);
                                                             ^
    extensions/gdal_wrap.cpp: In function ‘CPLErr GDALDatasetShadow_SetGCPs2(GDALDatasetShadow*, int, const GDAL_GCP*, OSRSpatialReferenceShadow*)’:
    extensions/gdal_wrap.cpp:4735:73: error: ‘GDALSetGCPs2’ was not declared in this scope
         return GDALSetGCPs2( self, nGCPs, pGCPs, (OGRSpatialReferenceH)hSRS );
                                                                             ^
    extensions/gdal_wrap.cpp:4736:3: warning: control reaches end of non-void function [-Wreturn-type]
       }
       ^
    error: command 'gcc' failed with exit status 1
    ----------------------------------------
ERROR: Command errored out with exit status 1: /root/.pyenv/versions/3.6.8/bin/python3.6 -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-j2lowkfe/GDAL/setup.py'"'"'; __file__='"'"'/tmp/pip-install-j2lowkfe/GDAL/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-w4f0b8w0/install-record.txt --single-version-externally-managed --compile Check the logs for full command output.
The command '/bin/sh -c pip install -r requirements-pre.txt;     pip install -r requirements.txt' returned a non-zero code: 1

Environment Information

  • Ubuntu 18.04.3
  • Python 3.6.8 [GCC 8.3.0]
  • Docker version 19.03.4

GeoLambda publish to New Region : Unable to import module 'lambda_function': No module named 'gdal'

I am trying to create a layer for a new region however I have failed all the time. I am getting error message

Runtime.ImportModuleError: Unable to import module 'lambda_function': No module named 'gdal'

I tried this build-and-test.sh script and tried to upload the lambda-deploy.zip files created from root folder as well from python folder still i get same issue.

Is there any step by instruction ?

My code works well if i use the ARN mentioned for us-east-1 . However I want in a new region. Kind support is highly appreciated.


Update i have updated my geolambda layer to us-east-1 and used the v2.1.0-python [arn:aws:lambda:us-east-1:552188055668:layer:geolambda-python:3] then my code works fine.

Means my v2.1.0-python deploy package is having issues.

Any support will be a great help.

split out installation into scripts

It would be useful to split out the installation of the libraries into scripts that would be added to the docker image via COPY and run, instead of having those instructions directly in the Dockerfile.

This way, the install scripts would be useful outside of Docker, as a way to install GDAL on an Amazon Base linux EC2.

Calling gdal2tiles.py

I'm desperately trying to call the gdal2tiles.py script from AWS lambda function like this

    import json
    import os
    from osgeo import gdal
    def lambda_handler(event, context):
       
         os.system("gdal2tiles.py -p -z [0-6] test.jpg")

But I get this error message sh: gdal2tiles.py: command not found
Any idea what is wrong?
Thanks!

add jpeg2k support

In the full GDAL version, look at adding jp2k support with openjpeg. Adding netcdf (see #22 ) is higher priority though, there might not be enough room for a deployable package in that version. In that case, HDF/NetCDF should be split off, and a separate jp2k version should be added.

Files missing in deployment package

I am creating a layer with gdal (3.0.1) , sklearn (0.22.2.post1) . While everything works fine and layer is created successfully, however some of the files always gets missed . One file in particular is pipeline.py inside sklearn which never shows up in sklearn folder inside layer.
This is the content inside python dir in zip
package

This is inside sklearn folder
Screenshot from 2020-05-05 22-42-23

I tried explicitly adding the file but that created some more dependency issue which was also not present in skearn. Just need some help in this.

OS: Amazon Linux AMI release 2018.03 on AWS
Python Version for Layer: 3.7

Dockerfile.hdf build doesn't work

when builded with the current configuration, the testpackage service produce this output:

Traceback (most recent call last):
File "/usr/local/lib/python2.7/site-packages/nose/loader.py", line 418, in loadTestsFromName
addr.filename, addr.module)
File "/usr/local/lib/python2.7/site-packages/nose/importer.py", line 47, in importFromPath
return self.importFromDir(dir_path, fqname)
File "/usr/local/lib/python2.7/site-packages/nose/importer.py", line 94, in importFromDir
mod = load_module(part_fqname, fh, filename, desc)
File "/home/geolambda/test/test_lambda.py", line 4, in
lambda_handler = imp.load_source('lambda_handler', 'lambda/lambda_handler.py')
File "lambda/lambda_handler.py", line 16, in
from osgeo import gdal
ImportError: No module named osgeo


Ran 1 test in 0.024s

Publish geolambda-python36 layer

The GeoLambda layer is usable in all runtimes, but there are also standard runtime specific libraries that are common for geo apps (e.g., GDAL python bindings, rasterio) which could be useful for some users as it would enable them to only have to provide a handler function if only using standard libraries.

Create a geolambda-python36 Lambda layer and publish it (include in CI deploys as well). The docker image is already built and published.

For Lambda layers though the Python packages need to be in a python/ subdirectory in the deploy zip:
see AWS conventions: https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html#configuration-layers-path

Using public ARN - No module named osgeo

Good day! I'm attempting to use public geolambda ARN for us-east-1, arn:aws:lambda:us-east-1:552188055668:layer:geolambda-dev:2 along with the example lambda_function.py you've provided in hopes I can use it for our current project. I've added the ARN above as a layer to that example function. However, when testing, I get the following error: "Unable to import module 'lambda_function': No module named osgeo". Perhaps I've missed something in the documentation, but it looked like I should just be able to use the example function and test this out of the box without having to create a new version. I'm in the US East region and I didn't have an issue when setting up the test lambda function to use the public geolambda ARN. Hopefully, I've just missed something simple. Thanks!

package-python.sh mistakes?

In the package-python.sh, the /lib and /share folders are copied down to the /lambda folder, then zipped under ./python. Although the python/lambda-deploy.zip contains /lib and /share, but they are under ./python/share ./python/lib. This makes them not available as /opt/lib/ /opt/share when it deploys to lambda as a single layer.

Therefore, the zip command needs to be modified to make sure /lib and /share is at the same level of ./python, not under .python.

Possible to use with node ogr2ogr?

Apologies if this is more of a StackOverflow question, but I'm trying to run ogr2ogr to push user-uploaded files to a Postgres database. The ogr2ogr module requires a native install of GDAL.

I've added your Lambda layer to my function but not sure if I need to import or call it. Thoughts?

Release for ap-northeast-1

I am trying to understand how to add ap-northeast-1, could you explain how to do it? I am not so familiar with Lambda functions.

unable to import osgeo gdal from lambda layer

Hello,
working with layer arn:aws:lambda:us-west-2:524387336408:layer:gdal33-al2:1 and having set the env vars for GDAL_DATA and PROJ_LIB I'm unable to import gdal from osgeo.

curious if I'm missing any configuration here..

libgdal.so: cannot open shared object file: No such file or directory

Hello,

First of all, thank you for this awesome code that simplify this process so much !

Although, i'm pretty new with AWS Lambda and I've had trouble using it. I followed the python readme in order to build the docker (as i want to use it on eu-west-3).

For the requirements, i just need GDAL (for the use of gdalinfo and gdal_translate) and Pyproj so I removed rasterio and shapely from the example requirements.

I built the docker, run the package.sh and the python-package.sh and publish the 'deploy-layer.zip' to aws lambda.

I copied-paste the lambda handler from this repo into the lambda_funtion on the AWS Lambda Gui and linked my new layer.

But when i try to run the lambda function this message appears :
"errorMessage": "Unable to import module 'lambda_function': libgdal.so: cannot open shared object file: No such file or directory",
"errorType": "Runtime.ImportModuleError"

I tried different configuration of the requirements, dockerfiles, package.sh and python-package.sh in order to correct this but without really understanding what causes this error ..

Would you have an idea on how to help me ?

Thank you very much !!

Unable to connect to database inside Lambda function with VPC

I'm really not sure if this is an issue related to developmentseed/geolambda or osgeo itself.

I'm using geolambda/python layers to access some files in s3 from inside a lambda function. My goal is to send data from s3 to a database. The database is a postgres+postgis in RDS on amazon AWS using VPC. The lambda is using x86_64 with Python 3.7 as it should. I've already configure lambda's VPC and permissions correctly, so I can connect to the database using psycopg2. However, when I try to create the connection with conn = osgeo.ogr.Open(connectionstring), the object conn is None.

I know that everything in connectionstring works, because I can connect to that same database from another computer in the exact same way.

missing lambda-layer-deploy.zip

The python documentation references lambda-layer-deploy.zip but following the current instructions it looks like only a lambda-deploy.zip is created both at the /geolambda level and at /geolambda/python level. In package-python.sh this seems to be the correct output:

zip -ruq lambda-deploy.zip ./python

This make the documentation hard to follow, unless I'm missing a step somewhere.

Tokyo region

Hello, May I know if you have available for Toyko region? Thank you

Library version updates

Ongoing issue to track changes to included library versions. When there's sufficient changes we will cut a new release.

simplify geolambda flavors

The different flavors of GeoLambda (min, hdf, full, cloud) actually have little impact on the final package size and there isn't any other compelling reasons to maintain different flavors.

Instead geolambda should be merged into one image that is a full install of GDAL. For users who wish to prune this down they can fork the repo and editing will be much easier without the multiple Dockerfiles.

ogr2ogr and other binaries not in path

I'm trying to use the public GeoLambda layer in a Node JS lambda function:
arn:aws:lambda:us-west-2:552188055668:layer:geolambda:1

In my lambda function code, I'm trying to call the ogr2ogr command line tool.

import { promisify } from 'util'
const exec = promisify(require('child_process').exec)

export const handler = async (event, _context) => {
  const ogr2ogrCmd = await exec('ogr2ogr')
  console.log('stdout:', ogr2ogrCmd.stdout)
  console.log('stderr:', ogr2ogrCmd.stderr)

  return {
    statusCode: 200,
    body: JSON.stringify(
      {
        message: ogr2ogrCmd.stdout,
        input: event,
      },
      null,
      2
    ),
  }
}

When I run the function it fails saying that ogr2ogr is not found.

Command failed: ogr2ogr
/bin/sh: ogr2ogr: command not found

It also fails when attempting other command line tools like gdalinfo, ogrinfo, etc.

Are these binaries not available by default in GeoLambda, or do I just need to specify specific paths? I've dug through the /opt/ dir and although I see many GDAL-related files, I don't see the binaries.

I'd love to help document how to do this if so.

Missing `lambda:GetLayerVersion` permission?

When trying to add arn:aws:lambda:eu-north-1:552188055668:layer:geolambda:4, I get the following error:

User: arn:aws:iam::{IAM} is not authorized to perform: 
lambda:GetLayerVersion on resource: 
arn:aws:lambda:eu-north-1:552188055668:layer:geolambda:4 
because no resource-based policy allows the lambda:GetLayerVersion action

Add example docker run command

The Readme describes how to get the docker image, but not how to use docker to create the deployment zip. For those not very familiar with docker this is quite confusing.

The following works, and clearly runs, but the resulting zip is not on the host system. It needs some sort of volume mounted, but the internal path is not clear.
docker run developmentseed/geolambda:min lambda-package.sh

Configuring geolambda GDAL error

I am trying to make a lambda_function.py works in AWS.

I have a lambda using geolambda v4 and geolambda-python v3 as layers, for running a script in Python that uses sentinel-2 jp2 files.

Python version is Python 3.7

I have added the 2 variables in the lambda environment:
GDAL_DATA=/opt/share/gdal
PROJ_LIB=/opt/share/proj (only needed for GeoLambda 2.0.0+)

However, when running the command:

src_tci_ds = gdal.Open('/vsis3/my-bucket/subfolder/image.jp2')

I got this error:

Warning 1: HTTP response code on https://my-bucket.s3.amazonaws.com/sub-folder/file.XML: 403
Warning 1: HTTP response code on https://my-bucket.s3.amazonaws.com/sub-folder/file.xml: 403
Warning 1: HTTP response code on https://my-bucket.s3.amazonaws.com/sub-folder/file.IMD: 403
Warning 1: HTTP response code on https://my-bucket.s3.amazonaws.com/sub-folder/file.imd: 403
Warning 1: HTTP response code on https://my-bucket.s3.amazonaws.com/sub-folder/file.RPB: 403
Warning 1: HTTP response code on https://my-bucket.s3.amazonaws.com/sub-folder/file.rpb: 403
Warning 1: HTTP response code on https://my-bucket.s3.amazonaws.com/sub-folder/file.PVL: 403
Warning 1: HTTP response code on https://my-bucket.s3.amazonaws.com/sub-folder/file.pvl: 403
Warning 1: HTTP response code on https://my-bucket.s3.amazonaws.com/sub-folder/file_rpc.txt: 403
Warning 1: HTTP response code on https://my-bucket.s3.amazonaws.com/sub-folder/file_RPC.TXT: 403
Warning 1: HTTP response code on https://my-bucket.s3.amazonaws.com/sub-folder/file_metadata.txt: 403

Surely, it must be some configuration I am missing, but what could it be?

Thanks,

Clarify READMEs for local testing

It's not clear from the READMEs that to do local testing of a Python Lambda the base geolambda libraries AND the Python libraries with handler both need to be packaged.

The top level README gives packaging instructions under development, but the packaging call should also be included in the steps for testing a Python deployment.

implement versioning

Related to #32 , once there is one geolambda image versioning should be implemented.

Without versioning a problem for users is that they can't count on the geolambda image they fetch to be the same over time, so either requires they keep their own copy. This can all be avoided and make it easier for users to use the main developmentseed/geolambda image directly be utilizing version tags on the images.

createcopy causing coordinate system to change in geo tiff

I'm attempting to correct a compression issue with a geotiff by creating a copy or using translate which works locally with gdal_translate. The operation below using geolambda oddly causes the projected coordinate system to change from WGS 84 / Pseudo-Mercator to WGS_1984_Web_Mercator_Auxiliary_Sphere. I'm using the latest public geolambda layer referenced from arn:aws:lambda:us-east-1:552188055668:layer:geolambda:4 and geolambda-python layer from arn:aws:lambda:us-east-1:552188055668:layer:geolambda-python:3

Why is the PROJCS changing along with other values? Perhaps there is a better way to accomplish the task but still would like to know why the issue below happens.

Lambda Code

import logging
from osgeo import gdal
import boto3
from botocore.exceptions import ClientError

def upload_file(file_name, bucket, object_name=None):
# If S3 object_name was not specified, use file_name
if object_name is None:
    object_name = file_name

# Upload the file
s3_client = boto3.client('s3')
try:
    response = s3_client.upload_file(file_name, bucket, object_name)
except ClientError as e:
    logging.error(e)
    return False
return True
def lambda_handler(event, context=None):
    s3 = boto3.client('s3')
s3_filename = event["s3file"]
fname = event.get('filename', s3_filename)
fname = fname.replace('s3://', '/vsis3/')
bucket_name = 'bucket-name-here'
key = fname.replace('/vsis3/bucket-name-here/', '')
key = key.replace('.tif', '-gdal.tif')

dataset = gdal.Open(fname, gdal.GA_ReadOnly)
#gdal.Translate('/tmp/output.tif', dataset)

# Load the dataset into the virtual filesystem
temp_name = '/vsimem/current.tif'
tiff_driver = gdal.GetDriverByName('GTiff')
tiff_driver.CreateCopy(temp_name, dataset, False, [ 'COMPRESS=LZW' ])
#tiff_driver.Warp(temp_name,dataset,outputSRS='EPSG:4326')

# Read the raw data from the virtual filesystem
f = gdal.VSIFOpenL(temp_name, 'rb')
gdal.VSIFSeekL(f, 0, 2)  # seek to end
size = gdal.VSIFTellL(f)
gdal.VSIFSeekL(f, 0, 0)  # seek to beginning
data = gdal.VSIFReadL(1, size, f)
gdal.VSIFCloseL(f)

# Upload the raw data to s3
if s3.put_object(Key=key, Bucket=bucket_name, Body=data, ContentLength=size):
    details = 'GDAL conversion success. Input: ' + s3_filename + ' and Output: ' + key
    status = '200'
    summary_msg = 'success'
else:
    details = 'GDAL conversion failed. Input: ' + s3_filename + ' and Output: ' + key
    status = '400'
    summary_msg = 'error'

response = { 
    'status':status, 
    'message':{
        'summary' : summary_msg,
        'details' : details
    }
}
return response

gdal.Unlink(temp_name)
dataset = None
f = None

Input

{ "s3file": "s3://bucket-name/project/f228713b-cb88-41aa-8d0d-b728c3022d0e_2019:12:10T04:05:36:343_dsm.tif" }

Result

{ "status": "200", "message": { "summary": "success", "details": "GDAL conversion success. Input: s3://bucket-name/project/f228713b-cb88-41aa-8d0d-b728c3022d0e_2019:12:10T04:05:36:343_dsm.tif and Output: s3://bucket-name/project/f228713b-cb88-41aa-8d0d-b728c3022d0e_2019:12:10T04:05:36:343_dsm-gdal.tif" } }

Original gdalinfo

Driver: GTiff/GeoTIFF Files: f228713b-cb88-41aa-8d0d-b728c3022d0e_2019:12:10T04:05:36:343_dsm.tif Size is 15974, 14281 Coordinate System is: PROJCS["WGS 84 / Pseudo-Mercator", GEOGCS["WGS 84", DATUM["WGS_1984", SPHEROID["WGS 84",6378137,298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich",0, AUTHORITY["EPSG","8901"]], UNIT["degree",0.0174532925199433, AUTHORITY["EPSG","9122"]], AUTHORITY["EPSG","4326"]], PROJECTION["Mercator_1SP"], PARAMETER["central_meridian",0], PARAMETER["scale_factor",1], PARAMETER["false_easting",0], PARAMETER["false_northing",0], UNIT["metre",1, AUTHORITY["EPSG","9001"]], AXIS["X",EAST], AXIS["Y",NORTH], EXTENSION["PROJ4","+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs"], AUTHORITY["EPSG","3857"]] Origin = (-8637199.014870001003146,4665140.998520000837743) Pixel Size = (0.020000000000000,-0.020000000000000) Metadata: AREA_OR_POINT=Area TIFFTAG_SOFTWARE=pix4dmapper Image Structure Metadata: COMPRESSION=LZW INTERLEAVE=BAND Corner Coordinates: Upper Left (-8637199.015, 4665140.999) ( 77d35'21.40"W, 38d36'15.29"N) Lower Left (-8637199.015, 4664855.379) ( 77d35'21.40"W, 38d36' 8.07"N) Upper Right (-8636879.535, 4665140.999) ( 77d35'11.07"W, 38d36'15.29"N) Lower Right (-8636879.535, 4664855.379) ( 77d35'11.07"W, 38d36' 8.07"N) Center (-8637039.275, 4664998.189) ( 77d35'16.24"W, 38d36'11.68"N) Band 1 Block=15974x1 Type=Float32, ColorInterp=Gray NoData Value=-10000

Output gdalinfo

Driver: GTiff/GeoTIFF Files: f228713b-cb88-41aa-8d0d-b728c3022d0e_2019:12:10T04:05:36:343_dsm-gdal.tif Size is 15974, 14281 Coordinate System is: PROJCS["WGS_1984_Web_Mercator_Auxiliary_Sphere", GEOGCS["WGS 84", DATUM["WGS_1984", SPHEROID["WGS 84",6378137,298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich",0], UNIT["degree",0.0174532925199433], AUTHORITY["EPSG","4326"]], PROJECTION["Mercator_1SP"], PARAMETER["central_meridian",0], PARAMETER["scale_factor",1], PARAMETER["false_easting",0], PARAMETER["false_northing",0], UNIT["metre",1, AUTHORITY["EPSG","9001"]], EXTENSION["PROJ4","+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs"], AUTHORITY["EPSG","3857"]] Origin = (-8637199.014870001003146,4665140.998520000837743) Pixel Size = (0.020000000000000,-0.020000000000000) Metadata: AREA_OR_POINT=Area Image Structure Metadata: INTERLEAVE=BAND Corner Coordinates: Upper Left (-8637199.015, 4665140.999) ( 77d35'21.40"W, 38d36'15.29"N) Lower Left (-8637199.015, 4664855.379) ( 77d35'21.40"W, 38d36' 8.07"N) Upper Right (-8636879.535, 4665140.999) ( 77d35'11.07"W, 38d36'15.29"N) Lower Right (-8636879.535, 4664855.379) ( 77d35'11.07"W, 38d36' 8.07"N) Center (-8637039.275, 4664998.189) ( 77d35'16.24"W, 38d36'11.68"N) Band 1 Block=15974x1 Type=Float32, ColorInterp=Gray

gdal_translate local command that works

gdal_translate -q f228713b-cb88-41aa-8d0d-b728c3022d0e_2019:12:10T04:05:36:343_dsm.tif f228713b-cb88-41aa-8d0d-b728c3022d0e_2019:12:10T04:05:36:343_dsm-gdal.tif -co COMPRESS=LZW

2.1.0 geolambda shared layer update

In the readme the ARNs for the shared public lambda layer are the same for 2.0.0 and 2.1.0 which is arn:aws:lambda:us-east-1:552188055668:layer:geolambda:4 and arn:aws:lambda:us-east-1:552188055668:layer:geolambda-python:3 . Did the shared image get updated from 2.0.0 to 2.1.0 or am I misunderstanding? Perhaps I should use :5 and :6?

Enable HTTP2

Compiling GDAL (>2.3) with a customized libcurl install (add nghttp2) could enable the use of HTTP\2 in geolambda instances.

The main advantage of HTTP2 is to do parallel requests and range request merge docs.

The interest of enabling HTTP/2 is the use of HTTP/2 multiplexing when reading GeoTIFFs stored on /vsicurl/ and related virtual file systems.

procedure is shown in https://github.com/vincentsarago/gdal-http2-benchmark/blob/master/Dockerfile#L35-L51 or in https://github.com/mojodna/lambda-layer-rasterio/blob/master/Dockerfile#L22-L37

This will make the layer a bit heavier but I think we could strip the libraries as shown in https://github.com/mojodna/lambda-layer-rasterio/blob/master/Dockerfile#L133-L137

cc @matthewhanson

Python 3.8 - Amazon linux 2

Hi all,

Thanks for this, it's an amazing idea. I tried it with Python 3.8 as the lambda runtime, which runs Amazon linux 2, and kept getting the error:

"No module named '_gdal'

I don't know if this is me missing something, but if it isn't, and it's possible to get it working on Amazon linux 2, that would be amazing.

Thanks again.

Use with geodjango

Hi,

am I right that simply adding your public layer to my lambda function makes GDAL available to my lambda function?

I get the following error invoking the function:

django.core.exceptions.ImproperlyConfigured: Could not find the GDAL library (tried "gdal", "GDAL", "gdal2.2.0", "gdal2.1.0", "gdal2.0.0", "gdal1.11.0", "gdal1.10.0", "gdal1.9.0"). Is GDAL installed? If it is, try setting GDAL_LIBRARY_PATH in your settings.

Is that some non-standard location for gdal? As far as I can see here, I might need to adjust the path. But, where to?

Basic usage failure?

Hello all,
So I did what I thought would be the simplest test ever.

  1. Created python lambda in eu-central-1
  2. Added the layer via ARN for the latest for that region
  3. Set the env vars.
  4. Literally just put an 'from osgeo import gdal' into the default python lambda code.
  5. Tested it.

I get 'Unable to import module ..: No module named osgeo'

Should that work?

Many thanks

Add python pre-built image to CI

Create pre-built Python docker images (at least 3.6) in the CI and push them Docker Hub

image name:
developmentseed/geolambda:${VERSION}-python36

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.