Best Python code snippet using playwright-python
markup.py
Source:markup.py
1# -*- coding: utf-8 -*-2#T. Lemberger, 20183import json4from xml.etree.ElementTree import fromstring5from copy import deepcopy6from typing import List7from collections import OrderedDict8from ..common.utils import xml_escape9from ..common.mapper import Catalogue10from ..predict.decode import Decoder11class AbstractElementSerializer(object):12 @staticmethod13 def make_element(inner_text):14 pass15 @staticmethod16 def mark_boundary(action):17 pass18 @staticmethod19 def map(tag, on_features, concept):20 pass21class XMLElementSerializer(AbstractElementSerializer):22 @staticmethod23 def make_element(tag, concepts, inner_text, scores):24 xml_string = ''25 if inner_text:26 attribute_list= {}27 attribute_score = {}28 for group in concepts:29 concept = concepts[group]30 score = int(scores[group] * 100)31 if concept != Catalogue.UNTAGGED:32 attribute, value = concept.for_serialization33 attribute_score[attribute] = score34 attribute_list[attribute] = value35 if attribute_list:36 xml_attributes = ' '.join(['{}="{}"'.format(a, attribute_list[a]) for a in attribute_list])37 xml_scores = ' '.join(['{}_score="{}"'.format(a, str(attribute_score[a])) for a in attribute_score])38 xml_string = "<{} {} {}>{}</{}>".format(tag, xml_attributes, xml_scores, inner_text, tag)39 else:40 xml_string = inner_text41 return xml_string # because both HTML and XML handled, working with strings is easier than return ET.tostring(xml_string)42 @staticmethod43 def mark_boundary(action): # in the future, it will accept a specific boundary but now only PANEL44 if action == 'open':45 return '<{}>'.format(Catalogue.PANEL_START.for_serialization) # discrepancy: here via Catalogue, whereas via param tag for elements46 elif action == 'close':47 return '</{}>'.format(Catalogue.PANEL_START.for_serialization)48class HTMLElementSerializer(AbstractElementSerializer):49 @staticmethod50 def make_element(tag, concepts, inner_text, scores):51 html_string = ''52 if inner_text:53 attribute_list = {}54 attribute_score = {}55 for group in concepts:56 concept = concepts[group]57 score = int(scores[group] * 100)58 if concept != Catalogue.UNTAGGED:59 attribute, value = concept.for_serialization60 attribute_list[attribute] = value61 attribute_score[attribute] = score62 if attribute_list:63 html_classes = ' '.join([a + "_" + attribute_list[a] for a in attribute_list])64 score_classes = ' '.join([a + "_score_" + str(attribute_score[a]) for a in attribute_score])65 html_string = "<span class=\"{} {} {}\">{}</span>".format(tag, html_classes, score_classes, inner_text)66 else:67 html_string = inner_text68 return html_string69 @staticmethod70 def mark_boundary(action): # in the future, it will accept a specific boundary but now only PANEL71 if action == 'open':72 return '<span class="{}">'.format(Catalogue.PANEL_START.for_serialization)73 elif action == 'close':74 return '</span>'75class AbstractTagger:76 def __init__(self, tag):77 self.tag = tag78 self.serialized_examples = []79 def serialize_element(self, current_concepts, inner_text, current_scores):80 raise NotImplementedError81 def serialize_boundary(self, action):82 raise NotImplementedError83 @property84 def opening_tag(self):85 raise NotImplementedError86 @property87 def closing_tag(self):88 raise NotImplementedError89 def panel_segmentation(self, char_level_panel_marks, token_list) -> List:90 panels = []91 indices = [i for i, c in enumerate(char_level_panel_marks) if c == Catalogue.PANEL_STOP]92 token_list = deepcopy(token_list)93 for i in indices:94 panel = []95 stop = 096 while stop < i:97 t = token_list.pop(0)98 panel.append(t)99 stop = t.stop100 panels.append(panel)101 rest= [t for t in token_list]102 if rest:103 panels.append(rest)104 return panels105 def serialize(self, decoded: Decoder) -> List[str]:106 ml_list = []107 for n in range(decoded.N):108 # INITIALIZATION FOR EACH EXAMPLE109 ml_string = ""110 inner_text = ""111 pos = 0112 num_open_elements = 0113 current_concepts = OrderedDict([(g, Catalogue.UNTAGGED) for g in decoded.semantic_groups]) # initialize with UNTAGGED?114 longitudinal_tagging_groups = deepcopy(decoded.semantic_groups)115 if 'panels' in longitudinal_tagging_groups:116 del longitudinal_tagging_groups['panels']117 need_to_open = OrderedDict([(g, False) for g in decoded.semantic_groups])118 need_to_close = OrderedDict([(g, False) for g in decoded.semantic_groups])119 need_to_open_any = False120 need_to_close_any = False121 current_scores = {g: 0 for g in decoded.semantic_groups}122 # PANELIZE IF NEEDED123 if 'panels' in decoded.semantic_groups:124 panels = self.panel_segmentation(decoded.char_level_concepts[n]['panels'], decoded.token_lists[n])125 open_tag = self.opening_tag126 closing_tag = self.closing_tag127 else:128 panels = [decoded.token_lists[n]]129 open_tag = ''130 closing_tag = ''131 # SERIALIZE EACH PANEL132 for panel in panels:133 if ml_string: # if in the middle of a multi-panel legend, 134 ml_string += panel[0].left_spacer # need first to add the spacer of first token of next panel135 ml_string += closing_tag # and close panel136 ml_string += open_tag137 for count, token in enumerate(panel):138 text = xml_escape(token.text)139 left_spacer = token.left_spacer if count > 0 else ""140 for group in longitudinal_tagging_groups: # scan across feature groups the features that need to be opened141 concept = decoded.concepts[n][group][pos]142 if concept != Catalogue.UNTAGGED and concept != current_concepts[group]: # a new concept143 need_to_open[group] = concept144 need_to_open_any = True145 if current_concepts[group] == Catalogue.UNTAGGED:146 num_open_elements += 1147 # print(f"2.inner_text: '{inner_text}', ml_string: '{ml_string}'"); import pdb; pdb.set_trace()148 if need_to_open_any:149 need_to_open_any = False150 tagged_string = self.serialize_element(current_concepts, inner_text, current_scores)151 ml_string += tagged_string + left_spacer # add the tagged alement to the nascent markup string152 inner_text = text153 # print(f"3.inner_text: '{inner_text}', ml_string: '{ml_string}'"); import pdb; pdb.set_trace()154 for group in longitudinal_tagging_groups:155 concept = decoded.concepts[n][group][pos]156 current_scores[group] = decoded.scores[n][group][pos]157 if need_to_open[group]: # CHANGED158 current_concepts[group] = concept159 need_to_open[group] = False160 elif current_concepts[group] != Catalogue.UNTAGGED and concept == Catalogue.UNTAGGED:161 num_open_elements -= 1162 163 # print(f"4.inner_text: '{inner_text}', ml_string: '{ml_string}'"); import pdb; pdb.set_trace()164 else:165 for group in longitudinal_tagging_groups:166 concept = decoded.concepts[n][group][pos]167 if current_concepts[group] != Catalogue.UNTAGGED and concept == Catalogue.UNTAGGED:168 need_to_close[group] = True169 need_to_close_any = True170 num_open_elements -= 1171 # print(f"5.inner_text: '{inner_text}', ml_string: '{ml_string}'"); import pdb; pdb.set_trace()172 if need_to_close_any:173 need_to_close_any = False174 tagged_string = self.serialize_element(current_concepts, inner_text, current_scores)175 ml_string += tagged_string + left_spacer176 inner_text = ''177 if num_open_elements > 0:178 inner_text = text179 else:180 ml_string += text181 # print(f"6.inner_text: '{inner_text}', ml_string: '{ml_string}'"); import pdb; pdb.set_trace()182 for group in longitudinal_tagging_groups:183 if need_to_close[group]:184 need_to_close[group] = False185 current_concepts[group] = Catalogue.UNTAGGED186 current_scores[group] = 0187 else:188 if num_open_elements > 0:189 inner_text += left_spacer + text190 else:191 ml_string += left_spacer + text192 pos += 1193 if num_open_elements > 0:194 tagged_string = self.serialize_element(current_concepts, inner_text, current_scores)195 # print(f"7.inner_text: '{inner_text}', ml_string: '{ml_string}'"); import pdb; pdb.set_trace()196 ml_string += closing_tag # hmm in principle left spacer of first token of next panel should go in here197 #phew!198 ml_list.append(ml_string)199 return ml_list200class XMLTagger(AbstractTagger):201 def __init__(self, tag):202 super(XMLTagger, self).__init__(tag)203 @property204 def opening_tag(self):205 return '<sd-panel>'206 @property207 def closing_tag(self):208 return '</sd-panel>'209 def serialize_element(self, on_features, inner_text, current_scores):210 return XMLElementSerializer.make_element(self.tag, on_features, inner_text, current_scores)211 def serialize_boundary(self, action): # preliminary naive implementation...212 return XMLElementSerializer.mark_boundary(action)213 def serialize(self, decoded_pred: Decoder) -> List[str]:214 xml_string_list = super(XMLTagger, self).serialize(decoded_pred)215 # need to provide valid xml216 xml_string_list = [f"<smtag>{x}</smtag>" for x in xml_string_list]217 return xml_string_list218class HTMLTagger(AbstractTagger):219 def __init__(self, tag):220 super(HTMLTagger, self).__init__(tag)221 @property222 def opening_tag(self):223 return '<li class="sd-panel">'224 @property225 def closing_tag(self):226 return '</li>'227 def serialize_element(self, on_features, inner_text, current_scores):228 return HTMLElementSerializer.make_element(self.tag, on_features, inner_text, current_scores)229 def serialize_boundary(self, action):230 return HTMLElementSerializer.mark_boundary(action)231 def serialize(self, decoded_pred: Decoder) -> List[str]:232 html_string_list = super(HTMLTagger, self).serialize(decoded_pred)233 html_string_list = [f"<ul>{x}</ul>" for x in html_string_list]234 return html_string_list235class JSONTagger(XMLTagger):236 def __init__(self, tag):237 super(JSONTagger, self).__init__(tag)238 def serialize(self, decoded_pred: Decoder) -> List[str]:239 xml_string_list: List[str] = super(JSONTagger, self).serialize(decoded_pred)240 js_list = []241 for xml_string in xml_string_list:242 j = {243 'smtag': []244 }245 xml = fromstring(xml_string)246 panels = xml.findall('sd-panel')247 if not panels:248 panels = [xml]249 for panel in panels:250 entities = []251 for e in panel.findall(self.tag):252 entity = e.attrib253 entity['text'] = e.text254 if entity not in entities:255 entities.append(entity)256 j['smtag'].append({'entities': entities})257 js = json.dumps(j)258 js_list.append(js)259 return js_list260class Serializer():261 def __init__(self, tag, format = 'xml'):262 self.tag = tag263 self.format = format.lower()264 assert format in ['xml', 'html', 'json'], f"unknown format: {self.format}"265 def serialize(self, decoded_pred):266 if self.format == 'html':267 s = HTMLTagger(self.tag)268 elif self.format == 'xml': # elif self.format == 'xml':269 s = XMLTagger(self.tag)270 elif self.format == 'json':271 s = JSONTagger(self.tag)...
matdocparser.py
Source:matdocparser.py
1#!/usr/bin/python2# file: matdocparser.py3# author: Andrea Vedaldi4# description: Utility to format MATLAB comments.5# Copyright (C) 2014-15 Andrea Vedaldi.6# All rights reserved.7#8# This file is part of the VLFeat library and is made available under9# the terms of the BSD license (see the COPYING file).10"""11MatDocParser is an interpreter for the MatDoc format. This is a simplified and12stricter version of Markdown suitable to commenting MATLAB functions. the format13is easily understood from an example:14A paragraph starts on a new line.15And continues on following lines.16Indenting with a whitespace introduces a verbatim code section:17 Like this18 This continues it19Different paragraphs are separated by blank lines.20* The *, -, + symbols at the beginning of a line introduce a list.21 Which can be continued on follwing paragraphs by proper indentation.22 Multiple paragraphs in a list item are also supported.23* This is the second item of the same list.24It is also possible to have definition lists such as25Term1:: Short description 226 Longer explanation.27 Behaves like a list item.28Term2:: Short description 229Term3:: Short description 330 Longer explanations are optional.31# Lines can begin with # to denote a title32## Is a smaller title33"""34import sys35import os36import re37__mpname__ = 'MatDocParser'38__version__ = '1.0-beta15'39__date__ = '2015-09-20'40__description__ = 'MatDoc MATLAB inline function description interpreter.'41__long_description__ = __doc__42__license__ = 'BSD'43__author__ = 'Andrea Vedaldi'44# --------------------------------------------------------------------45# Input line types (terminal symbols)46# --------------------------------------------------------------------47# Terminal symbols are organized in a hierarchy. Each line in the48# input document is mapped to leaf in this hierarchy, representing49# the type of line detected.50class Symbol(object):51 indent = None52 def isa(self, classinfo, indent = None):53 return isinstance(self, classinfo) and \54 (indent is None or self.indent == indent)55 def __str__(self, indent = 0):56 if self.indent is not None: x = "%d" % self.indent57 else: x = "*"58 return " "*indent + "%s(%s)" % (self.__class__.__name__, x)59# Terminal symbols60# Note that PL, BH, DH are all subclasses of L; the fields .text and .indent61# have the same meaning for all of them.62class Terminal(Symbol): pass63class EOF (Terminal): pass # end-of-file64class B (Terminal): pass # blank linke65class L (Terminal): # non-empty line: '<" "*indent><text>'66 text = ""67 def __str__(self, indent = 0):68 return "%s: %s" % (super(L, self).__str__(indent), self.text)69class PL (L): pass # regular line70class BH (L): # bullet: a line of type ' * <inner_text>'71 inner_indent = None72 inner_text = None73 bullet = None74class DH (L): # description: a line of type ' <description>::<inner_text>'75 inner_text = None76 description = None77 def __str__(self, indent = 0):78 return "%s: '%s' :: '%s'" % (super(L, self).__str__(indent),79 self.description, self.inner_text)80class SL (L): # section: '<#+><text>'81 section_level = 082 inner_text = None83 def __str__(self, indent = 0):84 return "%s: %s" % (super(L, self).__str__(indent), self.inner_text)85# A lexer object: parse lines of the input document into terminal symbols86class Lexer(object):87 def __init__(self, lines):88 self.lines = lines89 self.pos = -190 def next(self):91 self.pos = self.pos + 192 # no more93 if self.pos > len(self.lines)-1:94 x = EOF()95 return x96 line = self.lines[self.pos]97 # a blank line98 match = re.match(r"\s*\n?$", line) ;99 if match:100 return B()101 # a line of type ' <#+><inner_text>'102 match = re.match(r"(\s*)(#+)(.*)\n?$", line)103 if match:104 x = SL()105 x.indent = len(match.group(1))106 x.section_level = len(match.group(2))107 x.inner_text = match.group(3)108 #print x.indent, x.section_level, x.inner_text109 return x110 # a line of type ' <content>::<inner_text>'111 match = re.match(r"(\s*)(.*)::(.*)\n?$", line)112 if match:113 x = DH()114 x.indent = len(match.group(1))115 x.description = match.group(2)116 x.inner_text = match.group(3)117 x.text = x.description + "::" + x.inner_text118 return x119 # a line of type ' * <inner_contet>'120 match = re.match(r"(\s*)([-\*+]\s*)(\S.*)\n?$", line)121 if match:122 x = BH()123 x.indent = len(match.group(1))124 x.bullet = match.group(2)125 x.inner_indent = x.indent + len(x.bullet)126 x.inner_text = match.group(3)127 x.text = x.bullet + x.inner_text128 return x129 # a line of the type ' <content>'130 match = re.match(r"(\s*)(\S.*)\n?$", line)131 if match:132 x = PL()133 x.indent = len(match.group(1))134 x.text = match.group(2)135 return x136# --------------------------------------------------------------------137# Non-terminal138# --------------------------------------------------------------------139# DIVL is a consecutive list of blocks with the same indent and/or blank140# lines.141#142# DIVL(indent) -> (B | SL(indent) | P(indent) | V(indent) |143# BL(indent) | DL(indent))+144#145# S(indent) -> SL(indent)146#147# A P(indent) is a paragraph, a list of regular lines indentent by the148# same amount.149#150# P(indent) -> PL(indent)+151#152# A V(indent) is a verbatim (code) block. It contains text lines and blank153# lines that have indentation strictly larger than `indent`:154#155# V(indent) -> L(i) (B | L(j), j > indent)+, for all i > indent156#157# A DL(indent) is a description list:158#159# DL(indent) -> DH(indent) DIVL(i)*, i > indent160#161# A BL(indent) is a bullet list. It contains bullet list items, namely162# a sequence of special DIVL_BH(indent,inner_indent) whose first block163# is a paragaraph P_BH(indent,inner_indent) whose first line is a164# bullet header BH(indent,innner_indent). Here the bullet identation165# inner_indent is obtained as the inner_indent of the166# BH(indent,inner_indent) symbol. Formalising this with grammar rules167# is verbose; instead we use the simple `hack' of defining168#169# BL(indent) -> (DIVL(inner_indent))+170#171# where DIVL(inner_indent) are regular DIVL, obtaine after replacing172# the bullet header line BH with a standard paragraph line PL.173class NonTerminal(Symbol):174 children = []175 def __init__(self, *args):176 self.children = list(args)177 def __str__(self, indent = 0):178 s = " "*indent + super(NonTerminal, self).__str__() + "\n"179 for c in self.children:180 s += c.__str__(indent + 2) + "\n"181 return s[:-1]182class S(NonTerminal): pass183class DIVL(NonTerminal): pass184class DIV(NonTerminal): pass185class BL(NonTerminal): pass186class DL(NonTerminal): pass187class DI(NonTerminal): pass188class P(DIV): pass189class V(DIV): pass190# --------------------------------------------------------------------191class Parser(object):192 lexer = None193 stack = []194 lookahead = None195 def shift(self):196 if self.lookahead:197 self.stack.append(self.lookahead)198 self.lookahead = self.lexer.next()199 def reduce(self, X, n, indent = None):200 #print "reducing %s with %d" % (S.__name__, n)201 x = X(*self.stack[-n:])202 del self.stack[-n:]203 x.indent = indent204 self.stack.append(x)205 return x206 def parse(self, lexer):207 self.lexer = lexer208 self.stack = []209 while True:210 self.lookahead = self.lexer.next()211 if not self.lookahead.isa(B): break212 self.parse_DIVL(self.lookahead.indent)213 return self.stack[0]214 def parse_SL(self, indent):215 self.shift()216 self.reduce(S, 1, indent)217 def parse_P(self, indent):218 i = 0219 if indent is None: indent = self.lookahead.indent220 while self.lookahead.isa(PL, indent):221 self.shift()222 i = i + 1223 self.reduce(P, i, indent)224 def parse_V(self, indent):225 i = 0226 while (self.lookahead.isa(L) and self.lookahead.indent > indent) or \227 (self.lookahead.isa(B)):228 self.shift()229 i = i + 1230 self.reduce(V, i, indent)231 def parse_DIV_helper(self, indent):232 if self.lookahead.isa(SL, indent):233 self.parse_SL(indent)234 elif self.lookahead.isa(PL, indent):235 self.parse_P(indent)236 elif self.lookahead.isa(L) and (self.lookahead.indent > indent):237 self.parse_V(indent)238 elif self.lookahead.isa(BH, indent):239 self.parse_BL(indent)240 elif self.lookahead.isa(DH, indent):241 self.parse_DL(indent)242 elif self.lookahead.isa(B):243 self.shift()244 else:245 return False246 # leaves with B, P(indent), V(indent), BL(indent) or DL(indent)247 return True248 def parse_BI_helper(self, indent):249 x = self.lookahead250 if not x.isa(BH, indent): return False251 indent = x.inner_indent252 self.lookahead = PL()253 self.lookahead.text = x.inner_text254 self.lookahead.indent = indent255 self.parse_DIVL(indent)256 # leaves with DIVL(inner_indent) where inner_indent was257 # obtained from the bullet header symbol258 return True259 def parse_BL(self, indent):260 i = 0261 while self.parse_BI_helper(indent): i = i + 1262 if i == 0: print "Error", sys.exit(1)263 self.reduce(BL, i, indent)264 def parse_DI_helper(self, indent):265 if not self.lookahead.isa(DH, indent): return False266 self.shift()267 if self.lookahead.indent > indent:268 self.parse_DIVL(self.lookahead.indent)269 self.reduce(DI, 2, indent)270 else:271 self.reduce(DI, 1, indent)272 return True273 def parse_DL(self, indent):274 i = 0275 while self.parse_DI_helper(indent): i = i + 1276 if i == 0: print "Error", sys.exit(1)277 self.reduce(DL, i, indent)278 def parse_DIVL(self, indent = None):279 i = 0280 while self.parse_DIV_helper(indent):281 if indent is None: indent = self.stack[-1].indent282 i = i + 1283 self.reduce(DIVL, i, indent)284if __name__ == '__main__':285 str="""286Some text describing a MATLAB function F().287The function F() does nothing.288It has the following options:289CarryOn:: True290 Keep doing nothing for the time being.291Stop:: 'here'292 Stop doing whathever here. Example:293 % call the function294 f('stop', 'there')295 % contemplate the results296So in short we conclude that:297* This does nothing298* It could do something,299 but still does not.300 #301See also: hope for the best.302# Section number one303Bla304## More Sect305### Even more306blo307"""308 parser = Parser()309 lexer = Lexer(str.split('\n'))310 tree = parser.parse(lexer)...
website.py
Source:website.py
1# Copyright (c) 2013 Amazon.com, Inc. or its affiliates. All Rights Reserved2#3# Permission is hereby granted, free of charge, to any person obtaining a4# copy of this software and associated documentation files (the5# "Software"), to deal in the Software without restriction, including6# without limitation the rights to use, copy, modify, merge, publish, dis-7# tribute, sublicense, and/or sell copies of the Software, and to permit8# persons to whom the Software is furnished to do so, subject to the fol-9# lowing conditions:10#11# The above copyright notice and this permission notice shall be included12# in all copies or substantial portions of the Software.13#14# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS15# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-16# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT17# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,18# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,19# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20# IN THE SOFTWARE.21#22def tag(key, value):23 start = '<%s>' % key24 end = '</%s>' % key25 return '%s%s%s' % (start, value, end)26class WebsiteConfiguration(object):27 """28 Website configuration for a bucket.29 :ivar suffix: Suffix that is appended to a request that is for a30 "directory" on the website endpoint (e.g. if the suffix is31 index.html and you make a request to samplebucket/images/32 the data that is returned will be for the object with the33 key name images/index.html). The suffix must not be empty34 and must not include a slash character.35 :ivar error_key: The object key name to use when a 4xx class error36 occurs. This key identifies the page that is returned when37 such an error occurs.38 :ivar redirect_all_requests_to: Describes the redirect behavior for every39 request to this bucket's website endpoint. If this value is non None,40 no other values are considered when configuring the website41 configuration for the bucket. This is an instance of42 ``RedirectLocation``.43 :ivar routing_rules: ``RoutingRules`` object which specifies conditions44 and redirects that apply when the conditions are met.45 """46 WEBSITE_SKELETON = """<?xml version="1.0" encoding="UTF-8"?>47 <WebsiteConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">48 %(body)s49 </WebsiteConfiguration>"""50 def __init__(self, suffix=None, error_key=None,51 redirect_all_requests_to=None, routing_rules=None):52 self.suffix = suffix53 self.error_key = error_key54 self.redirect_all_requests_to = redirect_all_requests_to55 self.routing_rules = routing_rules56 def to_xml(self):57 body_parts = []58 if self.suffix is not None:59 body_parts.append(tag('IndexDocument', tag('Suffix', self.suffix)))60 if self.error_key is not None:61 body_parts.append(tag('ErrorDocument', tag('Key', self.error_key)))62 if self.redirect_all_requests_to is not None:63 body_parts.append(self.redirect_all_requests_to.to_xml())64 if self.routing_rules is not None:65 body_parts.append(self.routing_rules.to_xml())66 body = '\n'.join(body_parts)67 return self.WEBSITE_SKELETON % {'body': body}68class RedirectLocation(object):69 """Specify redirect behavior for every request to a bucket's endpoint.70 :ivar hostname: Name of the host where requests will be redirected.71 :ivar protocol: Protocol to use (http, https) when redirecting requests.72 The default is the protocol that is used in the original request.73 """74 def __init__(self, hostname, protocol=None):75 self.hostname = hostname76 self.protocol = protocol77 def to_xml(self):78 inner_text = []79 if self.hostname is not None:80 inner_text.append(tag('HostName', self.hostname))81 if self.protocol is not None:82 inner_text.append(tag('Protocol', self.protocol))83 return tag('RedirectAllRequestsTo', '\n'.join(inner_text))84class RoutingRules(object):85 def __init__(self):86 self._rules = []87 def add_rule(self, rule):88 """89 :type rule: :class:`boto.s3.website.RoutingRule`90 :param rule: A routing rule.91 :return: This ``RoutingRules`` object is returned,92 so that it can chain subsequent calls.93 """94 self._rules.append(rule)95 return self96 def to_xml(self):97 inner_text = []98 for rule in self._rules:99 inner_text.append(rule.to_xml())100 return tag('RoutingRules', '\n'.join(inner_text))101class RoutingRule(object):102 """Represents a single routing rule.103 There are convenience methods to making creating rules104 more concise::105 rule = RoutingRule.when(key_prefix='foo/').then_redirect('example.com')106 :ivar condition: Describes condition that must be met for the107 specified redirect to apply.108 :ivar redirect: Specifies redirect behavior. You can redirect requests to109 another host, to another page, or with another protocol. In the event110 of an error, you can can specify a different error code to return.111 """112 def __init__(self, condition, redirect):113 self.condition = condition114 self.redirect = redirect115 def to_xml(self):116 return tag('RoutingRule',117 self.condition.to_xml() + self.redirect.to_xml())118 @classmethod119 def when(cls, key_prefix=None, http_error_code=None):120 return cls(Condition(key_prefix=key_prefix,121 http_error_code=http_error_code), None)122 def then_redirect(self, hostname=None, protocol=None, replace_key=None,123 replace_key_prefix=None, http_redirect_code=None):124 self.redirect = Redirect(125 hostname=hostname, protocol=protocol,126 replace_key=replace_key,127 replace_key_prefix=replace_key_prefix,128 http_redirect_code=http_redirect_code)129 return self130class Condition(object):131 """132 :ivar key_prefix: The object key name prefix when the redirect is applied.133 For example, to redirect requests for ExamplePage.html, the key prefix134 will be ExamplePage.html. To redirect request for all pages with the135 prefix docs/, the key prefix will be /docs, which identifies all136 objects in the docs/ folder.137 :ivar http_error_code: The HTTP error code when the redirect is applied. In138 the event of an error, if the error code equals this value, then the139 specified redirect is applied.140 """141 def __init__(self, key_prefix=None, http_error_code=None):142 self.key_prefix = key_prefix143 self.http_error_code = http_error_code144 def to_xml(self):145 inner_text = []146 if self.key_prefix is not None:147 inner_text.append(tag('KeyPrefixEquals', self.key_prefix))148 if self.http_error_code is not None:149 inner_text.append(150 tag('HttpErrorCodeReturnedEquals',151 self.http_error_code))152 return tag('Condition', '\n'.join(inner_text))153class Redirect(object):154 """155 :ivar hostname: The host name to use in the redirect request.156 :ivar protocol: The protocol to use in the redirect request. Can be either157 'http' or 'https'.158 :ivar replace_key: The specific object key to use in the redirect request.159 For example, redirect request to error.html.160 :ivar replace_key_prefix: The object key prefix to use in the redirect161 request. For example, to redirect requests for all pages with prefix162 docs/ (objects in the docs/ folder) to documents/, you can set a163 condition block with KeyPrefixEquals set to docs/ and in the Redirect164 set ReplaceKeyPrefixWith to /documents.165 :ivar http_redirect_code: The HTTP redirect code to use on the response.166 """167 def __init__(self, hostname=None, protocol=None, replace_key=None,168 replace_key_prefix=None, http_redirect_code=None):169 self.hostname = hostname170 self.protocol = protocol171 self.replace_key = replace_key172 self.replace_key_prefix = replace_key_prefix173 self.http_redirect_code = http_redirect_code174 def to_xml(self):175 inner_text = []176 if self.hostname is not None:177 inner_text.append(tag('HostName', self.hostname))178 if self.protocol is not None:179 inner_text.append(tag('Protocol', self.protocol))180 if self.replace_key is not None:181 inner_text.append(tag('ReplaceKeyWith', self.replace_key))182 if self.replace_key_prefix is not None:183 inner_text.append(tag('ReplaceKeyPrefixWith',184 self.replace_key_prefix))185 if self.http_redirect_code is not None:186 inner_text.append(tag('HttpRedirectCode', self.http_redirect_code))...
LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!