geoservercloud 0.8.1.dev3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- geoservercloud-0.8.1.dev3/LICENSE +22 -0
- geoservercloud-0.8.1.dev3/PKG-INFO +166 -0
- geoservercloud-0.8.1.dev3/README.md +143 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/.gitignore +2 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/README.md +118 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/__init__.py +0 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/cli.py +40 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/compose/example.compose.yaml +37 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/compose/geodatabase/001_create_schemas.sql +3 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/config.py +82 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/data/sampledata.tgz +0 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/example.config.yaml +23 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/__init__.py +1 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/conftest.py +164 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/resources/__init__.py +0 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/resources/i18n/__init__.py +0 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/resources/i18n/labels/default_locale/default_value/language_None_expected.png +0 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/resources/i18n/labels/default_locale/default_value/language__expected.png +0 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/resources/i18n/labels/default_locale/default_value/language_de_expected.png +0 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/resources/i18n/labels/default_locale/default_value/language_fr_expected.png +0 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/resources/i18n/labels/default_locale/default_value/language_it_expected.png +0 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/resources/i18n/labels/default_locale/no_default_value/language_None_expected.png +0 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/resources/i18n/labels/default_locale/no_default_value/language__expected.png +0 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/resources/i18n/labels/default_locale/no_default_value/language_it_expected.png +0 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/resources/i18n/labels/no_default_locale/default_value/language_None_expected.png +0 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/resources/i18n/labels/no_default_locale/default_value/language__expected.png +0 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/resources/i18n/labels/no_default_locale/default_value/language_de_expected.png +0 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/resources/i18n/labels/no_default_locale/default_value/language_fr_expected.png +0 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/resources/i18n/labels/no_default_locale/default_value/language_it_expected.png +0 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/resources/i18n/labels/no_default_locale/no_default_value/language_None_expected.png +0 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/resources/i18n/labels/no_default_locale/no_default_value/language__expected.png +0 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/resources/i18n/labels/no_default_locale/no_default_value/language_it_expected.png +0 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/resources/i18n/localized_labels.sld +36 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/resources/i18n/localized_no_default.sld +37 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/resources/i18n/localized_with_default.sld +37 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/resources/wfs/__init__.py +0 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/resources/wfs/wfs_delete_payload.xml +13 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/resources/wfs/wfs_insert_payload.xml +16 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/resources/wms/__init__.py +0 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/resources/wms/getmap_expected.png +0 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/test_cascaded_stores.py +122 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/test_cog.py +58 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/test_datastore.py +26 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/test_get_version.py +11 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/test_gwc.py +45 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/test_i18n.py +520 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/test_imagemosaic.py +510 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/test_imagemosaic_cog.py +208 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/test_wfs.py +87 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/test_wms.py +133 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/test_workspace.py +23 -0
- geoservercloud-0.8.1.dev3/geoserver_acceptance_tests/tests/utils.py +42 -0
- geoservercloud-0.8.1.dev3/geoservercloud/__init__.py +4 -0
- geoservercloud-0.8.1.dev3/geoservercloud/geoservercloud.py +1380 -0
- geoservercloud-0.8.1.dev3/geoservercloud/geoservercloudsync.py +357 -0
- geoservercloud-0.8.1.dev3/geoservercloud/gridsets/2056.xml +83 -0
- geoservercloud-0.8.1.dev3/geoservercloud/gridsets/21781.xml +83 -0
- geoservercloud-0.8.1.dev3/geoservercloud/gridsets/3857.xml +92 -0
- geoservercloud-0.8.1.dev3/geoservercloud/models/__init__.py +0 -0
- geoservercloud-0.8.1.dev3/geoservercloud/models/abstractlayer.py +92 -0
- geoservercloud-0.8.1.dev3/geoservercloud/models/common.py +376 -0
- geoservercloud-0.8.1.dev3/geoservercloud/models/coverage.py +127 -0
- geoservercloud-0.8.1.dev3/geoservercloud/models/coverages.py +19 -0
- geoservercloud-0.8.1.dev3/geoservercloud/models/coveragestore.py +89 -0
- geoservercloud-0.8.1.dev3/geoservercloud/models/datastore.py +84 -0
- geoservercloud-0.8.1.dev3/geoservercloud/models/datastores.py +6 -0
- geoservercloud-0.8.1.dev3/geoservercloud/models/featuretype.py +177 -0
- geoservercloud-0.8.1.dev3/geoservercloud/models/featuretypes.py +6 -0
- geoservercloud-0.8.1.dev3/geoservercloud/models/layer.py +78 -0
- geoservercloud-0.8.1.dev3/geoservercloud/models/layergroup.py +120 -0
- geoservercloud-0.8.1.dev3/geoservercloud/models/layergroups.py +6 -0
- geoservercloud-0.8.1.dev3/geoservercloud/models/resourcedirectory.py +44 -0
- geoservercloud-0.8.1.dev3/geoservercloud/models/style.py +138 -0
- geoservercloud-0.8.1.dev3/geoservercloud/models/styles.py +26 -0
- geoservercloud-0.8.1.dev3/geoservercloud/models/wmslayer.py +102 -0
- geoservercloud-0.8.1.dev3/geoservercloud/models/wmssettings.py +159 -0
- geoservercloud-0.8.1.dev3/geoservercloud/models/wmsstore.py +74 -0
- geoservercloud-0.8.1.dev3/geoservercloud/models/workspace.py +32 -0
- geoservercloud-0.8.1.dev3/geoservercloud/models/workspaces.py +6 -0
- geoservercloud-0.8.1.dev3/geoservercloud/services/__init__.py +7 -0
- geoservercloud-0.8.1.dev3/geoservercloud/services/owsservice.py +223 -0
- geoservercloud-0.8.1.dev3/geoservercloud/services/restclient.py +147 -0
- geoservercloud-0.8.1.dev3/geoservercloud/services/restlogger.py +5 -0
- geoservercloud-0.8.1.dev3/geoservercloud/services/restservice.py +1053 -0
- geoservercloud-0.8.1.dev3/geoservercloud/templates.py +84 -0
- geoservercloud-0.8.1.dev3/geoservercloud/utils.py +88 -0
- geoservercloud-0.8.1.dev3/pyproject.toml +61 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2024, Camptocamp SA
|
|
2
|
+
All rights reserved.
|
|
3
|
+
|
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
|
5
|
+
modification, are permitted provided that the following conditions are met:
|
|
6
|
+
|
|
7
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
8
|
+
list of conditions and the following disclaimer.
|
|
9
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
10
|
+
this list of conditions and the following disclaimer in the documentation
|
|
11
|
+
and/or other materials provided with the distribution.
|
|
12
|
+
|
|
13
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
14
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
15
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
16
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
|
17
|
+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
18
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
19
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
20
|
+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
21
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
22
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: geoservercloud
|
|
3
|
+
Version: 0.8.1.dev3
|
|
4
|
+
Summary: Lightweight Python client to interact with GeoServer Cloud REST API, GeoServer ACL and OGC services
|
|
5
|
+
License: BSD-2-Clause
|
|
6
|
+
Author: Camptocamp
|
|
7
|
+
Author-email: info@camptocamp.com
|
|
8
|
+
Requires-Python: >=3.10
|
|
9
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Requires-Dist: OWSLib
|
|
16
|
+
Requires-Dist: psycopg2-binary
|
|
17
|
+
Requires-Dist: pytest
|
|
18
|
+
Requires-Dist: requests
|
|
19
|
+
Requires-Dist: sqlalchemy
|
|
20
|
+
Requires-Dist: xmltodict
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
|
|
23
|
+
# python-geoservercloud
|
|
24
|
+
|
|
25
|
+
## Documentation
|
|
26
|
+
|
|
27
|
+
https://camptocamp.github.io/python-geoservercloud/
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
From PyPI:
|
|
32
|
+
|
|
33
|
+
```shell
|
|
34
|
+
pip install geoservercloud
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
From git repository:
|
|
38
|
+
|
|
39
|
+
```shell
|
|
40
|
+
git clone https://github.com/camptocamp/python-geoservercloud
|
|
41
|
+
cd python-geoservercloud
|
|
42
|
+
python3 -m venv .venv
|
|
43
|
+
source .venv/bin/activate
|
|
44
|
+
poetry install
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Quick start
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
from geoservercloud import GeoServerCloud
|
|
51
|
+
|
|
52
|
+
geoserver = GeoServerCloud(
|
|
53
|
+
url="http://localhost:9090/geoserver/cloud/",
|
|
54
|
+
user="admin",
|
|
55
|
+
password="geoserver",
|
|
56
|
+
)
|
|
57
|
+
geoserver.create_workspace("newworkspace")
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## About
|
|
61
|
+
|
|
62
|
+
Lightweight Python client to interact with GeoServer Cloud REST API, GeoServer ACL and OGC services.
|
|
63
|
+
Intended use cases are listed below.
|
|
64
|
+
|
|
65
|
+
### Programmatic setup of a GeoServer catalog
|
|
66
|
+
|
|
67
|
+
For example, creating a workspace, connecting to a PostGIS datastore and publishing a PG layer:
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
geoserver.create_workspace("example")
|
|
71
|
+
geoserver.create_pg_datastore(
|
|
72
|
+
workspace_name="example",
|
|
73
|
+
datastore_name="example_store",
|
|
74
|
+
pg_host="localhost",
|
|
75
|
+
pg_port=5432,
|
|
76
|
+
pg_db="database",
|
|
77
|
+
pg_user="user",
|
|
78
|
+
pg_password="password"
|
|
79
|
+
)
|
|
80
|
+
geoserver.create_feature_type(
|
|
81
|
+
layer_name="layer_example",
|
|
82
|
+
workspace_name="example",
|
|
83
|
+
datastore_name="example_store",
|
|
84
|
+
title={
|
|
85
|
+
"en":"Layer title",
|
|
86
|
+
"fr": "Titre de la couche",
|
|
87
|
+
"default": "Default title",
|
|
88
|
+
},
|
|
89
|
+
)
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Testing
|
|
93
|
+
|
|
94
|
+
Automatic tests of GeoServer functionalities with `pytest`, for example before upgrading.
|
|
95
|
+
The example below tests the fallback mechanism for internationalized layer titles in the GetCapabilities document.
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
@pytest.mark.parametrize(
|
|
99
|
+
"language,expected_title",
|
|
100
|
+
[
|
|
101
|
+
(
|
|
102
|
+
"en",
|
|
103
|
+
"Layer title",
|
|
104
|
+
),
|
|
105
|
+
(
|
|
106
|
+
"fr",
|
|
107
|
+
"Titre de la couche",
|
|
108
|
+
),
|
|
109
|
+
(
|
|
110
|
+
"de,en",
|
|
111
|
+
"Layer title",
|
|
112
|
+
),
|
|
113
|
+
(
|
|
114
|
+
None,
|
|
115
|
+
"Default title",
|
|
116
|
+
),
|
|
117
|
+
],
|
|
118
|
+
)
|
|
119
|
+
def test_i18n_layer_title(geoserver, language, expected_title):
|
|
120
|
+
capabilities = geoserver.get_wms_layers(
|
|
121
|
+
workspace="example",
|
|
122
|
+
accept_languages=language,
|
|
123
|
+
)
|
|
124
|
+
layer = capabilities.get("Layer")
|
|
125
|
+
assert layer.get("Title") == expected_title
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
A test suite is provided in the directory `geoserver_acceptance_tests`.
|
|
129
|
+
|
|
130
|
+
### Syncing
|
|
131
|
+
|
|
132
|
+
Copying a workspace from one GeoServer instance to another, including PG datastores, layers, styles and style images.
|
|
133
|
+
|
|
134
|
+
#### In a Python console or script
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
from geoservercloud import GeoServerCloudSync
|
|
138
|
+
geoserversync = GeoServerCloudSync(
|
|
139
|
+
src_url="http://localhost:8080/geoserver",
|
|
140
|
+
src_user="admin",
|
|
141
|
+
src_password="geoserver",
|
|
142
|
+
dst_url="http://localhost:9099/geoserver",
|
|
143
|
+
dst_user="admin",
|
|
144
|
+
dst_password="geoserver",
|
|
145
|
+
)
|
|
146
|
+
geoserversync.copy_workspace("workspace_name", deep_copy=True)
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
#### In a shell terminal or script
|
|
150
|
+
|
|
151
|
+
First install the package in your current virtual environment (see [Installation](#installation)), then run the script with:
|
|
152
|
+
|
|
153
|
+
```shell
|
|
154
|
+
copy-workspace --src_url "http://localhost:8080/geoserver" --src_user admin --src_password geoserver --dst_url "http://localhost:9099/geoserver" --dst_user admin --dst_password geoserver --workspace workspace_name
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Logging
|
|
158
|
+
|
|
159
|
+
Set the log level using the standard `logging` module, e.g.:
|
|
160
|
+
|
|
161
|
+
```python
|
|
162
|
+
import logging
|
|
163
|
+
|
|
164
|
+
logging.getLogger("geoservercloud").setLevel(logging.DEBUG)
|
|
165
|
+
```
|
|
166
|
+
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# python-geoservercloud
|
|
2
|
+
|
|
3
|
+
## Documentation
|
|
4
|
+
|
|
5
|
+
https://camptocamp.github.io/python-geoservercloud/
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
From PyPI:
|
|
10
|
+
|
|
11
|
+
```shell
|
|
12
|
+
pip install geoservercloud
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
From git repository:
|
|
16
|
+
|
|
17
|
+
```shell
|
|
18
|
+
git clone https://github.com/camptocamp/python-geoservercloud
|
|
19
|
+
cd python-geoservercloud
|
|
20
|
+
python3 -m venv .venv
|
|
21
|
+
source .venv/bin/activate
|
|
22
|
+
poetry install
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Quick start
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
from geoservercloud import GeoServerCloud
|
|
29
|
+
|
|
30
|
+
geoserver = GeoServerCloud(
|
|
31
|
+
url="http://localhost:9090/geoserver/cloud/",
|
|
32
|
+
user="admin",
|
|
33
|
+
password="geoserver",
|
|
34
|
+
)
|
|
35
|
+
geoserver.create_workspace("newworkspace")
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## About
|
|
39
|
+
|
|
40
|
+
Lightweight Python client to interact with GeoServer Cloud REST API, GeoServer ACL and OGC services.
|
|
41
|
+
Intended use cases are listed below.
|
|
42
|
+
|
|
43
|
+
### Programmatic setup of a GeoServer catalog
|
|
44
|
+
|
|
45
|
+
For example, creating a workspace, connecting to a PostGIS datastore and publishing a PG layer:
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
geoserver.create_workspace("example")
|
|
49
|
+
geoserver.create_pg_datastore(
|
|
50
|
+
workspace_name="example",
|
|
51
|
+
datastore_name="example_store",
|
|
52
|
+
pg_host="localhost",
|
|
53
|
+
pg_port=5432,
|
|
54
|
+
pg_db="database",
|
|
55
|
+
pg_user="user",
|
|
56
|
+
pg_password="password"
|
|
57
|
+
)
|
|
58
|
+
geoserver.create_feature_type(
|
|
59
|
+
layer_name="layer_example",
|
|
60
|
+
workspace_name="example",
|
|
61
|
+
datastore_name="example_store",
|
|
62
|
+
title={
|
|
63
|
+
"en":"Layer title",
|
|
64
|
+
"fr": "Titre de la couche",
|
|
65
|
+
"default": "Default title",
|
|
66
|
+
},
|
|
67
|
+
)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Testing
|
|
71
|
+
|
|
72
|
+
Automatic tests of GeoServer functionalities with `pytest`, for example before upgrading.
|
|
73
|
+
The example below tests the fallback mechanism for internationalized layer titles in the GetCapabilities document.
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
@pytest.mark.parametrize(
|
|
77
|
+
"language,expected_title",
|
|
78
|
+
[
|
|
79
|
+
(
|
|
80
|
+
"en",
|
|
81
|
+
"Layer title",
|
|
82
|
+
),
|
|
83
|
+
(
|
|
84
|
+
"fr",
|
|
85
|
+
"Titre de la couche",
|
|
86
|
+
),
|
|
87
|
+
(
|
|
88
|
+
"de,en",
|
|
89
|
+
"Layer title",
|
|
90
|
+
),
|
|
91
|
+
(
|
|
92
|
+
None,
|
|
93
|
+
"Default title",
|
|
94
|
+
),
|
|
95
|
+
],
|
|
96
|
+
)
|
|
97
|
+
def test_i18n_layer_title(geoserver, language, expected_title):
|
|
98
|
+
capabilities = geoserver.get_wms_layers(
|
|
99
|
+
workspace="example",
|
|
100
|
+
accept_languages=language,
|
|
101
|
+
)
|
|
102
|
+
layer = capabilities.get("Layer")
|
|
103
|
+
assert layer.get("Title") == expected_title
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
A test suite is provided in the directory `geoserver_acceptance_tests`.
|
|
107
|
+
|
|
108
|
+
### Syncing
|
|
109
|
+
|
|
110
|
+
Copying a workspace from one GeoServer instance to another, including PG datastores, layers, styles and style images.
|
|
111
|
+
|
|
112
|
+
#### In a Python console or script
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
from geoservercloud import GeoServerCloudSync
|
|
116
|
+
geoserversync = GeoServerCloudSync(
|
|
117
|
+
src_url="http://localhost:8080/geoserver",
|
|
118
|
+
src_user="admin",
|
|
119
|
+
src_password="geoserver",
|
|
120
|
+
dst_url="http://localhost:9099/geoserver",
|
|
121
|
+
dst_user="admin",
|
|
122
|
+
dst_password="geoserver",
|
|
123
|
+
)
|
|
124
|
+
geoserversync.copy_workspace("workspace_name", deep_copy=True)
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
#### In a shell terminal or script
|
|
128
|
+
|
|
129
|
+
First install the package in your current virtual environment (see [Installation](#installation)), then run the script with:
|
|
130
|
+
|
|
131
|
+
```shell
|
|
132
|
+
copy-workspace --src_url "http://localhost:8080/geoserver" --src_user admin --src_password geoserver --dst_url "http://localhost:9099/geoserver" --dst_user admin --dst_password geoserver --workspace workspace_name
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Logging
|
|
136
|
+
|
|
137
|
+
Set the log level using the standard `logging` module, e.g.:
|
|
138
|
+
|
|
139
|
+
```python
|
|
140
|
+
import logging
|
|
141
|
+
|
|
142
|
+
logging.getLogger("geoservercloud").setLevel(logging.DEBUG)
|
|
143
|
+
```
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# GeoServer acceptance test suite
|
|
2
|
+
|
|
3
|
+
## Installation
|
|
4
|
+
|
|
5
|
+
The instructions below use `pip`, but it's also possible to use Poetry.
|
|
6
|
+
|
|
7
|
+
### From PyPI
|
|
8
|
+
|
|
9
|
+
We recommend working in a dedicated Python virtual environment.
|
|
10
|
+
To create and activate it (on Linux):
|
|
11
|
+
|
|
12
|
+
```shell
|
|
13
|
+
python -m venv .venv
|
|
14
|
+
source .venv/bin/activate
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Install the lib:
|
|
18
|
+
|
|
19
|
+
```shell
|
|
20
|
+
pip install geoservercloud
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### From local repository in development mode
|
|
24
|
+
|
|
25
|
+
```shell
|
|
26
|
+
git clone git@github.com:camptocamp/python-geoservercloud
|
|
27
|
+
cd python-geoservercloud/geoserver_acceptance_tests
|
|
28
|
+
python -m venv .venv
|
|
29
|
+
source .venv/bin/activate
|
|
30
|
+
pip install -e ..
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Prerequisites
|
|
34
|
+
|
|
35
|
+
- a GeoServer instance is running and accessible with an admin user
|
|
36
|
+
- a test Postgres DB with the PostGIS extension is accessible
|
|
37
|
+
- the ImageMosaic sample data is mounted in GeoServer at `/opt/geoserver_data/sampledata`
|
|
38
|
+
- Internet access (from GeoServer)
|
|
39
|
+
|
|
40
|
+
The ImageMosaic sample data is provided as an archive at data/sampledata.tgz.
|
|
41
|
+
A script is provided to copy the sample data and is available in the venv once the package is installed:
|
|
42
|
+
|
|
43
|
+
```shell
|
|
44
|
+
copy-test-data /example/path/
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
And to directly extract the sample data to its destination:
|
|
48
|
+
|
|
49
|
+
```shell
|
|
50
|
+
extract-test-data /example/path/
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Configuration
|
|
54
|
+
|
|
55
|
+
See example configuration file `example.config.yaml`. Most values can be overridden at run time through environment variables:
|
|
56
|
+
|
|
57
|
+
| Environment Variable | Description | Config Override |
|
|
58
|
+
| ----------------------------- | --------------------------------------------------- | ------------------- |
|
|
59
|
+
| `GEOSERVER_ACCEPTANCE_CONFIG` | Path to the config YAML file | (overrides default) |
|
|
60
|
+
| `GEOSERVER_URL` | GeoServer base URL | `server.url` |
|
|
61
|
+
| `GEOSERVER_VERIFYTLS` | Enable/disable TLS verification. Expects true/false | `server.verifytls` |
|
|
62
|
+
| `GEOSERVER_USER` | GeoServer admin username | `credentials.user` |
|
|
63
|
+
| `GEOSERVER_PASSWORD` | GeoServer admin password | `credentials.pass` |
|
|
64
|
+
| `GEOSERVER_PG_HOST_DOCKER` | PostgreSQL host from Docker container | `db.pg_host.docker` |
|
|
65
|
+
| `GEOSERVER_PG_PORT_DOCKER` | PostgreSQL port from Docker container | `db.pg_port.docker` |
|
|
66
|
+
| `GEOSERVER_PG_HOST_LOCAL` | PostgreSQL host from local host | `db.pg_host.local` |
|
|
67
|
+
| `GEOSERVER_PG_PORT_LOCAL` | PostgreSQL port from local host | `db.pg_port.local` |
|
|
68
|
+
| `GEOSERVER_PG_DB` | PostgreSQL database name | `db.pg_db` |
|
|
69
|
+
| `GEOSERVER_PG_USER` | PostgreSQL username | `db.pg_user` |
|
|
70
|
+
| `GEOSERVER_PG_PASSWORD` | PostgreSQL password | `db.pg_password` |
|
|
71
|
+
| `GEOSERVER_PG_SCHEMA` | PostgreSQL schema | `db.pg_schema` |
|
|
72
|
+
|
|
73
|
+
There are two separate settings for the DB host and port because typically GeoServer and the DB are run as a docker composition while the tests themselves are run from the host. Supported host platforms are Linux, MacOS (experimental) and Windows (experimental) - feedback and PRs are welcome.
|
|
74
|
+
|
|
75
|
+
## Usage
|
|
76
|
+
|
|
77
|
+
Run tests
|
|
78
|
+
|
|
79
|
+
```shell
|
|
80
|
+
pytest --pyargs geoserver_acceptance_tests.tests -v
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
The default path to the configuration file is `/opt/geoserver_acceptance/config.yaml`. To change it - for example to use a file in the current directory, use the environment variable `GEOSERVER_ACCEPTANCE_CONFIG`:
|
|
84
|
+
|
|
85
|
+
```shell
|
|
86
|
+
GEOSERVER_ACCEPTANCE_CONFIG=./config.yaml pytest --pyargs geoserver_acceptance_tests.tests -v
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Enabling and disabling tests
|
|
90
|
+
|
|
91
|
+
Certain kinds of tests can be enabled or disabled through environment variables:
|
|
92
|
+
|
|
93
|
+
| Environment Variable | Description | Default |
|
|
94
|
+
| ------------------------------------- | ------------------------------------------------------------- | ------- |
|
|
95
|
+
| `GEOSERVER_ACCEPTANCE_RUN_DB_TESTS` | Enable/disable tests requiring DB access | `true` |
|
|
96
|
+
| `GEOSERVER_ACCEPTANCE_RUN_SLOW_TESTS` | Enable/disable slow tests | `false` |
|
|
97
|
+
| `GEOSERVER_ACCEPTANCE_RUN_COG_TESTS` | Enable/disable COG tests | `false` |
|
|
98
|
+
| `GEOSERVER_ACCEPTANCE_RUN_JNDI_TESTS` | Enable/disable tests requiring a JNDI resource (jdbc/postgis) | `false` |
|
|
99
|
+
|
|
100
|
+
### Run the example docker composition
|
|
101
|
+
|
|
102
|
+
An example docker composition is provided in order to illustrate the complete setup required to run the tests.
|
|
103
|
+
First, follow the steps described at [From local repository in development mode](#from-local-repository-in-development-mode).
|
|
104
|
+
Then run:
|
|
105
|
+
|
|
106
|
+
```shell
|
|
107
|
+
extract-test-data ./compose/geoserver_data/
|
|
108
|
+
UID=$(id -u) docker compose -f compose/example.compose.yaml up -d
|
|
109
|
+
export GEOSERVER_ACCEPTANCE_CONFIG=./example.config.yaml
|
|
110
|
+
export GEOSERVER_ACCEPTANCE_RUN_JNDI_TESTS=true
|
|
111
|
+
pytest --pyargs geoserver_acceptance_tests.tests -v
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Image comparison tests
|
|
115
|
+
|
|
116
|
+
Some tests use image comparison. If such a test fails, the generated image will be persisted in a temporary directory created by pytest (check the test logs for the exact location). The temporary directory location can be overridden with the environment variable `GEOSERVER_ACCEPTANCE_FAILED_TESTS_DIR`.
|
|
117
|
+
|
|
118
|
+
This allows for visual comparison with the expected images which can be found in `tests/resources`.
|
|
File without changes
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import shutil
|
|
3
|
+
from importlib import resources
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def copy_test_data():
|
|
8
|
+
parser = argparse.ArgumentParser(description="Copy GeoServer acceptance test data.")
|
|
9
|
+
parser.add_argument(
|
|
10
|
+
"target_dir",
|
|
11
|
+
help="Directory where test data should be copied",
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
args = parser.parse_args()
|
|
15
|
+
target = Path(args.target_dir)
|
|
16
|
+
target.mkdir(parents=True, exist_ok=True)
|
|
17
|
+
|
|
18
|
+
with resources.path("geoserver_acceptance_tests.data", "sampledata.tgz") as p:
|
|
19
|
+
shutil.copy(p, target / "sampledata.tgz")
|
|
20
|
+
|
|
21
|
+
print(f"Copied test data to: {target}")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def extract_test_data():
|
|
25
|
+
parser = argparse.ArgumentParser(
|
|
26
|
+
description="Extract GeoServer acceptance test data."
|
|
27
|
+
)
|
|
28
|
+
parser.add_argument(
|
|
29
|
+
"target_dir",
|
|
30
|
+
help="Directory where test data should be extracted",
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
args = parser.parse_args()
|
|
34
|
+
target = Path(args.target_dir)
|
|
35
|
+
target.mkdir(parents=True, exist_ok=True)
|
|
36
|
+
|
|
37
|
+
with resources.path("geoserver_acceptance_tests.data", "sampledata.tgz") as p:
|
|
38
|
+
shutil.unpack_archive(p, target)
|
|
39
|
+
|
|
40
|
+
print(f"Extracted test data to: {target}")
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
volumes:
|
|
2
|
+
geoserver_data:
|
|
3
|
+
driver: local
|
|
4
|
+
driver_opts:
|
|
5
|
+
type: none
|
|
6
|
+
o: bind
|
|
7
|
+
device: ./geoserver_data
|
|
8
|
+
|
|
9
|
+
services:
|
|
10
|
+
geoserver:
|
|
11
|
+
image: docker.osgeo.org/geoserver:2.28.x
|
|
12
|
+
ports:
|
|
13
|
+
- "8080:8080"
|
|
14
|
+
environment:
|
|
15
|
+
GEOSERVER_DATA_DIR: /opt/app/data_dir
|
|
16
|
+
RUN_WITH_USER_UID: ${UID}
|
|
17
|
+
CHANGE_OWNERSHIP_ON_FOLDERS: "/opt/app/data_dir /opt/geoserver_data"
|
|
18
|
+
POSTGRES_JNDI_ENABLED: true
|
|
19
|
+
POSTGRES_HOST: geodatabase
|
|
20
|
+
POSTGRES_PORT: 5432
|
|
21
|
+
POSTGRES_DB: geoserver
|
|
22
|
+
POSTGRES_USERNAME: geoserver
|
|
23
|
+
POSTGRES_PASSWORD: geoserver
|
|
24
|
+
POSTGRES_JNDI_RESOURCE_NAME: jdbc/postgis
|
|
25
|
+
volumes:
|
|
26
|
+
- geoserver_data:/opt/geoserver_data
|
|
27
|
+
geodatabase:
|
|
28
|
+
#image with arm/64 support:
|
|
29
|
+
image: imresamu/postgis:15-3.4
|
|
30
|
+
environment:
|
|
31
|
+
POSTGRES_DB: acceptance
|
|
32
|
+
POSTGRES_USER: geoserver
|
|
33
|
+
POSTGRES_PASSWORD: geoserver
|
|
34
|
+
volumes:
|
|
35
|
+
- ./geodatabase:/docker-entrypoint-initdb.d:ro
|
|
36
|
+
ports:
|
|
37
|
+
- "6432:5432"
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
import yaml
|
|
5
|
+
|
|
6
|
+
DEFAULT_CONFIG_PATH = "/opt/geoserver_acceptance/config.yaml"
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def load_config():
|
|
10
|
+
"""Load test configuration from a YAML file.
|
|
11
|
+
Environment variables can be used to override specific configuration values."""
|
|
12
|
+
path = os.getenv("GEOSERVER_ACCEPTANCE_CONFIG", DEFAULT_CONFIG_PATH)
|
|
13
|
+
|
|
14
|
+
if not os.path.exists(path):
|
|
15
|
+
raise FileNotFoundError(f"Config file not found: {path}")
|
|
16
|
+
|
|
17
|
+
with open(path) as f:
|
|
18
|
+
config = yaml.safe_load(f)
|
|
19
|
+
|
|
20
|
+
# Environment variables have precedence over configuration file
|
|
21
|
+
override_url = os.getenv("GEOSERVER_URL")
|
|
22
|
+
if override_url:
|
|
23
|
+
config["server"]["url"] = override_url
|
|
24
|
+
override_verifytls = os.getenv("GEOSERVER_VERIFYTLS")
|
|
25
|
+
if override_verifytls is not None:
|
|
26
|
+
config["server"]["verifytls"] = override_verifytls.lower() == "true"
|
|
27
|
+
override_user = os.getenv("GEOSERVER_USER")
|
|
28
|
+
if override_user:
|
|
29
|
+
config["credentials"]["user"] = override_user
|
|
30
|
+
override_pass = os.getenv("GEOSERVER_PASSWORD")
|
|
31
|
+
if override_pass:
|
|
32
|
+
config["credentials"]["pass"] = override_pass
|
|
33
|
+
override_pg_host = os.getenv("GEOSERVER_PG_HOST_DOCKER")
|
|
34
|
+
if override_pg_host:
|
|
35
|
+
config["db"]["pg_host"]["docker"] = override_pg_host
|
|
36
|
+
override_pg_port = os.getenv("GEOSERVER_PG_PORT_DOCKER")
|
|
37
|
+
if override_pg_port:
|
|
38
|
+
config["db"]["pg_port"]["docker"] = int(override_pg_port)
|
|
39
|
+
override_pg_host = os.getenv("GEOSERVER_PG_HOST_LOCAL")
|
|
40
|
+
if override_pg_host:
|
|
41
|
+
config["db"]["pg_host"]["local"] = override_pg_host
|
|
42
|
+
override_pg_port = os.getenv("GEOSERVER_PG_PORT_LOCAL")
|
|
43
|
+
if override_pg_port:
|
|
44
|
+
config["db"]["pg_port"]["local"] = int(override_pg_port)
|
|
45
|
+
override_pg_db = os.getenv("GEOSERVER_PG_DB")
|
|
46
|
+
if override_pg_db:
|
|
47
|
+
config["db"]["pg_db"] = override_pg_db
|
|
48
|
+
override_pg_user = os.getenv("GEOSERVER_PG_USER")
|
|
49
|
+
if override_pg_user:
|
|
50
|
+
config["db"]["pg_user"] = override_pg_user
|
|
51
|
+
override_pg_password = os.getenv("GEOSERVER_PG_PASSWORD")
|
|
52
|
+
if override_pg_password:
|
|
53
|
+
config["db"]["pg_password"] = override_pg_password
|
|
54
|
+
override_pg_schema = os.getenv("GEOSERVER_PG_SCHEMA")
|
|
55
|
+
if override_pg_schema:
|
|
56
|
+
config["db"]["pg_schema"] = override_pg_schema
|
|
57
|
+
|
|
58
|
+
# Configure logging for geoservercloud library
|
|
59
|
+
_setup_logging(config)
|
|
60
|
+
|
|
61
|
+
return config
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _setup_logging(config: dict):
|
|
65
|
+
"""Set up logging for the geoservercloud library based on configuration."""
|
|
66
|
+
# Get logging configuration from config file or use defaults
|
|
67
|
+
log_config = config.get("logging", {})
|
|
68
|
+
log_level_str = log_config.get("level", "INFO").upper()
|
|
69
|
+
log_level = getattr(logging, log_level_str, logging.INFO)
|
|
70
|
+
log_format = log_config.get(
|
|
71
|
+
"format", "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
# Configure the geoservercloud logger
|
|
75
|
+
logger = logging.getLogger("geoservercloud")
|
|
76
|
+
logger.setLevel(log_level)
|
|
77
|
+
|
|
78
|
+
# Add console handler if not already present
|
|
79
|
+
if not logger.handlers:
|
|
80
|
+
handler = logging.StreamHandler()
|
|
81
|
+
handler.setFormatter(logging.Formatter(log_format))
|
|
82
|
+
logger.addHandler(handler)
|
|
Binary file
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
server:
|
|
2
|
+
url: "http://localhost:8080/geoserver"
|
|
3
|
+
verifytls: true
|
|
4
|
+
|
|
5
|
+
credentials:
|
|
6
|
+
user: "admin"
|
|
7
|
+
pass: "geoserver"
|
|
8
|
+
|
|
9
|
+
logging:
|
|
10
|
+
level: "DEBUG"
|
|
11
|
+
format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
|
12
|
+
|
|
13
|
+
db:
|
|
14
|
+
pg_host:
|
|
15
|
+
docker: "geodatabase"
|
|
16
|
+
local: "localhost"
|
|
17
|
+
pg_port:
|
|
18
|
+
docker: 5432
|
|
19
|
+
local: 6432
|
|
20
|
+
pg_db: "acceptance"
|
|
21
|
+
pg_user: "geoserver"
|
|
22
|
+
pg_password: "geoserver"
|
|
23
|
+
pg_schema: "test1"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Test package
|