Now that you are familiar with REST, it is time to get your hands on GeoServer and have a look at how its REST interface works.
Basically, it exposes operations to you so that you can manage all configurations' objects. You will find the same items, for example, layers and styles, which you are used to creating from the web interface.
In this first recipe, you will start with workspaces and namespaces, which are the logical groups that contain all other configuration's items.
We stated before that Python's main aims are simplicity and code readability; unfortunately, this is not always the case. Interacting with REST using standard Python libraries may be painful and very verbose. Luckily, there is an open source project that solves this problem. The project produced a library called Requests
and I have to say, it is a really appropriate name.
Requests
is an open source project started by Kenneth Reitz. You can download and use it liberally; it is released under the ISC license. You can also fork it on GitHub and add features. Refer to http://docs.python-requests.org/en/latest/.
Let's install it!
$ wget https://github.com/kennethreitz/requests/tarball/master -O master.tar.gz $ ls -al drwxrwxr-x 2 stefano stefano 4096 Oct 15 08:01 ./ drwxr-xr-x 9 stefano stefano 4096 Oct 15 07:41 ../ -rw-rw-r-- 1 stefano stefano 720204 Oct 15 08:02 master.tar.gz
$ tar xvfz master.tar.gz …
$ cd kennethreitz-requests-07f9a7e $ sudo python setup.py install
$ python Python 2.7.3 (default, Feb 27 2014, 19:58:35) [GCC 4.6.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import requests >>> resp = requests.get('http://geoserver.org/display/GEOS/License') >>> resp.text u'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <title>License - GeoServer</title> …
You just installed the Requests
library as a site package inside your Python installation. Furthermore, by asking for the license page on the GeoServer site, you also had your first taste of its power and simplicity. You can now use it inside any Python program, leveraging on its powerful objects to interact with the HTTP protocol.
Please note that REST operations require authentication, so you need to supply the user ID and password for the GeoServer administrator or a user you defined and granted the admin role to. In these recipes, the default admin/geoserver
values are used; replace them with proper values for your system.
GET
operation. The following code snippet shows you the syntax:$ curl -u admin:geoserver -v -XGET -H 'Accept: text/xml' http://localhost:8080/geoserver/rest/workspaces -o workspaces.xml
-v
parameter on the command line, a lot of information is displayed. Note the line reporting the status code of operation to check whether it was successful:> User-Agent: curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3 > Host: localhost:8080 > Accept: text/xml > < HTTP/1.1 200 OK
workspace.xml
; check that its length is not equal to zero. The code is as follows:$ ll total 12K drwxrwxr-x 2 stefano stefano 4.0K May 1 16:10 ./ drwxr-xr-x 20 stefano stefano 4.0K May 1 16:10 ../ -rw-rw-r-- 1 stefano stefano 254 May 1 16:15 workspaces.xml
$ python Python 2.7.3 (default, Feb 27 2014, 19:58:35) [GCC 4.6.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import requests >>> myUrl = 'http://localhost:8080/geoserver/rest/workspaces' >>> headers = {'Accept': 'text/xml'} >>> resp = requests.get(myUrl,auth=('admin','geoserver'),headers=headers) >>> resp.status_code 200
>>> file = open('workspaces_py.xml','w') >>> file.write(resp.text) >>> file.close()
$ diff workspaces.xml workspaces_py.xml $
<workspaces> <workspace> <name>NaturalEarth</name> <atom:link xmlns:atom="http://www.w3.org/2005/Atom" rel="alternate" href="http://localhost:8080/geoserver/rest/workspaces/NaturalEarth.xml" type="application/xml"/> </workspace> </workspaces>
$ curl -u admin:geoserver -XGET -H 'Accept: text/xml' http://localhost:8080/geoserver/rest/namespaces/NaturalEarth -o NaturalEarth.xml
… >>> myUrl = 'http://localhost:8080/geoserver/rest/namespaces/NaturalEarth' … file = open('NaturalEarth_py.xml','w') …
<namespace> <prefix>NaturalEarth</prefix> <uri>http://www.naturalearthdata.com/</uri> <featureTypes> <atom:link xmlns:atom="http://www.w3.org/2005/Atom" rel="alternate" href="http://localhost:8080/geoserver/rest/workspaces/NaturalEarth/featuretypes.xml" type="application/xml"/> </featureTypes> </namespace>
<namespace> <prefix>MyOrganization</prefix> <uri>http://www.someone.org/</uri> </namespace>
$ curl -u admin:geoserver -XPOST -H 'Content-type: text/xml' -d @MyOrganization.xml http://localhost:8080/geoserver/rest/namespaces
>>> myUrl = 'http://localhost:8080/geoserver/rest/namespaces' >>> file = open('MyOrganization.xml','r') >>> payload = file.read() >>> headers = {'Content-type': 'text/xml'} >>> resp = requests.post(myUrl, auth=('admin','geoserver'), data=payload, headers=headers) >>> resp.status_code 201
In this recipe, you learned how to manage workspaces and namespaces. In GeoServer, a workspace is a logical object that you can use to group together data stores, feature types, coverages, and styles.
What's the difference between a workspace and a namespace? You first queried GeoServer for the NaturalEarth
workspace and obtained its properties, which is basically a name:
<name>NaturalEarth</name>
A namespace associated with a workspace that is in the form of a Uniform Resource Identifier (URI) and typically a URL always exists. Although you can insert any URL, it is usually a good choice to select something that is associated with your project.
Workspaces and namespace are very similar and, in fact, you created both by calling the namespace operation, perhaps with an added trailing identifier indicating the workspace.
The GeoServer REST interface exposes resources for each one of them; there are two resources that you can use to access these elements:
/workspaces
/namespaces
On both the resources, GET
, POST
, PUT
, and DELETE
operations are defined. This allows you to view, create, update, and delete workspaces and namespaces.
You have to use GET
when you just want to retrieve information. If you want to create a new object, POST
comes in handy. PUT
is used to change properties of an existing item, while DELETE
lets you remove items.
As GeoServer REST interface uses the HTTP protocol, you should always look for the return code. This lets you know whether your request was successfully implemented by the server or some errors arose.
For a detailed list of operations supported and the HTTP status code expected, refer to the online GeoServer manual at http://docs.geoserver.org/stable/en/user/rest/api/index.html.
If you changed your mind about the URI assigned to a namespace, you don't need to delete it. You can change it with a PUT
request like this:
$ curl -u admin:geoserver -XPUT -H 'Content-type: text/xml' -H 'Accept: text/xml' -d '<namespace><prefix>MyOrganization</prefix><uri>http://about.me/geoserver</uri></namespace>' http://localhost:8080/geoserver/rest/namespaces/MyOrganization
Note that this time we didn't create a static file to submit information. In fact, the -d
cURL parameter accepts the data on the command line as well. While this may be useful for less data, when your XML code grows, a file is a more appropriate approach.
Going to the web interface, you can see that the URI was actually changed.
The following Python code lets you perform the same operation:
>>> myUrl = 'http://localhost:8080/geoserver/rest/namespaces/MyOrganization' >>> payload = '<namespace><prefix>MyOrganization</prefix><uri>http://about.me/geoserver</uri></namespace>' >>> headers = {'Content-type': 'text/xml'} >>> resp = requests.put(myUrl, auth=('admin','geoserver'), data=payload, headers=headers) >>> resp.status_code 200
To finish our tour of workspaces operations, we have to try the DELETE
option. Let's remove the MyOrganization
workspace:
$ curl -u admin:geoserver -XDELETE -H 'Accept: text/xml' http://localhost:8080/geoserver/rest/workspaces/MyOrganization
Here is the command to do so in Python:
>>> myUrl = 'http://localhost:8080/geoserver/rest/workspaces/MyOrganization' >>> headers = {'Accept': 'text/xml'} >>> resp = requests.delete(myUrl, auth=('admin','geoserver'), headers=headers) >>> resp.status_code 404
Can you guess why we got a 404 error?
404 stands for Not Found error (http://en.wikipedia.org/wiki/HTTP_404). You probably wondering whether the Python code contains an error.
This is not the case; it is just that we removed the workspace using cURL and obviously, you can't remove a nonexisting workspace. So, GeoServer complains when we try to remove it.
3.146.176.88