Coverage for gws-app/gws/base/ows/server/action.py: 53%
53 statements
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-05 13:35 +0200
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-05 13:35 +0200
1"""OWS server action."""
3from typing import Optional, cast
5import gws
6import gws.base.action
7import gws.base.web
8import gws.lib.mime
9import gws.lib.xmlx
11from . import core, layer_caps, error
14class GetServiceRequest(gws.Request):
15 """Request to an OWS service."""
17 serviceUid: str
18 """Service uid."""
21class GetSchemaRequest(gws.Request):
22 """Request for an XML schema."""
24 namespace: str
25 """Namespace prefix, optionally with the ``.xsd`` extension."""
28@gws.ext.config.action('ows')
29class Config(gws.base.action.Config):
30 """Action that serves the configured OWS services."""
33@gws.ext.object.action('ows')
34class Object(gws.base.action.Object):
35 """OWS action.
37 Dispatches requests to the configured OWS services and serves XML schemas
38 generated for layer namespaces.
39 """
41 @gws.ext.command.get('owsService')
42 def get_service(self, req: gws.WebRequester, p: GetServiceRequest) -> gws.ContentResponse:
43 """Handle an OWS service request."""
45 return self._handle_service(req, p)
47 @gws.ext.command.post('owsService')
48 def post_service(self, req: gws.WebRequester, p: GetServiceRequest) -> gws.ContentResponse:
49 """Handle an OWS service request."""
51 return self._handle_service(req, p)
53 def _handle_service(self, req: gws.WebRequester, p: GetServiceRequest) -> gws.ContentResponse:
54 """Locate the service, check access and pass the request to it."""
55 srv = cast(gws.OwsService, self.root.get(p.serviceUid, gws.ext.object.owsService))
56 if not srv:
57 raise gws.NotFoundError(f'{p.serviceUid=} not found')
58 if not req.user.can_use(srv):
59 raise gws.ForbiddenError(f'{p.serviceUid=} forbidden')
60 return srv.handle_request(req)
62 @gws.ext.command.get('owsXml')
63 def get_schema(self, req: gws.WebRequester, p: GetSchemaRequest) -> gws.ContentResponse:
64 """Return an XML schema for the layers with the given namespace prefix."""
66 try:
67 content = self._make_schema(req, p)
68 except Exception as exc:
69 return error.from_exception(exc).to_xml_response()
70 return gws.ContentResponse(mimeType=gws.lib.mime.XML, content=content)
72 def _make_schema(self, req, p) -> str:
73 """Create the XML schema document for a namespace."""
74 s = p.namespace
75 if s.endswith('.xsd'):
76 s = s[:-4]
77 lcs = []
79 for la in self.root.find_all(gws.ext.object.layer):
80 layer = cast(gws.Layer, la)
81 if req.user.can_read(layer) and layer.ows.xmlNamespace and layer.ows.xmlNamespace.prefix == s:
82 lcs.append(layer_caps.for_layer(layer, req.user))
84 if not lcs:
85 raise gws.NotFoundError(f'namespace not found: {p.namespace=}')
87 el, opts = layer_caps.xml_schema(lcs, req.user)
88 if not el:
89 raise gws.NotFoundError(f'cannot create schema: {p.namespace=}')
91 opts.withNamespaceDeclarations = True
92 opts.withSchemaLocations = True
93 opts.withXmlDeclaration = True
95 return el.to_string(opts)