The examples in this section use the scripting language Python. They will be based en the cURL examples.
We'll be working with Python3 and only with the Python Standard Library exclusively, but I'll mention alternatives and more adequate 3th party libraries when relevant.
Python includes an http module with enough tools to interact with a REST API. Although it is recommended to use the requests library.
First we need to import the necessary tools:
import requests
import json
from urllib.parse import urljoin
Then, lets define some variables we will reuse in all the examples as they will not change:
api_entry = 'http://localhost:8080/geoserver/rest/'
credential = ('admin', 'geoserver')
For all the examples, this preamble is assumed.
The following creates a new workspace named "acme" with a POST request:
resource = 'workspaces'
payload = {'workspace': {'name':'acme'}}
headers = {'content-type': 'application/json'}
request_url = urljoin(api_entry, resource)
r = requests.post(
request_url,
data=json.dumps(payload),
headers=headers,
auth=credential
)
r.raise_for_status()
The workspace information can be retrieved as JSON with a GET request:
resource = 'workspaces/acme'
headers = {'Accept' : 'application/json'}
request_url = urljoin(api_entry, resource)
r = requests.get(
request_url,
headers=headers,
auth=credential
)
print(r.json())
The response should look like this:
{'workspace':
{'wmsStores': 'http://localhost:8080/geoserver/rest/workspaces/acme/wmsstores.json',
'dataStores': 'http://localhost:8080/geoserver/rest/workspaces/acme/datastores.json',
'coverageStores': 'http://localhost:8080/geoserver/rest/workspaces/acme/coveragestores.json',
'name': 'acme'}}
In this example a new store will be created by uploading a shapefile.
The following request uploads a zipped shapefile named roads.zip
and creates a new store named roads
.
resource = 'workspaces/acme/datastores/roads/file.shp'
file_name = 'roads.zip'
headers = {'content-type': 'application/zip'}
request_url = urljoin(api_entry, resource)
with open(file_name, 'rb') as f:
r = requests.put(
request_url,
data=f,
headers=headers,
auth=credential
)
The roads
identifier in the URI refers to the name of the store to be created. To create a store named somethingelse
, the URI would be http://localhost:8080/geoserver/rest/workspaces/acme/datastores/somethingelse/file.shp
The new sotore information can be retreived with a GET request:
resource = 'workspaces/acme/datastores/roads.json'
headers = {'content-type': 'application/json'}
request_url = urljoin(api_entry, resource)
r = requests.get(
request_url,
headers=headers,
auth=credential
)
print(r.json())
When the shapefile is uploaded, a new feature type is also created. To see the feature type, issue a GET request with the adequate URI:
resource = 'workspaces/acme/datastores/roads/featuretype/roads.xml'
# ... Same code as above ...
In the previous example a shapefile was uploaded directly to GeoServer by sending a zip file in the body of a PUT request. This example shows how to publish a shapefile that already exists on the server.
Consider a directory on the server /data/shapefiles/rivers
that contains the shapefile rivers.shp
. The following adds a new store for the shapefile:
resource = 'workspaces/acme/datastores/rivers/external.shp'
payload = 'file:data/shapefiles/rivers/rivers.shp'
headers = {'content-type': 'text/plain'}
request_url = urljoin(api_entry, resource)
r = requests.put(
request_url,
data=payload,
headers=headers,
auth=credential
)
r.raise_for_status()
The shapefile will be added to the existing store and published as a layer.
To verify the contents of the store, execute a GET request. Let's try for an HTML response:
resource = 'workspaces/acme/datastores/rivers.html'
request_url = urljoin(api_entry, resource)
r = requests.get(
request_url,
auth=credential
)
print(r.text)
This example shows how to load and create a store that contains a number of shapefiles, all with a single operation. This example is very similar to the example above of adding a single shapefile.
Consider a directory on the server /data/shapefiles
that contains multiple shapefiles. The following adds a new store for the directory:
resource = 'workspaces/acme/datastores/shapefiles/external.shp?configure=all'
payload = 'file:///data/data/shapefiles'
headers = {'content-type': 'text/plain'}
request_url = urljoin(api_entry, resource)
r = requests.put(
request_url,
data=payload,
headers=headers,
auth=credential
)
Note the configure=all
query string parameter, which sets each shapefile in the directory to be loaded and published.
To verify the contents of the store, execute a GET request. Again, let's try with HTML:
resource = 'workspaces/acme/datastores/shapefiles.html'
request_url = urljoin(api_entry, resource)
r = requests.get(
request_url,
auth=credential
)
This example will create a new style on the server and populate it the contents of a local SLD file.
The following creates a new style named roads_style
:
resource = 'styles'
payload = \
'<style><name>roads_style</name><filename>roads.sld</filename></style>'
headers = {'content-type': 'text/xml'}
request_url = urljoin(api_entry, resource)
r = requests.post(
request_url,
data=payload,
headers=headers,
auth=credential
)
This request uploads a file called roads.sld
file and populates the roads_style
with its contents:
resource = 'styles/roads_style'
file_name = 'roads.sld'
headers = {'conten-type': 'application/vnd.ogc.sld+xml'}
request_url = urljoin(api_entry, resource)
with open(file_name, 'rb') as f:
r = requests.put(
request_url,
data=f,
headers=headers,
auth=credential
)
thank you for this work!
a note however: if we run twice the creation of the workspace, we get a 500 error. it is therefore necessary to test the existence of the workspace before actually creating it.