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

1893 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-04-17 01:37 +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 Iterable, 

15 Iterator, 

16 Literal, 

17 Optional, 

18 Protocol, 

19 Union, 

20) 

21 

22from collections.abc import ( 

23 Mapping, 

24 Sequence, 

25) 

26 

27import enum 

28 

29if TYPE_CHECKING: 

30 import datetime 

31 import sqlalchemy 

32 import sqlalchemy.orm 

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 get(self, key, default=None): 

78 """Get an attribute value. 

79 

80 Args: 

81 key: Attribute name. 

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

83 """ 

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

85 

86 def setdefault(self, key, val): 

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

88 

89 Args: 

90 key: Attribute name. 

91 val: Attribute value. 

92 """ 

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

94 

95 def set(self, key, val): 

96 """Set an attribute value. 

97 

98 Args: 

99 key: Attribute name. 

100 val: Attribute value. 

101 """ 

102 vars(self)[key] = val 

103 

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

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

106 

107 Args: 

108 *args: Dicts or Mappings. 

109 kwargs: Keyword args. 

110 """ 

111 

112 d = {} 

113 for a in args: 

114 if isinstance(a, Mapping): 

115 d.update(a) 

116 elif isinstance(a, Data): 

117 d.update(vars(a)) 

118 d.update(kwargs) 

119 vars(self).update(d) 

120 

121 

122# getattr needs to be defined out of class, otherwise IDEA accepts all attributes 

123 

124def _data_getattr(self, attr): 

125 if attr.startswith('_'): 

126 # do not use None fallback for special props 

127 raise AttributeError(attr) 

128 return None 

129 

130 

131setattr(Data, '__getattr__', _data_getattr) 

132 

133 

134def is_data_object(x): 

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

136 return isinstance(x, Data) 

137 

138 

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

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

141 

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

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

144 

145 Args: 

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

147 """ 

148 

149 if is_data_object(x): 

150 return x 

151 if isinstance(x, Mapping): 

152 return Data(x) 

153 if x is None: 

154 return Data() 

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

156################################################################################ 

157 

158 

159 

160u.is_data_object = is_data_object 

161u.to_data_object = to_data_object 

162 

163 

164 

165################################################################################ 

166# /core/_basic.pyinc 

167 

168 

169class Enum(enum.Enum): 

170 """Enumeration type. 

171 

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

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

174 

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

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

177 """ 

178 pass 

179 

180 

181# hack to make Enum a simple object 

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

183 

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

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

186 

187Point: TypeAlias = tuple[float, float] 

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

189 

190Size: TypeAlias = tuple[float, float] 

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

192 

193 

194class Origin(Enum): 

195 """Grid origin.""" 

196 

197 nw = 'nw' 

198 """north-west""" 

199 sw = 'sw' 

200 """south-west""" 

201 ne = 'ne' 

202 """north-east""" 

203 se = 'se' 

204 """south-east""" 

205 lt = 'nw' 

206 """left top""" 

207 lb = 'sw' 

208 """left bottom""" 

209 rt = 'ne' 

210 """right top""" 

211 rb = 'se' 

212 """right bottom""" 

213 

214 

215FilePath: TypeAlias = str 

216"""File path on the server.""" 

217 

218DirPath: TypeAlias = str 

219"""Directory path on the server.""" 

220 

221Duration: TypeAlias = str 

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

223 

224Color: TypeAlias = str 

225"""CSS color name.""" 

226 

227Regex: TypeAlias = str 

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

229 

230FormatStr: TypeAlias = str 

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

232 

233DateStr: TypeAlias = str 

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

235 

236DateTimeStr: TypeAlias = str 

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

238 

239Url: TypeAlias = str 

240"""URL.""" 

241 

242ClassRef: TypeAlias = type | str 

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

244 

245 

246class Config(Data): 

247 """Object configuration.""" 

248 

249 uid: str = '' 

250 """Unique ID.""" 

251 

252 

253class Props(Data): 

254 """Object properties.""" 

255 

256 uid: str = '' 

257 """Unique ID.""" 

258 

259 

260class Request(Data): 

261 """Command request.""" 

262 

263 projectUid: Optional[str] 

264 """Unique ID of the project.""" 

265 localeUid: Optional[str] 

266 """Locale ID for this request.""" 

267 

268 

269class EmptyRequest(Data): 

270 """Empty command request.""" 

271 

272 pass 

273 

274 

275class ResponseError(Data): 

276 """Response error.""" 

277 

278 code: Optional[int] 

279 """Error code.""" 

280 info: Optional[str] 

281 """Information about the error.""" 

282 

283 

284class Response(Data): 

285 """Command response.""" 

286 

287 error: Optional[ResponseError] 

288 """Response error.""" 

289 status: int 

290 """Response status or exit code.""" 

291 

292 

293class ContentResponse(Response): 

294 """Web response with literal content.""" 

295 

296 asAttachment: bool 

297 """Serve the content as an attachment.""" 

298 attachmentName: str 

299 """Name for the attachment.""" 

300 content: bytes | str 

301 """Response content.""" 

302 contentPath: str 

303 """Local path with the content.""" 

304 mime: str 

305 """Response mime type.""" 

306 headers: dict 

307 """Additional headers.""" 

308 

309 

310class RedirectResponse(Response): 

311 """Web redirect response.""" 

312 

313 location: str 

314 """Redirect URL.""" 

315 headers: dict 

316 """Additional headers.""" 

317 

318 

319class AttributeType(Enum): 

320 """Feature attribute type.""" 

321 

322 bool = 'bool' 

323 bytes = 'bytes' 

324 date = 'date' 

325 datetime = 'datetime' 

326 feature = 'feature' 

327 featurelist = 'featurelist' 

328 file = 'file' 

329 float = 'float' 

330 floatlist = 'floatlist' 

331 geometry = 'geometry' 

332 int = 'int' 

333 intlist = 'intlist' 

334 str = 'str' 

335 strlist = 'strlist' 

336 time = 'time' 

337 

338 

339class GeometryType(Enum): 

340 """Feature geometry type. 

341 

342 OGC and SQL/MM geometry types. 

343 

344 References: 

345 

346 OGC 06-103r4 (https://www.ogc.org/standards/sfa), https://postgis.net/docs/manual-3.3/using_postgis_dbmanagement.html 

347 """ 

348 

349 geometry = 'geometry' 

350 

351 point = 'point' 

352 curve = 'curve' 

353 surface = 'surface' 

354 

355 geometrycollection = 'geometrycollection' 

356 

357 linestring = 'linestring' 

358 line = 'line' 

359 linearring = 'linearring' 

360 

361 polygon = 'polygon' 

362 triangle = 'triangle' 

363 

364 polyhedralsurface = 'polyhedralsurface' 

365 tin = 'tin' 

366 

367 multipoint = 'multipoint' 

368 multicurve = 'multicurve' 

369 multilinestring = 'multilinestring' 

370 multipolygon = 'multipolygon' 

371 multisurface = 'multisurface' 

372 

373 circularstring = 'circularstring' 

374 compoundcurve = 'compoundcurve' 

375 curvepolygon = 'curvepolygon' 

376 

377 

378class CliParams(Data): 

379 """CLI params""" 

380 pass 

381################################################################################ 

382 

383 

384################################################################################ 

385# /core/_access.pyinc 

386 

387 

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

389"""Access Control list. 

390 

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

392""" 

393 

394AclStr: TypeAlias = str 

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

396 

397 

398class Access(Enum): 

399 """Access mode.""" 

400 

401 read = 'read' 

402 write = 'write' 

403 create = 'create' 

404 delete = 'delete' 

405 

406 

407class PermissionsConfig: 

408 """Permissions configuration.""" 

409 

410 all: Optional[AclStr] 

411 """All permissions.""" 

412 read: Optional[AclStr] 

413 """Permission to read the object.""" 

414 write: Optional[AclStr] 

415 """Permission to change the object.""" 

416 create: Optional[AclStr] 

417 """Permission to create new objects.""" 

418 delete: Optional[AclStr] 

419 """Permission to delete objects.""" 

420 edit: Optional[AclStr] 

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

422 

423 

424class ConfigWithAccess(Config): 

425 """Basic config with permissions.""" 

426 

427 access: Optional[AclStr] 

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

429 permissions: Optional[PermissionsConfig] 

430 """Access permissions.""" 

431################################################################################ 

432 

433 

434################################################################################ 

435# /core/_error.pyinc 

436 

437 

438"""App Error object""" 

439 

440class Error(Exception): 

441 """GWS error.""" 

442 def __repr__(self): 

443 return log.exception_backtrace(self)[0] 

444 

445 

446class ConfigurationError(Error): 

447 """GWS Configuration error.""" 

448 pass 

449 

450 

451class NotFoundError(Error): 

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

453 pass 

454 

455 

456class ForbiddenError(Error): 

457 """Generic 'forbidden' error.""" 

458 pass 

459 

460 

461class BadRequestError(Error): 

462 """Generic 'bad request' error.""" 

463 pass 

464 

465 

466class ResponseTooLargeError(Error): 

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

468 pass 

469 

470 

471## 

472################################################################################ 

473 

474 

475 

476################################################################################ 

477# /spec/types.pyinc 

478 

479 

480class ApplicationManifestPlugin(Data): 

481 """Plugin description.""" 

482 

483 path: DirPath 

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

485 

486 name: str = '' 

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

488 

489 

490class ApplicationManifest(Data): 

491 """Application manifest.""" 

492 

493 excludePlugins: Optional[list[str]] 

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

495 plugins: Optional[list[ApplicationManifestPlugin]] 

496 """Custom plugins.""" 

497 locales: list[str] 

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

499 withFallbackConfig: bool = False 

500 """Use a minimal fallback configuration.""" 

501 withStrictConfig: bool = False 

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

503 

504 

505class ExtObjectDescriptor(Data): 

506 """Extension object descriptor.""" 

507 

508 extName: str 

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

510 extType: str 

511 """Extension type like ``wms``.""" 

512 classPtr: type 

513 """Class object.""" 

514 ident: str 

515 """Identifier.""" 

516 modName: str 

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

518 modPath: str 

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

520 

521 

522class ExtCommandDescriptor(Data): 

523 extName: str 

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

525 extType: str 

526 """Extension type like ``wms``.""" 

527 methodName: str 

528 """Command method name.""" 

529 methodPtr: Callable 

530 """Command method.""" 

531 request: 'Request' 

532 """Request sent to the command.""" 

533 tArg: str 

534 """Type of the command argument.""" 

535 tOwner: str 

536 """Type of the command owner.""" 

537 owner: ExtObjectDescriptor 

538 """Descriptor of the command owner.""" 

539 

540 

541class SpecReadOption(Enum): 

542 """Read options.""" 

543 

544 acceptExtraProps = 'acceptExtraProps' 

545 """Accept extra object properties.""" 

546 allowMissing = 'allowMissing' 

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

548 caseInsensitive = 'caseInsensitive' 

549 """Case insensitive search for properties. """ 

550 convertValues = 'convertValues' 

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

552 ignoreExtraProps = 'ignoreExtraProps' 

553 """Silently ignore extra object properties.""" 

554 verboseErrors = 'verboseErrors' 

555 """Provide verbose error messages.""" 

556 

557 

558class CommandCategory(Enum): 

559 """Command category.""" 

560 

561 api = 'api' 

562 """API command.""" 

563 cli = 'cli' 

564 """CLI command.""" 

565 get = 'get' 

566 """Web GET command.""" 

567 post = 'post' 

568 """Web POST command.""" 

569 

570 

571class SpecRuntime: 

572 """Specification runtime.""" 

573 

574 version: str 

575 """Application version.""" 

576 manifest: ApplicationManifest 

577 """Application manifest.""" 

578 appBundlePaths: list[str] 

579 """List of client bundle paths.""" 

580 

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

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

583 

584 Args: 

585 value: Raw value from config or request. 

586 type_name: Object type name. 

587 path: Config file path. 

588 options: Read options. 

589 

590 Returns: 

591 A parsed object. 

592 """ 

593 

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

595 """Get an object descriptor. 

596 

597 Args: 

598 type_name: Object type name. 

599 

600 Returns: 

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

602 """ 

603 

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

605 """Get a command descriptor. 

606 

607 Args: 

608 command_category: Command category. 

609 command_name: Command name. 

610 

611 Returns: 

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

613 """ 

614 

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

616 """Dynamically register an extension object.""" 

617 

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

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

620 

621 Args: 

622 classref: Class reference. 

623 ext_type: Extension type. 

624 

625 Returns: 

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

627 """ 

628 

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

630 """Parse a class reference. 

631 

632 Args: 

633 classref: Class reference. 

634 

635 Returns: 

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

637 """ 

638################################################################################ 

639 

640 

641 

642################################################################################ 

643# /core/_tree.pyinc 

644 

645 

646class Object: 

647 """GWS object.""" 

648 

649 permissions: dict[Access, Acl] 

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

651 

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

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

654 

655 Args: 

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

657 """ 

658 

659 def __init__(self): 

660 self.permissions = {} 

661 

662 

663from .core import tree_impl 

664 

665setattr(tree_impl, 'Access', Access) 

666setattr(tree_impl, 'Error', Error) 

667setattr(tree_impl, 'ConfigurationError', ConfigurationError) 

668setattr(tree_impl, 'Data', Data) 

669setattr(tree_impl, 'Props', Props) 

670setattr(tree_impl, 'Object', Object) 

671 

672Object.__repr__ = tree_impl.object_repr 

673 

674 

675class Node(Object): 

676 """Configurable GWS object.""" 

677 

678 extName: str 

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

680 extType: str 

681 """Extension type like ``wms``.""" 

682 

683 config: Config 

684 """Configuration for this object.""" 

685 root: 'Root' 

686 """Root object.""" 

687 parent: 'Node' 

688 """Parent object.""" 

689 children: list['Node'] 

690 """Child objects.""" 

691 uid: str 

692 """Unique ID.""" 

693 

694 def initialize(self, config): 

695 return tree_impl.node_initialize(self, config) 

696 

697 def pre_configure(self): 

698 """Pre-configuration hook.""" 

699 

700 def configure(self): 

701 """Configuration hook.""" 

702 

703 def post_configure(self): 

704 """Post-configuration hook.""" 

705 

706 def activate(self): 

707 """Activation hook.""" 

708 

709 def create_child(self, classref: ClassRef, config: Config = None, **kwargs): 

710 """Create a child object. 

711 

712 Args: 

713 classref: Class reference. 

714 config: Configuration. 

715 **kwargs: Additional configuration properties. 

716 

717 Returns: 

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

719 """ 

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

721 

722 def create_child_if_configured(self, classref: ClassRef, config=None, **kwargs): 

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

724 

725 Args: 

726 classref: Class reference. 

727 config: Configuration. 

728 **kwargs: Additional configuration properties. 

729 

730 Returns: 

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

732 """ 

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

734 

735 def create_children(self, classref: ClassRef, configs: list[Config], **kwargs): 

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

737 

738 Args: 

739 classref: Class reference. 

740 configs: List of configurations. 

741 **kwargs: Additional configuration properties. 

742 

743 Returns: 

744 A list of newly created objects. 

745 """ 

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

747 

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

749 """Fetch a configuration property. 

750 

751 Args: 

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

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

754 

755 Returns: 

756 A property value. 

757 """ 

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

759 

760 def is_a(self, classref: ClassRef): 

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

762 

763 Args: 

764 classref: Class reference. 

765 

766 Returns: 

767 A boolean. 

768 """ 

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

770 

771 def find_all(self, classref: ClassRef): 

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

773 

774 Args: 

775 classref: Class reference. 

776 

777 Returns: 

778 A list of objects. 

779 """ 

780 return tree_impl.node_find_all(self, classref) 

781 

782 def find_first(self, classref: ClassRef): 

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

784 

785 Args: 

786 classref: Class reference. 

787 

788 Returns: 

789 An object or ``None``. 

790 """ 

791 return tree_impl.node_find_first(self, classref) 

792 

793 def find_closest(self, classref: ClassRef): 

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

795 

796 Args: 

797 classref: Class reference. 

798 

799 Returns: 

800 An object or ``None``. 

801 """ 

802 

803 return tree_impl.node_find_closest(self, classref) 

804 

805 def find_ancestors(self, classref: Optional[ClassRef] = None): 

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

807 

808 Args: 

809 classref: Class reference. 

810 

811 Returns: 

812 A list of objects. 

813 """ 

814 return tree_impl.node_find_ancestors(self, classref) 

815 

816 def find_descendants(self, classref: Optional[ClassRef] = None): 

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

818 

819 Args: 

820 classref: Class reference. 

821 

822 Returns: 

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

824 """ 

825 

826 return tree_impl.node_find_descendants(self, classref) 

827 

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

829 """Begin middleware processing. 

830 

831 Args: 

832 req: Requester object. 

833 

834 Returns: 

835 A Responder object or ``None``. 

836 """ 

837 

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

839 """Finish middleware processing. 

840 

841 Args: 

842 req: Requester object. 

843 res: Current responder object. 

844 """ 

845 

846 def register_middleware(self, name: str, depends_on: Optional[list[str]] = None): 

847 """Register itself as a middleware handler. 

848 

849 Args: 

850 name: Handler name. 

851 depends_on: List of handler names this handler depends on. 

852 """ 

853 return tree_impl.node_register_middleware(self, name, depends_on) 

854 

855 

856class Root: 

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

858 

859 app: 'Application' 

860 """Application object.""" 

861 specs: 'SpecRuntime' 

862 """Specs runtime.""" 

863 configErrors: list 

864 """List of configuration errors.""" 

865 

866 nodes: list['Node'] 

867 uidMap: dict[str, 'Node'] 

868 uidCount: int 

869 configStack: list['Node'] 

870 

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

872 tree_impl.root_init(self, specs) 

873 

874 def initialize(self, obj, config): 

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

876 

877 def post_initialize(self): 

878 """Post-initialization hook.""" 

879 return tree_impl.root_post_initialize(self) 

880 

881 def activate(self): 

882 return tree_impl.root_activate(self) 

883 

884 def find_all(self, classref: ClassRef): 

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

886 

887 Args: 

888 classref: Class reference. 

889 

890 Returns: 

891 A list of objects. 

892 """ 

893 return tree_impl.root_find_all(self, classref) 

894 

895 def find_first(self, classref: ClassRef): 

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

897 

898 Args: 

899 classref: Class reference. 

900 

901 Returns: 

902 An object or ``None``. 

903 """ 

904 return tree_impl.root_find_first(self, classref) 

905 

906 def get(self, uid: str = None, classref: Optional[ClassRef] = None): 

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

908 

909 Args: 

910 uid: Object uid. 

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

912 

913 Returns: 

914 An object or ``None``. 

915 """ 

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

917 

918 def object_count(self) -> int: 

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

920 return tree_impl.root_object_count(self) 

921 

922 def create(self, classref: ClassRef, parent: Optional['Node'] = None, config: Config = None, **kwargs): 

923 """Create an object. 

924 

925 Args: 

926 classref: Class reference. 

927 parent: Parent object. 

928 config: Configuration. 

929 **kwargs: Additional configuration properties. 

930 

931 Returns: 

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

933 """ 

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

935 

936 def create_shared(self, classref: ClassRef, config: Config = None, **kwargs): 

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

938 

939 Args: 

940 classref: Class reference. 

941 config: Configuration. 

942 **kwargs: Additional configuration properties. 

943 

944 Returns: 

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

946 """ 

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

948 

949 def create_temporary(self, classref: ClassRef, config: Config = None, **kwargs): 

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

951 

952 Args: 

953 classref: Class reference. 

954 config: Configuration. 

955 **kwargs: Additional configuration properties. 

956 

957 Returns: 

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

959 """ 

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

961 

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

963 """Create the Application object. 

964 

965 Args: 

966 config: Configuration. 

967 **kwargs: Additional configuration properties. 

968 

969 Returns: 

970 The Application object. 

971 """ 

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

973 

974 

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

976 return Root(specs) 

977 

978 

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

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

981################################################################################ 

982 

983 

984 

985################################################################################ 

986# /lib/image/types.pyinc 

987 

988 

989class ImageFormat(Enum): 

990 """Image format""" 

991 

992 png8 = 'png8' 

993 """png 8-bit""" 

994 png24 = 'png24' 

995 """png 24-bit""" 

996 

997 

998class Image: 

999 """Image object.""" 

1000 

1001 def size(self) -> Size: 

1002 """Get the image size. 

1003 

1004 Returns: 

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

1006 """ 

1007 

1008 def mode(self) -> str: 

1009 """Get the image mode. 

1010 

1011 Returns: 

1012 PIL image mode. 

1013 """ 

1014 

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

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

1017 

1018 Args: 

1019 color: Color of the box's lines. 

1020 

1021 Returns: 

1022 The image with a box around the edges. 

1023 """ 

1024 

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

1026 """Adds text to an image object. 

1027 

1028 Args: 

1029 text: Text to be displayed. 

1030 

1031 x: x-coordinate. 

1032 

1033 y: y-coordinate. 

1034 

1035 color: Color of the text. 

1036 

1037 Returns: 

1038 The image object with the text displayed. 

1039 """ 

1040 

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

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

1043 

1044 Args: 

1045 other: Image to place on top. 

1046 opacity: other image's opacity. 

1047 

1048 Returns: 

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

1050 """ 

1051 

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

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

1054 

1055 Args: 

1056 box: `(width, height)` 

1057 

1058 Returns: 

1059 The cropped image object. 

1060 """ 

1061 

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

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

1064 

1065 Args: 

1066 other: Image that will be placed. 

1067 

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

1069 

1070 Returns: 

1071 The image object with the other image placed inside. 

1072 """ 

1073 

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

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

1076 

1077 Args: 

1078 size: `(width, height)` 

1079 

1080 Returns: 

1081 The resized image object. 

1082 """ 

1083 

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

1085 """Rotates the image. 

1086 

1087 Args: 

1088 angle: Angle to rotate the image. 

1089 

1090 Returns: 

1091 The rotated image object. 

1092 """ 

1093 

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

1095 """Converts the image object to bytes. 

1096 

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

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

1099 

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

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

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

1103 

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

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

1106 

1107 Args: 

1108 mime: The mime type. 

1109 options: A dict of options. 

1110 

1111 Returns: 

1112 The image as bytes. 

1113 """ 

1114 

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

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

1117 

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

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

1120 

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

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

1123 

1124 Args: 

1125 path: Image's path location. 

1126 mime: The mime type. 

1127 options: A dict of options. 

1128 

1129 Returns: 

1130 The path to the image. 

1131 """ 

1132 

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

1134 """Converts the image to an array. 

1135 

1136 Returns: 

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

1138 """ 

1139 

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

1141 """Compare this image to another one. 

1142 

1143 @TODO describe the alogrithm 

1144 

1145 Returns: 

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

1147 '0' means images are equal. 

1148 """ 

1149################################################################################ 

1150 

1151 

1152################################################################################ 

1153# /lib/intl/types.pyinc 

1154 

1155 

1156class Locale(Data): 

1157 """Locale data.""" 

1158 

1159 uid: str 

1160 dateFormatLong: str 

1161 dateFormatMedium: str 

1162 dateFormatShort: str 

1163 dateUnits: str 

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

1165 dayNamesLong: list[str] 

1166 dayNamesShort: list[str] 

1167 dayNamesNarrow: list[str] 

1168 firstWeekDay: int 

1169 

1170 language: str 

1171 """Language code: ``de``""" 

1172 language3: str 

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

1174 languageBib: str 

1175 """Bibliographic language code..""" 

1176 languageName: str 

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

1178 languageNameEn: str 

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

1180 

1181 territory: str 

1182 territoryName: str 

1183 monthNamesLong: list[str] 

1184 monthNamesShort: list[str] 

1185 monthNamesNarrow: list[str] 

1186 numberDecimal: str 

1187 numberGroup: str 

1188 

1189 

1190class DateTimeFormat(Enum): 

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

1192 short = 'short' 

1193 """Local short format.""" 

1194 medium = 'medium' 

1195 """Local medium format.""" 

1196 long = 'long' 

1197 """Local long format.""" 

1198 iso = 'iso' 

1199 """ISO 8601 format.""" 

1200 

1201 

1202class NumberFormat(Enum): 

1203 """Enumeration indicating the number format.""" 

1204 decimal = 'decimal' 

1205 """Locale decimal format.""" 

1206 grouped = 'grouped' 

1207 """Locale grouped format.""" 

1208 currency = 'currency' 

1209 """Locale currency format""" 

1210 percent = 'percent' 

1211 """Locale percent format.""" 

1212 

1213 

1214class DateFormatter: 

1215 """Locale-aware date formatter.""" 

1216 

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

1218 """Formats the date. 

1219 

1220 Args: 

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

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

1223 

1224 Returns: 

1225 A formatted date string. 

1226 """ 

1227 

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

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

1230 

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

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

1233 

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

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

1236 

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

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

1239 

1240 

1241class TimeFormatter: 

1242 """Locale-aware time formatter.""" 

1243 

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

1245 """Formats the time. 

1246 

1247 Args: 

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

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

1250 

1251 Returns: 

1252 A formatted time string. 

1253 """ 

1254 

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

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

1257 

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

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

1260 

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

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

1263 

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

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

1266 

1267 

1268class NumberFormatter: 

1269 """Locale-aware number formatter.""" 

1270 

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

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

1273 

1274 Args: 

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

1276 n: Number. 

1277 kwargs: Passes the currency parameter forward. 

1278 

1279 Returns: 

1280 A formatted number. 

1281 """ 

1282 

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

1284 """Returns formatted decimal value.""" 

1285 

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

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

1288 

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

1290 """Returns formatted currency value.""" 

1291 

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

1293 """Returns formatted percent value.""" 

1294################################################################################ 

1295 

1296 

1297################################################################################ 

1298# /lib/job/types.pyinc 

1299 

1300 

1301class JobState(Enum): 

1302 """Background job state.""" 

1303 

1304 init = 'init' 

1305 """The job is being created.""" 

1306 open = 'open' 

1307 """The job is just created and waiting for start.""" 

1308 running = 'running' 

1309 """The job is running.""" 

1310 complete = 'complete' 

1311 """The job has been completed successfully.""" 

1312 error = 'error' 

1313 """There was an error.""" 

1314 cancel = 'cancel' 

1315 """The job was cancelled.""" 

1316 

1317 

1318class Job: 

1319 """Background Job object.""" 

1320 

1321 error: str 

1322 payload: dict 

1323 state: JobState 

1324 uid: str 

1325 user: 'User' 

1326 

1327 def run(self): ... 

1328 

1329 def update(self, payload: Optional[dict] = None, state: Optional[JobState] = None, error: Optional[str] = None): ... 

1330 

1331 def cancel(self): ... 

1332 

1333 def remove(self): ... 

1334################################################################################ 

1335 

1336 

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

1338# /lib/metadata/types.pyinc 

1339 

1340 

1341class MetadataLink(Data): 

1342 """Link metadata.""" 

1343 

1344 about: Optional[str] 

1345 description: Optional[str] 

1346 format: Optional[str] 

1347 formatVersion: Optional[str] 

1348 function: Optional[str] 

1349 mimeType: Optional[str] 

1350 scheme: Optional[str] 

1351 title: Optional[str] 

1352 type: Optional[str] 

1353 url: Optional[Url] 

1354 

1355 

1356class MetadataAccessConstraint(Data): 

1357 """Metadata AccessConstraint.""" 

1358 

1359 title: Optional[str] 

1360 type: Optional[str] 

1361 

1362 

1363class MetadataLicense(Data): 

1364 """Metadata License.""" 

1365 

1366 title: Optional[str] 

1367 url: Optional[Url] 

1368 

1369 

1370class MetadataAttribution(Data): 

1371 """Metadata Attribution.""" 

1372 

1373 title: Optional[str] 

1374 url: Optional[Url] 

1375 

1376 

1377class Metadata(Data): 

1378 """Metadata.""" 

1379 

1380 abstract: Optional[str] 

1381 accessConstraints: Optional[list[MetadataAccessConstraint]] 

1382 attribution: Optional[MetadataAttribution] 

1383 authorityIdentifier: Optional[str] 

1384 authorityName: Optional[str] 

1385 authorityUrl: Optional[str] 

1386 catalogCitationUid: Optional[str] 

1387 catalogUid: Optional[str] 

1388 fees: Optional[str] 

1389 image: Optional[str] 

1390 keywords: Optional[list[str]] 

1391 language3: Optional[str] 

1392 language: Optional[str] 

1393 languageName: Optional[str] 

1394 license: Optional[MetadataLicense] 

1395 name: Optional[str] 

1396 parentIdentifier: Optional[str] 

1397 title: Optional[str] 

1398 

1399 contactAddress: Optional[str] 

1400 contactAddressType: Optional[str] 

1401 contactArea: Optional[str] 

1402 contactCity: Optional[str] 

1403 contactCountry: Optional[str] 

1404 contactEmail: Optional[str] 

1405 contactFax: Optional[str] 

1406 contactOrganization: Optional[str] 

1407 contactPerson: Optional[str] 

1408 contactPhone: Optional[str] 

1409 contactPosition: Optional[str] 

1410 contactProviderName: Optional[str] 

1411 contactProviderSite: Optional[str] 

1412 contactRole: Optional[str] 

1413 contactUrl: Optional[str] 

1414 contactZip: Optional[str] 

1415 

1416 dateBegin: Optional[str] 

1417 dateCreated: Optional[str] 

1418 dateEnd: Optional[str] 

1419 dateUpdated: Optional[str] 

1420 

1421 inspireKeywords: Optional[list[str]] 

1422 inspireMandatoryKeyword: Optional[str] 

1423 inspireDegreeOfConformity: Optional[str] 

1424 inspireResourceType: Optional[str] 

1425 inspireSpatialDataServiceType: Optional[str] 

1426 inspireSpatialScope: Optional[str] 

1427 inspireSpatialScopeName: Optional[str] 

1428 inspireTheme: Optional[str] 

1429 inspireThemeName: Optional[str] 

1430 inspireThemeNameEn: Optional[str] 

1431 

1432 isoMaintenanceFrequencyCode: Optional[str] 

1433 isoQualityConformanceExplanation: Optional[str] 

1434 isoQualityConformanceQualityPass: Optional[bool] 

1435 isoQualityConformanceSpecificationDate: Optional[str] 

1436 isoQualityConformanceSpecificationTitle: Optional[str] 

1437 isoQualityLineageSource: Optional[str] 

1438 isoQualityLineageSourceScale: Optional[int] 

1439 isoQualityLineageStatement: Optional[str] 

1440 isoRestrictionCode: Optional[str] 

1441 isoServiceFunction: Optional[str] 

1442 isoScope: Optional[str] 

1443 isoScopeName: Optional[str] 

1444 isoSpatialRepresentationType: Optional[str] 

1445 isoTopicCategories: Optional[list[str]] 

1446 isoSpatialResolution: Optional[str] 

1447 

1448 metaLinks: Optional[list[MetadataLink]] 

1449 serviceMetaLink: Optional[MetadataLink] 

1450 extraLinks: Optional[list[MetadataLink]] 

1451################################################################################ 

1452 

1453 

1454################################################################################ 

1455# /lib/style/types.pyinc 

1456 

1457 

1458class StyleValues(Data): 

1459 """CSS Style values.""" 

1460 

1461 fill: Color 

1462 

1463 stroke: Color 

1464 stroke_dasharray: list[int] 

1465 stroke_dashoffset: int 

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

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

1468 stroke_miterlimit: int 

1469 stroke_width: int 

1470 

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

1472 marker_fill: Color 

1473 marker_size: int 

1474 marker_stroke: Color 

1475 marker_stroke_dasharray: list[int] 

1476 marker_stroke_dashoffset: int 

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

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

1479 marker_stroke_miterlimit: int 

1480 marker_stroke_width: int 

1481 

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

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

1484 

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

1486 label_background: Color 

1487 label_fill: Color 

1488 label_font_family: str 

1489 label_font_size: int 

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

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

1492 label_line_height: int 

1493 label_max_scale: int 

1494 label_min_scale: int 

1495 label_offset_x: int 

1496 label_offset_y: int 

1497 label_padding: list[int] 

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

1499 label_stroke: Color 

1500 label_stroke_dasharray: list[int] 

1501 label_stroke_dashoffset: int 

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

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

1504 label_stroke_miterlimit: int 

1505 label_stroke_width: int 

1506 

1507 point_size: int 

1508 icon: str 

1509 

1510 offset_x: int 

1511 offset_y: int 

1512 

1513 

1514class StyleProps(Props): 

1515 """CSS Style properties.""" 

1516 

1517 cssSelector: Optional[str] 

1518 text: Optional[str] 

1519 values: Optional[dict] 

1520 

1521 

1522class Style: 

1523 """CSS Style object.""" 

1524 

1525 cssSelector: str 

1526 text: str 

1527 values: StyleValues 

1528################################################################################ 

1529 

1530 

1531################################################################################ 

1532# /lib/xmlx/types.pyinc 

1533 

1534 

1535class XmlNamespace(Data): 

1536 """XML namespace.""" 

1537 

1538 uid: str 

1539 """Unique ID.""" 

1540 xmlns: str 

1541 """Default prefix for this Namespace.""" 

1542 uri: Url 

1543 """Namespace uri.""" 

1544 schemaLocation: Url 

1545 """Namespace schema location.""" 

1546 version: str 

1547 """Namespace version.""" 

1548 extendsGml: bool 

1549 """Namespace schema extends the GML3 schema.""" 

1550 

1551 

1552class XmlElement(Iterable): 

1553 """XML Element. 

1554 

1555 

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

1557 """ 

1558 

1559 tag: str 

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

1561 

1562 text: Optional[str] 

1563 """Text before first subelement.""" 

1564 

1565 tail: Optional[str] 

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

1567 

1568 attrib: dict 

1569 """Dictionary of element attributes.""" 

1570 

1571 name: str 

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

1573 

1574 lcName: str 

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

1576 

1577 caseInsensitive: bool 

1578 """Element is case-insensitive.""" 

1579 

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

1581 

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

1583 

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

1585 

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

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

1588 

1589 def attr(self, key: str, default=None): 

1590 """Finds the value for a given key in the ``XmlElementImpl``. 

1591 

1592 Args: 

1593 key: Key of the attribute. 

1594 default: The default return. 

1595 

1596 Returns: 

1597 The vale of the key, If the key is not found the default is returned. 

1598 """ 

1599 

1600 def clear(self): 

1601 """Resets an element.""" 

1602 

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

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

1605 

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

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

1608 

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

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

1611 

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

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

1614 

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

1616 """Returns the value to a given key.""" 

1617 

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

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

1620 

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

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

1623 

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

1625 """Creates a tree iterator.""" 

1626 

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

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

1629 

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

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

1632 

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

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

1635 

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

1637 """Removes the other element from the element.""" 

1638 

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

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

1641 

1642 # extensions 

1643 

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

1645 """Creates a new ``XmlElementImpl`` and adds it as a child. 

1646 

1647 Args: 

1648 tag: XML tag. 

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

1650 

1651 Returns: 

1652 A XmlElementImpl. 

1653 """ 

1654 

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

1656 """Returns the children of the current ``XmlElementImpl``.""" 

1657 

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

1659 """Returns the first element in the current element. 

1660 

1661 Args: 

1662 paths: Path as ``tag/tag2/tag3`` to the Element to search in. 

1663 

1664 Returns: 

1665 Returns the first found element. 

1666 """ 

1667 

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

1669 """Returns the text of a given child-element. 

1670 

1671 Args: 

1672 paths: Path as ``tag/tag2/tag3`` to the Element. 

1673 

1674 Returns: 

1675 The text of the element. 

1676 """ 

1677 

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

1679 """Collects texts from child-elements. 

1680 

1681 Args: 

1682 paths: Path as ``tag/tag2/tag3`` to the Element to collect texts from. 

1683 deep: If ``False`` it only looks into direct children, otherwise it searches for texts in the complete children-tree. 

1684 

1685 Returns: 

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

1687 """ 

1688 

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

1690 """Collects texts from child-elements. 

1691 

1692 Args: 

1693 paths: Path as ``tag/tag2/tag3`` to the Element to collect texts from. 

1694 deep: If ``False`` it only looks into direct children, otherwise it searches for texts in the complete children-tree. 

1695 

1696 Returns: 

1697 A dict containing all the text from the child-elements. 

1698 """ 

1699 

1700 def to_string( 

1701 self, 

1702 extra_namespaces: Optional[list[XmlNamespace]] = None, 

1703 compact_whitespace: bool = False, 

1704 remove_namespaces: bool = False, 

1705 with_namespace_declarations: bool = False, 

1706 with_schema_locations: bool = False, 

1707 with_xml_declaration: bool = False, 

1708 ) -> str: 

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

1710 

1711 Args: 

1712 extra_namespaces: Extra namespaces to add to the document. 

1713 compact_whitespace: Remove all whitespace outside of tags and elements. 

1714 remove_namespaces: Remove all namespace references. 

1715 with_namespace_declarations: Include the namespace declarations. 

1716 with_schema_locations: Include schema locations. 

1717 with_xml_declaration: Include the xml declaration. 

1718 

1719 Returns: 

1720 An XML string. 

1721 """ 

1722 

1723 def to_dict(self) -> dict: 

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

1725 

1726 def to_list( 

1727 self, 

1728 fold_tags: bool = True, 

1729 remove_namespaces: bool = False, 

1730 ) -> list: 

1731 """Parse an XML element into a list of arguments. 

1732 

1733 Args: 

1734 fold_tags: If true, folds nested tag names into ``parent/child`` names. 

1735 remove_namespaces: If true, removes all namespaces. 

1736 """ 

1737################################################################################ 

1738 

1739 

1740################################################################################ 

1741# /lib/uom/types.pyinc 

1742 

1743 

1744class Uom(Enum): 

1745 """Unit of measure.""" 

1746 

1747 mi = 'mi' 

1748 """statute mile (EPSG 9093)""" 

1749 us_ch = 'us-ch' 

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

1751 us_ft = 'us-ft' 

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

1753 us_in = 'us-in' 

1754 """us survey inch us_in""" 

1755 us_mi = 'us-mi' 

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

1757 us_yd = 'us-yd' 

1758 """us survey yard us_yd""" 

1759 cm = 'cm' 

1760 """centimetre (EPSG 1033)""" 

1761 ch = 'ch' 

1762 """chain (EPSG 9097)""" 

1763 dm = 'dm' 

1764 """decimeter dm""" 

1765 deg = 'deg' 

1766 """degree (EPSG 9102)""" 

1767 fath = 'fath' 

1768 """fathom (EPSG 9014)""" 

1769 ft = 'ft' 

1770 """foot (EPSG 9002)""" 

1771 grad = 'grad' 

1772 """grad (EPSG 9105)""" 

1773 inch = 'in' 

1774 """inch in""" 

1775 km = 'km' 

1776 """kilometre (EPSG 9036)""" 

1777 link = 'link' 

1778 """link (EPSG 9098)""" 

1779 m = 'm' 

1780 """metre (EPSG 9001)""" 

1781 mm = 'mm' 

1782 """millimetre (EPSG 1025)""" 

1783 kmi = 'kmi' 

1784 """nautical mile (EPSG 9030)""" 

1785 rad = 'rad' 

1786 """radian (EPSG 9101)""" 

1787 yd = 'yd' 

1788 """yard (EPSG 9096)""" 

1789 px = 'px' 

1790 """pixel""" 

1791 pt = 'pt' 

1792 """point""" 

1793 

1794 

1795UomValue: TypeAlias = tuple[float, Uom] 

1796"""A value with a unit.""" 

1797 

1798UomValueStr: TypeAlias = str 

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

1800 

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

1802"""A Point with a unit.""" 

1803 

1804UomPointStr: TypeAlias = list[str] 

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

1806 

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

1808"""A Size with a unit.""" 

1809 

1810UomSizeStr: TypeAlias = list[str] 

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

1812 

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

1814"""Extent with a unit.""" 

1815 

1816UomExtentStr: TypeAlias = list[str] 

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

1818################################################################################ 

1819 

1820 

1821 

1822################################################################################ 

1823# /gis/crs/types.pyinc 

1824 

1825 

1826CrsName: TypeAlias = int | str 

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

1828 

1829 

1830class CrsFormat(Enum): 

1831 """CRS name format.""" 

1832 

1833 none = '' 

1834 crs = 'crs' 

1835 """Like ``crs84``.""" 

1836 srid = 'srid' 

1837 """Like ``3857``.""" 

1838 epsg = 'epsg' 

1839 """Like ``EPSG:3857``.""" 

1840 url = 'url' 

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

1842 uri = 'uri' 

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

1844 urnx = 'urnx' 

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

1846 urn = 'urn' 

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

1848 

1849 

1850class Axis(Enum): 

1851 """Axis orientation.""" 

1852 

1853 xy = 'xy' 

1854 yx = 'yx' 

1855 

1856 

1857class Bounds(Data): 

1858 """Geo-referenced extent.""" 

1859 

1860 crs: 'Crs' 

1861 extent: Extent 

1862 

1863 

1864class Crs: 

1865 """Coordinate reference system.""" 

1866 

1867 srid: int 

1868 """CRS SRID.""" 

1869 axis: Axis 

1870 """Axis orientation.""" 

1871 uom: Uom 

1872 """CRS unit.""" 

1873 isGeographic: bool 

1874 """This CRS is geographic.""" 

1875 isProjected: bool 

1876 """This CRS is projected.""" 

1877 isYX: bool 

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

1879 proj4text: str 

1880 """Proj4 definition.""" 

1881 wkt: str 

1882 """WKT definition.""" 

1883 

1884 epsg: str 

1885 """Name in the "epsg" format.""" 

1886 urn: str 

1887 """Name in the "urn" format.""" 

1888 urnx: str 

1889 """Name in the "urnx" format.""" 

1890 url: str 

1891 """Name in the "url" format.""" 

1892 uri: str 

1893 """Name in the "uri" format.""" 

1894 

1895 name: str 

1896 """CRS name.""" 

1897 base: int 

1898 """Base CRS code.""" 

1899 datum: str 

1900 """Datum.""" 

1901 

1902 wgsExtent: Extent 

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

1904 extent: Extent 

1905 """CRS own Extent.""" 

1906 bounds: Bounds 

1907 """CRS own Bounds.""" 

1908 

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

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

1911 

1912 We adhere to the GeoServer convention here: 

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

1914 """ 

1915 

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

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

1918 

1919 Args: 

1920 extent: Extent. 

1921 crs_to: Target CRS. 

1922 

1923 Returns: 

1924 A transformed Extent. 

1925 """ 

1926 

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

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

1929 

1930 Args: 

1931 crs_to: Target CRS. 

1932 

1933 Returns: 

1934 A function. 

1935 """ 

1936 

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

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

1939 

1940 Args: 

1941 fmt: Format to use. 

1942 

1943 Returns: 

1944 A string. 

1945 """ 

1946 

1947 def to_geojson(self) -> dict: 

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

1949 

1950 Returns: 

1951 A GeoJson dict. 

1952 

1953 References: 

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

1955 """ 

1956################################################################################ 

1957 

1958 

1959################################################################################ 

1960# /gis/render/types.pyinc 

1961 

1962 

1963class MapView(Data): 

1964 """Map view.""" 

1965 

1966 bounds: Bounds 

1967 center: Point 

1968 rotation: int 

1969 scale: int 

1970 mmSize: Size 

1971 pxSize: Size 

1972 dpi: int 

1973 

1974 

1975class MapRenderInputPlaneType(Enum): 

1976 """Map render input plane type.""" 

1977 

1978 features = 'features' 

1979 image = 'image' 

1980 imageLayer = 'imageLayer' 

1981 svgLayer = 'svgLayer' 

1982 svgSoup = 'svgSoup' 

1983 

1984 

1985class MapRenderInputPlane(Data): 

1986 """Map render input plane.""" 

1987 

1988 type: MapRenderInputPlaneType 

1989 features: list['Feature'] 

1990 image: 'Image' 

1991 layer: 'Layer' 

1992 opacity: float 

1993 soupPoints: list[Point] 

1994 soupTags: list[Any] 

1995 styles: list['Style'] 

1996 subLayers: list[str] 

1997 

1998 

1999class MapRenderInput(Data): 

2000 """Map render input.""" 

2001 

2002 backgroundColor: int 

2003 bbox: Extent 

2004 center: Point 

2005 crs: 'Crs' 

2006 dpi: int 

2007 mapSize: UomSize 

2008 notify: Callable 

2009 planes: list['MapRenderInputPlane'] 

2010 project: 'Project' 

2011 rotation: int 

2012 scale: int 

2013 user: 'User' 

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

2015 

2016 

2017class MapRenderOutputPlaneType(Enum): 

2018 """Map render output plane type.""" 

2019 

2020 image = 'image' 

2021 path = 'path' 

2022 svg = 'svg' 

2023 

2024 

2025class MapRenderOutputPlane(Data): 

2026 """Map render output plane.""" 

2027 

2028 type: MapRenderOutputPlaneType 

2029 path: str 

2030 elements: list[XmlElement] 

2031 image: 'Image' 

2032 

2033 

2034class MapRenderOutput(Data): 

2035 """Map render output.""" 

2036 

2037 planes: list['MapRenderOutputPlane'] 

2038 view: MapView 

2039 

2040 

2041class LayerRenderInputType(Enum): 

2042 """Layer render input type.""" 

2043 

2044 box = 'box' 

2045 xyz = 'xyz' 

2046 svg = 'svg' 

2047 

2048 

2049class LayerRenderInput(Data): 

2050 """Layer render input.""" 

2051 

2052 boxBuffer: int 

2053 boxSize: int 

2054 extraParams: dict 

2055 project: 'Project' 

2056 style: 'Style' 

2057 type: LayerRenderInputType 

2058 user: 'User' 

2059 view: MapView 

2060 x: int 

2061 y: int 

2062 z: int 

2063 

2064 

2065class LayerRenderOutput(Data): 

2066 """Layer render output.""" 

2067 

2068 content: bytes 

2069 tags: list[XmlElement] 

2070################################################################################ 

2071 

2072 

2073################################################################################ 

2074# /gis/source/types.pyinc 

2075 

2076 

2077class TileMatrix(Data): 

2078 """WMTS TileMatrix object.""" 

2079 

2080 uid: str 

2081 scale: float 

2082 x: float 

2083 y: float 

2084 width: float 

2085 height: float 

2086 tileWidth: float 

2087 tileHeight: float 

2088 extent: Extent 

2089 

2090 

2091class TileMatrixSet(Data): 

2092 """WMTS TileMatrixSet object.""" 

2093 

2094 uid: str 

2095 crs: 'Crs' 

2096 matrices: list[TileMatrix] 

2097 

2098 

2099class SourceStyle(Data): 

2100 """Generic OGC Style.""" 

2101 

2102 isDefault: bool 

2103 legendUrl: Url 

2104 metadata: 'Metadata' 

2105 name: str 

2106 

2107 

2108class SourceLayer(Data): 

2109 """Generic OGC Layer.""" 

2110 

2111 aLevel: int 

2112 aPath: str 

2113 aUid: str 

2114 

2115 dataSource: dict 

2116 metadata: 'Metadata' 

2117 

2118 supportedCrs: list['Crs'] 

2119 wgsExtent: Extent 

2120 

2121 isExpanded: bool 

2122 isGroup: bool 

2123 isImage: bool 

2124 isQueryable: bool 

2125 isVisible: bool 

2126 

2127 layers: list['SourceLayer'] 

2128 

2129 name: str 

2130 title: str 

2131 

2132 legendUrl: Url 

2133 opacity: int 

2134 scaleRange: list[float] 

2135 

2136 styles: list[SourceStyle] 

2137 defaultStyle: Optional[SourceStyle] 

2138 

2139 tileMatrixIds: list[str] 

2140 tileMatrixSets: list[TileMatrixSet] 

2141 imageFormat: str 

2142 resourceUrls: dict 

2143 

2144 sourceId: str 

2145 properties: dict 

2146################################################################################ 

2147 

2148 

2149 

2150################################################################################ 

2151# /server/types.pyinc 

2152 

2153 

2154class ServerManager(Node): 

2155 """Server configuration manager.""" 

2156 

2157 templates: list['Template'] 

2158 

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

2160 """Create server configuration files.""" 

2161 

2162 

2163class ServerMonitor(Node): 

2164 """File Monitor facility.""" 

2165 

2166 def add_directory(self, path: str, pattern: 'Regex'): 

2167 """Add a directory to monitor. 

2168 

2169 Args: 

2170 path: Directory path. 

2171 pattern: Regex pattern for files to watch. 

2172 """ 

2173 

2174 def add_file(self, path: str): 

2175 """Add a file to watch. 

2176 

2177 Args: 

2178 path: File path. 

2179 """ 

2180 

2181 def start(self): 

2182 """Start the monitor.""" 

2183################################################################################ 

2184 

2185 

2186 

2187################################################################################ 

2188# /base/feature/types.pyinc 

2189 

2190 

2191FeatureUid: TypeAlias = str 

2192"""Unique Feature id.""" 

2193 

2194class FeatureRecord(Data): 

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

2196 

2197 attributes: dict 

2198 meta: dict 

2199 uid: Optional[str] 

2200 shape: Optional['Shape'] 

2201 

2202 

2203class FeatureProps(Props): 

2204 """Feature Proprieties.""" 

2205 

2206 attributes: dict 

2207 cssSelector: str 

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

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

2210 isNew: bool 

2211 modelUid: str 

2212 uid: str 

2213 views: dict 

2214 

2215 

2216class Feature: 

2217 """Feature object.""" 

2218 

2219 attributes: dict 

2220 category: str 

2221 cssSelector: str 

2222 errors: list['ModelValidationError'] 

2223 isNew: bool 

2224 model: 'Model' 

2225 props: 'FeatureProps' 

2226 record: 'FeatureRecord' 

2227 views: dict 

2228 createWithFeatures: list['Feature'] 

2229 insertedPrimaryKey: str 

2230 

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

2232 

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

2234 

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

2236 

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

2238 

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

2240 

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

2242 

2243 def to_geojson(self, user: 'User') -> dict: ... 

2244 

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

2246 

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

2248 

2249 def uid(self) -> FeatureUid: ... 

2250################################################################################ 

2251 

2252 

2253################################################################################ 

2254# /base/shape/types.pyinc 

2255 

2256 

2257class ShapeProps(Props): 

2258 """Shape properties.""" 

2259 

2260 crs: str 

2261 geometry: dict 

2262 

2263 

2264class Shape(Object): 

2265 """Geo-referenced geometry.""" 

2266 

2267 type: GeometryType 

2268 """Geometry type.""" 

2269 

2270 crs: 'Crs' 

2271 """CRS of this shape.""" 

2272 

2273 x: Optional[float] 

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

2275 

2276 y: Optional[float] 

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

2278 

2279 # common props 

2280 

2281 def area(self) -> float: 

2282 """Computes the area of the geometry.""" 

2283 

2284 def bounds(self) -> Bounds: 

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

2286 

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

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

2289 

2290 # formats 

2291 

2292 def to_wkb(self) -> bytes: 

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

2294 

2295 def to_wkb_hex(self) -> str: 

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

2297 

2298 def to_ewkb(self) -> bytes: 

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

2300 

2301 def to_ewkb_hex(self) -> str: 

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

2303 

2304 def to_wkt(self) -> str: 

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

2306 

2307 def to_ewkt(self) -> str: 

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

2309 

2310 def to_geojson(self, always_xy=False) -> dict: 

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

2312 

2313 def to_props(self) -> ShapeProps: 

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

2315 

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

2317 

2318 def is_empty(self) -> bool: 

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

2320 

2321 def is_ring(self) -> bool: 

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

2323 

2324 def is_simple(self) -> bool: 

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

2326 

2327 def is_valid(self) -> bool: 

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

2329 

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

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

2332 

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

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

2335 

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

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

2338 

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

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

2341 

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

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

2344 

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

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

2347 

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

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

2350 

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

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

2353 

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

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

2356 

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

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

2359 

2360 # set operations 

2361 

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

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

2364 

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

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

2367 

2368 # convertors 

2369 

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

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

2372 

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

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

2375 

2376 # misc 

2377 

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

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

2380 

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

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

2383################################################################################ 

2384 

2385 

2386 

2387################################################################################ 

2388# /base/action/types.pyinc 

2389 

2390 

2391class ActionManager(Node): 

2392 """Action manager.""" 

2393 

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

2395 """Get a list of actions for a Project, to which a User has access to.""" 

2396 

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

2398 """Locate an Action object. 

2399 

2400 Args: 

2401 project: Project to se 

2402 ext_type: 

2403 user: 

2404 

2405 Returns: 

2406 

2407 """ 

2408 

2409 def prepare_action( 

2410 self, 

2411 command_category: CommandCategory, 

2412 command_name: str, 

2413 params: dict, 

2414 user: 'User', 

2415 read_options=None, 

2416 ) -> tuple[Callable, Request]: ... 

2417 

2418 

2419class Action(Node): 

2420 pass 

2421################################################################################ 

2422 

2423 

2424################################################################################ 

2425# /base/auth/types.pyinc 

2426 

2427 

2428class User(Object): 

2429 """User object.""" 

2430 

2431 isGuest: bool 

2432 """User is a Guest.""" 

2433 

2434 authProvider: 'AuthProvider' 

2435 """User authorization provider.""" 

2436 

2437 attributes: dict 

2438 """Public user attributes.""" 

2439 data: dict 

2440 """Private user data.""" 

2441 roles: set[str] 

2442 """User roles.""" 

2443 uid: str 

2444 """Global user uid.""" 

2445 

2446 authToken: str 

2447 """Token used for authorization.""" 

2448 displayName: str 

2449 """User display name.""" 

2450 email: str 

2451 """User email.""" 

2452 localUid: str 

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

2454 loginName: str 

2455 """User login name.""" 

2456 mfaUid: str 

2457 """MFA adapter uid.""" 

2458 mfaSecret: str 

2459 """MFA secret.""" 

2460 

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

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

2463 

2464 Args: 

2465 access: Access mode. 

2466 obj: Requested object. 

2467 

2468 Returns: 

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

2470 """ 

2471 

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

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

2474 

2475 Args: 

2476 access: Access mode. 

2477 obj: Requested object. 

2478 *context: Further objects to check. 

2479 

2480 Returns: 

2481 ``True`` is access is granted. 

2482 """ 

2483 

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

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

2486 

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

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

2489 

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

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

2492 

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

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

2495 

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

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

2498 

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

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

2501 

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

2503 """Get a readable object by uid. 

2504 

2505 Args: 

2506 uid: Object uid. 

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

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

2509 

2510 Returns: 

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

2512 """ 

2513 

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

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

2516 

2517 Args: 

2518 uid: Object uid. 

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

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

2521 

2522 Returns: 

2523 A readable object. 

2524 

2525 Raises: 

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

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

2528 """ 

2529 

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

2531 """Get a readable Project object. 

2532 

2533 Args: 

2534 uid: Project uid. 

2535 

2536 Returns: 

2537 A Project object. 

2538 """ 

2539 

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

2541 """Get a readable Layer object. 

2542 

2543 Args: 

2544 uid: Layer uid. 

2545 

2546 Returns: 

2547 A Layer object. 

2548 """ 

2549 

2550 

2551class AuthManager(Node): 

2552 """Authentication manager.""" 

2553 

2554 guestSession: 'AuthSession' 

2555 """Preconfigured Guest session.""" 

2556 

2557 guestUser: 'User' 

2558 """Preconfigured Guest user.""" 

2559 systemUser: 'User' 

2560 """Preconfigured System user.""" 

2561 

2562 providers: list['AuthProvider'] 

2563 """Authentication providers.""" 

2564 methods: list['AuthMethod'] 

2565 """Authentication methods.""" 

2566 mfAdapters: list['AuthMultiFactorAdapter'] 

2567 """Authentication MFA handlers.""" 

2568 

2569 sessionMgr: 'AuthSessionManager' 

2570 """Session manager.""" 

2571 

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

2573 """Authenticate a user. 

2574 

2575 Args: 

2576 method: Authentication method. 

2577 credentials: Credentials object. 

2578 

2579 Returns: 

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

2581 """ 

2582 

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

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

2585 

2586 Args: 

2587 user_uid: Global user uid. 

2588 Returns: 

2589 A User or ``None``. 

2590 """ 

2591 

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

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

2594 

2595 Args: 

2596 uid: Uid. 

2597 Returns: 

2598 A Provider or ``None``. 

2599 """ 

2600 

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

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

2603 

2604 Args: 

2605 uid: Uid. 

2606 Returns: 

2607 A Method or ``None``. 

2608 """ 

2609 

2610 def get_mf_adapter(self, uid: str) -> Optional['AuthMultiFactorAdapter']: 

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

2612 

2613 Args: 

2614 uid: Uid. 

2615 Returns: 

2616 A Provider or ``None``. 

2617 """ 

2618 

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

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

2621 

2622 Args: 

2623 user: A User object. 

2624 

2625 Returns: 

2626 A json string. 

2627 """ 

2628 

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

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

2631 

2632 Args: 

2633 ser: A json string. 

2634 

2635 Returns: 

2636 A User object. 

2637 """ 

2638 

2639 

2640class AuthMethod(Node): 

2641 """Authentication Method.""" 

2642 

2643 authMgr: 'AuthManager' 

2644 

2645 secure: bool 

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

2647 

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

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

2650 

2651 Args: 

2652 req: Requester object. 

2653 

2654 Returns: 

2655 A Session or ``None``. 

2656 """ 

2657 

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

2659 """Close a previously opened Session. 

2660 

2661 Args: 

2662 req: Requester object. 

2663 res: Responder object. 

2664 

2665 Returns: 

2666 True if the Session was successfully closed. 

2667 """ 

2668 

2669 

2670class AuthMultiFactorState(Enum): 

2671 open = 'open' 

2672 ok = 'ok' 

2673 retry = 'retry' 

2674 failed = 'failed' 

2675 

2676 

2677class AuthMultiFactorTransaction(Data): 

2678 state: AuthMultiFactorState 

2679 restartCount: int 

2680 verifyCount: int 

2681 secret: str 

2682 startTime: int 

2683 generateTime: int 

2684 message: str 

2685 adapter: 'AuthMultiFactorAdapter' 

2686 user: 'User' 

2687 

2688 

2689class AuthMultiFactorAdapter(Node): 

2690 """Multi-factor authentication adapter.""" 

2691 

2692 message: str 

2693 lifeTime: int 

2694 maxRestarts: int 

2695 maxVerifyAttempts: int 

2696 

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

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

2699 

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

2701 """Verify a payload.""" 

2702 

2703 def cancel(self, mfa: AuthMultiFactorTransaction): 

2704 """Cancel the transaction.""" 

2705 

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

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

2708 

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

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

2711 

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

2713 """Restart the transaction.""" 

2714 

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

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

2717 

2718 

2719class AuthProvider(Node): 

2720 """Authentication Provider.""" 

2721 

2722 allowedMethods: list[str] 

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

2724 

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

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

2727 

2728 Args: 

2729 local_uid: User local uid. 

2730 

2731 Returns: 

2732 A User or ``None``. 

2733 """ 

2734 

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

2736 """Authenticate a user. 

2737 

2738 Args: 

2739 method: Authentication method. 

2740 credentials: Credentials object. 

2741 

2742 Returns: 

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

2744 """ 

2745 

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

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

2748 

2749 Args: 

2750 user: A User object. 

2751 

2752 Returns: 

2753 A json string. 

2754 """ 

2755 

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

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

2758 

2759 Args: 

2760 ser: A json string. 

2761 

2762 Returns: 

2763 A User object. 

2764 """ 

2765 

2766 

2767class AuthSession: 

2768 """Authentication session.""" 

2769 

2770 uid: str 

2771 """Session uid.""" 

2772 method: Optional['AuthMethod'] 

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

2774 user: 'User' 

2775 """Authorized User.""" 

2776 data: dict 

2777 """Session data.""" 

2778 created: 'datetime.datetime' 

2779 """Session create time.""" 

2780 updated: 'datetime.datetime' 

2781 """Session update time.""" 

2782 isChanged: bool 

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

2784 

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

2786 """Get a session data value. 

2787 

2788 Args: 

2789 key: Value name. 

2790 default: Default value. 

2791 

2792 Returns: 

2793 A value or the default. 

2794 """ 

2795 

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

2797 """Set a session data value. 

2798 

2799 Args: 

2800 key: Value name. 

2801 value: A value. 

2802 """ 

2803 

2804 

2805class AuthSessionManager(Node): 

2806 """Authentication session Manager.""" 

2807 

2808 lifeTime: int 

2809 """Session lifetime in seconds.""" 

2810 

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

2812 """Create a new Session, 

2813 

2814 Args: 

2815 method: Auth Method that creates the Session. 

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

2817 data: Session data. 

2818 

2819 Returns: 

2820 A new Session. 

2821 """ 

2822 

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

2824 """Delete a Session. 

2825 

2826 Args: 

2827 sess: Session object. 

2828 """ 

2829 

2830 def delete_all(self): 

2831 """Delete all Sessions. 

2832 """ 

2833 

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

2835 """Get Session by its uid. 

2836 

2837 Args: 

2838 uid: Session uid. 

2839 

2840 Returns: 

2841 A Session or ``None``. 

2842 """ 

2843 

2844 def get_valid(self, uid: str) -> Optional['AuthSession']: 

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

2846 

2847 Args: 

2848 uid: Session uid. 

2849 

2850 Returns: 

2851 A Session or ``None`` if uid does not exists or the Session is not valid. 

2852 """ 

2853 

2854 def get_all(self) -> list['AuthSession']: 

2855 """Get all sessions.""" 

2856 

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

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

2859 

2860 Args: 

2861 sess: Session object. 

2862 """ 

2863 

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

2865 """Update the Session last activity timestamp. 

2866 

2867 Args: 

2868 sess: Session object. 

2869 """ 

2870 

2871 def cleanup(self): 

2872 """Remove invalid Sessions from the storage. 

2873 """ 

2874################################################################################ 

2875 

2876 

2877 

2878################################################################################ 

2879# /base/layer/types.pyinc 

2880 

2881 

2882class LayerDisplayMode(Enum): 

2883 """Layer display mode.""" 

2884 

2885 box = 'box' 

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

2887 tile = 'tile' 

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

2889 client = 'client' 

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

2891 

2892 

2893class LayerClientOptions(Data): 

2894 """Client options for a layer.""" 

2895 

2896 expanded: bool 

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

2898 unlisted: bool 

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

2900 selected: bool 

2901 """A layer is initially selected.""" 

2902 hidden: bool 

2903 """A layer is initially hidden.""" 

2904 unfolded: bool 

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

2906 exclusive: bool 

2907 """Only one of this layer's children is visible at a time.""" 

2908 

2909 

2910class TileGrid(Data): 

2911 """Tile grid.""" 

2912 

2913 uid: str 

2914 bounds: Bounds 

2915 origin: Origin 

2916 resolutions: list[float] 

2917 tileSize: int 

2918 

2919 

2920class LayerCache(Data): 

2921 """Layer cache.""" 

2922 

2923 maxAge: int 

2924 maxLevel: int 

2925 requestBuffer: int 

2926 requestTiles: int 

2927 

2928 

2929class FeatureLoadingStrategy(Enum): 

2930 """Loading strategy for features.""" 

2931 

2932 all = 'all' 

2933 """Load all features.""" 

2934 bbox = 'bbox' 

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

2936 lazy = 'lazy' 

2937 """Load features on demand.""" 

2938 

2939 

2940class LayerOws(Node): 

2941 """Layer OWS controller.""" 

2942 

2943 allowedServiceUids: list[str] 

2944 deniedServiceUids: list[str] 

2945 featureName: str 

2946 geometryName: str 

2947 layerName: str 

2948 models: list['Model'] 

2949 xmlNamespace: Optional['XmlNamespace'] 

2950 

2951 

2952class Layer(Node): 

2953 """Layer object.""" 

2954 

2955 canRenderBox: bool 

2956 canRenderSvg: bool 

2957 canRenderXyz: bool 

2958 

2959 isEnabledForOws: bool 

2960 isGroup: bool 

2961 isSearchable: bool 

2962 

2963 hasLegend: bool 

2964 

2965 bounds: Bounds 

2966 zoomBounds: Bounds 

2967 wgsExtent: Extent 

2968 mapCrs: 'Crs' 

2969 clientOptions: LayerClientOptions 

2970 displayMode: LayerDisplayMode 

2971 loadingStrategy: FeatureLoadingStrategy 

2972 imageFormat: str 

2973 opacity: float 

2974 resolutions: list[float] 

2975 title: str 

2976 

2977 grid: Optional[TileGrid] 

2978 cache: Optional[LayerCache] 

2979 

2980 metadata: 'Metadata' 

2981 legend: Optional['Legend'] 

2982 legendUrl: str 

2983 

2984 finders: list['Finder'] 

2985 templates: list['Template'] 

2986 models: list['Model'] 

2987 ows: 'LayerOws' 

2988 

2989 layers: list['Layer'] 

2990 

2991 sourceLayers: list['SourceLayer'] 

2992 

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

2994 

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

2996 

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

2998 

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

3000 

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

3002 

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

3004################################################################################ 

3005 

3006 

3007################################################################################ 

3008# /base/legend/types.pyinc 

3009 

3010 

3011class LegendRenderOutput(Data): 

3012 """Legend render output.""" 

3013 

3014 html: str 

3015 image: 'Image' 

3016 image_path: str 

3017 size: Size 

3018 mime: str 

3019 

3020 

3021class Legend(Node): 

3022 """Legend object.""" 

3023 

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

3025################################################################################ 

3026 

3027 

3028################################################################################ 

3029# /base/map/types.pyinc 

3030 

3031 

3032class Map(Node): 

3033 """Map object.""" 

3034 

3035 rootLayer: 'Layer' 

3036 

3037 bounds: Bounds 

3038 center: Point 

3039 coordinatePrecision: int 

3040 initResolution: float 

3041 resolutions: list[float] 

3042 title: str 

3043 wgsExtent: Extent 

3044################################################################################ 

3045 

3046 

3047 

3048################################################################################ 

3049# /base/model/types.pyinc 

3050 

3051 

3052class ModelClientOptions(Data): 

3053 """Client options for a model""" 

3054 

3055 keepFormOpen: Optional[bool] 

3056 

3057class ModelValidationError(Data): 

3058 """Validation error.""" 

3059 

3060 fieldName: str 

3061 message: str 

3062 

3063 

3064class ModelOperation(Enum): 

3065 """Model operation.""" 

3066 

3067 read = 'read' 

3068 create = 'create' 

3069 update = 'update' 

3070 delete = 'delete' 

3071 

3072 

3073class ModelReadTarget(Enum): 

3074 """Target for the read operation.""" 

3075 

3076 map = 'map' 

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

3078 searchResults = 'searchResults' 

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

3080 list = 'list' 

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

3082 editList = 'editList' 

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

3084 editForm = 'editForm' 

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

3086 

3087 

3088class ModelDbSelect(Data): 

3089 """Database select statement.""" 

3090 

3091 columns: list['sqlalchemy.Column'] 

3092 geometryWhere: list 

3093 keywordWhere: list 

3094 where: list 

3095 order: list 

3096 

3097 

3098class ModelContext(Data): 

3099 """Model context.""" 

3100 

3101 op: ModelOperation 

3102 target: ModelReadTarget 

3103 user: 'User' 

3104 project: 'Project' 

3105 relDepth: int = 0 

3106 maxDepth: int = 0 

3107 search: 'SearchQuery' 

3108 dbSelect: ModelDbSelect 

3109 dbConnection: 'sqlalchemy.Connection' 

3110 

3111 

3112EmptyValue = object() 

3113"""Special value for empty fields.""" 

3114 

3115ErrorValue = object() 

3116"""Special value for invalid fields.""" 

3117 

3118 

3119class ModelWidget(Node): 

3120 """Model widget.""" 

3121 

3122 supportsTableView: bool = True 

3123 

3124 

3125class ModelValidator(Node): 

3126 """Model Validator.""" 

3127 

3128 message: str 

3129 ops: set[ModelOperation] 

3130 

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

3132 

3133 

3134class ModelValue(Node): 

3135 """Model value.""" 

3136 

3137 isDefault: bool 

3138 ops: set[ModelOperation] 

3139 

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

3141 

3142 

3143class ModelField(Node): 

3144 """Model field.""" 

3145 

3146 name: str 

3147 title: str 

3148 

3149 attributeType: AttributeType 

3150 

3151 widget: Optional['ModelWidget'] = None 

3152 

3153 values: list['ModelValue'] 

3154 validators: list['ModelValidator'] 

3155 

3156 isPrimaryKey: bool 

3157 isRequired: bool 

3158 isUnique: bool 

3159 isAuto: bool 

3160 

3161 supportsFilterSearch: bool = False 

3162 supportsGeometrySearch: bool = False 

3163 supportsKeywordSearch: bool = False 

3164 

3165 model: 'Model' 

3166 

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

3168 

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

3170 

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

3172 

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

3174 

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

3176 

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

3178 

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

3180 

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

3182 

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

3184 

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

3186 

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

3188 

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

3190 

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

3192 

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

3194 

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

3196 

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

3198 

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

3200 

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

3202 

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

3204 

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

3206 

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

3208 

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

3210 

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

3212 

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

3214 

3215 

3216class Model(Node): 

3217 """Data Model.""" 

3218 

3219 clientOptions: ModelClientOptions 

3220 defaultSort: list['SearchSort'] 

3221 fields: list['ModelField'] 

3222 geometryCrs: Optional['Crs'] 

3223 geometryName: str 

3224 geometryType: Optional[GeometryType] 

3225 isEditable: bool 

3226 loadingStrategy: 'FeatureLoadingStrategy' 

3227 title: str 

3228 uidName: str 

3229 withTableView: bool 

3230 

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

3232 

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

3234 

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

3236 

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

3238 

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

3240 

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

3242 

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

3244 

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

3246 

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

3248 

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

3250 

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

3252 

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

3254 

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

3256 

3257 

3258class ModelManager(Node): 

3259 """Model manager.""" 

3260 

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

3262 

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

3264 

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

3266 

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

3268################################################################################ 

3269 

3270 

3271################################################################################ 

3272# /base/database/types.pyinc 

3273 

3274 

3275class DatabaseModel(Model): 

3276 """Database-based data model.""" 

3277 

3278 db: 'DatabaseProvider' 

3279 sqlFilter: str 

3280 tableName: str 

3281 

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

3283 

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

3285 

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

3287 

3288 

3289 

3290 

3291class ColumnDescription(Data): 

3292 """Database column description.""" 

3293 

3294 columnIndex: int 

3295 comment: str 

3296 default: str 

3297 geometrySrid: int 

3298 geometryType: GeometryType 

3299 isAutoincrement: bool 

3300 isNullable: bool 

3301 isPrimaryKey: bool 

3302 isUnique: bool 

3303 hasDefault: bool 

3304 name: str 

3305 nativeType: str 

3306 options: dict 

3307 type: AttributeType 

3308 

3309 

3310class RelationshipDescription(Data): 

3311 """Database relationship description.""" 

3312 

3313 name: str 

3314 schema: str 

3315 fullName: str 

3316 foreignKeys: str 

3317 referredKeys: str 

3318 

3319 

3320class DataSetDescription(Data): 

3321 """Description of a database Table or a GDAL Dataset.""" 

3322 

3323 columns: list[ColumnDescription] 

3324 columnMap: dict[str, ColumnDescription] 

3325 fullName: str 

3326 geometryName: str 

3327 geometrySrid: int 

3328 geometryType: GeometryType 

3329 name: str 

3330 schema: str 

3331 

3332 

3333class DatabaseManager(Node): 

3334 """Database manager.""" 

3335 

3336 providers: list['DatabaseProvider'] 

3337 

3338 def create_provider(self, cfg: Config, **kwargs) -> 'DatabaseProvider': ... 

3339 

3340 def find_provider(self, uid: Optional[str] = None, ext_type: Optional[str] = None) -> Optional['DatabaseProvider']: ... 

3341 

3342 

3343DatabaseTableAlike: TypeAlias = Union['sqlalchemy.Table', str] 

3344"""SA ``Table`` object or a string table name.""" 

3345 

3346 

3347class DatabaseProvider(Node): 

3348 """Database Provider. 

3349 

3350 A database Provider wraps SQLAlchemy ``Engine`` and ``Connection`` objects 

3351 and provides common db functionality. 

3352 """ 

3353 

3354 url: str 

3355 """Connection url.""" 

3356 

3357 def column(self, table: DatabaseTableAlike, column_name: str) -> 'sqlalchemy.Column': 

3358 """SA ``Column`` object for a specific column.""" 

3359 

3360 def connect(self) -> ContextManager['sqlalchemy.Connection']: 

3361 """Context manager for a SA ``Connection``. 

3362 

3363 Context calls to this method can be nested. An inner call is a no-op, as no new connection is created. 

3364 Only the outermost connection is closed upon exit:: 

3365 

3366 with db.connect(): 

3367 ... 

3368 with db.connect(): # no-op 

3369 ... 

3370 # connection remains open 

3371 ... 

3372 # connection closed 

3373 """ 

3374 

3375 def describe(self, table: DatabaseTableAlike) -> 'DataSetDescription': 

3376 """Describe a table.""" 

3377 

3378 def count(self, table: DatabaseTableAlike) -> int: 

3379 """Return table record count or 0 if the table does not exist.""" 

3380 

3381 def engine(self, **kwargs) -> 'sqlalchemy.Engine': 

3382 """SA ``Engine`` object for this provider.""" 

3383 

3384 def has_column(self, table: DatabaseTableAlike, column_name: str) -> bool: 

3385 """Check if a specific column exists.""" 

3386 

3387 def has_table(self, table_name: str) -> bool: 

3388 """Check if a specific table exists.""" 

3389 

3390 def join_table_name(self, schema: str, name: str) -> str: 

3391 """Create a full table name from the schema and table names.""" 

3392 

3393 def split_table_name(self, table_name: str) -> tuple[str, str]: 

3394 """Split a full table name into the schema and table names.""" 

3395 

3396 def table(self, table_name: str, **kwargs) -> 'sqlalchemy.Table': 

3397 """SA ``Table`` object for a specific table.""" 

3398 

3399 def table_bounds(self, table: DatabaseTableAlike) -> Optional[Bounds]: 

3400 """Compute a bounding box for the table primary geometry.""" 

3401 

3402 def select_text(self, sql: str, **kwargs) -> list[dict]: 

3403 """Execute a textual SELECT statement and return a list of record dicts.""" 

3404 

3405 def execute_text(self, sql: str, **kwargs) -> 'sqlalchemy.CursorResult': 

3406 """Execute a textual DML statement and return a result.""" 

3407################################################################################ 

3408 

3409 

3410 

3411################################################################################ 

3412# /base/ows/types.pyinc 

3413 

3414 

3415import gws 

3416 

3417 

3418class OwsProtocol(Enum): 

3419 """Supported OWS protocol.""" 

3420 

3421 WMS = 'WMS' 

3422 WMTS = 'WMTS' 

3423 WCS = 'WCS' 

3424 WFS = 'WFS' 

3425 CSW = 'CSW' 

3426 

3427 

3428class OwsAuthorization(Data): 

3429 type: str 

3430 username: str 

3431 password: str 

3432 

3433 

3434class OwsVerb(Enum): 

3435 """OWS verb.""" 

3436 

3437 CreateStoredQuery = 'CreateStoredQuery' 

3438 DescribeCoverage = 'DescribeCoverage' 

3439 DescribeFeatureType = 'DescribeFeatureType' 

3440 DescribeLayer = 'DescribeLayer' 

3441 DescribeRecord = 'DescribeRecord' 

3442 DescribeStoredQueries = 'DescribeStoredQueries' 

3443 DropStoredQuery = 'DropStoredQuery' 

3444 GetCapabilities = 'GetCapabilities' 

3445 GetFeature = 'GetFeature' 

3446 GetFeatureInfo = 'GetFeatureInfo' 

3447 GetFeatureWithLock = 'GetFeatureWithLock' 

3448 GetLegendGraphic = 'GetLegendGraphic' 

3449 GetMap = 'GetMap' 

3450 GetPrint = 'GetPrint' 

3451 GetPropertyValue = 'GetPropertyValue' 

3452 GetRecordById = 'GetRecordById' 

3453 GetRecords = 'GetRecords' 

3454 GetTile = 'GetTile' 

3455 ListStoredQueries = 'ListStoredQueries' 

3456 LockFeature = 'LockFeature' 

3457 Transaction = 'Transaction' 

3458 

3459 

3460class OwsOperation(Data): 

3461 """OWS operation.""" 

3462 

3463 allowedParameters: dict[str, list[str]] 

3464 constraints: dict[str, list[str]] 

3465 formats: list[str] 

3466 handlerName: str 

3467 params: dict[str, str] 

3468 postUrl: Url 

3469 preferredFormat: str 

3470 url: Url 

3471 verb: OwsVerb 

3472 

3473 

3474class OwsCapabilities(Data): 

3475 """OWS capabilities structure.""" 

3476 

3477 metadata: 'Metadata' 

3478 operations: list['OwsOperation'] 

3479 sourceLayers: list['SourceLayer'] 

3480 tileMatrixSets: list['TileMatrixSet'] 

3481 version: str 

3482 

3483 

3484class OwsImageFormat(Data): 

3485 mimeTypes: list[str] 

3486 """Mime types for this format.""" 

3487 options: dict 

3488 """Image options.""" 

3489 

3490 

3491class OwsService(Node): 

3492 """OWS Service.""" 

3493 

3494 isRasterService: bool = False 

3495 """Service provides raster services.""" 

3496 isVectorService: bool = False 

3497 """Service provides vector services.""" 

3498 isOwsCommon: bool = False 

3499 """Conforms to OGC Web Services Common Standard.""" 

3500 

3501 alwaysXY: bool 

3502 """Force lon/lat order for geographic projections.""" 

3503 metadata: 'Metadata' 

3504 """Service metadata.""" 

3505 name: str 

3506 """Service name.""" 

3507 project: Optional['Project'] 

3508 """Project this service is configured for.""" 

3509 rootLayer: Optional['Layer'] 

3510 """Root layer of the service.""" 

3511 protocol: OwsProtocol 

3512 """Supported protocol.""" 

3513 defaultFeatureCount: int 

3514 """Default limit of features per page.""" 

3515 maxFeatureCount: int 

3516 """Max limit of features per page.""" 

3517 searchTolerance: UomValue 

3518 """Default tolerance for spatial search.""" 

3519 supportedBounds: list[Bounds] 

3520 """Supported bounds.""" 

3521 supportedVersions: list[str] 

3522 """Supported versions.""" 

3523 supportedOperations: list['OwsOperation'] 

3524 """Supported operations.""" 

3525 templates: list['Template'] 

3526 """Service templates.""" 

3527 imageFormats: list[OwsImageFormat] 

3528 """Supported image formats.""" 

3529 updateSequence: str 

3530 """Service update sequence.""" 

3531 withInspireMeta: bool 

3532 """Include INSPIRE metadata.""" 

3533 withStrictParams: bool 

3534 """Strict parameter checking.""" 

3535 

3536 def handle_request(self, req: 'WebRequester') -> ContentResponse: 

3537 """Handle a service request.""" 

3538 

3539 def layer_is_suitable(self, layer: 'Layer') -> bool: 

3540 """True if layer can be used in this service.""" 

3541 

3542 

3543class OwsProvider(Node): 

3544 """OWS services Provider.""" 

3545 

3546 alwaysXY: bool 

3547 authorization: Optional['OwsAuthorization'] 

3548 bounds: Optional[Bounds] 

3549 forceCrs: 'Crs' 

3550 maxRequests: int 

3551 metadata: 'Metadata' 

3552 operations: list['OwsOperation'] 

3553 protocol: 'OwsProtocol' 

3554 sourceLayers: list['SourceLayer'] 

3555 url: Url 

3556 version: str 

3557 wgsExtent: Optional[Extent] 

3558 

3559 def get_operation(self, verb: 'OwsVerb', method: Optional['RequestMethod'] = None) -> Optional['OwsOperation']: ... 

3560 

3561 def get_features(self, args: 'SearchQuery', source_layers: list['SourceLayer']) -> list['FeatureRecord']: ... 

3562################################################################################ 

3563 

3564 

3565################################################################################ 

3566# /base/printer/types.pyinc 

3567 

3568 

3569class PrintPlaneType(Enum): 

3570 """Print plane type.""" 

3571 

3572 bitmap = 'bitmap' 

3573 url = 'url' 

3574 features = 'features' 

3575 raster = 'raster' 

3576 vector = 'vector' 

3577 soup = 'soup' 

3578 

3579 

3580class PrintPlane(Data): 

3581 """Print plane.""" 

3582 

3583 type: PrintPlaneType 

3584 

3585 opacity: Optional[float] 

3586 cssSelector: Optional[str] 

3587 

3588 bitmapData: Optional[bytes] 

3589 bitmapMode: Optional[str] 

3590 bitmapWidth: Optional[int] 

3591 bitmapHeight: Optional[int] 

3592 

3593 url: Optional[str] 

3594 

3595 features: Optional[list['FeatureProps']] 

3596 

3597 layerUid: Optional[str] 

3598 subLayers: Optional[list[str]] 

3599 

3600 soupPoints: Optional[list[Point]] 

3601 soupTags: Optional[list[Any]] 

3602 

3603 

3604class PrintMap(Data): 

3605 """Map properties for printing.""" 

3606 

3607 backgroundColor: Optional[int] 

3608 bbox: Optional[Extent] 

3609 center: Optional[Point] 

3610 planes: list[PrintPlane] 

3611 rotation: Optional[int] 

3612 scale: int 

3613 styles: Optional[list['StyleProps']] 

3614 visibleLayers: Optional[list[str]] 

3615 

3616 

3617class PrintRequestType(Enum): 

3618 """Type of the print request.""" 

3619 

3620 template = 'template' 

3621 map = 'map' 

3622 

3623 

3624class PrintRequest(Request): 

3625 """Print request.""" 

3626 

3627 type: PrintRequestType 

3628 

3629 args: Optional[dict] 

3630 crs: Optional[CrsName] 

3631 outputFormat: Optional[str] 

3632 maps: Optional[list[PrintMap]] 

3633 

3634 printerUid: Optional[str] 

3635 dpi: Optional[int] 

3636 outputSize: Optional[Size] 

3637 

3638 

3639class PrintJobResponse(Response): 

3640 """Print job information response.""" 

3641 

3642 jobUid: str 

3643 progress: int 

3644 state: 'JobState' 

3645 stepType: str 

3646 stepName: str 

3647 url: str 

3648 

3649 

3650class Printer(Node): 

3651 """Printer object.""" 

3652 

3653 title: str 

3654 template: 'Template' 

3655 models: list['Model'] 

3656 qualityLevels: list['TemplateQualityLevel'] 

3657 

3658 

3659class PrinterManager(Node): 

3660 """Print Manager.""" 

3661 

3662 def printers_for_project(self, project: 'Project', user: 'User') -> list['Printer']: ... 

3663 

3664 def start_job(self, request: PrintRequest, user: 'User') -> 'Job': ... 

3665 

3666 def get_job(self, uid: str, user: 'User') -> Optional['Job']: ... 

3667 

3668 def run_job(self, request: PrintRequest, user: 'User'): ... 

3669 

3670 def cancel_job(self, job: 'Job'): ... 

3671 

3672 def result_path(self, job: 'Job') -> str: ... 

3673 

3674 def status(self, job: 'Job') -> PrintJobResponse: ... 

3675################################################################################ 

3676 

3677 

3678################################################################################ 

3679# /base/project/types.pyinc 

3680 

3681 

3682class Client(Node): 

3683 """GWS Client control object.""" 

3684 

3685 options: dict 

3686 elements: list 

3687 

3688 

3689class Project(Node): 

3690 """Project object.""" 

3691 

3692 assetsRoot: Optional['WebDocumentRoot'] 

3693 client: 'Client' 

3694 

3695 localeUids: list[str] 

3696 map: 'Map' 

3697 metadata: 'Metadata' 

3698 

3699 actions: list['Action'] 

3700 finders: list['Finder'] 

3701 models: list['Model'] 

3702 printers: list['Printer'] 

3703 templates: list['Template'] 

3704 owsServices: list['OwsService'] 

3705################################################################################ 

3706 

3707 

3708################################################################################ 

3709# /base/search/types.pyinc 

3710 

3711 

3712class SearchSort(Data): 

3713 """Search sort specification.""" 

3714 

3715 fieldName: str 

3716 reverse: bool 

3717 

3718 

3719class SearchOgcFilter(Data): 

3720 """Search filter.""" 

3721 

3722 name: str 

3723 operator: str 

3724 shape: 'Shape' 

3725 subFilters: list['SearchOgcFilter'] 

3726 value: str 

3727 

3728 

3729class SearchQuery(Data): 

3730 """Search query.""" 

3731 

3732 access: Access 

3733 all: bool 

3734 bounds: Bounds 

3735 extraColumns: list 

3736 extraParams: dict 

3737 extraWhere: list 

3738 keyword: str 

3739 layers: list['Layer'] 

3740 limit: int 

3741 ogcFilter: SearchOgcFilter 

3742 project: 'Project' 

3743 relDepth: int 

3744 resolution: float 

3745 shape: 'Shape' 

3746 sort: list[SearchSort] 

3747 tolerance: 'UomValue' 

3748 uids: list[str] 

3749 

3750 

3751class SearchResult(Data): 

3752 """Search result.""" 

3753 

3754 feature: 'Feature' 

3755 layer: 'Layer' 

3756 finder: 'Finder' 

3757 

3758 

3759class TextSearchType(Enum): 

3760 """Text search type.""" 

3761 

3762 exact = 'exact' 

3763 """Match the whole string.""" 

3764 begin = 'begin' 

3765 """Match the beginning of the string.""" 

3766 end = 'end' 

3767 """Match the end of the string.""" 

3768 any = 'any' 

3769 """Match any substring.""" 

3770 like = 'like' 

3771 """Use the percent sign as a placeholder.""" 

3772 

3773 

3774class TextSearchOptions(Data): 

3775 """Text search options.""" 

3776 

3777 type: TextSearchType 

3778 """Type of the search.""" 

3779 minLength: int = 0 

3780 """Minimal pattern length.""" 

3781 caseSensitive: bool = False 

3782 """Use the case sensitive search.""" 

3783 

3784 

3785class SortOptions(Data): 

3786 """Sort options.""" 

3787 fieldName: str 

3788 reverse: bool = False 

3789 

3790 

3791class SearchManager(Node): 

3792 """Search Manager.""" 

3793 

3794 def run_search(self, search: 'SearchQuery', user: 'User') -> list['SearchResult']: ... 

3795 

3796 

3797class Finder(Node): 

3798 """Finder object.""" 

3799 

3800 title: str 

3801 

3802 supportsFilterSearch: bool = False 

3803 supportsGeometrySearch: bool = False 

3804 supportsKeywordSearch: bool = False 

3805 

3806 withFilter: bool 

3807 withGeometry: bool 

3808 withKeyword: bool 

3809 

3810 templates: list['Template'] 

3811 models: list['Model'] 

3812 sourceLayers: list['SourceLayer'] 

3813 

3814 tolerance: 'UomValue' 

3815 

3816 def run(self, search: SearchQuery, user: 'User', layer: Optional['Layer'] = None) -> list['Feature']: ... 

3817 

3818 def can_run(self, search: SearchQuery, user: 'User') -> bool: ... 

3819################################################################################ 

3820 

3821 

3822################################################################################ 

3823# /base/storage/types.pyinc 

3824 

3825 

3826class StorageManager(Node): 

3827 """Storage manager.""" 

3828 

3829 providers: list['StorageProvider'] 

3830 

3831 def create_provider(self, cfg: Config, **kwargs) -> 'StorageProvider': ... 

3832 

3833 def find_provider(self, uid: Optional[str] = None) -> Optional['StorageProvider']: ... 

3834 

3835 

3836 

3837class StorageRecord(Data): 

3838 """Storage record.""" 

3839 

3840 name: str 

3841 userUid: str 

3842 data: str 

3843 created: int 

3844 updated: int 

3845 

3846 

3847class StorageProvider(Node): 

3848 """Storage provider.""" 

3849 

3850 def list_names(self, category: str) -> list[str]: ... 

3851 

3852 def read(self, category: str, name: str) -> Optional['StorageRecord']: ... 

3853 

3854 def write(self, category: str, name: str, data: str, user_uid: str): ... 

3855 

3856 def delete(self, category: str, name: str): ... 

3857################################################################################ 

3858 

3859 

3860################################################################################ 

3861# /base/template/types.pyinc 

3862 

3863 

3864class TemplateArgs(Data): 

3865 """Template arguments.""" 

3866 

3867 app: 'Application' 

3868 """Application object.""" 

3869 gwsVersion: str 

3870 """GWS version. (deprecated in 8.1)""" 

3871 gwsBaseUrl: str 

3872 """GWS server base url. (deprecated in 8.1)""" 

3873 locale: 'Locale' 

3874 """Current locale.""" 

3875 date: 'DateFormatter' 

3876 """Locale-aware date formatter.""" 

3877 time: 'TimeFormatter' 

3878 """Locale-aware time formatter.""" 

3879 number: 'NumberFormatter' 

3880 """Locale-aware number formatter.""" 

3881 

3882 

3883class TemplateRenderInput(Data): 

3884 """Template render input.""" 

3885 

3886 args: dict | Data 

3887 crs: 'Crs' 

3888 dpi: int 

3889 locale: 'Locale' 

3890 maps: list[MapRenderInput] 

3891 mimeOut: str 

3892 notify: Callable 

3893 project: 'Project' 

3894 user: 'User' 

3895 

3896 

3897class TemplateQualityLevel(Data): 

3898 """Template quality level.""" 

3899 

3900 name: str 

3901 dpi: int 

3902 

3903 

3904class Template(Node): 

3905 """Template object.""" 

3906 

3907 mapSize: UomSize 

3908 """Default map size for the template.""" 

3909 mimeTypes: list[str] 

3910 """MIME types the template can generate.""" 

3911 pageSize: UomSize 

3912 """Default page size for printing.""" 

3913 pageMargin: UomExtent 

3914 """Default page margin for printing.""" 

3915 subject: str 

3916 """Template subject (category).""" 

3917 title: str 

3918 """Template title.""" 

3919 

3920 def render(self, tri: TemplateRenderInput) -> ContentResponse: 

3921 """Render the template and return the generated response.""" 

3922 

3923 

3924class TemplateManager(Node): 

3925 """Template manager.""" 

3926 

3927 def find_template(self, subject: str, where: list[Node], user: 'User' = None, mime: str = None) -> Optional['Template']: ... 

3928 

3929 def template_from_path(self, path: str) -> Optional['Template']: ... 

3930################################################################################ 

3931 

3932 

3933################################################################################ 

3934# /base/web/types.pyinc 

3935 

3936 

3937class RequestMethod(Enum): 

3938 """Web request method.""" 

3939 

3940 GET = 'GET' 

3941 HEAD = 'HEAD' 

3942 POST = 'POST' 

3943 PUT = 'PUT' 

3944 DELETE = 'DELETE' 

3945 CONNECT = 'CONNECT' 

3946 OPTIONS = 'OPTIONS' 

3947 TRACE = 'TRACE' 

3948 PATCH = 'PATCH' 

3949 

3950 

3951class WebRequester: 

3952 """Web Requester object.""" 

3953 

3954 environ: dict 

3955 """Request environment.""" 

3956 method: RequestMethod 

3957 """Request method.""" 

3958 root: 'Root' 

3959 """Object tree root.""" 

3960 site: 'WebSite' 

3961 """Website the request is processed for.""" 

3962 

3963 session: 'AuthSession' 

3964 """Current session.""" 

3965 user: 'User' 

3966 """Current use.""" 

3967 

3968 isApi: bool 

3969 """The request is an 'api' request.""" 

3970 isGet: bool 

3971 """The request is a 'get' request.""" 

3972 isPost: bool 

3973 """The request is a 'post' request.""" 

3974 isSecure: bool 

3975 """The request is secure.""" 

3976 

3977 def params(self) -> dict: 

3978 """GET parameters.""" 

3979 

3980 def struct(self) -> dict: 

3981 """Structured JSON payload.""" 

3982 

3983 def command(self) -> str: 

3984 """Command name to execute.""" 

3985 

3986 def cookie(self, key: str, default: str = '') -> str: 

3987 """Get a cookie. 

3988 

3989 Args: 

3990 key: Cookie name. 

3991 default: Default value. 

3992 

3993 Returns: 

3994 A cookie value. 

3995 """ 

3996 

3997 def header(self, key: str, default: str = '') -> str: 

3998 """Get a header. 

3999 

4000 Args: 

4001 key: Header name. 

4002 default: Default value. 

4003 

4004 Returns: 

4005 A header value. 

4006 """ 

4007 

4008 def has_param(self, key: str) -> bool: 

4009 """Check if a GET parameter exists. 

4010 

4011 Args: 

4012 key: Parameter name. 

4013 """ 

4014 

4015 def param(self, key: str, default: str = '') -> str: 

4016 """Get a GET parameter. 

4017 

4018 Args: 

4019 key: Parameter name. 

4020 default: Default value. 

4021 

4022 Returns: 

4023 A parameter value. 

4024 """ 

4025 

4026 def env(self, key: str, default: str = '') -> str: 

4027 """Get an environment variable. 

4028 

4029 Args: 

4030 key: Variable name. 

4031 default: Default value. 

4032 

4033 Returns: 

4034 A variable value. 

4035 """ 

4036 

4037 def data(self) -> Optional[bytes]: 

4038 """Get POST data. 

4039 

4040 Returns: 

4041 Data bytes or ``None`` if request is not a POST. 

4042 """ 

4043 

4044 def text(self) -> Optional[str]: 

4045 """Get POST data as a text. 

4046 

4047 Returns: 

4048 Data string or ``None`` if request is not a POST. 

4049 """ 

4050 

4051 def content_responder(self, response: ContentResponse) -> 'WebResponder': 

4052 """Return a Responder object for a content response. 

4053 

4054 Args: 

4055 response: Response object. 

4056 

4057 Returns: 

4058 A Responder. 

4059 """ 

4060 

4061 def redirect_responder(self, response: RedirectResponse) -> 'WebResponder': 

4062 """Return a Responder object for a redirect response. 

4063 

4064 Args: 

4065 response: Response object. 

4066 

4067 Returns: 

4068 A Responder. 

4069 """ 

4070 

4071 def api_responder(self, response: Response) -> 'WebResponder': 

4072 """Return a Responder object for an Api (structured) response. 

4073 

4074 Args: 

4075 response: Response object. 

4076 

4077 Returns: 

4078 A Responder. 

4079 """ 

4080 

4081 def error_responder(self, exc: Exception) -> 'WebResponder': 

4082 """Return a Responder object for an Exception. 

4083 

4084 Args: 

4085 exc: An Exception. 

4086 

4087 Returns: 

4088 A Responder. 

4089 """ 

4090 

4091 def url_for(self, request_path: str, **kwargs) -> str: 

4092 """Return a canonical Url for the given request path. 

4093 

4094 Args: 

4095 request_path: Request path. 

4096 **kwargs: Additional GET parameters. 

4097 

4098 Returns: 

4099 An URL. 

4100 """ 

4101 

4102 def set_session(self, session: 'AuthSession'): 

4103 """Attach a session to the requester. 

4104 

4105 Args: 

4106 session: A Session object. 

4107 """ 

4108 

4109 

4110class WebResponder: 

4111 """Web Responder object.""" 

4112 

4113 status: int 

4114 """Response status.""" 

4115 

4116 def send_response(self, environ: dict, start_response: Callable): 

4117 """Send the response to the client. 

4118 

4119 Args: 

4120 environ: WSGI environment. 

4121 start_response: WSGI ``start_response`` function. 

4122 """ 

4123 

4124 def set_cookie(self, key: str, value: str, **kwargs): 

4125 """Set a cookie. 

4126 

4127 Args: 

4128 key: Cookie name. 

4129 value: Cookie value. 

4130 **kwargs: Cookie options. 

4131 """ 

4132 

4133 def delete_cookie(self, key: str, **kwargs): 

4134 """Delete a cookie. 

4135 

4136 Args: 

4137 key: Cookie name. 

4138 **kwargs: Cookie options. 

4139 """ 

4140 

4141 def set_status(self, status: int): 

4142 """Set the response status. 

4143 

4144 Args: 

4145 status: HTTP status code. 

4146 """ 

4147 

4148 def add_header(self, key: str, value: str): 

4149 """Add a header. 

4150 

4151 Args: 

4152 key: Header name. 

4153 value: Header value. 

4154 """ 

4155 

4156 

4157class WebDocumentRoot(Data): 

4158 """Web document root.""" 

4159 

4160 dir: DirPath 

4161 """Local directory.""" 

4162 allowMime: list[str] 

4163 """Allowed mime types.""" 

4164 denyMime: list[str] 

4165 """Restricted mime types.""" 

4166 

4167 

4168class WebRewriteRule(Data): 

4169 """Rewrite rule.""" 

4170 

4171 pattern: Regex 

4172 """URL matching pattern.""" 

4173 target: str 

4174 """Rule target, with dollar placeholders.""" 

4175 options: dict 

4176 """Extra options.""" 

4177 reversed: bool 

4178 """Reversed rewrite rule.""" 

4179 

4180 

4181class WebCors(Data): 

4182 """CORS options.""" 

4183 

4184 allowCredentials: bool 

4185 allowHeaders: str 

4186 allowMethods: str 

4187 allowOrigin: str 

4188 

4189 

4190class WebManager(Node): 

4191 """Web manager.""" 

4192 

4193 sites: list['WebSite'] 

4194 """Configured web sites.""" 

4195 

4196 def site_from_environ(self, environ: dict) -> 'WebSite': 

4197 """Returns a site object for the given request environment. 

4198 

4199 Args: 

4200 environ: WSGI environment. 

4201 

4202 Returns: 

4203 A Site object. 

4204 """ 

4205 

4206 

4207class WebSite(Node): 

4208 """Web site.""" 

4209 

4210 assetsRoot: Optional[WebDocumentRoot] 

4211 """Root directory for assets.""" 

4212 corsOptions: WebCors 

4213 """CORS options.""" 

4214 errorPage: Optional['Template'] 

4215 """Error page template.""" 

4216 host: str 

4217 """Host name for this site.""" 

4218 rewriteRules: list[WebRewriteRule] 

4219 """Rewrite rule.""" 

4220 staticRoot: WebDocumentRoot 

4221 """Root directory for static files.""" 

4222 

4223 def url_for(self, req: 'WebRequester', path: str, **kwargs) -> str: 

4224 """Rewrite a request path to an Url. 

4225 

4226 Args: 

4227 req: Web Requester. 

4228 path: Raw request path. 

4229 **kwargs: Extra GET params. 

4230 

4231 Returns: 

4232 A rewritten URL. 

4233 """ 

4234################################################################################ 

4235 

4236 

4237 

4238################################################################################ 

4239# /base/application/types.pyinc 

4240 

4241 

4242class MiddlewareManager(Node): 

4243 def register(self, obj: Node, name: str, depends_on: Optional[list[str]] = None): 

4244 """Register an object as a middleware.""" 

4245 

4246 def objects(self) -> list[Node]: 

4247 """Return a list of registered middleware objects.""" 

4248 

4249 

4250class Application(Node): 

4251 """The main Application object.""" 

4252 

4253 client: 'Client' 

4254 localeUids: list[str] 

4255 metadata: 'Metadata' 

4256 monitor: 'ServerMonitor' 

4257 version: str 

4258 versionString: str 

4259 defaultPrinter: 'Printer' 

4260 

4261 actionMgr: 'ActionManager' 

4262 authMgr: 'AuthManager' 

4263 databaseMgr: 'DatabaseManager' 

4264 modelMgr: 'ModelManager' 

4265 printerMgr: 'PrinterManager' 

4266 searchMgr: 'SearchManager' 

4267 storageMgr: 'StorageManager' 

4268 templateMgr: 'TemplateManager' 

4269 serverMgr: 'ServerManager' 

4270 webMgr: 'WebManager' 

4271 middlewareMgr: 'MiddlewareManager' 

4272 

4273 actions: list['Action'] 

4274 projects: list['Project'] 

4275 finders: list['Finder'] 

4276 templates: list['Template'] 

4277 printers: list['Printer'] 

4278 models: list['Model'] 

4279 owsServices: list['OwsService'] 

4280 

4281 def project(self, uid: str) -> Optional['Project']: 

4282 """Get a Project object by its uid.""" 

4283 

4284 def helper(self, ext_type: str) -> Optional['Node']: 

4285 """Get a Helper object by its extension type.""" 

4286 

4287 def developer_option(self, key: str): 

4288 """Get a value of a developer option.""" 

4289################################################################################