Skip to content

Python scripts

Python runs before Convert in the same sandboxed spatial runtime.

You must be signed in. The script must be a .py file no larger than 1 MiB.

Execution contract

python3 script.py <input_path> <output_path>
Input sys.argv[1] — current dataset file
Output sys.argv[2]must be created
Working directory Job workspace
Network Not available
pip install Not available

If the output file is missing, GeoJibe reports The Python script did not create the output file. and restores the previous dataset.

If the process fails, you see The Python script failed. with stderr.

Available modules

Verified in the runtime:

  • Python standard library (sys, shutil, …)
  • osgeo.gdal
  • osgeo.ogr

There is no project requirements.txt for user scripts.

File types

sys.argv[2] uses the same filename as the input. If you started with neighborhoods.gpkg, write a GeoPackage to that path.

shutil.copy(sys.argv[1], sys.argv[2]) is fine for single-file formats. It is not enough for a Shapefile — only .shp would be copied. Use OGR to write Shapefiles.

Examples

Copy (single file)

Verified against GeoJibe's Python tests (internal/jobs/preprocess_live_test.go).

import sys
import shutil

shutil.copy(sys.argv[1], sys.argv[2])

Keep matching rows

Verified against the same live preprocess test (GeoJSON, field status).

import sys
from osgeo import ogr

src = ogr.Open(sys.argv[1])
layer = src.GetLayer(0)
drv = ogr.GetDriverByName("GeoJSON")
out = drv.CreateDataSource(sys.argv[2])
dst = out.CreateLayer(layer.GetName(), layer.GetSpatialRef(), layer.GetGeomType())
defn = layer.GetLayerDefn()
for i in range(defn.GetFieldCount()):
    dst.CreateField(defn.GetFieldDefn(i))
layer.ResetReading()
for feat in layer:
    if feat.GetField("status") == "active":
        dst.CreateFeature(feat)
src = None
out = None

Rename shape_len to shape

Same OGR contract as the filter example: open argv[1], create argv[2], copy features. Change "GeoJSON" to "GPKG" or "ESRI Shapefile" when the output path is that format.

import sys
from osgeo import ogr, gdal

gdal.UseExceptions()

src = ogr.Open(sys.argv[1])
if src is None:
    raise SystemExit("Could not open the input file.")

layer = src.GetLayer(0)
drv = ogr.GetDriverByName("GeoJSON")
out = drv.CreateDataSource(sys.argv[2])
dst = out.CreateLayer(layer.GetName(), layer.GetSpatialRef(), layer.GetGeomType())
defn = layer.GetLayerDefn()
for i in range(defn.GetFieldCount()):
    field = defn.GetFieldDefn(i)
    if field.GetName() == "shape_len":
        renamed = ogr.FieldDefn("shape", field.GetType())
        renamed.SetWidth(field.GetWidth())
        renamed.SetPrecision(field.GetPrecision())
        dst.CreateField(renamed)
    else:
        dst.CreateField(field)

layer.ResetReading()
for feat in layer:
    new_feat = ogr.Feature(dst.GetLayerDefn())
    new_feat.SetGeometry(feat.GetGeometryRef())
    for i in range(defn.GetFieldCount()):
        name = defn.GetFieldDefn(i).GetName()
        dest_name = "shape" if name == "shape_len" else name
        new_feat.SetField(dest_name, feat.GetField(i))
    dst.CreateFeature(new_feat)

src = None
out = None

Debugging

  1. Test / Preview on the Python card
  2. Read stderr on failure
  3. Confirm the script creates sys.argv[2] even for an empty layer

See also