Skip to content

Commit b89e6c5

Browse files
authored
Merge branch 'master' into request-verify
2 parents 06af79a + fd7a80a commit b89e6c5

32 files changed

Lines changed: 1606 additions & 461 deletions

.github/workflows/main.yml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ on: [ push, pull_request ]
44

55
jobs:
66
main:
7-
runs-on: ubuntu-latest
7+
runs-on: ubuntu-24.04
88
strategy:
99
matrix:
1010
python-version: ["3.12"]
1111
steps:
1212
- uses: actions/checkout@master
13-
- uses: actions/setup-python@v5
13+
- uses: actions/setup-python@v6
1414
name: Setup Python ${{ matrix.python-version }}
1515
with:
1616
python-version: ${{ matrix.python-version }}
@@ -19,15 +19,15 @@ jobs:
1919
- name: Install requirements 📦
2020
run: |
2121
pip3 install -e .
22-
pip3 install -r requirements.txt
23-
pip3 install -r requirements-dev.txt
24-
pip3 install -r docs/requirements.txt
22+
pip3 install ".[dev]"
23+
pip3 install ".[docs]"
24+
pip3 install ".[test]"
2525
- name: run tests ⚙️
26-
run: python3 -m pytest
26+
run: pytest tests/
2727
- name: run tests in offline mode
2828
if: matrix.python-version == '3.12'
2929
run: |
30-
python3 -m pytest \
30+
pytest tests/\
3131
-m "not online" \
3232
--disable-socket \
3333
--deselect="tests/doctests/wcs_thredds.txt::wcs_thredds.txt" \
@@ -45,4 +45,4 @@ jobs:
4545
- name: build docs 🏗️
4646
run: cd docs && make html
4747
- name: run flake8 ⚙️
48-
run: flake8 owslib
48+
run: flake8 owslib/

.github/workflows/windows.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,17 @@ jobs:
1010
python-version: ["3.12"]
1111
steps:
1212
- uses: actions/checkout@master
13-
- uses: actions/setup-python@v5
13+
- uses: actions/setup-python@v6
1414
name: Setup Python ${{ matrix.python-version }}
1515
with:
1616
python-version: ${{ matrix.python-version }}
1717

1818
- name: Install requirements 📦
1919
run: |
2020
pip install -e .
21-
pip install -r requirements.txt
22-
pip install -r requirements-dev.txt
21+
pip install ".[dev]"
22+
pip install ".[docs]"
23+
pip install ".[test]"
2324
2425
- name: run tests ⚙️
25-
run: python -m pytest
26+
run: pytest tests/

MANIFEST.in

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,2 @@
1-
include LICENSE
2-
include *.md
3-
include *.rst
4-
include *.txt
5-
recursive-exclude tests *
1+
# this file controls the contents of sdist
2+
prune tests

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ pip3 install OWSLib
3131

3232
### Dependencies
3333

34-
Dependencies are listed in [requirements.txt](requirements.txt). Dependencies
34+
Dependencies are listed in [pyproject.toml](pyproject.toml). Dependencies
3535
are automatically installed during OWSLib installation.
3636

3737
### Installing OWSLib
@@ -147,8 +147,8 @@ Releasing
147147

148148
```bash
149149
# update version
150-
vi owslib/__init__.py
151-
git commit -m 'update release version' owslib/__init__.py
150+
vi pyproject.toml # update [project]/version
151+
git commit -m 'update release version' owslib/pyproject.toml
152152
# push changes
153153
git push origin master
154154
git tag -a x.y.z -m 'tagging OWSLib release x.y.z'
30.6 KB
Loading
-16.6 KB
Binary file not shown.

docs/source/development.rst

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,45 @@ You can find out about software metrics at the OWSLib OpenHub page at https://ww
1010
Testing
1111
-------
1212

13+
Create a virtual environment and install OWSLib with the development dependencies:
14+
1315
.. code-block:: bash
1416
15-
# install requirements
16-
pip3 install -r requirements.txt
17-
pip3 install -r requirements-dev.txt # needed for tests only
17+
python3 -m venv owslibenv
18+
source owslibenv/bin/activate
19+
20+
git clone https://github.com/geopython/OWSLib.git
21+
cd OWSLib
22+
23+
pip install -e ".[dev]"
24+
25+
Run the test suite:
26+
27+
.. code-block:: bash
1828
19-
# run tests
2029
python3 -m pytest
2130
22-
# linting
23-
flake8 owslib/wmts.py
31+
Run linting:
32+
33+
.. code-block:: bash
34+
35+
flake8 owslib/
36+
37+
Documentation
38+
-------------
39+
40+
To build the documentation locally:
41+
42+
.. code-block:: bash
43+
44+
pip install -e ".[docs]"
45+
cd docs && make html
46+
47+
Release
48+
-------
49+
50+
To install the release tooling:
51+
52+
.. code-block:: bash
53+
54+
pip install -e ".[release]"

docs/source/usage.rst

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,71 +9,66 @@ Find out what a WMS has to offer. Service metadata:
99
.. code-block:: python
1010
1111
>>> from owslib.wms import WebMapService
12-
>>> wms = WebMapService('http://wms.jpl.nasa.gov/wms.cgi', version='1.1.1')
12+
>>> wms = WebMapService('https://mesonet.agron.iastate.edu/cgi-bin/mapserv/mapserv?map=/opt/iem/data/wms/goes/west_ir.map&SERVICE=WMS&REQUEST=GetCapabilities')
1313
>>> wms.identification.type
1414
'OGC:WMS'
1515
>>> wms.identification.version
1616
'1.1.1'
1717
>>> wms.identification.title
18-
'JPL Global Imagery Service'
18+
'IEM GOES IR WMS Service'
1919
>>> wms.identification.abstract
20-
'WMS Server maintained by JPL, worldwide satellite imagery.'
20+
'IEM generated CONUS composite of GOES IR Satellite.'
2121
2222
Available layers:
2323

2424
.. code-block:: python
2525
2626
>>> list(wms.contents)
27-
['global_mosaic', 'global_mosaic_base', 'us_landsat_wgs84', 'srtm_mag', 'daily_terra_721', 'daily_aqua_721', 'daily_terra_ndvi', 'daily_aqua_ndvi', 'daily_terra', 'daily_aqua', 'BMNG', 'modis', 'huemapped_srtm', 'srtmplus', 'worldwind_dem', 'us_ned', 'us_elevation', 'us_colordem']
27+
['goes_west_ir', 'west_ir_4km', 'west_ir_4km_gray']
2828
2929
Details of a layer:
3030

3131
.. code-block:: python
3232
33-
>>> wms['global_mosaic'].title
34-
'WMS Global Mosaic, pan sharpened'
35-
>>> wms['global_mosaic'].queryable
33+
>>> wms['goes_west_ir'].title
34+
'IEM GOES IR WMS Service'
35+
>>> wms['goes_west_ir'].queryable
3636
0
37-
>>> wms['global_mosaic'].opaque
37+
>>> wms['goes_west_ir'].opaque
3838
0
39-
>>> wms['global_mosaic'].boundingBox
40-
>>> wms['global_mosaic'].boundingBoxWGS84
41-
(-180.0, -60.0, 180.0, 84.0)
42-
>>> wms['global_mosaic'].crsOptions
43-
['EPSG:4326', 'AUTO:42003']
44-
>>> wms['global_mosaic'].styles
45-
{'pseudo_bright': {'title': 'Pseudo-color image (Uses IR and Visual bands, 542 mapping), gamma 1.5'}, 'pseudo': {'title': '(default) Pseudo-color image, pan sharpened (Uses IR and Visual bands, 542 mapping), gamma 1.5'}, 'visual': {'title': 'Real-color image, pan sharpened (Uses the visual bands, 321 mapping), gamma 1.5'}, 'pseudo_low': {'title': 'Pseudo-color image, pan sharpened (Uses IR and Visual bands, 542 mapping)'}, 'visual_low': {'title': 'Real-color image, pan sharpened (Uses the visual bands, 321 mapping)'}, 'visual_bright': {'title': 'Real-color image (Uses the visual bands, 321 mapping), gamma 1.5'}}
39+
>>> wms['goes_west_ir'].boundingBox
40+
(-126.0, 24.0, -66.0, 50.0, 'EPSG:4326')
41+
>>> wms['goes_west_ir'].boundingBoxWGS84
42+
(-126.0, 24.0, -66.0, 50.0)
43+
>>> wms['goes_west_ir'].crsOptions
44+
['EPSG:3857', 'EPSG:4326']
4645
4746
Available methods, their URLs, and available formats:
4847

4948
.. code-block:: python
5049
5150
>>> [op.name for op in wms.operations]
52-
['GetCapabilities', 'GetMap']
51+
['GetCapabilities', 'GetMap', 'GetFeatureInfo', 'DescribeLayer', 'GetLegendGraphic', 'GetStyles']
5352
>>> wms.getOperationByName('GetMap').methods
54-
{'Get': {'url': 'http://wms.jpl.nasa.gov/wms.cgi?'}}
53+
[{'type': 'Get', 'url': 'https://mesonet.agron.iastate.edu/cgi-bin/mapserv/mapserv?map=/opt/iem/data/wms/goes/west_ir.map&SERVICE=WMS&'}, {'type': 'Post', 'url': 'https://mesonet.agron.iastate.edu/cgi-bin/mapserv/mapserv?map=/opt/iem/data/wms/goes/west_ir.map&SERVICE=WMS&'}]
5554
>>> wms.getOperationByName('GetMap').formatOptions
56-
['image/jpeg', 'image/png', 'image/geotiff', 'image/tiff']
55+
['image/png', 'image/jpeg', 'image/png; mode=8bit', 'image/vnd.jpeg-png', 'image/vnd.jpeg-png8', 'application/x-pdf', 'image/svg+xml', 'image/tiff', 'application/json']
5756
5857
That's everything needed to make a request for imagery:
5958

6059
.. code-block:: python
6160
62-
>>> img = wms.getmap( layers=['global_mosaic'],
63-
... styles=['visual_bright'],
64-
... srs='EPSG:4326',
65-
... bbox=(-112, 36, -106, 41),
66-
... size=(300, 250),
67-
... format='image/jpeg',
68-
... transparent=True
69-
... )
70-
>>> out = open('jpl_mosaic_visb.jpg', 'wb')
71-
>>> out.write(img.read())
72-
>>> out.close()
61+
>>> img = wms.getmap(layers=['goes_west_ir'],
62+
size=(300, 250),
63+
bbox=(-126, 24, -66, 50),
64+
srs='EPSG:4326',
65+
format='image/png')
66+
>>> with open('iem_goes_ir.png', 'wb') as fh:
67+
... fh.write(img.read())
7368
7469
Result:
7570

76-
.. image:: _static/jpl_mosaic_visb.jpg
71+
.. image:: _static/iem_goes_ir.png
7772
:width: 300px
7873
:height: 250px
7974
:alt: WMS GetMap generated by OWSLib

owslib/__init__.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,12 @@
1-
__version__ = '0.35.0'
1+
# -*- coding: ISO-8859-15 -*-
2+
# =============================================================================
3+
# Copyright (c) 2026 Tom Kralidis
4+
#
5+
# Authors : Tom Kralidis <tomkralidis@gmail.com>
6+
#
7+
# Contact email: tomkralidis@gmail.com
8+
# =============================================================================
9+
10+
from owslib.util import get_package_version
11+
12+
__version__ = get_package_version()

owslib/catalogue/csw2.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -849,15 +849,26 @@ def __init__(self, record):
849849
for i in record.findall(util.nspath_eval('dc:rights', namespaces)):
850850
self.rights.append(util.testXMLValue(i))
851851

852-
val = record.find(util.nspath_eval('dct:spatial', namespaces))
853-
self.spatial = util.testXMLValue(val)
854-
855852
val = record.find(util.nspath_eval('ows:BoundingBox', namespaces))
856853
if val is not None:
857854
self.bbox = ows.BoundingBox(val, namespaces['ows'])
858855
else:
859856
self.bbox = None
860857

858+
val = record.find(util.nspath_eval('dct:spatial', namespaces))
859+
self.spatial = None
860+
if val is not None:
861+
val = util.testXMLValue(val)
862+
bbox_tokens = val.split(',')
863+
if len(bbox_tokens) == 4:
864+
self.bbox = ows.BoundingBox(None, namespaces['ows'])
865+
self.bbox.minx = bbox_tokens[0]
866+
self.bbox.miny = bbox_tokens[1]
867+
self.bbox.maxx = bbox_tokens[2]
868+
self.bbox.maxy = bbox_tokens[3]
869+
else:
870+
self.spatial = val
871+
861872
val = record.find(util.nspath_eval('ows:WGS84BoundingBox', namespaces))
862873
if val is not None:
863874
self.bbox_wgs84 = ows.WGS84BoundingBox(val, namespaces['ows'])

0 commit comments

Comments
 (0)