Coverage for gws-app/gws/__init__.py: 99%

2188 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-08-24 12:46 +0200

1"""Basic types. 

2 

3This module contains essential type definitions and utilities from the core GWS library. 

4It should be imported in every gws module. 

5""" 

6 

7from typing import ( 

8 TYPE_CHECKING, 

9 TypeAlias, 

10 cast, 

11 Any, 

12 Callable, 

13 ContextManager, 

14 Generator, 

15 Iterable, 

16 Iterator, 

17 Literal, 

18 Optional, 

19 Protocol, 

20 Union, 

21) 

22 

23from collections.abc import ( 

24 Mapping, 

25 Sequence, 

26) 

27 

28import enum 

29import datetime 

30 

31if TYPE_CHECKING: 

32 import sqlalchemy 

33 import numpy.typing 

34 

35# mypy: disable-error-code="empty-body" 

36 

37 

38from . import ext 

39 

40from .core import ( 

41 log, 

42 debug, 

43 env, 

44 const as c, 

45 util as u, 

46) 

47 

48 

49################################################################################ 

50# /core/_data.pyinc 

51 

52 

53# basic data type 

54 

55class Data: 

56 """Basic data object. 

57 

58 This object can be instantiated by passing one or or ``dict`` arguments 

59 and/or keyword args. All dicts keys and keywords become attributes of the object. 

60 

61 Accessing an undefined attribute returns ``None`` and no error is raised, 

62 unless the attribute name starts with an underscore. 

63 """ 

64 

65 def __init__(self, *args, **kwargs): 

66 self.update(*args, **kwargs) 

67 

68 def __repr__(self): 

69 return repr(vars(self)) 

70 

71 def __getitem__(self, key): 

72 return vars(self).get(key) 

73 

74 def __setitem__(self, key, value): 

75 vars(self)[key] = value 

76 

77 # def __getattr__(self, attr): 

78 # if attr.startswith('_'): 

79 # # do not use None fallback for special props 

80 # raise AttributeError(attr) 

81 # return None 

82 

83 def get(self, key, default=None): 

84 """Get an attribute value. 

85 

86 Args: 

87 key: Attribute name. 

88 default: Default value, returned if the attribute is undefined. 

89 """ 

90 return vars(self).get(key, default) 

91 

92 def setdefault(self, key, val): 

93 """Set an attribute value if not already set. 

94 

95 Args: 

96 key: Attribute name. 

97 val: Attribute value. 

98 """ 

99 return vars(self).setdefault(key, val) 

100 

101 def set(self, key, val): 

102 """Set an attribute value. 

103 

104 Args: 

105 key: Attribute name. 

106 val: Attribute value. 

107 """ 

108 vars(self)[key] = val 

109 

110 def update(self, *args, **kwargs): 

111 """Update the object with keys and values from args and keywords. 

112 

113 Args: 

114 *args: Dicts or Mappings. 

115 kwargs: Keyword args. 

116 """ 

117 

118 d = {} 

119 for a in args: 

120 if isinstance(a, Mapping): 

121 d.update(a) 

122 elif isinstance(a, Data): 

123 d.update(vars(a)) 

124 d.update(kwargs) 

125 vars(self).update(d) 

126 

127 

128# getattr needs to be defined out of class, otherwise the type checker will accept any attribute 

129 

130def _data_getattr(self, attr): 

131 if attr.startswith('_'): 

132 # do not use None fallback for special props 

133 raise AttributeError(attr) 

134 return None 

135 

136 

137setattr(Data, '__getattr__', _data_getattr) 

138 

139 

140def is_data_object(x): 

141 """True if the argument is a ``Data`` object.""" 

142 return isinstance(x, Data) 

143 

144 

145def to_data_object(x) -> 'Data': 

146 """Convert a value to a ``Data`` object. 

147 

148 If the argument is already a ``Data`` object, simply return it. 

149 If the argument is ``None``, an empty object is returned. 

150 

151 Args: 

152 x: A Mapping or ``None``. 

153 """ 

154 

155 if is_data_object(x): 

156 return x 

157 if isinstance(x, Mapping): 

158 return Data(x) 

159 if x is None: 

160 return Data() 

161 raise ValueError(f'cannot convert {x!r} to Data') 

162################################################################################ 

163 

164 

165 

166u.is_data_object = is_data_object 

167u.to_data_object = to_data_object 

168 

169 

170 

171################################################################################ 

172# /core/_basic.pyinc 

173 

174 

175class Enum(enum.Enum): 

176 """Enumeration type. 

177 

178 Despite being declared as extending ``Enum`` (for IDE support), this class is actually just a simple object 

179 and intended to be used as a collection of attributes. It doesn't provide any ``Enum``-specific utilities. 

180 

181 The rationale behind this is that we need ``Enum`` members (e.g. ``Color.RED``) to be scalars, 

182 and not complex objects as in the standard ``Enum``. 

183 """ 

184 pass 

185 

186 

187# hack to make Enum a simple object 

188globals()['Enum'] = type('Enum', (), {}) 

189 

190Extent: TypeAlias = tuple[float, float, float, float] 

191"""An array of 4 elements representing extent coordinates ``[min-x, min-y, max-x, max-y]``.""" 

192 

193Point: TypeAlias = tuple[float, float] 

194"""Point coordinates ``[x, y]``.""" 

195 

196Size: TypeAlias = tuple[float, float] 

197"""Size ``[width, height]``.""" 

198 

199 

200class Origin(Enum): 

201 """Grid origin.""" 

202 

203 nw = 'nw' 

204 """North-west.""" 

205 sw = 'sw' 

206 """South-west.""" 

207 ne = 'ne' 

208 """North-east.""" 

209 se = 'se' 

210 """South-east.""" 

211 lt = 'nw' 

212 """Left top.""" 

213 lb = 'sw' 

214 """Left bottom.""" 

215 rt = 'ne' 

216 """Right top.""" 

217 rb = 'se' 

218 """Right bottom.""" 

219 

220 

221FilePath: TypeAlias = str 

222"""File path on the server.""" 

223 

224DirPath: TypeAlias = str 

225"""Directory path on the server.""" 

226 

227Duration: TypeAlias = str 

228"""Duration like ``1w 2d 3h 4m 5s`` or an integer number of seconds.""" 

229 

230Color: TypeAlias = str 

231"""CSS color name.""" 

232 

233Regex: TypeAlias = str 

234"""Regular expression, as used in Python.""" 

235 

236FormatStr: TypeAlias = str 

237"""Format string as used in Python.""" 

238 

239DateStr: TypeAlias = str 

240"""ISO date string like ``2019-01-30``.""" 

241 

242DateTimeStr: TypeAlias = str 

243"""ISO datetime string like ``2019-01-30 01:02:03``.""" 

244 

245Url: TypeAlias = str 

246"""URL.""" 

247 

248ClassRef: TypeAlias = type | str 

249"""Class reference, a type, and 'ext' object or a class name.""" 

250 

251 

252class Config(Data): 

253 """Object configuration.""" 

254 

255 uid: str = '' 

256 """Unique ID.""" 

257 

258 

259class Props(Data): 

260 """Object properties.""" 

261 

262 uid: str = '' 

263 """Unique ID.""" 

264 

265 

266class Request(Data): 

267 """Command request.""" 

268 

269 projectUid: Optional[str] 

270 """Unique ID of the project.""" 

271 localeUid: Optional[str] 

272 """Locale ID for this request.""" 

273 

274 

275class EmptyRequest(Data): 

276 """Empty command request.""" 

277 

278 pass 

279 

280 

281class ResponseError(Data): 

282 """Response error.""" 

283 

284 code: Optional[int] 

285 """Error code.""" 

286 info: Optional[str] 

287 """Information about the error.""" 

288 

289 

290class Response(Data): 

291 """Command response.""" 

292 

293 error: Optional[ResponseError] 

294 """Response error.""" 

295 status: int 

296 """Response status or exit code.""" 

297 

298 

299class ContentResponse(Response): 

300 """Web response with literal content.""" 

301 

302 content: bytes | str 

303 """Response content.""" 

304 contentFilename: str 

305 """Name for the attachment, if provided, content will be served as an attachment.""" 

306 contentPath: str 

307 """Local path with the content.""" 

308 mime: str 

309 """Response mime type.""" 

310 headers: dict 

311 """Additional headers.""" 

312 

313 

314class RedirectResponse(Response): 

315 """Web redirect response.""" 

316 

317 location: str 

318 """Redirect URL.""" 

319 headers: dict 

320 """Additional headers.""" 

321 

322 

323class AttributeType(Enum): 

324 """Feature attribute type.""" 

325 

326 bool = 'bool' 

327 """Boolean value.""" 

328 bytes = 'bytes' 

329 """Binary data.""" 

330 date = 'date' 

331 """Date value.""" 

332 datetime = 'datetime' 

333 """Date and time value.""" 

334 feature = 'feature' 

335 """Feature reference.""" 

336 featurelist = 'featurelist' 

337 """List of features.""" 

338 file = 'file' 

339 """File reference.""" 

340 float = 'float' 

341 """Floating-point number.""" 

342 floatlist = 'floatlist' 

343 """List of floating-point numbers.""" 

344 geometry = 'geometry' 

345 """Geometry reference.""" 

346 int = 'int' 

347 """Integer number.""" 

348 intlist = 'intlist' 

349 """List of integer numbers.""" 

350 str = 'str' 

351 """String value.""" 

352 strlist = 'strlist' 

353 """List of strings.""" 

354 time = 'time' 

355 """Time value.""" 

356 

357 

358class GeometryType(Enum): 

359 """Feature geometry type. 

360 

361 OGC and SQL/MM geometry types. 

362 

363 References: 

364 

365 - OGC 06-103r4 (https://www.ogc.org/standards/sfa),  

366 - https://postgis.net/docs/manual-3.3/using_postgis_dbmanagement.html 

367 """ 

368 

369 geometry = 'geometry' 

370 

371 point = 'point' 

372 curve = 'curve' 

373 surface = 'surface' 

374 

375 geometrycollection = 'geometrycollection' 

376 

377 linestring = 'linestring' 

378 line = 'line' 

379 linearring = 'linearring' 

380 

381 polygon = 'polygon' 

382 triangle = 'triangle' 

383 

384 polyhedralsurface = 'polyhedralsurface' 

385 tin = 'tin' 

386 

387 multipoint = 'multipoint' 

388 multicurve = 'multicurve' 

389 multilinestring = 'multilinestring' 

390 multipolygon = 'multipolygon' 

391 multisurface = 'multisurface' 

392 

393 circularstring = 'circularstring' 

394 compoundcurve = 'compoundcurve' 

395 curvepolygon = 'curvepolygon' 

396 

397 

398class CliParams(Data): 

399 """CLI params""" 

400 pass 

401################################################################################ 

402 

403 

404################################################################################ 

405# /core/_access.pyinc 

406 

407 

408Acl: TypeAlias = list[tuple[int, str]] 

409"""Access Control list. 

410 

411A list of tuples ``(ACL bit, role-name)`` where ``ACL bit`` is ``1`` if the access is allowed and ``0`` otherwise. 

412""" 

413 

414AclStr: TypeAlias = str 

415"""A string of comma-separated pairs ``allow <role>`` or ``deny <role>``.""" 

416 

417 

418class Access(Enum): 

419 """Access mode.""" 

420 

421 read = 'read' 

422 """Permission to read the object.""" 

423 write = 'write' 

424 """Permission to change the object.""" 

425 create = 'create' 

426 """Permission to create new objects.""" 

427 delete = 'delete' 

428 """Permission to delete objects.""" 

429 

430 

431class PermissionsConfig(Config): 

432 """Permissions configuration.""" 

433 

434 all: Optional[AclStr] 

435 """All permissions.""" 

436 read: Optional[AclStr] 

437 """Permission to read the object.""" 

438 write: Optional[AclStr] 

439 """Permission to change the object.""" 

440 create: Optional[AclStr] 

441 """Permission to create new objects.""" 

442 delete: Optional[AclStr] 

443 """Permission to delete objects.""" 

444 edit: Optional[AclStr] 

445 """A combination of write, create and delete.""" 

446 

447 

448class ConfigWithAccess(Config): 

449 """Basic config with permissions.""" 

450 

451 access: Optional[AclStr] 

452 """Permission to read or use the object.""" 

453 permissions: Optional[PermissionsConfig] 

454 """Access permissions.""" 

455################################################################################ 

456 

457 

458################################################################################ 

459# /core/_error.pyinc 

460 

461 

462"""App Error object""" 

463 

464class Error(Exception): 

465 """Generic GWS error.""" 

466 def __repr__(self): 

467 return log.exception_backtrace(self)[0] 

468 

469 

470class ConfigurationError(Error): 

471 """GWS Configuration error.""" 

472 pass 

473 

474 

475class NotFoundError(Error): 

476 """Generic 'object not found' error.""" 

477 pass 

478 

479 

480class ForbiddenError(Error): 

481 """Generic 'forbidden' error.""" 

482 pass 

483 

484 

485class BadRequestError(Error): 

486 """Generic 'bad request' error.""" 

487 pass 

488 

489 

490class TooManyRequestsError(Error): 

491 """Generic 'too many requests' error.""" 

492 

493 retryAfter: int = 0 

494 """Time in seconds after which the request can be repeated.""" 

495 

496 

497class ResponseTooLargeError(Error): 

498 """Generic error when a response is too large.""" 

499 pass 

500################################################################################ 

501 

502 

503 

504################################################################################ 

505# /spec/types.pyinc 

506 

507 

508class ApplicationManifestPlugin(Data): 

509 """Plugin description.""" 

510 

511 path: DirPath 

512 """Path to the plugin python module.""" 

513 

514 name: str = '' 

515 """Optional name, when omitted, the directory name will be used.""" 

516 

517 

518class ApplicationManifest(Data): 

519 """Application manifest.""" 

520 

521 excludePlugins: Optional[list[str]] 

522 """Names of the core plugins that should be deactivated.""" 

523 plugins: Optional[list[ApplicationManifestPlugin]] 

524 """Custom plugins.""" 

525 locales: list[str] 

526 """Locale names supported by this application.""" 

527 tsConfig: list[str] 

528 """Path to tsconfig.json.""" 

529 withFallbackConfig: bool = False 

530 """Use a minimal fallback configuration.""" 

531 withStrictConfig: bool = False 

532 """Stop the application upon a configuration error.""" 

533 

534 

535class ExtObjectDescriptor(Data): 

536 """Extension object descriptor.""" 

537 

538 extName: str 

539 """Full extension name like ``gws.ext.object.layer.wms``.""" 

540 extType: str 

541 """Extension type like ``wms``.""" 

542 classPtr: type 

543 """Class object.""" 

544 ident: str 

545 """Identifier.""" 

546 modName: str 

547 """Name of the module that contains the class.""" 

548 modPath: str 

549 """Path to the module that contains the class.""" 

550 

551 

552class ExtCommandDescriptor(Data): 

553 """ 

554 Represents a command descriptor for an extension. 

555 

556 Contains attributes to describe and handle a specific extension command. 

557 """ 

558 

559 extName: str 

560 """Full extension name like ``gws.ext.object.layer.wms``.""" 

561 extType: str 

562 """Extension type like ``wms``.""" 

563 extCommandCategory: 'CommandCategory' 

564 """Command category.""" 

565 methodName: str 

566 """Command method name.""" 

567 methodPtr: Callable 

568 """Command method.""" 

569 request: 'Request' 

570 """Request sent to the command.""" 

571 tArg: str 

572 """Type of the command argument.""" 

573 tOwner: str 

574 """Type of the command owner.""" 

575 owner: ExtObjectDescriptor 

576 """Descriptor of the command owner.""" 

577 

578 

579class SpecReadOption(Enum): 

580 """Options for structured reading based on Specs.""" 

581 

582 acceptExtraProps = 'acceptExtraProps' 

583 """Accept extra object properties.""" 

584 allowMissing = 'allowMissing' 

585 """Allow otherwise required properties to be missing.""" 

586 caseInsensitive = 'caseInsensitive' 

587 """Case insensitive search for properties. """ 

588 convertValues = 'convertValues' 

589 """Try to convert values to specified types.""" 

590 ignoreExtraProps = 'ignoreExtraProps' 

591 """Silently ignore extra object properties.""" 

592 verboseErrors = 'verboseErrors' 

593 """Provide verbose error messages.""" 

594 

595 

596class CommandCategory(Enum): 

597 """Command category.""" 

598 

599 api = 'api' 

600 """API command.""" 

601 cli = 'cli' 

602 """CLI command.""" 

603 get = 'get' 

604 """Web GET command.""" 

605 post = 'post' 

606 """Web POST command.""" 

607 raw = 'raw' 

608 """Raw Web command without preprocessing.""" 

609 

610 

611class SpecRuntime: 

612 """Specification runtime.""" 

613 

614 version: str 

615 """Application version.""" 

616 manifest: ApplicationManifest 

617 """Application manifest.""" 

618 appBundlePaths: list[str] 

619 """List of client bundle paths.""" 

620 

621 def read(self, value, type_name: str, path: str = '', options: set[SpecReadOption] = None): 

622 """Read a raw value according to a spec. 

623 

624 Args: 

625 value: Raw value from config or request. 

626 type_name: Object type name. 

627 path: Config file path. 

628 options: Read options. 

629 

630 Returns: 

631 A parsed object. 

632 """ 

633 

634 def object_descriptor(self, type_name: str) -> Optional[ExtObjectDescriptor]: 

635 """Get an object descriptor. 

636 

637 Args: 

638 type_name: Object type name. 

639 

640 Returns: 

641 A descriptor or ``None`` if the type is not found. 

642 """ 

643 

644 def command_descriptor(self, command_category: CommandCategory, command_name: str) -> Optional[ExtCommandDescriptor]: 

645 """Get a command descriptor. 

646 

647 Args: 

648 command_category: Command category. 

649 command_name: Command name. 

650 

651 Returns: 

652 A descriptor or ``None`` if the command is not found. 

653 """ 

654 

655 def register_object(self, ext_name: ClassRef, obj_type: str, cls: type): 

656 """Dynamically register an extension object.""" 

657 

658 def get_class(self, classref: ClassRef, ext_type: Optional[str] = None) -> Optional[type]: 

659 """Get a class object for a class reference. 

660 

661 Args: 

662 classref: Class reference. 

663 ext_type: Extension type. 

664 

665 Returns: 

666 A class or ``None`` if the reference is not found. 

667 """ 

668 

669 def parse_classref(self, classref: ClassRef) -> tuple[Optional[type], str, str]: 

670 """Parse a class reference. 

671 

672 Args: 

673 classref: Class reference. 

674 

675 Returns: 

676 A tuple ``(class object, class name, extension name)``. 

677 """ 

678 

679 def get_config_types(self, lang: str) -> list[dict]: 

680 """Get a list of config-related spec types as dictionaries.""" 

681################################################################################ 

682 

683 

684 

685################################################################################ 

686# /core/_tree.pyinc 

687 

688 

689class Object: 

690 """Basic GWS object.""" 

691 

692 permissions: dict[Access, Acl] 

693 """Mapping from an access mode to a list of ACL tuples.""" 

694 

695 def props(self, user: 'User') -> Props: 

696 """Generate a ``Props`` struct for this object. 

697 

698 Args: 

699 user: The user for which the props should be generated. 

700 """ 

701 

702 def __init__(self): 

703 self.permissions = {} 

704 

705 

706from .core import tree_impl 

707 

708setattr(tree_impl, 'Access', Access) 

709setattr(tree_impl, 'Error', Error) 

710setattr(tree_impl, 'Data', Data) 

711setattr(tree_impl, 'Props', Props) 

712setattr(tree_impl, 'Object', Object) 

713 

714Object.__repr__ = tree_impl.object_repr 

715 

716 

717class Node(Object): 

718 """GWS object tree node.""" 

719 

720 extName: str 

721 """Full extension name like ``gws.ext.object.layer.wms``.""" 

722 extType: str 

723 """Extension type like ``wms``.""" 

724 

725 config: Config 

726 """Configuration for this object.""" 

727 root: 'Root' 

728 """Root object.""" 

729 parent: 'Node' 

730 """Parent object.""" 

731 children: list['Node'] 

732 """Child objects.""" 

733 uid: str 

734 """Unique ID.""" 

735 

736 def initialize(self, config): 

737 return tree_impl.node_initialize(self, config) 

738 

739 def pre_configure(self): 

740 """Pre-configuration hook.""" 

741 

742 def configure(self): 

743 """Configuration hook.""" 

744 

745 def post_configure(self): 

746 """Post-configuration hook.""" 

747 

748 def activate(self): 

749 """Activation hook.""" 

750 

751 def create_child(self, classref: ClassRef, config: Config = None, **kwargs) -> Optional['Node']: 

752 """Create a child object. 

753 

754 Args: 

755 classref: Class reference. 

756 config: Configuration. 

757 **kwargs: Additional configuration properties. 

758 

759 Returns: 

760 A newly created object or ``None`` if the object cannot be initialized. 

761 """ 

762 return tree_impl.node_create_child(self, classref, config, **kwargs) 

763 

764 def create_child_if_configured(self, classref: ClassRef, config=None, **kwargs) -> Optional['Node']: 

765 """Create a child object if the configuration is not None. 

766 

767 Args: 

768 classref: Class reference. 

769 config: Configuration. 

770 **kwargs: Additional configuration properties. 

771 

772 Returns: 

773 A newly created object or ``None`` if the configuration is ``None`` or the object cannot be initialized. 

774 """ 

775 return tree_impl.node_create_child_if_configured(self, classref, config, **kwargs) 

776 

777 def create_children(self, classref: ClassRef, configs: list[Config], **kwargs) -> list['Node']: 

778 """Create a list of child objects from a list of configurations. 

779 

780 Args: 

781 classref: Class reference. 

782 configs: List of configurations. 

783 **kwargs: Additional configuration properties. 

784 

785 Returns: 

786 A list of newly created objects. 

787 """ 

788 return tree_impl.node_create_children(self, classref, configs, **kwargs) 

789 

790 def cfg(self, key: str, default=None): 

791 """Fetch a configuration property. 

792 

793 Args: 

794 key: Property key. If it contains dots, fetch nested properties. 

795 default: Default to return if the property is not found. 

796 

797 Returns: 

798 A property value. 

799 """ 

800 return tree_impl.node_cfg(self, key, default) 

801 

802 def is_a(self, classref: ClassRef) -> bool: 

803 """Check if a the node matches the class reference. 

804 

805 Args: 

806 classref: Class reference. 

807 

808 Returns: 

809 A boolean. 

810 """ 

811 return tree_impl.is_a(self.root, self, classref) 

812 

813 def find_all(self, classref: Optional[ClassRef] = None) -> list['Node']: 

814 """Find all children that match a specific class. 

815 

816 Args: 

817 classref: Class reference. 

818 

819 Returns: 

820 A list of objects. 

821 """ 

822 return tree_impl.node_find_all(self, classref) 

823 

824 def find_first(self, classref: Optional[ClassRef] = None) -> Optional['Node']: 

825 """Find the first child that matches a specific class. 

826 

827 Args: 

828 classref: Class reference. 

829 

830 Returns: 

831 An object or ``None``. 

832 """ 

833 return tree_impl.node_find_first(self, classref) 

834 

835 def find_closest(self, classref: Optional[ClassRef] = None) -> Optional['Node']: 

836 """Find the closest node ancestor that matches a specific class. 

837 

838 Args: 

839 classref: Class reference. 

840 

841 Returns: 

842 An object or ``None``. 

843 """ 

844 

845 return tree_impl.node_find_closest(self, classref) 

846 

847 def find_ancestors(self, classref: Optional[ClassRef] = None) -> list['Node']: 

848 """Find node ancestors that match a specific class. 

849 

850 Args: 

851 classref: Class reference. 

852 

853 Returns: 

854 A list of objects. 

855 """ 

856 return tree_impl.node_find_ancestors(self, classref) 

857 

858 def find_descendants(self, classref: Optional[ClassRef] = None) -> list['Node']: 

859 """Find node descendants that match a specific class. 

860 

861 Args: 

862 classref: Class reference. 

863 

864 Returns: 

865 A list of objects in the depth-first order. 

866 """ 

867 

868 return tree_impl.node_find_descendants(self, classref) 

869 

870 def enter_middleware(self, req: 'WebRequester') -> Optional['WebResponder']: 

871 """Begin middleware processing. 

872 

873 Args: 

874 req: Requester object. 

875 

876 Returns: 

877 A Responder object or ``None``. 

878 """ 

879 

880 def exit_middleware(self, req: 'WebRequester', res: 'WebResponder'): 

881 """Finish middleware processing. 

882 

883 Args: 

884 req: Requester object. 

885 res: Current responder object. 

886 """ 

887 

888 def periodic_task(self): 

889 """Periodic task hook.""" 

890 

891 

892class Root: 

893 """Root node of the object tree.""" 

894 

895 app: 'Application' 

896 """Application object.""" 

897 specs: 'SpecRuntime' 

898 """Specs runtime.""" 

899 configErrors: list 

900 """List of configuration errors.""" 

901 

902 nodes: list['Node'] 

903 uidMap: dict[str, 'Node'] 

904 uidCount: int 

905 configStack: list['Node'] 

906 configPaths: list[str] 

907 

908 def __init__(self, specs: 'SpecRuntime'): 

909 tree_impl.root_init(self, specs) 

910 

911 def initialize(self, obj, config): 

912 return tree_impl.root_initialize(self, obj, config) 

913 

914 def post_initialize(self): 

915 """Post-initialization hook.""" 

916 return tree_impl.root_post_initialize(self) 

917 

918 def activate(self): 

919 return tree_impl.root_activate(self) 

920 

921 def find_all(self, classref: Optional[ClassRef] = None) -> list['Node']: 

922 """Find all objects that match a specific class. 

923 

924 Args: 

925 classref: Class reference. 

926 

927 Returns: 

928 A list of objects. 

929 """ 

930 return tree_impl.root_find_all(self, classref) 

931 

932 def find_first(self, classref: Optional[ClassRef] = None) -> Optional['Node']: 

933 """Find the first object that match a specific class. 

934 

935 Args: 

936 classref: Class reference. 

937 

938 Returns: 

939 An object or ``None``. 

940 """ 

941 return tree_impl.root_find_first(self, classref) 

942 

943 def get(self, uid: str = None, classref: Optional[ClassRef] = None) -> Optional['Node']: 

944 """Get an object by its unique ID. 

945 

946 Args: 

947 uid: Object uid. 

948 classref: Class reference. If provided, ensures that the object matches the reference. 

949 

950 Returns: 

951 An object or ``None``. 

952 """ 

953 return tree_impl.root_get(self, uid, classref) 

954 

955 def object_count(self) -> int: 

956 """Return the number of objects in the tree.""" 

957 return tree_impl.root_object_count(self) 

958 

959 def create( 

960 self, 

961 classref: ClassRef, 

962 parent: Optional['Node'] = None, 

963 config: Config = None, 

964 **kwargs, 

965 ) -> Optional['Node']: 

966 """Create an object. 

967 

968 Args: 

969 classref: Class reference. 

970 parent: Parent object. 

971 config: Configuration. 

972 **kwargs: Additional configuration properties. 

973 

974 Returns: 

975 A newly created object or ``None`` if the object cannot be initialized. 

976 """ 

977 return tree_impl.root_create(self, classref, parent, config, **kwargs) 

978 

979 def create_shared(self, classref: ClassRef, config: Config = None, **kwargs) -> Optional['Node']: 

980 """Create a shared object, attached directly to the root. 

981 

982 Args: 

983 classref: Class reference. 

984 config: Configuration. 

985 **kwargs: Additional configuration properties. 

986 

987 Returns: 

988 A newly created object or ``None`` if the object cannot be initialized. 

989 """ 

990 return tree_impl.root_create_shared(self, classref, config, **kwargs) 

991 

992 def create_temporary(self, classref: ClassRef, config: Config = None, **kwargs) -> Optional['Node']: 

993 """Create a temporary object, not attached to the tree. 

994 

995 Args: 

996 classref: Class reference. 

997 config: Configuration. 

998 **kwargs: Additional configuration properties. 

999 

1000 Returns: 

1001 A newly created object or ``None`` if the object cannot be initialized. 

1002 """ 

1003 return tree_impl.root_create_temporary(self, classref, config, **kwargs) 

1004 

1005 def create_application(self, config: Config = None, **kwargs) -> 'Application': 

1006 """Create the Application object. 

1007 

1008 Args: 

1009 config: Configuration. 

1010 **kwargs: Additional configuration properties. 

1011 

1012 Returns: 

1013 The Application object. 

1014 """ 

1015 return tree_impl.root_create_application(self, config, **kwargs) 

1016 

1017 

1018def create_root(specs: 'SpecRuntime') -> Root: 

1019 return Root(specs) 

1020 

1021 

1022def props_of(obj: Object, user: 'User', *context) -> Optional['Props']: 

1023 return tree_impl.props_of(obj, user, *context) 

1024################################################################################ 

1025 

1026 

1027 

1028################################################################################ 

1029# /lib/mapserver/types.pyinc 

1030 

1031 

1032class MapServerLayerType(Enum): 

1033 """MapServer layer type.""" 

1034 

1035 point = 'point' 

1036 line = 'line' 

1037 polygon = 'polygon' 

1038 raster = 'raster' 

1039 

1040class MapServerLayerOptions(Data): 

1041 """Options for a MapServer-based layer.""" 

1042 

1043 type: MapServerLayerType 

1044 """Layer type.""" 

1045 path: str 

1046 """Path to the image file.""" 

1047 tileIndex: str 

1048 """Path to the tile index SHP file""" 

1049 crs: 'Crs' 

1050 """Layer CRS.""" 

1051 connectionType: str 

1052 """Type of connection (e.g., 'postgres').""" 

1053 connectionString: str 

1054 """Connection string for the data source.""" 

1055 dataString: str 

1056 """Layer DATA option.""" 

1057 style: 'StyleValues' 

1058 """Style for the layer.""" 

1059 processing: list[str] 

1060 """Processing options for the layer.""" 

1061 transparentColor: str 

1062 """Color to treat as transparent in the layer (OFFSITE).""" 

1063 sldPath: str 

1064 """Path to SLD file for styling the layer.""" 

1065 sldName: str 

1066 """Name of an SLD NamedLayer to apply.""" 

1067################################################################################ 

1068 

1069 

1070################################################################################ 

1071# /lib/mime/types.pyinc 

1072 

1073 

1074MimeType: TypeAlias = str 

1075"""A mime type or an alias.""" 

1076################################################################################ 

1077 

1078 

1079################################################################################ 

1080# /lib/uom/types.pyinc 

1081 

1082 

1083class Uom(Enum): 

1084 """Unit of measure.""" 

1085 

1086 mi = 'mi' 

1087 """statute mile (EPSG 9093)""" 

1088 us_ch = 'us-ch' 

1089 """us survey chain (EPSG 9033)""" 

1090 us_ft = 'us-ft' 

1091 """us survey foot (EPSG 9003)""" 

1092 us_in = 'us-in' 

1093 """us survey inch us_in""" 

1094 us_mi = 'us-mi' 

1095 """us survey mile (EPSG 9035)""" 

1096 us_yd = 'us-yd' 

1097 """us survey yard us_yd""" 

1098 cm = 'cm' 

1099 """centimetre (EPSG 1033)""" 

1100 ch = 'ch' 

1101 """chain (EPSG 9097)""" 

1102 dm = 'dm' 

1103 """decimeter dm""" 

1104 deg = 'deg' 

1105 """degree (EPSG 9102)""" 

1106 fath = 'fath' 

1107 """fathom (EPSG 9014)""" 

1108 ft = 'ft' 

1109 """foot (EPSG 9002)""" 

1110 grad = 'grad' 

1111 """grad (EPSG 9105)""" 

1112 inch = 'in' 

1113 """inch in""" 

1114 km = 'km' 

1115 """kilometre (EPSG 9036)""" 

1116 link = 'link' 

1117 """link (EPSG 9098)""" 

1118 m = 'm' 

1119 """metre (EPSG 9001)""" 

1120 mm = 'mm' 

1121 """millimetre (EPSG 1025)""" 

1122 kmi = 'kmi' 

1123 """nautical mile (EPSG 9030)""" 

1124 rad = 'rad' 

1125 """radian (EPSG 9101)""" 

1126 yd = 'yd' 

1127 """yard (EPSG 9096)""" 

1128 px = 'px' 

1129 """pixel""" 

1130 pt = 'pt' 

1131 """point""" 

1132 

1133 

1134UomValue: TypeAlias = tuple[float, Uom] 

1135"""A value with a unit.""" 

1136 

1137UomValueStr: TypeAlias = str 

1138"""A value with a unit like ``5mm``.""" 

1139 

1140UomPoint: TypeAlias = tuple[float, float, Uom] 

1141"""A Point with a unit.""" 

1142 

1143UomPointStr: TypeAlias = list[str] 

1144"""A Point with a unit like ``["1mm", "2mm"]``.""" 

1145 

1146UomSize: TypeAlias = tuple[float, float, Uom] 

1147"""A Size with a unit.""" 

1148 

1149UomSizeStr: TypeAlias = list[str] 

1150"""A Size with a unit like ``["1mm", "2mm"]``.""" 

1151 

1152UomExtent: TypeAlias = tuple[float, float, float, float, Uom] 

1153"""Extent with a unit.""" 

1154 

1155UomExtentStr: TypeAlias = list[str] 

1156"""Extent with a unit like ``["1mm", "2mm", "3mm", "4mm"]``.""" 

1157################################################################################ 

1158 

1159 

1160################################################################################ 

1161# /lib/image/types.pyinc 

1162 

1163 

1164class ImageFormat(Data): 

1165 """Image format""" 

1166 

1167 name: str 

1168 """Name of the format.""" 

1169 mimeTypes: list[str] 

1170 """Mime types for this format.""" 

1171 options: dict 

1172 """Image options.""" 

1173 

1174 

1175class Image: 

1176 """Image object.""" 

1177 

1178 def size(self) -> Size: 

1179 """Get the image size. 

1180 

1181 Returns: 

1182 A tuple ``(width, height)``. 

1183 """ 

1184 

1185 def mode(self) -> str: 

1186 """Get the image mode. 

1187 

1188 Returns: 

1189 PIL image mode. 

1190 """ 

1191 

1192 def add_box(self, color=None) -> 'Image': 

1193 """Creates a 1 pixel wide box on the image's edge. 

1194 

1195 Args: 

1196 color: Color of the box's lines. 

1197 

1198 Returns: 

1199 The image with a box around the edges. 

1200 """ 

1201 

1202 def add_text(self, text: str, x=0, y=0, color=None) -> 'Image': 

1203 """Adds text to an image object. 

1204 

1205 Args: 

1206 text: Text to be displayed. 

1207 

1208 x: x-coordinate. 

1209 

1210 y: y-coordinate. 

1211 

1212 color: Color of the text. 

1213 

1214 Returns: 

1215 The image object with the text displayed. 

1216 """ 

1217 

1218 def compose(self, other: 'Image', opacity=1) -> 'Image': 

1219 """Places other image on top of the current image. 

1220 

1221 Args: 

1222 other: Image to place on top. 

1223 opacity: other image's opacity. 

1224 

1225 Returns: 

1226 The image object with the other image on top as an alpha composition. 

1227 """ 

1228 

1229 def crop(self, box) -> 'Image': 

1230 """Crops the image with respect to the given box. 

1231 

1232 Args: 

1233 box: `(width, height)` 

1234 

1235 Returns: 

1236 The cropped image object. 

1237 """ 

1238 

1239 def paste(self, other: 'Image', where=None) -> 'Image': 

1240 """Pastes an image to a specific location. 

1241 

1242 Args: 

1243 other: Image that will be placed. 

1244 

1245 where: `(x-coord, y-coord)` indicating where the upper left corer should be pasted. 

1246 

1247 Returns: 

1248 The image object with the other image placed inside. 

1249 """ 

1250 

1251 def resize(self, size: Size, **kwargs) -> 'Image': 

1252 """Resizes the image and scales it to fit the new size. 

1253 

1254 Args: 

1255 size: `(width, height)` 

1256 

1257 Returns: 

1258 The resized image object. 

1259 """ 

1260 

1261 def resize_to(self, width: int = 0, height: int = 0, **kwargs) -> 'Image': 

1262 """Resizes the image to the specified width and height, maintaining aspect ratio if only one dimension is provided. 

1263 

1264 Args: 

1265 width: The desired width. 

1266 height: The desired height. 

1267 

1268 Returns: 

1269 The resized image object. 

1270 """ 

1271 

1272 def rotate(self, angle: int, **kwargs) -> 'Image': 

1273 """Rotates the image. 

1274 

1275 Args: 

1276 angle: Angle to rotate the image. 

1277 

1278 Returns: 

1279 The rotated image object. 

1280 """ 

1281 

1282 def to_bytes(self, mime: Optional[str] = None, options: Optional[dict] = None) -> bytes: 

1283 """Converts the image object to bytes. 

1284 

1285 The ``options`` dict can contain any PIL save option 

1286 (see https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html). 

1287 

1288 An additional option ``mode`` is the image mode 

1289 (see https://pillow.readthedocs.io/en/stable/handbook/concepts.html#concept-modes). 

1290 If provided, the image is converted to that mode before saving. 

1291 

1292 An additional option ``background`` sets the color to replace the alpha channel with 

1293 when converting from RGBA to RGB (default is white). 

1294 

1295 Args: 

1296 mime: The mime type. 

1297 options: A dict of options. 

1298 

1299 Returns: 

1300 The image as bytes. 

1301 """ 

1302 

1303 def to_base64(self, mime: Optional[str] = None, options: Optional[dict] = None) -> str: 

1304 """Return the image content as a base64 encoded string.""" 

1305 

1306 def to_data_url(self, mime: Optional[str] = None, options: Optional[dict] = None) -> str: 

1307 """Return the image content as a base64-based data url.""" 

1308 

1309 def to_path(self, path: str, mime: Optional[str] = None, options: Optional[dict] = None) -> str: 

1310 """Saves the image object at a given path. 

1311 

1312 Args: 

1313 path: Image's path location. 

1314 mime: The mime type. 

1315 options: A dict of options. 

1316 

1317 Returns: 

1318 The path to the image. 

1319 """ 

1320 

1321 def to_array(self) -> 'numpy.typing.NDArray': 

1322 """Converts the image to an array. 

1323 

1324 Returns: 

1325 The image as an array. For each row each entry contains the pixel information. 

1326 """ 

1327 

1328 def compare_to(self, other: 'Image') -> float: 

1329 """Compare this image to another one. 

1330 

1331 @TODO describe the alogrithm 

1332 

1333 Returns: 

1334 The similarity factor as a float (the more, the different). 

1335 '0' means images are equal. 

1336 """ 

1337################################################################################ 

1338 

1339 

1340################################################################################ 

1341# /lib/intl/types.pyinc 

1342 

1343 

1344LocaleUid: TypeAlias = str 

1345"""Locale uid like `de_DE`.""" 

1346 

1347 

1348class Locale(Data): 

1349 """Locale data.""" 

1350 

1351 uid: str 

1352 dateFormatLong: str 

1353 dateFormatMedium: str 

1354 dateFormatShort: str 

1355 dateUnits: str 

1356 """date unit names, e.g. 'YMD' for 'en', 'JMT' for 'de'""" 

1357 dayNamesLong: list[str] 

1358 dayNamesShort: list[str] 

1359 dayNamesNarrow: list[str] 

1360 firstWeekDay: int 

1361 

1362 language: str 

1363 """Language code: ``de``""" 

1364 language3: str 

1365 """ISO 3166-1 alpha-3 language code: ``deu``.""" 

1366 languageBib: str 

1367 """Bibliographic language code..""" 

1368 languageName: str 

1369 """Native language name: ``Deutsch``.""" 

1370 languageNameEn: str 

1371 """English language name: ``German``.""" 

1372 

1373 territory: str 

1374 territoryName: str 

1375 monthNamesLong: list[str] 

1376 monthNamesShort: list[str] 

1377 monthNamesNarrow: list[str] 

1378 numberDecimal: str 

1379 numberGroup: str 

1380 

1381 

1382class DateTimeFormat(Enum): 

1383 """Enumeration indicating the length of the date/time format.""" 

1384 short = 'short' 

1385 """Local short format.""" 

1386 medium = 'medium' 

1387 """Local medium format.""" 

1388 long = 'long' 

1389 """Local long format.""" 

1390 iso = 'iso' 

1391 """ISO 8601 format.""" 

1392 

1393 

1394class NumberFormat(Enum): 

1395 """Enumeration indicating the number format.""" 

1396 decimal = 'decimal' 

1397 """Locale decimal format.""" 

1398 grouped = 'grouped' 

1399 """Locale grouped format.""" 

1400 currency = 'currency' 

1401 """Locale currency format""" 

1402 percent = 'percent' 

1403 """Locale percent format.""" 

1404 

1405 

1406class DateFormatter: 

1407 """Locale-aware date formatter.""" 

1408 

1409 def format(self, fmt: DateTimeFormat | str, date: Optional[Union['datetime.date', str]] = None) -> str: 

1410 """Formats the date. 

1411 

1412 Args: 

1413 fmt: Format type or a `strftime` format string 

1414 date: Date, if none is given the current date will be used as default. 

1415 

1416 Returns: 

1417 A formatted date string. 

1418 """ 

1419 

1420 def short(self, date=None) -> str: 

1421 """Returns the date in the short format ``11.12.13``.""" 

1422 

1423 def medium(self, date=None) -> str: 

1424 """Returns the date in the medium format ``11.12.2013``.""" 

1425 

1426 def long(self, date=None) -> str: 

1427 """Returns the date in the medium format ``11. Dezember 2013``.""" 

1428 

1429 def iso(self, date=None) -> str: 

1430 """Returns the date in the ISO 8601 format ``2013-12-11``.""" 

1431 

1432 

1433class TimeFormatter: 

1434 """Locale-aware time formatter.""" 

1435 

1436 def format(self, fmt: DateTimeFormat | str, time: Optional[Union['datetime.time', str]] = None) -> str: 

1437 """Formats the time. 

1438 

1439 Args: 

1440 fmt: Format type or a `strftime` format string 

1441 time: Time, if none is given the current time will be used as default. 

1442 

1443 Returns: 

1444 A formatted time string. 

1445 """ 

1446 

1447 def short(self, time=None) -> str: 

1448 """Returns the time in the short format ``11:22``.""" 

1449 

1450 def medium(self, time=None) -> str: 

1451 """Returns the time in the medium format ``11:22:33``.""" 

1452 

1453 def long(self, time=None) -> str: 

1454 """Returns the time in the medium format ``11:22:33``.""" 

1455 

1456 def iso(self, time=None) -> str: 

1457 """Returns the time and date in the ISO 8601 format.""" 

1458 

1459 

1460class NumberFormatter: 

1461 """Locale-aware number formatter.""" 

1462 

1463 def format(self, fmt: NumberFormat | str, n, *args, **kwargs) -> str: 

1464 """Formats the number with respect to the locale. 

1465 

1466 Args: 

1467 fmt: Format type or a python `format` string 

1468 n: Number. 

1469 kwargs: Passes the currency parameter forward. 

1470 

1471 Returns: 

1472 A formatted number. 

1473 """ 

1474 

1475 def decimal(self, n, *args, **kwargs) -> str: 

1476 """Returns formatted decimal value.""" 

1477 

1478 def grouped(self, n, *args, **kwargs) -> str: 

1479 """Returns formatted decimal value with group separators.""" 

1480 

1481 def currency(self, n, currency: str, *args, **kwargs) -> str: 

1482 """Returns formatted currency value.""" 

1483 

1484 def percent(self, n, *args, **kwargs) -> str: 

1485 """Returns formatted percent value.""" 

1486################################################################################ 

1487 

1488 

1489################################################################################ 

1490# /lib/style/types.pyinc 

1491 

1492 

1493class StyleValues(Data): 

1494 """CSS Style values.""" 

1495 

1496 fill: Color 

1497 

1498 stroke: Color 

1499 stroke_dasharray: list[int] 

1500 stroke_dashoffset: int 

1501 stroke_linecap: Literal['butt', 'round', 'square'] 

1502 stroke_linejoin: Literal['bevel', 'round', 'miter'] 

1503 stroke_miterlimit: int 

1504 stroke_width: int 

1505 

1506 marker: Literal['circle', 'square', 'arrow', 'cross'] 

1507 marker_fill: Color 

1508 marker_size: int 

1509 marker_stroke: Color 

1510 marker_stroke_dasharray: list[int] 

1511 marker_stroke_dashoffset: int 

1512 marker_stroke_linecap: Literal['butt', 'round', 'square'] 

1513 marker_stroke_linejoin: Literal['bevel', 'round', 'miter'] 

1514 marker_stroke_miterlimit: int 

1515 marker_stroke_width: int 

1516 

1517 with_geometry: Literal['all', 'none'] 

1518 with_label: Literal['all', 'none'] 

1519 

1520 label_align: Literal['left', 'right', 'center'] 

1521 label_background: Color 

1522 label_fill: Color 

1523 label_font_family: str 

1524 label_font_size: int 

1525 label_font_style: Literal['normal', 'italic'] 

1526 label_font_weight: Literal['normal', 'bold'] 

1527 label_line_height: int 

1528 label_max_scale: int 

1529 label_min_scale: int 

1530 label_offset_x: int 

1531 label_offset_y: int 

1532 label_padding: list[int] 

1533 label_placement: Literal['start', 'end', 'middle'] 

1534 label_stroke: Color 

1535 label_stroke_dasharray: list[int] 

1536 label_stroke_dashoffset: int 

1537 label_stroke_linecap: Literal['butt', 'round', 'square'] 

1538 label_stroke_linejoin: Literal['bevel', 'round', 'miter'] 

1539 label_stroke_miterlimit: int 

1540 label_stroke_width: int 

1541 

1542 point_size: int 

1543 icon: str 

1544 

1545 offset_x: int 

1546 offset_y: int 

1547 

1548 

1549class StyleProps(Props): 

1550 """CSS Style properties.""" 

1551 

1552 cssSelector: Optional[str] 

1553 text: Optional[str] 

1554 values: Optional[dict] 

1555 

1556 

1557class Style: 

1558 """CSS Style object.""" 

1559 

1560 cssSelector: str 

1561 text: str 

1562 values: StyleValues 

1563################################################################################ 

1564 

1565 

1566################################################################################ 

1567# /lib/xmlx/types.pyinc 

1568 

1569 

1570class XmlNamespace(Data): 

1571 """XML namespace.""" 

1572 

1573 uid: str 

1574 """Unique ID.""" 

1575 xmlns: str 

1576 """Default prefix for this Namespace.""" 

1577 uri: Url 

1578 """Namespace uri.""" 

1579 schemaLocation: Url 

1580 """Namespace schema location.""" 

1581 version: str 

1582 """Namespace version.""" 

1583 isDefault: bool 

1584 """Is this the default namespace for the given xmlns prefix.""" 

1585 extendsGml: bool 

1586 """Namespace schema extends the GML3 schema.""" 

1587 

1588 

1589class XmlOptions(Data): 

1590 """XML options for parsing and serialization.""" 

1591 

1592 namespaces: Optional[dict[str, XmlNamespace]] = None 

1593 """Mapping of prefixes to namespaces.""" 

1594 

1595 customXmlns: Optional[dict[str, str]] = None 

1596 """A mapping of namespace ids to custom prefixes.""" 

1597 

1598 defaultNamespace: Optional['XmlNamespace'] = None 

1599 """Default namespace to use for serialization.""" 

1600 

1601 doctype: Optional[str] = None 

1602 """Document type definition (DTD) to use for serialization.""" 

1603 

1604 compactWhitespace: bool = False 

1605 """Remove all whitespace outside of tags and elements.""" 

1606 

1607 removeNamespaces: bool = False 

1608 """Remove all namespace references.""" 

1609 

1610 foldTags: bool = False 

1611 """If true, folds nested tag names into ``parent/child`` names.""" 

1612 

1613 withNamespaceDeclarations: bool = False 

1614 """Include the namespace declarations.""" 

1615 

1616 withSchemaLocations: bool = False 

1617 """Include schema locations.""" 

1618 

1619 withXmlDeclaration: bool = False 

1620 """Include the xml declaration.""" 

1621 

1622 

1623class XmlElement(Iterable): 

1624 """XML Element. 

1625 

1626 Extends ``ElementTree.Element`` (https://docs.python.org/3/library/xml.etree.elementtree.html#element-objects). 

1627 """ 

1628 

1629 tag: str 

1630 """Tag name, with an optional namespace in the Clark notation.""" 

1631 

1632 text: str 

1633 """Text before first subelement.""" 

1634 

1635 tail: str 

1636 """Text after this element's end tag.""" 

1637 

1638 attrib: dict 

1639 """Dictionary of element attributes.""" 

1640 

1641 name: str 

1642 """Element name (tag without a namespace).""" 

1643 

1644 lcName: str 

1645 """Element name (tag without a namespace) in lower case.""" 

1646 

1647 caseInsensitive: bool 

1648 """Element is case-insensitive.""" 

1649 

1650 def __len__(self) -> int: ... 

1651 

1652 def __iter__(self) -> Iterator['XmlElement']: ... 

1653 

1654 def __getitem__(self, item: int) -> 'XmlElement': ... 

1655 

1656 def append(self, subelement: 'XmlElement'): 

1657 """Adds the element subelement to the end of this element’s internal list of subelements.""" 

1658 

1659 def clear(self): 

1660 """Resets an element.""" 

1661 

1662 def extend(self, subelements: Iterable['XmlElement']): 

1663 """Appends subelements from a sequence object with zero or more elements.""" 

1664 

1665 def find(self, path: str) -> Optional['XmlElement']: 

1666 """Finds first matching element by tag name or path.""" 

1667 

1668 def require(self, path: str) -> 'XmlElement': 

1669 """Finds first matching element and raises an error if not found.""" 

1670 

1671 def findall(self, path: str) -> list['XmlElement']: 

1672 """Finds all matching subelements by name or path.""" 

1673 

1674 def findtext(self, path: str, default: Optional[str] = None) -> str: 

1675 """Finds text for first matching element by name or path.""" 

1676 

1677 def get(self, key: str, default='') -> str: 

1678 """Gets the element attribute named key.""" 

1679 

1680 def insert(self, index: int, subelement: 'XmlElement'): 

1681 """Inserts subelement at the given position in this element.""" 

1682 

1683 def items(self) -> Iterable[tuple[str, Any]]: 

1684 """Returns the element attributes as a sequence of (name, value) pairs.""" 

1685 

1686 def iter(self, tag: Optional[str] = None) -> Iterable['XmlElement']: 

1687 """Creates a tree iterator.""" 

1688 

1689 def iterfind(self, path: Optional[str] = None) -> Iterable['XmlElement']: 

1690 """Returns an iterable of all matching subelements by name or path.""" 

1691 

1692 def itertext(self) -> Iterable[str]: 

1693 """Creates a text iterator and returns all inner text.""" 

1694 

1695 def keys(self) -> Iterable[str]: 

1696 """Returns the elements attribute names as a list.""" 

1697 

1698 def remove(self, other: 'XmlElement'): 

1699 """Removes the other element from the element.""" 

1700 

1701 def set(self, key: str, value: Any): 

1702 """Set the attribute key on the element to value.""" 

1703 

1704 # extensions 

1705 

1706 def attr(self, key: str, default='') -> str: 

1707 """Alias for 'get'.""" 

1708 

1709 def hasattr(self, key: str) -> bool: 

1710 """Check if an attribute exists.""" 

1711 

1712 def add(self, tag: str, attrib: Optional[dict] = None, **extra) -> 'XmlElement': 

1713 """Creates a new element and adds it as a child. 

1714 

1715 Args: 

1716 tag: XML tag. 

1717 attrib: XML attributes ``{key, value}``. 

1718 """ 

1719 

1720 def children(self) -> list['XmlElement']: 

1721 """Returns the children of the current element.""" 

1722 

1723 def findfirst(self, *paths) -> Optional['XmlElement']: 

1724 """Given a list of paths, returns the first matching element.""" 

1725 

1726 def textof(self, *paths) -> str: 

1727 """Given a list of paths, returns the text of the first matching element that has text.""" 

1728 

1729 def textlist(self, *paths, deep=False) -> list[str]: 

1730 """Collects texts from child elements. 

1731 

1732 Args: 

1733 paths: List of paths to search for. 

1734 deep: If ``False`` it only looks into direct children, otherwise search the entire subtree. 

1735 

1736 Returns: 

1737 A list containing all the text from the child-elements. 

1738 """ 

1739 

1740 def textdict(self, *paths, deep=False) -> dict[str, str]: 

1741 """Collects texts from child elements. 

1742 

1743 Args: 

1744 paths: List of paths to search for. 

1745 deep: If ``False`` it only looks into direct children, otherwise search the entire subtree. 

1746 

1747 Returns: 

1748 A dict tag name -> text. 

1749 """ 

1750 

1751 def remove_namespaces(self) -> 'XmlElement': 

1752 """Removes all namespace references from the element and its children.""" 

1753 

1754 def to_string(self, opts: Optional[XmlOptions] = None) -> str: 

1755 """Converts the Element object to a string. 

1756 

1757 Args: 

1758 opts: XML options for serialization. 

1759 

1760 Returns: 

1761 An XML string. 

1762 """ 

1763 

1764 def to_dict(self) -> dict: 

1765 """Creates a dictionary from an XmlElement object.""" 

1766 

1767 def to_list(self, opts: Optional[XmlOptions] = None) -> list: 

1768 """Parse an XML element into a list of arguments (reverse of `gws.lib.xmlx.tag`). 

1769 

1770 Args: 

1771 opts: XML options for serialization. 

1772 """ 

1773################################################################################ 

1774 

1775 

1776 

1777################################################################################ 

1778# /lib/crs/types.pyinc 

1779 

1780 

1781CrsName: TypeAlias = int | str 

1782"""A CRS code like ``EPSG:3857`` or a SRID like ``3857``.""" 

1783 

1784 

1785class CrsFormat(Enum): 

1786 """CRS name format.""" 

1787 

1788 none = '' 

1789 """No format.""" 

1790 crs = 'crs' 

1791 """Like ``crs84``.""" 

1792 srid = 'srid' 

1793 """Like ``3857``.""" 

1794 epsg = 'epsg' 

1795 """Like ``EPSG:3857``.""" 

1796 url = 'url' 

1797 """Like ``http://www.opengis.net/gml/srs/epsg.xml#3857``.""" 

1798 uri = 'uri' 

1799 """Like ``http://www.opengis.net/def/crs/epsg/0/3857``.""" 

1800 urnx = 'urnx' 

1801 """Like ``urn:x-ogc:def:crs:EPSG:3857``.""" 

1802 urn = 'urn' 

1803 """Like ``urn:ogc:def:crs:EPSG::3857``.""" 

1804 

1805 

1806class Axis(Enum): 

1807 """Axis orientation.""" 

1808 

1809 xy = 'xy' 

1810 """XY (longitude/latitude) axis orientation.""" 

1811 yx = 'yx' 

1812 """YX (latitude/longitude) axis orientation.""" 

1813 

1814 

1815class Bounds(Data): 

1816 """Geo-referenced extent.""" 

1817 

1818 crs: 'Crs' 

1819 extent: Extent 

1820 

1821 

1822class Crs: 

1823 """Coordinate reference system.""" 

1824 

1825 srid: int 

1826 """CRS SRID.""" 

1827 axis: Axis 

1828 """Axis orientation.""" 

1829 uom: Uom 

1830 """CRS unit.""" 

1831 isGeographic: bool 

1832 """This CRS is geographic.""" 

1833 isProjected: bool 

1834 """This CRS is projected.""" 

1835 isYX: bool 

1836 """This CRS has a lat/lon axis.""" 

1837 proj4text: str 

1838 """Proj4 definition.""" 

1839 wkt: str 

1840 """WKT definition.""" 

1841 

1842 epsg: str 

1843 """Name in the "epsg" format.""" 

1844 urn: str 

1845 """Name in the "urn" format.""" 

1846 urnx: str 

1847 """Name in the "urnx" format.""" 

1848 url: str 

1849 """Name in the "url" format.""" 

1850 uri: str 

1851 """Name in the "uri" format.""" 

1852 

1853 name: str 

1854 """CRS name.""" 

1855 base: int 

1856 """Base CRS code.""" 

1857 datum: str 

1858 """Datum.""" 

1859 

1860 wgsExtent: Extent 

1861 """CRS Extent in the WGS projection.""" 

1862 extent: Extent 

1863 """CRS own Extent.""" 

1864 bounds: Bounds 

1865 """CRS own Bounds.""" 

1866 

1867 coordinatePrecision: int 

1868 """Preferred precision for coordinates in this CRS.""" 

1869 

1870 def axis_for_format(self, fmt: 'CrsFormat') -> Axis: 

1871 """Get the axis depending on the string format. 

1872 

1873 We adhere to the GeoServer convention here: 

1874 https://docs.geoserver.org/latest/en/user/services/wfs/axis_order.html 

1875 """ 

1876 

1877 def transform_extent(self, extent: Extent, crs_to: 'Crs') -> Extent: 

1878 """Transform an Extent from this CRS to another. 

1879 

1880 Args: 

1881 extent: Extent. 

1882 crs_to: Target CRS. 

1883 

1884 Returns: 

1885 A transformed Extent. 

1886 """ 

1887 

1888 def extent_size_in_meters(self, extent: Extent) -> Size: 

1889 """Calculate the width and height of an extent in meters; 

1890 

1891 Args: 

1892 extent: Extent. 

1893 """ 

1894 

1895 def point_offset_in_meters(self, xy: Point, dist: float, az: int) -> Point: 

1896 """Calculate a point with an offset in meters. 

1897 Args: 

1898 xy: Point. 

1899 dist: Distance in meters. 

1900 az: Azimuth in degrees (0 = North, 90 = East, etc.). 

1901 """ 

1902 

1903 def transformer(self, crs_to: 'Crs') -> Callable: 

1904 """Create a transformer function to another CRS. 

1905 

1906 Args: 

1907 crs_to: Target CRS. 

1908 

1909 Returns: 

1910 A function. 

1911 """ 

1912 

1913 def to_string(self, fmt: Optional['CrsFormat'] = None) -> str: 

1914 """Return a string representation of the CRS. 

1915 

1916 Args: 

1917 fmt: Format to use. 

1918 

1919 Returns: 

1920 A string. 

1921 """ 

1922 

1923 def to_geojson(self) -> dict: 

1924 """Return a geojson representation of the CRS (as per GJ2008). 

1925 

1926 Returns: 

1927 A GeoJson dict. 

1928 

1929 References: 

1930 https://geojson.org/geojson-spec#named-crs 

1931 """ 

1932################################################################################ 

1933 

1934 

1935################################################################################ 

1936# /gis/render/types.pyinc 

1937 

1938 

1939class MapView(Data): 

1940 """Map view.""" 

1941 

1942 bounds: Bounds 

1943 center: Point 

1944 rotation: int 

1945 scale: int 

1946 mmSize: Size 

1947 pxSize: Size 

1948 dpi: int 

1949 

1950 

1951class MapRenderInputPlaneType(Enum): 

1952 """Map render input plane type.""" 

1953 

1954 features = 'features' 

1955 image = 'image' 

1956 imageLayer = 'imageLayer' 

1957 svgLayer = 'svgLayer' 

1958 svgSoup = 'svgSoup' 

1959 

1960 

1961class MapRenderInputPlane(Data): 

1962 """Map render input plane.""" 

1963 

1964 type: MapRenderInputPlaneType 

1965 features: list['Feature'] 

1966 image: 'Image' 

1967 layer: 'Layer' 

1968 opacity: float 

1969 soupPoints: list[Point] 

1970 soupTags: list[Any] 

1971 styles: list['Style'] 

1972 compositeLayerUids: list[str] 

1973 

1974 

1975class MapRenderInput(Data): 

1976 """Map render input.""" 

1977 

1978 backgroundColor: int 

1979 bbox: Extent 

1980 center: Point 

1981 crs: 'Crs' 

1982 dpi: int 

1983 mapSize: UomSize 

1984 notify: Callable 

1985 planes: list['MapRenderInputPlane'] 

1986 project: 'Project' 

1987 rotation: int 

1988 scale: int 

1989 user: 'User' 

1990 visibleLayers: Optional[list['Layer']] 

1991 

1992 

1993class MapRenderOutputPlaneType(Enum): 

1994 """Map render output plane type.""" 

1995 

1996 image = 'image' 

1997 path = 'path' 

1998 svg = 'svg' 

1999 

2000 

2001class MapRenderOutputPlane(Data): 

2002 """Map render output plane.""" 

2003 

2004 type: MapRenderOutputPlaneType 

2005 path: str 

2006 elements: list[XmlElement] 

2007 image: 'Image' 

2008 

2009 

2010class MapRenderOutput(Data): 

2011 """Map render output.""" 

2012 

2013 planes: list['MapRenderOutputPlane'] 

2014 view: MapView 

2015 

2016 

2017class LayerRenderInputType(Enum): 

2018 """Layer render input type.""" 

2019 

2020 box = 'box' 

2021 xyz = 'xyz' 

2022 svg = 'svg' 

2023 

2024 

2025class LayerRenderInput(Data): 

2026 """Layer render input.""" 

2027 

2028 extraParams: dict 

2029 project: 'Project' 

2030 style: 'Style' 

2031 type: LayerRenderInputType 

2032 user: 'User' 

2033 view: MapView 

2034 x: int 

2035 y: int 

2036 z: int 

2037 

2038 

2039class LayerRenderOutput(Data): 

2040 """Layer render output.""" 

2041 

2042 content: bytes 

2043 tags: list[XmlElement] 

2044################################################################################ 

2045 

2046 

2047################################################################################ 

2048# /gis/source/types.pyinc 

2049 

2050 

2051class TileMatrix(Data): 

2052 """WMTS TileMatrix object.""" 

2053 

2054 uid: str 

2055 scale: float 

2056 x: float 

2057 y: float 

2058 width: float 

2059 height: float 

2060 tileWidth: float 

2061 tileHeight: float 

2062 extent: Extent 

2063 

2064 

2065class TileMatrixSet(Data): 

2066 """WMTS TileMatrixSet object.""" 

2067 

2068 uid: str 

2069 crs: 'Crs' 

2070 matrices: list[TileMatrix] 

2071 

2072 

2073class SourceStyle(Data): 

2074 """Generic OGC Style.""" 

2075 

2076 isDefault: bool 

2077 legendUrl: Url 

2078 metadata: 'Metadata' 

2079 name: str 

2080 

2081 

2082class SourceLayer(Data): 

2083 """Generic OGC Layer.""" 

2084 

2085 aLevel: int 

2086 aPath: str 

2087 aUid: str 

2088 

2089 dataSource: dict 

2090 metadata: 'Metadata' 

2091 

2092 supportedCrs: list['Crs'] 

2093 wgsExtent: Extent 

2094 

2095 isExpanded: bool 

2096 isGroup: bool 

2097 isImage: bool 

2098 isQueryable: bool 

2099 isVisible: bool 

2100 

2101 layers: list['SourceLayer'] 

2102 

2103 name: str 

2104 title: str 

2105 

2106 legendUrl: Url 

2107 opacity: float 

2108 scaleRange: list[float] 

2109 

2110 styles: list[SourceStyle] 

2111 defaultStyle: Optional[SourceStyle] 

2112 

2113 tileMatrixIds: list[str] 

2114 tileMatrixSets: list[TileMatrixSet] 

2115 imageFormat: str 

2116 resourceUrls: dict 

2117 

2118 sourceId: str 

2119 properties: dict 

2120################################################################################ 

2121 

2122 

2123 

2124################################################################################ 

2125# /config/types.pyinc 

2126 

2127 

2128class ConfigLocation(Data): 

2129 """Location in the configuration tree.""" 

2130 

2131 objectUid: str 

2132 """UID of the object.""" 

2133 objectType: str 

2134 """Type of the object.""" 

2135 objectName: str 

2136 """Name of the object.""" 

2137 propName: str 

2138 """Property of the parent this object is located at.""" 

2139 

2140 

2141class ConfigErrorInfo(Data): 

2142 """Full information about a configuration error.""" 

2143 

2144 message: str 

2145 """Error message.""" 

2146 path: str 

2147 """Path to the configuration file.""" 

2148 line: int 

2149 """Line number where the error occurred.""" 

2150 value: str 

2151 """Value that caused the error.""" 

2152 stack: list[ConfigLocation] 

2153 """Stack trace of the error.""" 

2154 contextLines: list[str] 

2155 """Lines of context around the error.""" 

2156 cause: str 

2157 """Cause of the error.""" 

2158 

2159 

2160class ConfigContext(Data): 

2161 """Configuration context for parsing and validation.""" 

2162 

2163 specs: SpecRuntime 

2164 readOptions: set[SpecReadOption] 

2165 errors: list[ConfigErrorInfo] 

2166 paths: set[str] 

2167 

2168 

2169 

2170class ConfigResult(Data): 

2171 """Configuration result.""" 

2172 

2173 root: Optional['Root'] 

2174 config: Optional['Config'] 

2175 errors: list[ConfigErrorInfo] 

2176 info: str 

2177################################################################################ 

2178 

2179 

2180################################################################################ 

2181# /server/types.pyinc 

2182 

2183 

2184class ServerManager(Node): 

2185 """Server configuration manager.""" 

2186 

2187 templates: list['Template'] 

2188 

2189 def create_server_configs(self, target_dir: str, script_path: str, pid_paths: dict): 

2190 """Create server configuration files.""" 

2191 

2192 

2193class ServerMonitor(Node): 

2194 """File Monitor facility.""" 

2195 

2196 def watch_directory(self, path: str, pattern: 'Regex', recursive=False): 

2197 """Add a directory to watch. 

2198 

2199 Args: 

2200 path: Directory path. 

2201 pattern: Regex pattern for files to watch. 

2202 recursive: Watch subdirectories. 

2203 """ 

2204 

2205 def watch_file(self, path: str): 

2206 """Add a file to watch. 

2207 

2208 Args: 

2209 path: File path. 

2210 """ 

2211 

2212 def register_periodic_task(self, obj: Node, frequency: int = 0): 

2213 """Register an object as a periodic task handler. 

2214 

2215 Args: 

2216 obj: A node with a ``periodic_task`` method. 

2217 frequency: Task frequency in seconds. 

2218 """ 

2219 

2220 def schedule_reload(self, with_reconfigure: bool = False): 

2221 """Schedule a system reload. 

2222 

2223 Args: 

2224 with_reconfigure: Reconfigure the server before reloading. 

2225 """ 

2226 

2227 def start(self): 

2228 """Start the monitor.""" 

2229################################################################################ 

2230 

2231 

2232 

2233################################################################################ 

2234# /base/metadata/types.pyinc 

2235 

2236 

2237class MetadataLink(Data): 

2238 about: str 

2239 description: str 

2240 format: str 

2241 formatVersion: str 

2242 function: str 

2243 mimeType: str 

2244 scheme: str 

2245 title: str 

2246 type: str 

2247 url: str 

2248 

2249 

2250class Metadata(Data): 

2251 name: str 

2252 title: str 

2253 

2254 abstract: str 

2255 accessConstraints: str 

2256 accessConstraintsType: str 

2257 attribution: str 

2258 attributionUrl: str 

2259 dateCreated: Optional['datetime.datetime'] 

2260 dateUpdated: Optional['datetime.datetime'] 

2261 fees: str 

2262 image: str 

2263 keywords: list[str] 

2264 license: str 

2265 licenseUrl: str 

2266 

2267 contactAddress: str 

2268 contactAddressType: str 

2269 contactArea: str 

2270 contactCity: str 

2271 contactCountry: str 

2272 contactEmail: str 

2273 contactFax: str 

2274 contactOrganization: str 

2275 contactPerson: str 

2276 contactPhone: str 

2277 contactPosition: str 

2278 contactProviderName: str 

2279 contactProviderSite: str 

2280 contactRole: str 

2281 contactUrl: str 

2282 contactZip: str 

2283 

2284 authorityIdentifier: str 

2285 authorityName: str 

2286 authorityUrl: str 

2287 

2288 metaLinks: list[MetadataLink] 

2289 serviceMetadataURL: str 

2290 

2291 catalogCitationUid: str 

2292 catalogUid: str 

2293 

2294 language: str 

2295 language3: str 

2296 languageBib: str 

2297 languageName: str 

2298 

2299 parentIdentifier: str 

2300 wgsExtent: Optional[Extent] 

2301 crs: Optional['Crs'] 

2302 temporalBegin: Optional['datetime.datetime'] 

2303 temporalEnd: Optional['datetime.datetime'] 

2304 

2305 inspireMandatoryKeyword: str 

2306 inspireDegreeOfConformity: str 

2307 inspireResourceType: str 

2308 inspireSpatialDataServiceType: str 

2309 inspireSpatialScope: str 

2310 inspireSpatialScopeName: str 

2311 inspireTheme: str 

2312 

2313 inspireThemeNameLocal: str 

2314 inspireThemeNameEn: str 

2315 

2316 isoMaintenanceFrequencyCode: str 

2317 isoQualityConformanceExplanation: str 

2318 isoQualityConformanceQualityPass: bool 

2319 isoQualityConformanceSpecificationDate: str 

2320 isoQualityConformanceSpecificationTitle: str 

2321 isoQualityLineageSource: str 

2322 isoQualityLineageSourceScale: int 

2323 isoQualityLineageStatement: str 

2324 isoRestrictionCode: str 

2325 isoServiceFunction: str 

2326 isoScope: str 

2327 isoScopeName: str 

2328 isoSpatialRepresentationType: str 

2329 isoTopicCategories: list[str] 

2330 isoSpatialResolution: int 

2331################################################################################ 

2332 

2333 

2334################################################################################ 

2335# /base/feature/types.pyinc 

2336 

2337 

2338FeatureUid: TypeAlias = str 

2339"""Unique Feature id.""" 

2340 

2341class FeatureRecord(Data): 

2342 """Raw data from a feature source.""" 

2343 

2344 attributes: dict 

2345 meta: dict 

2346 uid: Optional[str] 

2347 shape: Optional['Shape'] 

2348 ewkt: str 

2349 

2350 

2351class FeatureProps(Props): 

2352 """Feature Proprieties.""" 

2353 

2354 attributes: dict 

2355 category: Optional[str] 

2356 cssSelector: str 

2357 errors: Optional[list['ModelValidationError']] 

2358 createWithFeatures: Optional[list['FeatureProps']] 

2359 isNew: bool 

2360 modelUid: str 

2361 uid: str 

2362 views: dict 

2363 

2364 

2365class Feature: 

2366 """Feature object.""" 

2367 

2368 attributes: dict 

2369 category: str 

2370 cssSelector: str 

2371 errors: list['ModelValidationError'] 

2372 isNew: bool 

2373 model: 'Model' 

2374 props: 'FeatureProps' 

2375 record: 'FeatureRecord' 

2376 views: dict 

2377 createWithFeatures: list['Feature'] 

2378 insertedPrimaryKey: Optional[int | str] 

2379 

2380 def get(self, name: str, default=None) -> Any: 

2381 """Get attribute value.""" 

2382 

2383 def has(self, name: str) -> bool: 

2384 """Check if attribute exists.""" 

2385 

2386 def set(self, name: str, value: Any) -> 'Feature': 

2387 """Set attribute value.""" 

2388 

2389 def raw(self, name: str) -> Any: 

2390 """Get raw attribute value from the record.""" 

2391 

2392 def render_views(self, templates: list['Template'], **kwargs) -> 'Feature': 

2393 """Render feature views using provided templates, populate views`.""" 

2394 

2395 def shape(self) -> Optional['Shape']: 

2396 """Get feature shape.""" 

2397 

2398 def to_svg(self, view: 'MapView', label: Optional[str] = None, style: Optional['Style'] = None) -> list[XmlElement]: 

2399 """Render feature shape to SVG fragments for the given map view.""" 

2400 

2401 def to_geojson(self, keep_crs=False) -> dict: 

2402 """Convert feature to GeoJSON dict.""" 

2403 

2404 def transform_to(self, crs: 'Crs') -> 'Feature': 

2405 """Transform feature shape to the given CRS.""" 

2406 

2407 def uid(self) -> FeatureUid: 

2408 """Get feature unique id.""" 

2409################################################################################ 

2410 

2411 

2412################################################################################ 

2413# /base/shape/types.pyinc 

2414 

2415 

2416class ShapeProps(Props): 

2417 """Shape properties.""" 

2418 

2419 crs: str 

2420 geometry: dict 

2421 

2422 

2423class Shape(Object): 

2424 """Geo-referenced geometry.""" 

2425 

2426 type: GeometryType 

2427 """Geometry type.""" 

2428 

2429 crs: 'Crs' 

2430 """CRS of this shape.""" 

2431 

2432 x: Optional[float] 

2433 """X-coordinate for Point geometries, None otherwise.""" 

2434 

2435 y: Optional[float] 

2436 """Y-coordinate for Point geometries, None otherwise.""" 

2437 

2438 # common props 

2439 

2440 def area(self) -> float: 

2441 """Computes the area of the geometry.""" 

2442 

2443 def bounds(self) -> Bounds: 

2444 """Returns a Bounds object that bounds this shape.""" 

2445 

2446 def centroid(self) -> 'Shape': 

2447 """Returns a centroid as a Point shape.""" 

2448 

2449 # formats 

2450 

2451 def to_wkb(self) -> bytes: 

2452 """Returns a WKB representation of this shape as a binary string.""" 

2453 

2454 def to_wkb_hex(self) -> str: 

2455 """Returns a WKB representation of this shape as a hex string.""" 

2456 

2457 def to_ewkb(self) -> bytes: 

2458 """Returns an EWKB representation of this shape as a binary string.""" 

2459 

2460 def to_ewkb_hex(self) -> str: 

2461 """Returns an EWKB representation of this shape as a hex string.""" 

2462 

2463 def to_wkt(self, trim=False, rounding_precision=-1, output_dimension=3) -> str: 

2464 """Returns a WKT representation of this shape.""" 

2465 

2466 def to_ewkt(self, trim=False, rounding_precision=-1, output_dimension=3) -> str: 

2467 """Returns an EWKT representation of this shape.""" 

2468 

2469 def to_geojson(self, keep_crs=False) -> dict: 

2470 """Returns a GeoJSON representation of this shape. 

2471 

2472 Args: 

2473 keep_crs: Do not transform to WGS. 

2474 """ 

2475 

2476 def to_props(self) -> ShapeProps: 

2477 """Returns a GeoJSON representation of this shape.""" 

2478 

2479 # predicates (https://shapely.readthedocs.io/en/stable/manual.html#predicates-and-relationships) 

2480 

2481 def is_empty(self) -> bool: 

2482 """Returns True if this shape is empty.""" 

2483 

2484 def is_ring(self) -> bool: 

2485 """Returns True if this shape is a ring.""" 

2486 

2487 def is_simple(self) -> bool: 

2488 """Returns True if this shape is 'simple'.""" 

2489 

2490 def is_valid(self) -> bool: 

2491 """Returns True if this shape is valid.""" 

2492 

2493 def equals(self, other: 'Shape') -> bool: 

2494 """Returns True if this shape is equal to the other.""" 

2495 

2496 def contains(self, other: 'Shape') -> bool: 

2497 """Returns True if this shape contains the other.""" 

2498 

2499 def covers(self, other: 'Shape') -> bool: 

2500 """Returns True if this shape covers the other.""" 

2501 

2502 def covered_by(self, other: 'Shape') -> bool: 

2503 """Returns True if this shape is covered by the other.""" 

2504 

2505 def crosses(self, other: 'Shape') -> bool: 

2506 """Returns True if this shape crosses the other.""" 

2507 

2508 def disjoint(self, other: 'Shape') -> bool: 

2509 """Returns True if this shape does not intersect with the other.""" 

2510 

2511 def intersects(self, other: 'Shape') -> bool: 

2512 """Returns True if this shape intersects with the other.""" 

2513 

2514 def overlaps(self, other: 'Shape') -> bool: 

2515 """Returns True if this shape overlaps the other.""" 

2516 

2517 def touches(self, other: 'Shape') -> bool: 

2518 """Returns True if this shape touches the other.""" 

2519 

2520 def within(self, other: 'Shape') -> bool: 

2521 """Returns True if this shape is within the other.""" 

2522 

2523 # set operations 

2524 

2525 def union(self, others: list['Shape']) -> 'Shape': 

2526 """Computes a union of this shape and other shapes.""" 

2527 

2528 def intersection(self, *others: 'Shape') -> 'Shape': 

2529 """Computes an intersection of this shape and other shapes.""" 

2530 

2531 # convertors 

2532 

2533 def to_multi(self) -> 'Shape': 

2534 """Converts a singly-geometry shape to a multi-geometry one.""" 

2535 

2536 def to_type(self, new_type: 'GeometryType') -> 'Shape': 

2537 """Converts a geometry to another type.""" 

2538 

2539 def to_2d(self) -> 'Shape': 

2540 """Converts a geometry to 2-dimensional.""" 

2541 

2542 # misc 

2543 

2544 def tolerance_polygon(self, tolerance=None, quad_segs=None) -> 'Shape': 

2545 """Builds a buffer polygon around the shape.""" 

2546 

2547 def transformed_to(self, crs: 'Crs') -> 'Shape': 

2548 """Returns this shape transformed to another CRS.""" 

2549################################################################################ 

2550 

2551 

2552 

2553################################################################################ 

2554# /base/action/types.pyinc 

2555 

2556 

2557class ActionManager(Node): 

2558 """Action manager.""" 

2559 

2560 def actions_for_project(self, project: 'Project', user: 'User') -> list['Action']: 

2561 """ 

2562 Get a list of actions for a project, to which a user has access to. 

2563 

2564 Args: 

2565 project: The project requiring actions. 

2566 user: The user for whom the actions are retrieved. 

2567 

2568 Returns: 

2569 A list of accessible actions. 

2570 """ 

2571 

2572 def find_action(self, project: Optional['Project'], ext_type: str, user: 'User') -> Optional['Action']: 

2573 """ 

2574 Locate an Action object. 

2575 

2576 Args: 

2577 project: If provided, find the action for that project; otherwise, search globally. 

2578 ext_type: The extension type to search for. 

2579 user: Locate actions only for this user. 

2580 

2581 Returns: 

2582 The located action object, or None if no match is found. 

2583 """ 

2584 

2585 def prepare_action( 

2586 self, 

2587 command_category: CommandCategory, 

2588 command_name: str, 

2589 params: dict, 

2590 path: str, 

2591 user: 'User', 

2592 read_options: Optional[set[SpecReadOption]]=None, 

2593 ) -> tuple[Callable, Request]: 

2594 """ 

2595 Prepare an action to be executed based on the provided parameters. 

2596 

2597 Args: 

2598 command_category: The category of the command to execute. 

2599 command_name: The name of the command to execute. 

2600 params: Request parameters for the command. 

2601 path: Request path for which the action is being prepared. 

2602 user: The user initiating the action. 

2603 read_options: Read options for parsing parameters. 

2604 

2605 Returns: 

2606 A tuple containing the callable to execute and the associated request object. 

2607 """ 

2608 

2609 

2610class Action(Node): 

2611 """Base Action class.""" 

2612################################################################################ 

2613 

2614 

2615################################################################################ 

2616# /base/auth/types.pyinc 

2617 

2618 

2619class User(Object): 

2620 """User object.""" 

2621 

2622 isGuest: bool 

2623 """User is a Guest.""" 

2624 

2625 authProvider: 'AuthProvider' 

2626 """User authorization provider.""" 

2627 

2628 attributes: dict 

2629 """Public user attributes.""" 

2630 data: dict 

2631 """Private user data.""" 

2632 roles: set[str] 

2633 """User roles.""" 

2634 uid: str 

2635 """Global user uid.""" 

2636 

2637 authToken: str 

2638 """Token used for authorization.""" 

2639 displayName: str 

2640 """User display name.""" 

2641 email: str 

2642 """User email.""" 

2643 localUid: str 

2644 """User uid within its authorization provider.""" 

2645 loginName: str 

2646 """User login name.""" 

2647 mfaUid: str 

2648 """MFA adapter uid.""" 

2649 mfaSecret: str 

2650 """MFA secret.""" 

2651 

2652 def acl_bit(self, access: Access, obj: Object) -> Optional[int]: 

2653 """Get the ACL bit for a specific object. 

2654 

2655 Args: 

2656 access: Access mode. 

2657 obj: Requested object. 

2658 

2659 Returns: 

2660 ``1`` or ``0`` if the user's permissions have the bit and ``None`` otherwise. 

2661 """ 

2662 

2663 def can(self, access: Access, obj: Object, *context) -> bool: 

2664 """Check if the user can access an object. 

2665 

2666 Args: 

2667 access: Access mode. 

2668 obj: Requested object. 

2669 *context: Further objects to check. 

2670 

2671 Returns: 

2672 ``True`` is access is granted. 

2673 """ 

2674 

2675 def can_create(self, obj: Object, *context) -> bool: 

2676 """Check if the user has "create" permission on an object.""" 

2677 

2678 def can_delete(self, obj: Object, *context) -> bool: 

2679 """Check if the user has "delete" permission on an object.""" 

2680 

2681 def can_read(self, obj: Object, *context) -> bool: 

2682 """Check if the user has "read" permission on an object.""" 

2683 

2684 def can_use(self, obj: Object, *context) -> bool: 

2685 """Check if the user has "read" permission on an object.""" 

2686 

2687 def can_write(self, obj: Object, *context) -> bool: 

2688 """Check if the user has "write" permission on an object.""" 

2689 

2690 def can_edit(self, obj: Object, *context) -> bool: 

2691 """Check if the user has "edit" permissions on an object.""" 

2692 

2693 def acquire(self, uid: str = None, classref: Optional[ClassRef] = None, access: Optional[Access] = None) -> Optional[Object]: 

2694 """Get a readable object by uid. 

2695 

2696 Args: 

2697 uid: Object uid. 

2698 classref: Class reference. If provided, ensures that the object matches the reference. 

2699 access: Access mode, assumed ``Access.read`` if omitted. 

2700 

2701 Returns: 

2702 A readable object or ``None`` if the object does not exists or user doesn't have a permission. 

2703 """ 

2704 

2705 def require(self, uid: str = None, classref: Optional[ClassRef] = None, access: Optional[Access] = None) -> Object: 

2706 """Get a readable object by uid and fail if not found. 

2707 

2708 Args: 

2709 uid: Object uid. 

2710 classref: Class reference. If provided, ensures that the object matches the reference. 

2711 access: Access mode, assumed ``Access.read`` if omitted. 

2712 

2713 Returns: 

2714 A readable object. 

2715 

2716 Raises: 

2717 ``NotFoundError`` if the object doesn't exist. 

2718 ``ForbiddenError`` if the user cannot read the object. 

2719 """ 

2720 

2721 def require_project(self, uid: str = None) -> 'Project': 

2722 """Get a readable Project object. 

2723 

2724 Args: 

2725 uid: Project uid. 

2726 

2727 Returns: 

2728 A Project object. 

2729 """ 

2730 

2731 def require_layer(self, uid=None) -> 'Layer': 

2732 """Get a readable Layer object. 

2733 

2734 Args: 

2735 uid: Layer uid. 

2736 

2737 Returns: 

2738 A Layer object. 

2739 """ 

2740 

2741 

2742class AuthManager(Node): 

2743 """Authentication manager.""" 

2744 

2745 guestSession: 'AuthSession' 

2746 """Preconfigured Guest session.""" 

2747 

2748 guestUser: 'User' 

2749 """Preconfigured Guest user.""" 

2750 systemUser: 'User' 

2751 """Preconfigured System user.""" 

2752 

2753 providers: list['AuthProvider'] 

2754 """Authentication providers.""" 

2755 methods: list['AuthMethod'] 

2756 """Authentication methods.""" 

2757 mfAdapters: list['AuthMultiFactorAdapter'] 

2758 """Authentication MFA handlers.""" 

2759 

2760 sessionMgr: 'AuthSessionManager' 

2761 """Session manager.""" 

2762 

2763 def authenticate(self, method: 'AuthMethod', credentials: Data, req: 'WebRequester') -> Optional['User']: 

2764 """Authenticate a user.""" 

2765 

2766 def create_transient_session(self, method: 'AuthMethod', user: 'User', data: Optional[dict] = None) -> 'AuthSession': 

2767 """Create a Session which only lives for the duration of the request. (added in 8.4) 

2768 

2769 Args: 

2770 method: Auth Method that creates the Session. 

2771 user: 'User' for which the Session is created. 

2772 data: Session data. 

2773 

2774 Returns: 

2775 A new Session. 

2776 """ 

2777 

2778 def get_user(self, user_uid: str) -> Optional['User']: 

2779 """Get a User by its global uid.""" 

2780 

2781 def add_provider(self, provider: 'AuthProvider'): 

2782 """Register an authentication Provider.""" 

2783 

2784 def add_method(self, method: 'AuthMethod'): 

2785 """Register an authentication Method.""" 

2786 

2787 def add_multi_factor_adapter(self, adapter: 'AuthMultiFactorAdapter'): 

2788 """Register a Multi-Factor Adapter.""" 

2789 

2790 def can_use_method(self, req: 'WebRequester', method: 'AuthMethod') -> bool: 

2791 """Check if a Method may be used in the context of a Requester.""" 

2792 

2793 def get_provider(self, uid: str) -> Optional['AuthProvider']: 

2794 """Get an authentication Provider by its uid.""" 

2795 

2796 def get_method(self, uid: str) -> Optional['AuthMethod']: 

2797 """Get an authentication Method by its uid.""" 

2798 

2799 def get_multi_factor_adapter(self, uid: str) -> Optional['AuthMultiFactorAdapter']: 

2800 """Get a Multi-Factor Adapter by its uid.""" 

2801 

2802 def serialize_user(self, user: 'User') -> str: 

2803 """Return a string representation of a User.""" 

2804 

2805 def unserialize_user(self, ser: str) -> Optional['User']: 

2806 """Restore a User object from a serialized representation.""" 

2807 

2808 def is_public_object(self, obj: Object, *context) -> bool: 

2809 """Check if an object is public.""" 

2810 

2811 

2812class AuthMethod(Node): 

2813 """Authentication Method.""" 

2814 

2815 secure: bool 

2816 """Method is only allowed in a secure context.""" 

2817 

2818 allowInsecureFrom: list[str] 

2819 """List of IPs from which insecure access is allowed.""" 

2820 

2821 def open_session(self, req: 'WebRequester') -> Optional['AuthSession']: 

2822 """Attempt to open a Session for a Requester. 

2823 

2824 Args: 

2825 req: Requester object. 

2826 

2827 Returns: 

2828 A Session or ``None``. 

2829 """ 

2830 

2831 def close_session(self, req: 'WebRequester', res: 'WebResponder') -> bool: 

2832 """Close a previously opened Session. 

2833 

2834 Args: 

2835 req: Requester object. 

2836 res: Responder object. 

2837 

2838 Returns: 

2839 True if the Session was successfully closed. 

2840 """ 

2841 

2842 

2843class AuthMultiFactorState(Enum): 

2844 """State of a multifactor authorization transaction.""" 

2845 open = 'open' 

2846 """Transaction opened.""" 

2847 ok = 'ok' 

2848 """Transaction completed successfully.""" 

2849 retry = 'retry' 

2850 """Authorization has to be retried.""" 

2851 failed = 'failed' 

2852 """Authorization failed.""" 

2853 

2854 

2855class AuthMultiFactorTransaction(Data): 

2856 """Multifactor authorization transaction.""" 

2857 

2858 state: AuthMultiFactorState 

2859 """The current state of the authorization transaction.""" 

2860 restartCount: int 

2861 """The number of times the transaction has been restarted.""" 

2862 verifyCount: int 

2863 """The number of verification attempts made.""" 

2864 secret: str 

2865 """The secret associated with this transaction.""" 

2866 startTime: int 

2867 """The timestamp when the transaction started.""" 

2868 generateTime: int 

2869 """The timestamp when the code was last generated.""" 

2870 message: str 

2871 """A message associated with the transaction.""" 

2872 adapter: 'AuthMultiFactorAdapter' 

2873 """The MFA adapter handling this transaction.""" 

2874 user: 'User' 

2875 """The user associated with this transaction.""" 

2876 

2877 

2878class AuthMultiFactorAdapter(Node): 

2879 """Multi-factor authentication adapter.""" 

2880 

2881 message: str 

2882 lifeTime: int 

2883 maxRestarts: int 

2884 maxVerifyAttempts: int 

2885 

2886 def start(self, user: 'User') -> Optional[AuthMultiFactorTransaction]: 

2887 """Initialize an MFA transaction for the user.""" 

2888 

2889 def verify(self, mfa: AuthMultiFactorTransaction, payload: dict) -> AuthMultiFactorTransaction: 

2890 """Verify a payload.""" 

2891 

2892 def cancel(self, mfa: AuthMultiFactorTransaction): 

2893 """Cancel the transaction.""" 

2894 

2895 def check_state(self, mfa: AuthMultiFactorTransaction) -> bool: 

2896 """Check if the MFA transaction is valid.""" 

2897 

2898 def check_restart(self, mfa: AuthMultiFactorTransaction) -> bool: 

2899 """Check if the transaction can be restarted.""" 

2900 

2901 def restart(self, mfa: AuthMultiFactorTransaction) -> Optional[AuthMultiFactorTransaction]: 

2902 """Restart the transaction.""" 

2903 

2904 def key_uri(self, secret: str | bytes, issuer_name: str, account_name: str) -> Optional[str]: 

2905 """Generate a key uri for this adapter.""" 

2906 

2907 

2908class AuthProvider(Node): 

2909 """Authentication Provider.""" 

2910 

2911 allowedMethods: list[str] 

2912 """List of Method types allowed to be used with this Provider.""" 

2913 

2914 def get_user(self, local_uid: str) -> Optional['User']: 

2915 """Get a User from its local uid. 

2916 

2917 Args: 

2918 local_uid: User local uid. 

2919 

2920 Returns: 

2921 A User or ``None``. 

2922 """ 

2923 

2924 def authenticate(self, method: 'AuthMethod', credentials: Data) -> Optional['User']: 

2925 """Authenticate a user. 

2926 

2927 Args: 

2928 method: Authentication method. 

2929 credentials: Credentials object. 

2930 

2931 Returns: 

2932 An authenticated User or ``None`` if authentication failed. 

2933 """ 

2934 

2935 def serialize_user(self, user: 'User') -> str: 

2936 """Return a string representation of a User. 

2937 

2938 Args: 

2939 user: A User object. 

2940 

2941 Returns: 

2942 A json string. 

2943 """ 

2944 

2945 def unserialize_user(self, ser: str) -> Optional['User']: 

2946 """Restore a User object from a serialized representation. 

2947 

2948 Args: 

2949 ser: A json string. 

2950 

2951 Returns: 

2952 A User object. 

2953 """ 

2954 

2955 

2956class AuthSession: 

2957 """Authentication session.""" 

2958 

2959 uid: str 

2960 """Session uid.""" 

2961 method: Optional['AuthMethod'] 

2962 """Authentication method that created the session.""" 

2963 user: 'User' 

2964 """Authorized User.""" 

2965 data: dict 

2966 """Session data.""" 

2967 created: 'datetime.datetime' 

2968 """Session create time.""" 

2969 updated: 'datetime.datetime' 

2970 """Session update time.""" 

2971 isChanged: bool 

2972 """Session has changed since the last update..""" 

2973 isTransient: bool 

2974 """Session is not stored in the session manager.""" 

2975 

2976 def get(self, key: str, default=None): 

2977 """Get a session data value. 

2978 

2979 Args: 

2980 key: Value name. 

2981 default: Default value. 

2982 

2983 Returns: 

2984 A value or the default. 

2985 """ 

2986 

2987 def set(self, key: str, value): 

2988 """Set a session data value. 

2989 

2990 Args: 

2991 key: Value name. 

2992 value: A value. 

2993 """ 

2994 

2995 

2996class AuthSessionManager(Node): 

2997 """Authentication session Manager.""" 

2998 

2999 lifeTime: int 

3000 """Session lifetime in seconds.""" 

3001 

3002 maxLifeTime: int 

3003 """Absolute session lifetime in seconds, or 0 if not limited.""" 

3004 

3005 def create(self, method: 'AuthMethod', user: 'User', data: Optional[dict] = None) -> 'AuthSession': 

3006 """Create a new Session, 

3007 

3008 Args: 

3009 method: Auth Method that creates the Session. 

3010 user: 'User' for which the Session is created. 

3011 data: Session data. 

3012 

3013 Returns: 

3014 A new Session. 

3015 """ 

3016 

3017 def delete(self, sess: 'AuthSession'): 

3018 """Delete a Session. 

3019 

3020 Args: 

3021 sess: Session object. 

3022 """ 

3023 

3024 def delete_all(self): 

3025 """Delete all Sessions. 

3026 """ 

3027 

3028 def get(self, uid: str) -> Optional['AuthSession']: 

3029 """Get a valid Session by its uid. 

3030 

3031 Args: 

3032 uid: Session uid. 

3033 

3034 Returns: 

3035 A Session or ``None`` if uid does not exist or the Session is not valid. 

3036 """ 

3037 

3038 def list_all(self) -> list['AuthSession']: 

3039 """Get all sessions.""" 

3040 

3041 def save(self, sess: 'AuthSession'): 

3042 """Save the Session state into a persistent storage. 

3043 

3044 Args: 

3045 sess: Session object. 

3046 """ 

3047 

3048 def touch(self, sess: 'AuthSession'): 

3049 """Update the Session last activity timestamp. 

3050 

3051 Args: 

3052 sess: Session object. 

3053 """ 

3054 

3055 def cleanup(self): 

3056 """Remove invalid Sessions from the storage. 

3057 """ 

3058################################################################################ 

3059 

3060 

3061 

3062################################################################################ 

3063# /base/layer/types.pyinc 

3064 

3065 

3066class LayerDisplayMode(Enum): 

3067 """Layer display mode.""" 

3068 

3069 box = 'box' 

3070 """Display a layer as one big image (WMS-alike).""" 

3071 tile = 'tile' 

3072 """Display a layer in a tile grid.""" 

3073 client = 'client' 

3074 """Draw a layer in the client.""" 

3075 

3076 

3077class LayerClientOptions(Data): 

3078 """Client options for a layer.""" 

3079 

3080 expanded: bool 

3081 """A layer is expanded in the list view.""" 

3082 unlisted: bool 

3083 """A layer is hidden in the list view.""" 

3084 selected: bool 

3085 """A layer is initially selected.""" 

3086 hidden: bool 

3087 """A layer is initially hidden.""" 

3088 unfolded: bool 

3089 """A layer is not listed, but its children are.""" 

3090 exclusive: bool 

3091 """Only one of this layer children is visible at a time.""" 

3092 treeClassName: str 

3093 """CSS class name for the layer tree item.""" 

3094 

3095 

3096class TileGrid(Data): 

3097 """Tile grid.""" 

3098 

3099 uid: str 

3100 bounds: Bounds 

3101 origin: Origin 

3102 resolutions: list[float] 

3103 tileSize: int 

3104 

3105 

3106class LayerCache(Data): 

3107 """Layer cache.""" 

3108 

3109 maxAge: int 

3110 maxLevel: int 

3111 requestBuffer: int 

3112 requestTiles: int 

3113 

3114 

3115class FeatureLoadingStrategy(Enum): 

3116 """Loading strategy for features.""" 

3117 

3118 all = 'all' 

3119 """Load all features.""" 

3120 bbox = 'bbox' 

3121 """Load only features in the current map extent.""" 

3122 lazy = 'lazy' 

3123 """Load features on demand.""" 

3124 

3125 

3126class LayerOws(Node): 

3127 """Layer OWS controller.""" 

3128 

3129 allowedServiceUids: list[str] 

3130 deniedServiceUids: list[str] 

3131 featureName: str 

3132 geometryName: str 

3133 layerName: str 

3134 models: list['Model'] 

3135 xmlNamespace: Optional['XmlNamespace'] 

3136 

3137 

3138class Layer(Node): 

3139 """Layer object.""" 

3140 

3141 canRenderBox: bool 

3142 canRenderSvg: bool 

3143 canRenderXyz: bool 

3144 

3145 isEnabledForOws: bool 

3146 isGroup: bool 

3147 isSearchable: bool 

3148 

3149 hasLegend: bool 

3150 

3151 bounds: Bounds 

3152 zoomBounds: Bounds 

3153 wgsExtent: Extent 

3154 mapCrs: 'Crs' 

3155 clientOptions: LayerClientOptions 

3156 displayMode: LayerDisplayMode 

3157 loadingStrategy: FeatureLoadingStrategy 

3158 imageFormat: ImageFormat 

3159 opacity: float 

3160 resolutions: list[float] 

3161 title: str 

3162 

3163 grid: Optional[TileGrid] 

3164 cache: Optional[LayerCache] 

3165 

3166 metadata: 'Metadata' 

3167 legend: Optional['Legend'] 

3168 legendUrl: str 

3169 

3170 finders: list['Finder'] 

3171 templates: list['Template'] 

3172 models: list['Model'] 

3173 ows: 'LayerOws' 

3174 

3175 msOptions: Optional['MapServerLayerOptions'] 

3176 

3177 layers: list['Layer'] 

3178 

3179 sourceLayers: list['SourceLayer'] 

3180 

3181 def render(self, lri: LayerRenderInput) -> Optional['LayerRenderOutput']: ... 

3182 

3183 def find_features(self, search: 'SearchQuery', user: 'User') -> list['Feature']: ... 

3184 

3185 def render_legend(self, args: Optional[dict] = None) -> Optional['LegendRenderOutput']: ... 

3186 

3187 def url_path(self, kind: str) -> str: ... 

3188 

3189 def ancestors(self) -> list['Layer']: ... 

3190 

3191 def descendants(self) -> list['Layer']: ... 

3192################################################################################ 

3193 

3194 

3195################################################################################ 

3196# /base/legend/types.pyinc 

3197 

3198 

3199class LegendRenderOutput(Data): 

3200 """Legend render output.""" 

3201 

3202 html: str 

3203 image: 'Image' 

3204 image_path: str 

3205 size: Size 

3206 mime: str 

3207 

3208 

3209class Legend(Node): 

3210 """Legend object.""" 

3211 

3212 def render(self, args: Optional[dict] = None) -> Optional[LegendRenderOutput]: ... 

3213################################################################################ 

3214 

3215 

3216################################################################################ 

3217# /base/map/types.pyinc 

3218 

3219 

3220class Map(Node): 

3221 """Map object.""" 

3222 

3223 rootLayer: 'Layer' 

3224 

3225 bounds: Bounds 

3226 center: Point 

3227 coordinatePrecision: int 

3228 initResolution: float 

3229 resolutions: list[float] 

3230 title: str 

3231 wgsExtent: Extent 

3232################################################################################ 

3233 

3234 

3235 

3236################################################################################ 

3237# /base/model/types.pyinc 

3238 

3239 

3240class ModelClientOptions(Data): 

3241 """Client options for a model""" 

3242 

3243 keepFormOpen: Optional[bool] 

3244 

3245class ModelValidationError(Data): 

3246 """Validation error.""" 

3247 

3248 fieldName: str 

3249 message: str 

3250 

3251 

3252class ModelOperation(Enum): 

3253 """Model operation.""" 

3254 

3255 read = 'read' 

3256 create = 'create' 

3257 update = 'update' 

3258 delete = 'delete' 

3259 export = 'export' 

3260 

3261 

3262class ModelReadTarget(Enum): 

3263 """Target for the read operation.""" 

3264 

3265 map = 'map' 

3266 """The feature is to be drawn on a map.""" 

3267 searchResults = 'searchResults' 

3268 """The feature is to be displayed in the search results list.""" 

3269 list = 'list' 

3270 """The feature is to be displayed in a list view.""" 

3271 editList = 'editList' 

3272 """The feature is to be displayed in an editable list view.""" 

3273 editForm = 'editForm' 

3274 """The feature is to be displayed in an edit form .""" 

3275 

3276 

3277class ModelSelectBuild(Data): 

3278 """Database select statement.""" 

3279 

3280 columns: list['sqlalchemy.Column'] 

3281 geometryWhere: list 

3282 keywordWhere: list 

3283 where: list 

3284 order: list 

3285 

3286 

3287class ModelContext(Data): 

3288 """Model context.""" 

3289 

3290 op: ModelOperation 

3291 target: ModelReadTarget 

3292 user: 'User' 

3293 project: 'Project' 

3294 relDepth: int = 0 

3295 maxDepth: int = 0 

3296 search: 'SearchQuery' 

3297 dbSelect: ModelSelectBuild 

3298 

3299 

3300EmptyValue = object() 

3301"""Special value for empty fields.""" 

3302 

3303ErrorValue = object() 

3304"""Special value for invalid fields.""" 

3305 

3306 

3307class ModelWidget(Node): 

3308 """Model widget.""" 

3309 

3310 supportsTableView: bool = True 

3311 

3312 

3313class ModelValidator(Node): 

3314 """Model Validator.""" 

3315 

3316 message: str 

3317 ops: set[ModelOperation] 

3318 

3319 def validate(self, field: 'ModelField', feature: 'Feature', mc: ModelContext) -> bool: ... 

3320 

3321 

3322class ModelValue(Node): 

3323 """Model value.""" 

3324 

3325 isDefault: bool 

3326 ops: set[ModelOperation] 

3327 

3328 def compute(self, field: 'ModelField', feature: 'Feature', mc: 'ModelContext'): ... 

3329 

3330 

3331class ModelField(Node): 

3332 """Model field.""" 

3333 

3334 name: str 

3335 title: str 

3336 

3337 attributeType: AttributeType 

3338 

3339 widget: Optional['ModelWidget'] = None 

3340 

3341 values: list['ModelValue'] 

3342 validators: list['ModelValidator'] 

3343 

3344 isPrimaryKey: bool 

3345 isRequired: bool 

3346 isUnique: bool 

3347 isAuto: bool 

3348 isHidden: bool 

3349 

3350 supportsFilterSearch: bool = False 

3351 supportsGeometrySearch: bool = False 

3352 supportsKeywordSearch: bool = False 

3353 

3354 model: 'Model' 

3355 

3356 def before_select(self, mc: ModelContext): ... 

3357 

3358 def after_select(self, features: list['Feature'], mc: ModelContext): ... 

3359 

3360 def before_create(self, feature: 'Feature', mc: ModelContext): ... 

3361 

3362 def after_create(self, feature: 'Feature', mc: ModelContext): ... 

3363 

3364 def before_create_related(self, to_feature: 'Feature', mc: ModelContext): ... 

3365 

3366 def after_create_related(self, to_feature: 'Feature', mc: ModelContext): ... 

3367 

3368 def before_update(self, feature: 'Feature', mc: ModelContext): ... 

3369 

3370 def after_update(self, feature: 'Feature', mc: ModelContext): ... 

3371 

3372 def before_delete(self, feature: 'Feature', mc: ModelContext): ... 

3373 

3374 def after_delete(self, feature: 'Feature', mc: ModelContext): ... 

3375 

3376 def do_init(self, feature: 'Feature', mc: ModelContext): ... 

3377 

3378 def do_init_related(self, to_feature: 'Feature', mc: ModelContext): ... 

3379 

3380 def do_validate(self, feature: 'Feature', mc: ModelContext): ... 

3381 

3382 def from_props(self, feature: 'Feature', mc: ModelContext): ... 

3383 

3384 def to_props(self, feature: 'Feature', mc: ModelContext): ... 

3385 

3386 def from_record(self, feature: 'Feature', mc: ModelContext): ... 

3387 

3388 def to_record(self, feature: 'Feature', mc: ModelContext): ... 

3389 

3390 def related_models(self) -> list['Model']: ... 

3391 

3392 def find_relatable_features(self, search: 'SearchQuery', mc: ModelContext) -> list['Feature']: ... 

3393 

3394 def raw_to_python(self, feature: 'Feature', value, mc: ModelContext): ... 

3395 

3396 def prop_to_python(self, feature: 'Feature', value, mc: ModelContext): ... 

3397 

3398 def python_to_raw(self, feature: 'Feature', value, mc: ModelContext): ... 

3399 

3400 def python_to_prop(self, feature: 'Feature', value, mc: ModelContext): ... 

3401 

3402 def describe(self) -> Optional['ColumnDescription']: ... 

3403 

3404 

3405class Model(Node): 

3406 """Data Model.""" 

3407 

3408 clientOptions: ModelClientOptions 

3409 defaultSort: list['SearchSort'] 

3410 fields: list['ModelField'] 

3411 geometryCrs: Optional['Crs'] 

3412 geometryName: str 

3413 geometryType: Optional[GeometryType] 

3414 isEditable: bool 

3415 loadingStrategy: 'FeatureLoadingStrategy' 

3416 exportStrategy: 'FeatureExportStrategy' 

3417 title: str 

3418 uidName: str 

3419 withTableView: bool 

3420 

3421 def find_features(self, search: 'SearchQuery', mc: ModelContext) -> list['Feature']: ... 

3422 

3423 def get_features(self, uids: Iterable[str | int], mc: ModelContext) -> list['Feature']: ... 

3424 

3425 def get_feature(self, uid: str | int, mc: ModelContext) -> Optional['Feature']: ... 

3426 

3427 def init_feature(self, feature: 'Feature', mc: ModelContext): ... 

3428 

3429 def create_feature(self, feature: 'Feature', mc: ModelContext) -> FeatureUid: ... 

3430 

3431 def update_feature(self, feature: 'Feature', mc: ModelContext) -> FeatureUid: ... 

3432 

3433 def delete_feature(self, feature: 'Feature', mc: ModelContext) -> FeatureUid: ... 

3434 

3435 def validate_feature(self, feature: 'Feature', mc: ModelContext) -> bool: ... 

3436 

3437 def feature_from_props(self, props: 'FeatureProps', mc: ModelContext) -> 'Feature': ... 

3438 

3439 def feature_to_props(self, feature: 'Feature', mc: ModelContext) -> 'FeatureProps': ... 

3440 

3441 def feature_to_view_props(self, feature: 'Feature', mc: ModelContext) -> 'FeatureProps': ... 

3442 

3443 def describe(self) -> Optional['DataSetDescription']: ... 

3444 

3445 def field(self, name: str) -> Optional['ModelField']: ... 

3446 

3447 def related_models(self) -> list['Model']: ... 

3448 

3449 

3450class ModelManager(Node): 

3451 """Model manager.""" 

3452 

3453 def get_model(self, uid: str, user: 'User' = None, access: Access = None) -> Optional['Model']: ... 

3454 

3455 def find_model(self, *objects, user: 'User' = None, access: Access = None) -> Optional['Model']: ... 

3456 

3457 def editable_models(self, project: 'Project', user: 'User') -> list['Model']: ... 

3458 

3459 def default_model(self) -> 'Model': ... 

3460################################################################################ 

3461 

3462 

3463################################################################################ 

3464# /base/database/types.pyinc 

3465 

3466 

3467class DatabaseModel(Model): 

3468 """Database-based data model.""" 

3469 

3470 db: 'DatabaseProvider' 

3471 """Database provider.""" 

3472 sqlFilter: str 

3473 """Literal SQL condition applied when selecting rows.""" 

3474 tableName: str 

3475 """Table name associated with this model.""" 

3476 

3477 def table(self) -> 'sqlalchemy.Table': 

3478 """Return the SQLAlchemy Table object for this database model.""" 

3479 

3480 def column(self, column_name: str) -> 'sqlalchemy.Column': 

3481 """Retrieve the SQLAlchemy Column object for the given column name.""" 

3482 

3483 def uid_column(self) -> 'sqlalchemy.Column': 

3484 """Return the SQLAlchemy Column object representing the unique identifier column.""" 

3485 

3486 def fetch_features(self, select: 'sqlalchemy.Select') -> list['Feature']: 

3487 """Fetch features from the database based on the provided SQLAlchemy Select statement.""" 

3488 

3489 def build_select(self, mc: 'ModelContext') -> Optional['sqlalchemy.Select']: 

3490 """Build a SQLAlchemy Select statement based on the provided ModelContext.""" 

3491 

3492 

3493class ColumnDescription(Data): 

3494 """Description of a dataset column.""" 

3495 

3496 columnIndex: int 

3497 """The index of the column within the table.""" 

3498 comment: str 

3499 """Column comment or description provided in the database metadata.""" 

3500 default: str 

3501 """The default value assigned to the column, if any.""" 

3502 geometrySrid: int 

3503 """The Spatial Reference Identifier (SRID) for geometry columns.""" 

3504 geometryType: GeometryType 

3505 """The type of geometry stored in the column (e.g., Point, Polygon).""" 

3506 isAutoincrement: bool 

3507 """Indicates if the column is auto-incremented.""" 

3508 isNullable: bool 

3509 """Specifies if the column permits NULL values.""" 

3510 isPrimaryKey: bool 

3511 """Specifies if the column is part of the primary key.""" 

3512 isUnique: bool 

3513 """Indicates if the column has a unique constraint.""" 

3514 hasDefault: bool 

3515 """Indicates if the column has a database-defined default value.""" 

3516 isIndexed: bool 

3517 """Indicates if the column has an index.""" 

3518 name: str 

3519 """The name of the column.""" 

3520 nativeType: str 

3521 """The database-specific data type of the column.""" 

3522 options: dict 

3523 """Additional options or configurations for the column, if any.""" 

3524 type: AttributeType 

3525 """The abstract type of the column used in higher-level processing.""" 

3526 

3527 

3528class DataSetDescription(Data): 

3529 """Description of a dataset, like a DB table or a GDAL data set.""" 

3530 

3531 columns: list[ColumnDescription] 

3532 """A list of column descriptions.""" 

3533 columnMap: dict[str, ColumnDescription] 

3534 """A dictionary mapping column names to their descriptions.""" 

3535 fullName: str 

3536 """The full name of the dataset, including schema if applicable.""" 

3537 geometryName: str 

3538 """The name of the geometry column, if any.""" 

3539 geometrySrid: int 

3540 """The Spatial Reference Identifier (SRID) for the geometry.""" 

3541 geometryType: GeometryType 

3542 """The type of geometry stored in the dataset.""" 

3543 name: str 

3544 """The name of the dataset or table.""" 

3545 schema: str 

3546 """The schema to which the dataset belongs.""" 

3547 

3548 

3549class DatabaseManager(Node): 

3550 """Database manager.""" 

3551 

3552 providers: list['DatabaseProvider'] 

3553 """A list of database providers managed by this DatabaseManager.""" 

3554 

3555 def create_provider(self, cfg: Config, **kwargs) -> 'DatabaseProvider': 

3556 """Create and return a DatabaseProvider instance based on the given configuration. 

3557 

3558 Args: 

3559 cfg: The configuration object for the database provider. 

3560 **kwargs: Additional keyword arguments to customize the provider creation. 

3561 

3562 Returns: 

3563 DatabaseProvider: A new database provider instance. 

3564 """ 

3565 

3566 def find_provider(self, uid: Optional[str] = None, ext_type: Optional[str] = None) -> Optional['DatabaseProvider']: 

3567 """Find and return a DatabaseProvider that matches the given UID and/or extension type. 

3568 

3569 Args: 

3570 uid: The unique identifier of the database provider to find. 

3571 ext_type: The type of the database provider to find. 

3572 

3573 Returns: 

3574 The matching database provider if found, otherwise None. 

3575 """ 

3576 

3577 

3578DatabaseTableAlike: TypeAlias = Union['sqlalchemy.Table', str] 

3579"""An SQLAlchemy ``Table`` object or a string table name.""" 

3580 

3581 

3582DatabaseStmt: TypeAlias = Union['sqlalchemy.Executable', str] 

3583"""An Executable SQLAlchemy object or a string SQL statement.""" 

3584 

3585 

3586class DatabaseConnection: 

3587 """Database connection. 

3588 

3589 Extends ``sqlalchemy.Connection`` and provides some convenience methods. 

3590 """ 

3591 

3592 saConn: 'sqlalchemy.Connection' 

3593 

3594 def __enter__(self) -> 'DatabaseConnection': ... 

3595 

3596 def __exit__(self, exc_type, exc_value, traceback): ... 

3597 

3598 def execute(self, stmt: 'sqlalchemy.Executable', params=None, execution_options: dict=None) -> 'sqlalchemy.CursorResult': ... 

3599 

3600 def commit(self): ... 

3601 

3602 def rollback(self): ... 

3603 

3604 def close(self): ... 

3605 

3606 def exec(self, stmt: 'DatabaseStmt', **params) -> 'sqlalchemy.CursorResult': ... 

3607 

3608 def exec_commit(self, stmt: 'DatabaseStmt', **params) -> 'sqlalchemy.CursorResult': ... 

3609 

3610 def exec_rollback(self, stmt: 'DatabaseStmt', **params) -> 'sqlalchemy.CursorResult': ... 

3611 

3612 def fetch_all(self, stmt: 'DatabaseStmt', **params) -> list[dict]: ... 

3613 

3614 def fetch_first(self, stmt: 'DatabaseStmt', **params) -> dict | None: ... 

3615 

3616 def fetch_scalars(self, stmt: 'DatabaseStmt', **params) -> list: ... 

3617 

3618 def fetch_strings(self, stmt: 'DatabaseStmt', **params) -> list[str]: ... 

3619 

3620 def fetch_ints(self, stmt: 'DatabaseStmt', **params) -> list[int]: ... 

3621 

3622 def fetch_scalar(self, stmt: 'DatabaseStmt', **params) -> Any: ... 

3623 

3624 def fetch_string(self, stmt: 'DatabaseStmt', **params) -> str | None: ... 

3625 

3626 def fetch_int(self, stmt: 'DatabaseStmt', **params) -> int | None: ... 

3627 

3628class DatabaseInspectOptions(Data): 

3629 """Options for database inspection.""" 

3630 

3631 refresh: bool = False 

3632 """Whether to force inspection even if cached information is available.""" 

3633 cacheLifeTime: int = 0 

3634 """Schema cache lifetime in seconds.""" 

3635 

3636 

3637class DatabaseProvider(Node): 

3638 """Database Provider. 

3639 

3640 A database Provider wraps SQLAlchemy ``Engine`` and ``Connection`` objects 

3641 and provides common db functionality. 

3642 """ 

3643 

3644 def connect(self) -> 'DatabaseConnection': 

3645 """Context manager for SQLAlchemy ``Connection``. 

3646 

3647 Context calls to this method can be nested. An inner call is a no-op, as no new connection is created. 

3648 Only the outermost connection is closed upon exit:: 

3649 

3650 with db.connect(): 

3651 ... 

3652 with db.connect(): # no-op 

3653 ... 

3654 # connection remains open 

3655 ... 

3656 # connection closed 

3657 """ 

3658 

3659 def engine_options(self, **kwargs): 

3660 """Add defaults to the SA engine options.""" 

3661 

3662 def url(self) -> str: 

3663 """Return the connection URL.""" 

3664 

3665 def engine(self) -> 'sqlalchemy.Engine': 

3666 """Get SQLAlchemy ``Engine`` object for this provider.""" 

3667 

3668 def create_engine(self, **kwargs) -> 'sqlalchemy.Engine': 

3669 """CreateSQLAlchemy ``Engine`` object for this provider.""" 

3670 

3671 def describe(self, table: DatabaseTableAlike) -> 'DataSetDescription': 

3672 """Describe a table.""" 

3673 

3674 def describe_column(self, table: DatabaseTableAlike, column_name: str) -> ColumnDescription: 

3675 """Describe a specific column in a table.""" 

3676 

3677 def table(self, table: 'DatabaseTableAlike', **kwargs) -> 'sqlalchemy.Table': 

3678 """SQLAlchemy ``Table`` object for a specific table.""" 

3679 

3680 def column(self, table: DatabaseTableAlike, column_name: str) -> 'sqlalchemy.Column': 

3681 """SQLAlchemy ``Column`` object for a specific column.""" 

3682 

3683 def count(self, table: DatabaseTableAlike) -> int: 

3684 """Return table record count or 0 if the table does not exist.""" 

3685 

3686 def has_schema(self, schema_name: str) -> bool: 

3687 """Check if a specific schema exists.""" 

3688 

3689 def has_table(self, table_name: str) -> bool: 

3690 """Check if a specific table exists.""" 

3691 

3692 def has_column(self, table: DatabaseTableAlike, column_name: str) -> bool: 

3693 """Check if a specific column exists.""" 

3694 

3695 def join_table_name(self, schema: str, name: str) -> str: 

3696 """Create a full table name from the schema and table names.""" 

3697 

3698 def split_table_name(self, table_name: str) -> tuple[str, str]: 

3699 """Split a full table name into the schema and table names.""" 

3700 

3701 def table_bounds(self, table: DatabaseTableAlike) -> Optional[Bounds]: 

3702 """Compute a bounding box for the table primary geometry.""" 

3703 

3704 def select_text(self, sql: str, **kwargs) -> list[dict]: 

3705 """Execute a textual SELECT stmt and return a list of record dicts.""" 

3706 

3707 def execute_text(self, sql: str, **kwargs) -> 'sqlalchemy.CursorResult': 

3708 """Execute a textual DML stmt and return a result.""" 

3709 

3710 def schema_names(self) -> list[str]: 

3711 """Return a list of schema names in the database.""" 

3712 

3713 def inspect_schema(self, schema: str, options: Optional[DatabaseInspectOptions] = None): 

3714 """Inspect the database schema and cache the results based on the provided options.""" 

3715################################################################################ 

3716 

3717 

3718 

3719################################################################################ 

3720# /base/job/types.pyinc 

3721 

3722 

3723class JobTerminated(Exception): 

3724 pass 

3725 

3726 

3727class JobState(Enum): 

3728 """Background job state.""" 

3729 

3730 init = 'init' 

3731 """The job is being created.""" 

3732 open = 'open' 

3733 """The job is just created and waiting for start.""" 

3734 running = 'running' 

3735 """The job is running.""" 

3736 complete = 'complete' 

3737 """The job has been completed successfully.""" 

3738 error = 'error' 

3739 """There was an error.""" 

3740 cancel = 'cancel' 

3741 """The job was cancelled.""" 

3742 

3743 

3744class Job(Data): 

3745 """Background job data.""" 

3746 

3747 uid: str 

3748 user: 'User' 

3749 worker: str 

3750 state: JobState 

3751 error: str 

3752 numSteps: int 

3753 step: int 

3754 stepName: str 

3755 payload: dict 

3756 result: dict 

3757 timeCreated: datetime.datetime 

3758 timeUpdated: datetime.datetime 

3759 

3760 

3761class JobRequest(Request): 

3762 jobUid: str 

3763 

3764 

3765class JobStatusResponse(Response): 

3766 jobUid: str 

3767 state: JobState 

3768 progress: int 

3769 stepName: str 

3770 output: dict 

3771 

3772 

3773class JobManager(Node): 

3774 """Job Manager.""" 

3775 

3776 def create_job(self, worker: type, user: User, payload: dict | Data = None) -> Job: ... 

3777 

3778 def get_job(self, job_uid: str, user: User = None, state: JobState = None) -> Optional[Job]: ... 

3779 

3780 def update_job(self, job: Job, **kwargs) -> Optional[Job]: ... 

3781 

3782 def run_job(self, job: Job) -> Optional[Job]: ... 

3783 

3784 def cancel_job(self, job: Job) -> Optional[Job]: ... 

3785 

3786 def remove_job(self, job: Job): ... 

3787 

3788 def schedule_job(self, job: Job) -> Job: ... 

3789 

3790 def require_job(self, req: 'WebRequester', p: JobRequest) -> Job: ... 

3791 

3792 def require_result(self, req: 'WebRequester', p: JobRequest) -> dict: ... 

3793 

3794 def handle_status_request(self, req: 'WebRequester', p: JobRequest) -> JobStatusResponse: ... 

3795 

3796 def handle_cancel_request(self, req: 'WebRequester', p: JobRequest) -> JobStatusResponse: ... 

3797 

3798 def job_status_response(self, job: Job, **kwargs) -> 'JobStatusResponse': ... 

3799################################################################################ 

3800 

3801 

3802################################################################################ 

3803# /base/ows/types.pyinc 

3804 

3805 

3806import gws 

3807 

3808 

3809class OwsProtocol(Enum): 

3810 """Supported OWS protocol.""" 

3811 

3812 WMS = 'WMS' 

3813 WMTS = 'WMTS' 

3814 WCS = 'WCS' 

3815 WFS = 'WFS' 

3816 CSW = 'CSW' 

3817 

3818 

3819class OwsAuthorization(Data): 

3820 type: str 

3821 username: str 

3822 password: str 

3823 

3824 

3825class OwsVerb(Enum): 

3826 """OWS verb.""" 

3827 

3828 CreateStoredQuery = 'CreateStoredQuery' 

3829 DescribeCoverage = 'DescribeCoverage' 

3830 DescribeFeatureType = 'DescribeFeatureType' 

3831 DescribeLayer = 'DescribeLayer' 

3832 DescribeRecord = 'DescribeRecord' 

3833 DescribeStoredQueries = 'DescribeStoredQueries' 

3834 DropStoredQuery = 'DropStoredQuery' 

3835 GetCapabilities = 'GetCapabilities' 

3836 GetFeature = 'GetFeature' 

3837 GetFeatureInfo = 'GetFeatureInfo' 

3838 GetFeatureWithLock = 'GetFeatureWithLock' 

3839 GetLegendGraphic = 'GetLegendGraphic' 

3840 GetMap = 'GetMap' 

3841 GetPrint = 'GetPrint' 

3842 GetPropertyValue = 'GetPropertyValue' 

3843 GetRecordById = 'GetRecordById' 

3844 GetRecords = 'GetRecords' 

3845 GetTile = 'GetTile' 

3846 ListStoredQueries = 'ListStoredQueries' 

3847 LockFeature = 'LockFeature' 

3848 Transaction = 'Transaction' 

3849 

3850 

3851class OwsOperation(Data): 

3852 """OWS operation.""" 

3853 

3854 allowedParameters: dict[str, list[str]] 

3855 constraints: dict[str, list[str]] 

3856 formats: list[str] 

3857 handlerName: str 

3858 params: dict[str, str] 

3859 postUrl: Url 

3860 preferredFormat: str 

3861 url: Url 

3862 verb: OwsVerb 

3863 

3864 

3865class OwsCapabilities(Data): 

3866 """OWS capabilities structure.""" 

3867 

3868 metadata: 'Metadata' 

3869 operations: list['OwsOperation'] 

3870 sourceLayers: list['SourceLayer'] 

3871 tileMatrixSets: list['TileMatrixSet'] 

3872 version: str 

3873 

3874 

3875class OwsService(Node): 

3876 """OWS Service.""" 

3877 

3878 isRasterService: bool = False 

3879 """Service provides raster services.""" 

3880 isVectorService: bool = False 

3881 """Service provides vector services.""" 

3882 isOwsCommon: bool = False 

3883 """Conforms to OGC Web Services Common Standard.""" 

3884 

3885 alwaysXY: bool 

3886 """Force lon/lat order for geographic projections.""" 

3887 metadata: 'Metadata' 

3888 """Service metadata.""" 

3889 name: str 

3890 """Service name.""" 

3891 project: Optional['Project'] 

3892 """Project this service is configured for.""" 

3893 rootLayer: Optional['Layer'] 

3894 """Root layer of the service.""" 

3895 protocol: OwsProtocol 

3896 """Supported protocol.""" 

3897 defaultFeatureCount: int 

3898 """Default limit of features per page.""" 

3899 maxFeatureCount: int 

3900 """Max limit of features per page.""" 

3901 searchTolerance: UomValue 

3902 """Default tolerance for spatial search.""" 

3903 supportedBounds: list[Bounds] 

3904 """Supported bounds.""" 

3905 supportedVersions: list[str] 

3906 """Supported versions.""" 

3907 supportedOperations: list['OwsOperation'] 

3908 """Supported operations.""" 

3909 templates: list['Template'] 

3910 """Service templates.""" 

3911 imageFormats: list[ImageFormat] 

3912 """Supported image formats.""" 

3913 updateSequence: str 

3914 """Service update sequence.""" 

3915 withInspireMeta: bool 

3916 """Include INSPIRE metadata.""" 

3917 withStrictParams: bool 

3918 """Strict parameter checking.""" 

3919 

3920 def handle_request(self, req: 'WebRequester') -> ContentResponse: 

3921 """Handle a service request.""" 

3922 

3923 def layer_is_compatible(self, layer: 'Layer') -> bool: 

3924 """True if layer can be used in this service.""" 

3925 

3926 

3927class OwsProvider(Node): 

3928 """OWS services Provider.""" 

3929 

3930 alwaysXY: bool 

3931 authorization: Optional['OwsAuthorization'] 

3932 bounds: Optional[Bounds] 

3933 forceCrs: 'Crs' 

3934 maxRequests: int 

3935 metadata: 'Metadata' 

3936 operations: list['OwsOperation'] 

3937 protocol: 'OwsProtocol' 

3938 sourceLayers: list['SourceLayer'] 

3939 url: Url 

3940 version: str 

3941 wgsExtent: Optional[Extent] 

3942 

3943 def get_operation(self, verb: 'OwsVerb', method: Optional['RequestMethod'] = None) -> Optional['OwsOperation']: ... 

3944 

3945 def get_features(self, args: 'SearchQuery', source_layers: list['SourceLayer']) -> list['FeatureRecord']: ... 

3946################################################################################ 

3947 

3948 

3949################################################################################ 

3950# /base/printer/types.pyinc 

3951 

3952 

3953class PrintPlaneType(Enum): 

3954 """Print plane type.""" 

3955 

3956 bitmap = 'bitmap' 

3957 url = 'url' 

3958 features = 'features' 

3959 raster = 'raster' 

3960 vector = 'vector' 

3961 soup = 'soup' 

3962 

3963 

3964class PrintPlane(Data): 

3965 """Print plane.""" 

3966 

3967 type: PrintPlaneType 

3968 

3969 opacity: Optional[float] 

3970 cssSelector: Optional[str] 

3971 

3972 bitmapData: Optional[bytes] 

3973 bitmapMode: Optional[str] 

3974 bitmapWidth: Optional[int] 

3975 bitmapHeight: Optional[int] 

3976 

3977 url: Optional[str] 

3978 

3979 features: Optional[list['FeatureProps']] 

3980 

3981 layerUid: Optional[str] 

3982 compositeLayerUids: Optional[list[str]] 

3983 

3984 soupPoints: Optional[list[Point]] 

3985 soupTags: Optional[list[Any]] 

3986 

3987 

3988class PrintMap(Data): 

3989 """Map properties for printing.""" 

3990 

3991 backgroundColor: Optional[int] 

3992 bbox: Optional[Extent] 

3993 center: Optional[Point] 

3994 planes: list[PrintPlane] 

3995 rotation: Optional[int] 

3996 scale: int 

3997 styles: Optional[list['StyleProps']] 

3998 visibleLayers: Optional[list[str]] 

3999 

4000 

4001class PrintRequestType(Enum): 

4002 """Type of the print request.""" 

4003 

4004 template = 'template' 

4005 map = 'map' 

4006 

4007 

4008class PrintRequest(Request): 

4009 """Print request.""" 

4010 

4011 type: PrintRequestType 

4012 

4013 args: Optional[dict] 

4014 crs: Optional[CrsName] 

4015 outputFormat: Optional[str] 

4016 maps: Optional[list[PrintMap]] 

4017 

4018 printerUid: Optional[str] 

4019 dpi: Optional[int] 

4020 outputSize: Optional[Size] 

4021 

4022 

4023class PrintResult(Data): 

4024 """Print result.""" 

4025 

4026 path: str 

4027 mime: str 

4028 

4029 

4030class Printer(Node): 

4031 """Printer object.""" 

4032 

4033 title: str 

4034 template: 'Template' 

4035 models: list['Model'] 

4036 qualityLevels: list['TemplateQualityLevel'] 

4037 

4038 

4039class PrinterManager(Node): 

4040 """Print Manager.""" 

4041 

4042 def start_print_job(self, request: PrintRequest, user: 'User') -> 'JobStatusResponse': ... 

4043 

4044 def exec_print(self, request: PrintRequest, out_path: str): ... 

4045################################################################################ 

4046 

4047 

4048################################################################################ 

4049# /base/project/types.pyinc 

4050 

4051 

4052class Client(Node): 

4053 """GWS Client control object.""" 

4054 

4055 options: dict 

4056 elements: list 

4057 

4058 

4059class Project(Node): 

4060 """Project object.""" 

4061 

4062 assetsRoot: Optional['WebDocumentRoot'] 

4063 client: 'Client' 

4064 

4065 localeUids: list[str] 

4066 map: 'Map' 

4067 metadata: 'Metadata' 

4068 title: str 

4069 

4070 actions: list['Action'] 

4071 finders: list['Finder'] 

4072 models: list['Model'] 

4073 exporters: list['Exporter'] 

4074 printers: list['Printer'] 

4075 templates: list['Template'] 

4076 owsServices: list['OwsService'] 

4077 

4078 vars: dict 

4079################################################################################ 

4080 

4081 

4082################################################################################ 

4083# /base/search/types.pyinc 

4084 

4085 

4086class SearchSort(Data): 

4087 """Search sort specification.""" 

4088 

4089 fieldName: str 

4090 reverse: bool 

4091 

4092 

4093class SearchFilterOperator(Enum): 

4094 """Search filter operator.""" 

4095 

4096 And = 'And' 

4097 Or = 'Or' 

4098 Not = 'Not' 

4099 

4100 PropertyIsEqualTo = 'PropertyIsEqualTo' 

4101 PropertyIsNotEqualTo = 'PropertyIsNotEqualTo' 

4102 PropertyIsLessThan = 'PropertyIsLessThan' 

4103 PropertyIsGreaterThan = 'PropertyIsGreaterThan' 

4104 PropertyIsLessThanOrEqualTo = 'PropertyIsLessThanOrEqualTo' 

4105 PropertyIsGreaterThanOrEqualTo = 'PropertyIsGreaterThanOrEqualTo' 

4106 PropertyIsLike = 'PropertyIsLike' 

4107 PropertyIsNull = 'PropertyIsNull' 

4108 PropertyIsNil = 'PropertyIsNil' 

4109 PropertyIsBetween = 'PropertyIsBetween' 

4110 

4111 Equals = 'Equals' 

4112 Disjoint = 'Disjoint' 

4113 Touches = 'Touches' 

4114 Within = 'Within' 

4115 Overlaps = 'Overlaps' 

4116 Crosses = 'Crosses' 

4117 Intersects = 'Intersects' 

4118 Contains = 'Contains' 

4119 DWithin = 'DWithin' 

4120 Beyond = 'Beyond' 

4121 BBOX = 'BBOX' 

4122 

4123 

4124class SearchFilterMatchAction(Enum): 

4125 """Search filter match action.""" 

4126 

4127 All = 'All' 

4128 Any = 'Any' 

4129 One = 'One' 

4130 

4131 

4132class SearchFilter(Data): 

4133 """Search filter.""" 

4134 

4135 operator: SearchFilterOperator 

4136 property: str 

4137 value: str 

4138 shape: 'Shape' 

4139 subFilters: list['SearchFilter'] 

4140 matchCase: bool 

4141 matchAction: SearchFilterMatchAction 

4142 wildCard: str 

4143 singleChar: str 

4144 escapeChar: str 

4145 

4146 

4147class SearchQuery(Data): 

4148 """Search query.""" 

4149 

4150 bounds: Bounds 

4151 """Search bounds.""" 

4152 extraArgs: dict 

4153 """Extra arguments for custom searches.""" 

4154 extraColumns: list 

4155 """Extra columns to select.""" 

4156 extraParams: dict 

4157 """Extra parameters to pass to a provider""" 

4158 extraWhere: list 

4159 """Extra where clauses.""" 

4160 keyword: str 

4161 """Keyword to search for.""" 

4162 layers: list['Layer'] 

4163 """Layers to search in.""" 

4164 limit: int 

4165 """Limit the number of results.""" 

4166 filter: SearchFilter 

4167 """Search filter.""" 

4168 project: 'Project' 

4169 """Project to search in.""" 

4170 resolution: float 

4171 """Pixel resolution for geometry search.""" 

4172 shape: 'Shape' 

4173 """Shape to search in.""" 

4174 sort: list[SearchSort] 

4175 """Sort options.""" 

4176 tolerance: 'UomValue' 

4177 """Tolerance for geometry search.""" 

4178 uids: list[str] 

4179 """UIDs to search for.""" 

4180 

4181 

4182class SearchResult(Data): 

4183 """Search result.""" 

4184 

4185 feature: 'Feature' 

4186 layer: 'Layer' 

4187 finder: 'Finder' 

4188 

4189 

4190class TextSearchType(Enum): 

4191 """Text search type.""" 

4192 

4193 exact = 'exact' 

4194 """Match the whole string.""" 

4195 begin = 'begin' 

4196 """Match the beginning of the string.""" 

4197 end = 'end' 

4198 """Match the end of the string.""" 

4199 any = 'any' 

4200 """Match any substring.""" 

4201 like = 'like' 

4202 """Use the percent sign as a placeholder.""" 

4203 

4204 

4205class TextSearchOptions(Data): 

4206 """Text search options.""" 

4207 

4208 type: TextSearchType 

4209 """Type of the search.""" 

4210 minLength: int = 0 

4211 """Minimal pattern length.""" 

4212 caseSensitive: bool = False 

4213 """Use the case sensitive search.""" 

4214 

4215 

4216class SortOptions(Data): 

4217 """Sort options.""" 

4218 

4219 fieldName: str 

4220 """Field name to sort by.""" 

4221 reverse: bool = False 

4222 """Sort in reverse order.""" 

4223 

4224 

4225class SearchManager(Node): 

4226 """Search Manager.""" 

4227 

4228 def run_search(self, search: 'SearchQuery', user: 'User') -> list['SearchResult']: ... 

4229 

4230 

4231class Finder(Node): 

4232 """Finder object.""" 

4233 

4234 title: str 

4235 category: str 

4236 

4237 supportsFilterSearch: bool = False 

4238 supportsGeometrySearch: bool = False 

4239 supportsKeywordSearch: bool = False 

4240 

4241 withFilter: bool 

4242 withGeometry: bool 

4243 withKeyword: bool 

4244 

4245 templates: list['Template'] 

4246 models: list['Model'] 

4247 sourceLayers: list['SourceLayer'] 

4248 

4249 tolerance: 'UomValue' 

4250 

4251 def run(self, search: SearchQuery, user: 'User', layer: Optional['Layer'] = None) -> list['Feature']: ... 

4252 

4253 def can_run(self, search: SearchQuery, user: 'User') -> bool: ... 

4254################################################################################ 

4255 

4256 

4257################################################################################ 

4258# /base/storage/types.pyinc 

4259 

4260 

4261class StorageManager(Node): 

4262 """Storage manager.""" 

4263 

4264 providers: list['StorageProvider'] 

4265 

4266 def create_provider(self, cfg: Config, **kwargs) -> 'StorageProvider': ... 

4267 

4268 def find_provider(self, uid: Optional[str] = None) -> Optional['StorageProvider']: ... 

4269 

4270 

4271 

4272class StorageRecord(Data): 

4273 """Storage record.""" 

4274 

4275 name: str 

4276 """Record name.""" 

4277 userUid: str 

4278 """User uid.""" 

4279 data: str 

4280 """Serialized record data.""" 

4281 created: 'datetime.datetime' 

4282 """Record create time.""" 

4283 updated: 'datetime.datetime' 

4284 """Record update time.""" 

4285 

4286 

4287class StorageProvider(Node): 

4288 """Storage provider.""" 

4289 

4290 def list_names(self, category: str) -> list[str]: ... 

4291 

4292 def read(self, category: str, name: str) -> Optional['StorageRecord']: ... 

4293 

4294 def write(self, category: str, name: str, data: str, user_uid: str): ... 

4295 

4296 def delete(self, category: str, name: str): ... 

4297################################################################################ 

4298 

4299 

4300################################################################################ 

4301# /base/template/types.pyinc 

4302 

4303 

4304class TemplateArgs(Data): 

4305 """Template arguments.""" 

4306 

4307 app: 'Application' 

4308 """Application object.""" 

4309 locale: 'Locale' 

4310 """Current locale.""" 

4311 date: 'DateFormatter' 

4312 """Locale-aware date formatter.""" 

4313 time: 'TimeFormatter' 

4314 """Locale-aware time formatter.""" 

4315 number: 'NumberFormatter' 

4316 """Locale-aware number formatter.""" 

4317 

4318 

4319class TemplateRenderInput(Data): 

4320 """Template render input.""" 

4321 

4322 args: dict | Data 

4323 crs: 'Crs' 

4324 dpi: int 

4325 locale: 'Locale' 

4326 maps: list[MapRenderInput] 

4327 mimeOut: str 

4328 notify: Callable 

4329 project: 'Project' 

4330 user: 'User' 

4331 

4332 

4333class TemplateQualityLevel(Config): 

4334 """Template quality level.""" 

4335 

4336 name: str 

4337 """Quality level name.""" 

4338 dpi: int 

4339 """DPI for the quality level.""" 

4340 

4341 

4342class Template(Node): 

4343 """Template object.""" 

4344 

4345 mapSize: UomSize 

4346 """Default map size for the template.""" 

4347 mimeTypes: list[str] 

4348 """MIME types the template can generate.""" 

4349 pageSize: UomSize 

4350 """Default page size for printing.""" 

4351 pageMargin: UomExtent 

4352 """Default page margin for printing.""" 

4353 subject: str 

4354 """Template subject (category).""" 

4355 title: str 

4356 """Template title.""" 

4357 

4358 def render(self, tri: TemplateRenderInput) -> ContentResponse: 

4359 """Render the template and return the generated response.""" 

4360 

4361 

4362class TemplateManager(Node): 

4363 """Template manager.""" 

4364 

4365 def find_templates(self, subjects: list[str], where: list[Node], user: 'User' = None, mime: str = None) -> list['Template']: ... 

4366 

4367 def find_template(self, subject: str, where: list[Node], user: 'User' = None, mime: str = None) -> Optional['Template']: ... 

4368 

4369 def template_from_path(self, path: str) -> Optional['Template']: ... 

4370################################################################################ 

4371 

4372 

4373################################################################################ 

4374# /base/web/types.pyinc 

4375 

4376 

4377class RequestMethod(Enum): 

4378 """Web request method.""" 

4379 

4380 GET = 'GET' 

4381 HEAD = 'HEAD' 

4382 POST = 'POST' 

4383 PUT = 'PUT' 

4384 DELETE = 'DELETE' 

4385 CONNECT = 'CONNECT' 

4386 OPTIONS = 'OPTIONS' 

4387 TRACE = 'TRACE' 

4388 PATCH = 'PATCH' 

4389 

4390 

4391class WebRequester: 

4392 """Web Requester object.""" 

4393 

4394 environ: dict 

4395 """Request environment.""" 

4396 method: RequestMethod 

4397 """Request method.""" 

4398 contentType: str 

4399 """Request content type.""" 

4400 root: 'Root' 

4401 """Object tree root.""" 

4402 site: 'WebSite' 

4403 """Website the request is processed for.""" 

4404 

4405 session: 'AuthSession' 

4406 """Current session.""" 

4407 user: 'User' 

4408 """Current use.""" 

4409 

4410 isGet: bool 

4411 """The request is a GET request.""" 

4412 isPost: bool 

4413 """The request is a POST request.""" 

4414 isApi: bool 

4415 """The request provides json data in the POST body.""" 

4416 isForm: bool 

4417 """The request provides form data in the POST body.""" 

4418 isSecure: bool 

4419 """The request is secure.""" 

4420 

4421 scheme: str 

4422 """Request scheme, http or https.""" 

4423 host: str 

4424 """Request host name, without the port, empty if the host is invalid.""" 

4425 port: int 

4426 """Request port, 0 if not given.""" 

4427 ip: str 

4428 """Client address.""" 

4429 

4430 def parse(self): 

4431 """Parse the request data, raise an error if the request is invalid.""" 

4432 

4433 def params(self) -> dict: 

4434 """GET parameters, including parsed path params.""" 

4435 

4436 def query_params(self) -> dict: 

4437 """GET parameters from the query string.""" 

4438 

4439 def path(self) -> str: 

4440 """Request path, after the command is removed.""" 

4441 

4442 def struct(self) -> dict: 

4443 """Structured JSON payload.""" 

4444 

4445 def command(self) -> str: 

4446 """Command name from the request.""" 

4447 

4448 def data(self) -> bytes: 

4449 """Raw POST data.""" 

4450 

4451 def form(self) -> list[tuple[str, Any]]: 

4452 """POST form data as a list of (key, value) tuples.""" 

4453 

4454 def text(self) -> str: 

4455 """POST data decoded to text.""" 

4456 

4457 def cookie(self, key: str, default: str = '') -> str: 

4458 """Get a cookie. 

4459 

4460 Args: 

4461 key: Cookie name. 

4462 default: Default value. 

4463 

4464 Returns: 

4465 A cookie value. 

4466 """ 

4467 

4468 def header(self, key: str, default: str = '') -> str: 

4469 """Get a header. 

4470 

4471 Args: 

4472 key: Header name. 

4473 default: Default value. 

4474 

4475 Returns: 

4476 A header value. 

4477 """ 

4478 

4479 def has_param(self, key: str) -> bool: 

4480 """Check if a GET parameter exists. 

4481 

4482 Args: 

4483 key: Parameter name. 

4484 """ 

4485 

4486 def param(self, key: str, default: str = '') -> str: 

4487 """Get a GET parameter. 

4488 

4489 Args: 

4490 key: Parameter name. 

4491 default: Default value. 

4492 

4493 Returns: 

4494 A parameter value. 

4495 """ 

4496 

4497 def env(self, key: str, default: str = '') -> str: 

4498 """Get an environment variable. 

4499 

4500 Args: 

4501 key: Variable name. 

4502 default: Default value. 

4503 

4504 Returns: 

4505 A variable value. 

4506 """ 

4507 

4508 def content_responder(self, response: ContentResponse) -> 'WebResponder': 

4509 """Return a Responder object for a content response. 

4510 

4511 Args: 

4512 response: Response object. 

4513 

4514 Returns: 

4515 A Responder. 

4516 """ 

4517 

4518 def redirect_responder(self, response: RedirectResponse) -> 'WebResponder': 

4519 """Return a Responder object for a redirect response. 

4520 

4521 Args: 

4522 response: Response object. 

4523 

4524 Returns: 

4525 A Responder. 

4526 """ 

4527 

4528 def api_responder(self, response: Response) -> 'WebResponder': 

4529 """Return a Responder object for an Api (structured) response. 

4530 

4531 Args: 

4532 response: Response object. 

4533 

4534 Returns: 

4535 A Responder. 

4536 """ 

4537 

4538 def error_responder(self, exc: Exception) -> 'WebResponder': 

4539 """Return a Responder object for an Exception. 

4540 

4541 Args: 

4542 exc: An Exception. 

4543 

4544 Returns: 

4545 A Responder. 

4546 """ 

4547 

4548 def absolute_url_for(self, request_path: str, **params) -> str: 

4549 """Return an absolute Url, pointing to the requested host. 

4550 

4551 Args: 

4552 request_path: Request path. 

4553 **params: Additional GET parameters. 

4554 

4555 Returns: 

4556 An URL. 

4557 """ 

4558 

4559 def relative_url_for(self, request_path: str, **params) -> str: 

4560 """Return a host-relative Url. 

4561 

4562 Args: 

4563 request_path: Request path. 

4564 **params: Additional GET parameters. 

4565 

4566 Returns: 

4567 An URL. 

4568 """ 

4569 

4570 def canonical_url_for(self, request_path: str, **params) -> str: 

4571 """Return an absolute Url, pointing to the canonical host. 

4572 

4573 Args: 

4574 request_path: Request path. 

4575 **params: Additional GET parameters. 

4576 

4577 Returns: 

4578 An URL. 

4579 """ 

4580 

4581 def set_session(self, session: 'AuthSession'): 

4582 """Attach a session to the requester. 

4583 

4584 Args: 

4585 session: A Session object. 

4586 """ 

4587 

4588 

4589class WebResponder: 

4590 """Web Responder object.""" 

4591 

4592 status: int 

4593 """Response status.""" 

4594 

4595 def send_response(self, environ: dict, start_response: Callable): 

4596 """Send the response to the client. 

4597 

4598 Args: 

4599 environ: WSGI environment. 

4600 start_response: WSGI ``start_response`` function. 

4601 """ 

4602 

4603 def set_cookie(self, key: str, value: str, **kwargs): 

4604 """Set a cookie. 

4605 

4606 Args: 

4607 key: Cookie name. 

4608 value: Cookie value. 

4609 **kwargs: Cookie options. 

4610 """ 

4611 

4612 def delete_cookie(self, key: str, **kwargs): 

4613 """Delete a cookie. 

4614 

4615 Args: 

4616 key: Cookie name. 

4617 **kwargs: Cookie options. 

4618 """ 

4619 

4620 def set_status(self, status: int): 

4621 """Set the response status. 

4622 

4623 Args: 

4624 status: HTTP status code. 

4625 """ 

4626 

4627 def add_header(self, key: str, value: str): 

4628 """Add a header. 

4629 

4630 Args: 

4631 key: Header name. 

4632 value: Header value. 

4633 """ 

4634 

4635 def set_body(self, body: str | bytes): 

4636 """Set the response body. 

4637 

4638 Args: 

4639 body: New response body. 

4640 """ 

4641 

4642 

4643class WebDocumentRoot(Data): 

4644 """Web document root.""" 

4645 

4646 dir: DirPath 

4647 """Local directory.""" 

4648 allowMime: list[str] 

4649 """Allowed mime types.""" 

4650 denyMime: list[str] 

4651 """Restricted mime types.""" 

4652 

4653 

4654class WebRewriteRule(Data): 

4655 """Rewrite rule.""" 

4656 

4657 pattern: Regex 

4658 """URL matching pattern.""" 

4659 target: str 

4660 """Rule target, with dollar placeholders.""" 

4661 options: dict 

4662 """Extra options.""" 

4663 reversed: bool 

4664 """Reversed rewrite rule.""" 

4665 

4666 

4667class WebCors(Data): 

4668 """CORS options.""" 

4669 

4670 allowCredentials: bool 

4671 allowHeaders: str 

4672 allowMethods: str 

4673 allowOrigin: str 

4674 

4675 

4676class WebManager(Node): 

4677 """Web manager.""" 

4678 

4679 site: 'WebSite' 

4680 """Configured web site.""" 

4681 

4682 

4683class WebSite(Node): 

4684 """Web site.""" 

4685 

4686 assetsRoot: Optional[WebDocumentRoot] 

4687 """Root directory for assets.""" 

4688 canonicalHost: str 

4689 """Host name for absolute canonical URLs.""" 

4690 corsOptions: WebCors 

4691 """CORS options.""" 

4692 hostnames: list[str] 

4693 """Host names this site responds to.""" 

4694 rewriteRules: list[WebRewriteRule] 

4695 """Rewrite rule.""" 

4696 proxyCount: int 

4697 """Number of proxies in front of the server.""" 

4698 ssl: bool 

4699 """The site is served over https.""" 

4700 staticRoot: WebDocumentRoot 

4701 """Root directory for static files.""" 

4702 

4703 def url_for(self, req: 'WebRequester', path: str, mode: str, **params) -> str: 

4704 """Rewrite a request path to an Url. 

4705 

4706 Args: 

4707 req: Web Requester. 

4708 path: Raw request path. 

4709 mode: ``absolute``, ``relative`` or ``canonical``. 

4710 **params: Extra GET params. 

4711 

4712 Returns: 

4713 A rewritten URL. 

4714 """ 

4715################################################################################ 

4716 

4717 

4718################################################################################ 

4719# /base/exporter/types.pyinc 

4720 

4721 

4722class ExportArgs(Data): 

4723 """Exporter arguments.""" 

4724 

4725 exporter: 'Exporter' 

4726 features: Optional[list['Feature']] 

4727 shape: Optional['Shape'] 

4728 project: 'Project' 

4729 user: 'User' 

4730 notify: Callable 

4731 maxErrors: int = 100 

4732 

4733 

4734class ExportTarget(Enum): 

4735 file = 'file' 

4736 download = 'download' 

4737 

4738 

4739class ExportResult(Data): 

4740 """Export result.""" 

4741 

4742 path: str 

4743 mime: str 

4744 numFiles: int 

4745 numFeaturesTotal: int 

4746 numFeaturesExported: int 

4747 errors: list[str] 

4748 

4749 

4750class FeatureExportStrategy(Enum): 

4751 """Export strategy for features.""" 

4752 

4753 load = 'load' 

4754 """Load features by ids from the source model.""" 

4755 client = 'client' 

4756 """Export features using properties as received from the client.""" 

4757 

4758 

4759class ExportRequestType(Enum): 

4760 vector = 'vector' 

4761 raster = 'raster' 

4762 

4763 

4764class ExportRequest(Request): 

4765 type: ExportRequestType 

4766 exporterUid: str 

4767 features: Optional[list['FeatureProps']] 

4768 shape: Optional['ShapeProps'] 

4769 

4770 

4771class ExportResponse(Response): 

4772 content: str | bytes 

4773 contentFilename: str 

4774 mime: str 

4775 

4776 

4777class ExporterManager(Node): 

4778 """Exporter manager.""" 

4779 

4780 def start_export_job(self, request: ExportRequest, user: 'User') -> 'JobStatusResponse': ... 

4781 

4782 def exec_export(self, request: ExportRequest, out_path: str): ... 

4783 

4784 def list_exporters(self, where: list['Node'], user: 'User') -> list['Exporter']: ... 

4785 

4786 def get_exporter(self, where: list['Node'], uid: str, user: 'User') -> Optional['Exporter']: ... 

4787 

4788 

4789class Exporter(Node): 

4790 """Exporter object.""" 

4791 

4792 title: str 

4793 options: dict 

4794 

4795 supportsVector: bool 

4796 supportsRaster: bool 

4797 supportsMultiLayer: bool 

4798 

4799 withNoGeometry: bool 

4800 withMixedGeometry: bool 

4801 withMixedCrs: bool 

4802 withMultiLayer: bool 

4803 

4804 supportedAttributeTypes: Optional[list[gws.AttributeType]] 

4805 

4806 def run(self, ea: ExportArgs, er: ExportResult): 

4807 """Perform format-specific export.""" 

4808################################################################################ 

4809 

4810 

4811 

4812################################################################################ 

4813# /base/application/types.pyinc 

4814 

4815 

4816class MiddlewareManager(Node): 

4817 """Manage middleware and their dependencies.""" 

4818 

4819 def register(self, obj: Node, name: str, depends_on: Optional[list[str]] = None): 

4820 """Register an object as a middleware.""" 

4821 

4822 def objects(self) -> list[Node]: 

4823 """Return a list of registered middleware objects.""" 

4824 

4825 

4826class TemplateOptions(Data): 

4827 """Options for default templates.""" 

4828 

4829 withLogin: bool = True 

4830 """Show login form in the application home page.""" 

4831 footerText: Optional[str] 

4832 """Footer text for the application home page.""" 

4833 withGws: bool = True 

4834 """Show GWS logo in the application home page.""" 

4835 homeResources: Optional[list[str]] 

4836 """List of additional resource URLs for the application home ('style.css' by default).""" 

4837 projectResources: Optional[list[str]] 

4838 """List of additional resource URLs for the project page ('style.css' by default).""" 

4839 

4840 

4841class Application(Node): 

4842 """Main Application object.""" 

4843 

4844 client: 'Client' 

4845 """Represents the client object associated with the application.""" 

4846 

4847 localeUids: list[str] 

4848 """List of locale identifiers.""" 

4849 

4850 metadata: 'Metadata' 

4851 """Metadata for the application.""" 

4852 

4853 monitor: 'ServerMonitor' 

4854 """Server monitor object.""" 

4855 

4856 templateOptions: TemplateOptions 

4857 """Options for default templates.""" 

4858 

4859 title: str 

4860 """Application title.""" 

4861 

4862 vars: dict 

4863 """Application variables.""" 

4864 

4865 version: str 

4866 """Application version as a string.""" 

4867 

4868 versionString: str 

4869 """Full version string for display purposes.""" 

4870 

4871 defaultPrinter: 'Printer' 

4872 """Default printer object.""" 

4873 

4874 actionMgr: 'ActionManager' 

4875 """Manager for application actions.""" 

4876 

4877 authMgr: 'AuthManager' 

4878 """Manager for authentication operations.""" 

4879 

4880 databaseMgr: 'DatabaseManager' 

4881 """Manager for database operations.""" 

4882 

4883 exporterMgr: 'ExporterManager' 

4884 """Manager for exporters.""" 

4885 

4886 jobMgr: 'JobManager' 

4887 """Manager for handling jobs.""" 

4888 

4889 middlewareMgr: 'MiddlewareManager' 

4890 """Manager for middleware and dependencies.""" 

4891 

4892 modelMgr: 'ModelManager' 

4893 """Manager for model operations.""" 

4894 

4895 printerMgr: 'PrinterManager' 

4896 """Manager for printers.""" 

4897 

4898 searchMgr: 'SearchManager' 

4899 """Manager for search functionality.""" 

4900 

4901 serverMgr: 'ServerManager' 

4902 """Manager for server operations.""" 

4903 

4904 storageMgr: 'StorageManager' 

4905 """Manager for storage operations.""" 

4906 

4907 templateMgr: 'TemplateManager' 

4908 """Manager for templates.""" 

4909 

4910 webMgr: 'WebManager' 

4911 """Manager for web operations.""" 

4912 

4913 actions: list['Action'] 

4914 """List of defined application actions.""" 

4915 

4916 projects: list['Project'] 

4917 """List of configured projects.""" 

4918 

4919 exporters: list['Exporter'] 

4920 """List of configured exporters.""" 

4921 

4922 finders: list['Finder'] 

4923 """List of finder objects.""" 

4924 

4925 templates: list['Template'] 

4926 """List of global templates.""" 

4927 

4928 printers: list['Printer'] 

4929 """List of global printer objects.""" 

4930 

4931 models: list['Model'] 

4932 """List of global models.""" 

4933 

4934 owsServices: list['OwsService'] 

4935 """List of OWS services.""" 

4936 

4937 def project(self, uid: str) -> Optional['Project']: 

4938 """Get a Project object by its uid.""" 

4939 

4940 def helper(self, ext_type: str) -> Optional['Node']: 

4941 """Get a Helper object by its extension type.""" 

4942 

4943 def developer_option(self, key: str): 

4944 """Get a value of a developer option.""" 

4945################################################################################