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¶
| 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.gdalosgeo.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).
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¶
- Test / Preview on the Python card
- Read stderr on failure
- Confirm the script creates
sys.argv[2]even for an empty layer