How to use _subresources method in localstack

Best Python code snippet using localstack_python

webarchive.py

Source:webarchive.py Github

copy

Full Screen

1"""WebArchive class implementation."""2import os3import io4import plistlib5import mimetypes6from urllib.parse import urlparse, urljoin7from .exceptions import WebArchiveError8from .webresource import WebResource9from .util import (is_html_mime_type,10 process_css_resource, process_html_resource)11__all__ = ["WebArchive"]12class WebArchive(object):13 """An archive storing a webpage's content and embedded external media.14 A webarchive consists of the following elements:15 * A main resource (required). This is a WebResource object storing16 the page's HTML content.17 * Subresources (optional). These are WebResource objects storing18 external media like images, scripts, and style sheets.19 * Subframe archives (optional). These are nested WebArchive objects20 storing other webpages displayed in HTML frames.21 You can examine these resources using this class's main_resource,22 subresources, and subframe_archives properties, respectively.23 The main operation of interest on webarchives is extraction, which24 here simply means converting the webarchive to a standard HTML page.25 See the extract() method's documentation for details.26 Note: You should always use webarchive.open() to access a webarchive27 file rather than instantiate this class directly.28 """29 __slots__ = ["_parent",30 "_main_resource", "_subresources", "_subframe_archives",31 "_local_paths"]32 def __init__(self, parent=None):33 """Return a new WebArchive object.34 You should always use webarchive.open() to access a WebArchive35 rather than instantiate this class directly, since the constructor36 arguments may change in a future release.37 """38 self._parent = parent39 self._main_resource = None40 self._subresources = []41 self._subframe_archives = []42 # Basenames for extracted subresources, indexed by (absolute) URL43 #44 # This also contains entries for the main resources, but not45 # subresources, of any subframe archives.46 #47 # Each subframe archive has its own local paths dictionary so it48 # can be extracted independently of its parent archive.49 self._local_paths = {}50 def __del__(self):51 """Clean up before deleting this object."""52 self.close()53 def __enter__(self):54 """Enter the runtime context."""55 return self56 def __exit__(self, exc_type, exc_value, traceback):57 """Exit the runtime context."""58 self.close()59 return False # process any raised exception normally60 def close(self):61 """Close this webarchive."""62 # This currently does nothing, but is provided for semantic63 # compatibility with io.open().64 pass65 def extract(self, output_path, embed_subresources=False,66 *, before_cb=None, after_cb=None, canceled_cb=None):67 """Extract this webarchive.68 Extraction converts a webarchive to a standard HTML document.69 The resulting document should look and behave identically to the70 original webarchive file as displayed by Safari (apart from the71 usual rendering differences if you are using a different browser).72 External media such as images, scripts, and style sheets are73 handled as follows:74 * If embed_subresources is False (the default), this archive's75 subresources will be saved as individual files. References76 to those resources will be rewritten to use the local copies.77 This is how the "Save As" command in other browsers like78 Mozilla Firefox usually works.79 * If embed_subresources is True, subresources will be embedded80 inline using data URIs. This allows the entire page to be81 stored in a single file, mimicking the webarchive format's82 main feature, with full cross-browser support but much lower83 efficiency. Be aware that this typically requires more disk84 space and processing time than extracting to separate files.85 * Regardless of the above setting, references to media not86 stored as subresources will be replaced with absolute URLs.87 To allow monitoring or canceling an extraction in process, you88 can specify callback functions for the following keyword arguments:89 before_cb(res, path)90 Called just before extracting a WebResource. No return value.91 - res is the WebResource object to be extracted.92 - path is the absolute path where it will be extracted.93 after_cb(res, path)94 Called just after extracting a WebResource. No return value.95 - res is the WebResource object that was extracted.96 - path is the absolute path where it was extracted.97 canceled_cb()98 Called periodically to check if extraction was canceled99 by the user. Should return True to cancel, False otherwise.100 If an error occurs during extraction, this will raise a101 WebArchiveError with a message explaining what went wrong.102 """103 # Note: _extract_main_resource() checks that an archive actually104 # has a main resource, and raises an exception if it's missing.105 # The embed_subresources argument was previously named single_file.106 # Since it is intended to be used as a positional rather than a107 # keyword argument, I think this is an acceptable change to provide108 # a more descriptive name for this feature. However, this does break109 # backwards compatibility for any code passing single_file as a110 # keyword argument against our intentions.111 if canceled_cb and canceled_cb():112 return113 def BEFORE(res, path):114 if before_cb:115 before_cb(res, path)116 def AFTER(res, path):117 if after_cb:118 after_cb(res, path)119 # Strip the extension from the output path120 base, ext = os.path.splitext(os.path.basename(output_path))121 if embed_subresources:122 # Extract the main resource, embedding subresources recursively123 # using data URIs124 BEFORE(self._main_resource, output_path)125 self._extract_main_resource(output_path, None)126 AFTER(self._main_resource, output_path)127 else:128 # Make sure all subresources have local paths129 # (this is redundant for read-only archives, but could be130 # useful if pywebarchive ever implements write support)131 self._make_local_paths()132 # Basename of the directory containing extracted subresources133 subresource_dir_base = "{0}_files".format(base)134 # Full path to the directory containing extracted subresources135 subresource_dir = os.path.join(os.path.dirname(output_path),136 subresource_dir_base)137 # Extract the main resource138 BEFORE(self._main_resource, output_path)139 self._extract_main_resource(output_path, subresource_dir_base)140 AFTER(self._main_resource, output_path)141 # Make a directory for subresources142 if self._subresources or self._subframe_archives:143 os.makedirs(subresource_dir, exist_ok=True)144 # Extract subresources145 for res in self._subresources:146 # Full path to the extracted subresource147 subresource_path = os.path.join(subresource_dir,148 self._local_paths[res.url])149 if canceled_cb and canceled_cb():150 return151 # Extract this subresource152 BEFORE(res, subresource_path)153 self._extract_subresource(res, subresource_path)154 AFTER(res, subresource_path)155 # Recursively extract subframe archives156 for subframe_archive in self._subframe_archives:157 # We test this here to stop processing further subframe158 # archives; the nested calls to extract() will separately159 # test this to stop subresource extraction.160 if canceled_cb and canceled_cb():161 return162 sf_main = subframe_archive._main_resource163 sf_local_path = os.path.join(subresource_dir,164 self._local_paths[sf_main.url])165 subframe_archive.extract(sf_local_path,166 embed_subresources,167 before_cb=before_cb,168 after_cb=after_cb,169 canceled_cb=canceled_cb)170 def get_local_path(self, url):171 """Return the local path for the subresource at the specified URL.172 The local path is the basename for the file that would be created173 for this subresource if this archive were extracted.174 If no such subresource exists in this archive, this will raise175 a WebArchiveError exception.176 """177 if url in self._local_paths:178 return self._local_paths[url]179 else:180 raise WebArchiveError("no local path for the specified URL")181 def get_subframe_archive(self, url):182 """Return the subframe archive for the specified URL.183 If no such subframe archive exists in this archive, this will184 raise a WebArchiveError exception.185 """186 if not "://" in url:187 raise WebArchiveError("must specify an absolute URL")188 for subframe_archive in self._subframe_archives:189 if subframe_archive.main_resource.url == url:190 return subframe_archive191 else:192 raise WebArchiveError("no subframe archive for the specified URL")193 def get_subresource(self, url):194 """Return the subresource at the specified URL.195 If no such subresource exists in this archive, this will raise196 a WebArchiveError exception.197 """198 if not "://" in url:199 raise WebArchiveError("must specify an absolute URL")200 for subresource in self._subresources:201 if subresource.url == url:202 return subresource203 else:204 raise WebArchiveError("no subresource for the specified URL")205 def resource_count(self):206 """Return the total number of WebResources in this archive.207 This includes WebResources in subframe archives.208 """209 res_count = 0210 # Just because we should have a main resource doesn't mean we do211 if self._main_resource:212 res_count += 1213 res_count += len(self._subresources)214 for subframe_archive in self._subframe_archives:215 res_count += subframe_archive.resource_count()216 return res_count217 def to_html(self):218 """Return this archive's contents as an HTML document.219 Subresources will be embedded recursively using data URIs,220 as they are when extracting the archive in single-file mode.221 """222 if not self._main_resource:223 raise WebArchiveError("archive does not have a main resource")224 with io.StringIO() as output:225 process_html_resource(self._main_resource, output, None)226 return output.getvalue()227 def _extract_main_resource(self, output_path, subresource_dir):228 """Extract the archive's main resource."""229 main_resource = self._main_resource230 if not main_resource:231 raise WebArchiveError("archive does not have a main resource")232 if is_html_mime_type(main_resource.mime_type):233 with io.open(output_path, "w",234 encoding=main_resource.text_encoding) as output:235 process_html_resource(main_resource, output, subresource_dir)236 else:237 # Non-HTML main resources are possible; for example, I have238 # one from YouTube where the main resource is JavaScript.239 with io.open(output_path, "wb") as output:240 output.write(bytes(main_resource))241 def _extract_subresource(self, res, output_path):242 """Extract the specified subresource from the archive."""243 if res.mime_type == "text/css":244 with io.open(output_path, "w",245 encoding=res.text_encoding) as output:246 # URLs in CSS are resolved relative to the style sheet's247 # location, and in our case all subresources are extracted248 # to the same directory.249 process_css_resource(res, output, "")250 elif is_html_mime_type(res.mime_type):251 # HTML subresources are weird, but possible252 with io.open(output_path, "w",253 encoding=res.text_encoding) as output:254 process_html_resource(res, output, "")255 else:256 # Extract other subresources as-is257 with io.open(output_path, "wb") as output:258 output.write(bytes(res))259 def _get_absolute_url(self, url, base=None):260 """Return the absolute URL to the specified resource.261 Relative URLs are resolved from the main resource's URL262 unless an alternative base is specified. For example,263 URLs in CSS files are resolved relative to the style sheet.264 """265 if not base:266 # Rewrite URLs relative to this archive's main resource267 base = self._main_resource.url268 elif not "://" in base:269 raise WebArchiveError("base must be an absolute URL")270 return urljoin(base, url)271 def _get_local_url(self, subresource_dir, orig_url, base=None):272 """Return a (preferably local) URL for the specified resource.273 This is used to rewrite subresource URLs in HTML and CSS274 resources when extracting a webarchive.275 Relative URLs are resolved from the main resource's URL276 unless an alternative base is specified. For example,277 URLs in CSS files are resolved relative to the style sheet.278 If the resource exists in this archive, this will return its279 local path if subresource_dir is a string, or a data URI280 otherwise. If the resource is not in this archive, this will281 return its absolute URL, so the extracted page will still282 display correctly so long as the original remains available.283 Note: If subresource_dir == '', this returns a local path284 relative to the current directory; this is used when rewriting285 url() values in style sheets. This is deliberately distinct286 from if subresource_dir is None, which returns a data URI.287 """288 # Get the absolute URL of the original resource289 abs_url = self._get_absolute_url(orig_url, base)290 try:291 if subresource_dir is None:292 # Single-file extraction mode293 res = self.get_subresource(abs_url)294 return res.to_data_uri()295 else:296 # Multi-file extraction mode297 local_path = self.get_local_path(abs_url)298 if subresource_dir:299 return "{0}/{1}".format(subresource_dir, local_path)300 else:301 return local_path302 except (WebArchiveError):303 # Resource not in archive; return its absolute URL304 return abs_url305 def _make_local_path(self, res):306 """Returns a local path for the specified WebResource."""307 # Basename for the extracted resource308 base = ""309 if res.url:310 # Parse the resource's URL311 parsed_url = urlparse(res.url)312 if parsed_url.scheme == "data":313 # Data URLs are anonymous, so assign a default basename314 base = "data_url"315 else:316 # Get the basename of the URL path317 url_path_basename = os.path.basename(parsed_url.path)318 base, ext = os.path.splitext(url_path_basename)319 if not base:320 # No URL, or blank URL path (why would this occur?)321 base = "blank_url"322 # Files served over HTTP(S) can have any extension, or none at323 # all, because the Content-type header indicates what type of324 # data they contain. However, local files don't have HTTP headers,325 # so browsers rely on file extensions to determine their types.326 # We should thus choose extensions they'll be likely to recognize.327 ext = mimetypes.guess_extension(res.mime_type)328 if not ext:329 ext = ""330 # Certain characters can cause problems in local paths.331 # "%" is used as an escape character in URLs, and both forward-332 # and backslashes are common directory separators. The other333 # characters are forbidden on Windows and some Unix filesystems.334 for c in "%", "<", ">", ":", '"', "/", "\\", "|", "?", "*":335 base = base.replace(c, "_")336 # Windows also doesn't allow certain reserved names that were337 # historically used for DOS devices. Even if we're not running338 # on Windows, it's better to avoid these names anyway in case339 # our extracted files are later copied over to a Windows system.340 if (base.lower() in ("con", "prn", "aux", "nul")341 or (len(base) == 4342 and base[:3].lower() in ("com", "lpt")343 and base[3].isdigit())):344 base = "{0}_".format(base)345 # Re-join the base and extension346 local_path = "{0}{1}".format(base, ext)347 # Append a copy number if needed to ensure a unique basename348 copy_num = 1349 while local_path in self._local_paths.values():350 copy_num += 1351 local_path = "{0}.{1}{2}".format(base, copy_num, ext)352 # Save this resource's local path353 self._local_paths[res.url] = local_path354 return local_path355 def _make_local_paths(self):356 """Make local paths for all of this archive's resources."""357 resources = []358 # This check is to safely handle archives without a main resource.359 # A well-formed webarchive should always have one, but this isn't360 # the place to enforce that.361 if self._main_resource:362 resources.append(self._main_resource)363 for subresource in self._subresources:364 resources.append(subresource)365 # The main resource of a subframe archive is effectively also366 # a subresource, so we include entries for those here367 for subframe_archive in self._subframe_archives:368 resources.append(subframe_archive._main_resource)369 # Generate local paths for any URLs we don't have them for370 for res in resources:371 if not res.url in self._local_paths:372 self._local_paths[res.url] = self._make_local_path(res)373 def _populate_from_plist_data(self, archive_data):374 """Populate this webarchive using parsed data from plistlib."""375 # Property names:376 # - WebMainResource377 # - WebSubresources378 # - WebSubframeArchives379 # Process the main resource380 self._main_resource = WebResource._create_from_plist_data(381 archive_data["WebMainResource"], self382 )383 # Process subresources384 if "WebSubresources" in archive_data:385 for res_data in archive_data["WebSubresources"]:386 res = WebResource._create_from_plist_data(res_data, self)387 self._subresources.append(res)388 # Process subframe archives389 if "WebSubframeArchives" in archive_data:390 for sa_data in archive_data["WebSubframeArchives"]:391 sa = WebArchive._create_from_plist_data(sa_data, self)392 self._subframe_archives.append(sa)393 # Make local paths for subresources394 self._make_local_paths()395 def _populate_from_stream(self, stream):396 """Populate this webarchive from the specified stream."""397 if isinstance(stream, io.IOBase):398 archive_data = plistlib.load(stream)399 self._populate_from_plist_data(archive_data)400 else:401 raise WebArchiveError("invalid stream type")402 @classmethod403 def _create_from_plist_data(cls, archive_data, parent=None):404 """Create a WebArchive object using parsed data from plistlib."""405 res = cls(parent)406 res._populate_from_plist_data(archive_data)407 return res408 @classmethod409 def _open(cls, path, mode="r"):410 """Open the specified webarchive file.411 Only mode 'r' (reading) is currently supported.412 """413 # Note this is the actual function exported as webarchive.open().414 # It uses a private name here to hide its real location from pydoc,415 # since that is an implementation detail that could change, but be416 # aware that any changes made here will be very public indeed.417 archive = cls()418 if isinstance(mode, str):419 if mode == "r":420 # Read this webarchive421 with io.open(path, "rb") as stream:422 archive._populate_from_stream(stream)423 else:424 raise WebArchiveException(425 "only mode 'r' (reading) is currently supported"426 )427 else:428 raise WebArchiveError("mode must be a str")429 return archive430 @property431 def main_resource(self):432 """This archive's main resource (a WebResource object)."""433 return self._main_resource434 @property435 def parent(self):436 """This archive's parent WebArchive, if this is a subframe archive.437 This will be set to None if this is the top-level webarchive.438 Note this property is not part of the webarchive format itself,439 but rather is provided by pywebarchive as a convenience.440 """441 return self._parent442 @property443 def subresources(self):444 """This archive's subresources (a list of WebResource objects)."""445 return self._subresources446 @property447 def subframe_archives(self):448 """This archive's subframes (a list of WebArchive objects)."""449 return self._subframe_archives450# These are common file extensions for web content451# that the mimetypes module may not already know452mimetypes.add_type("application/font-woff", ".woff")453mimetypes.add_type("application/x-font-woff", ".woff")454mimetypes.add_type("application/x-javascript", ".js")455mimetypes.add_type("font/woff", ".woff")456mimetypes.add_type("font/woff2", ".woff2")...

Full Screen

Full Screen

HypermediaCollection.py

Source:HypermediaCollection.py Github

copy

Full Screen

1"""2Hypermedia Collection extends the Hypermedia Resource class by adding hypermedia based URI routing and 3senml modeling of items and subresources.4Routing uses link relations rel=grp, rel=sub and rel=item5routing is done by identifying subresources that match the next uri segment to be routed until the last6segment in the request uri is identified for resource selection. Each collection routes requests in a 7self contained way, using only knowledge of it's own uri path and it's direct subresources.8group links labeled grp will be processed by forwarding the request to the href uri of the group link9items are senml modeled values in the local context of the collection, stored in an array of objects.10items are processed locally using the SenmlItems class in the same way an instance of the Links class 11is used to store the collection's links.12subresources are sub-collections in the context of the collection. requests to subresources are routed 13to the subresources selected14items and subresources are selected by either matching the resource uri with the request uri, or matching 15the collection uri with the request uri and seleting the resource(s) using query filtering on the link 16attributes, or by selecting the collection uri and matching resource names with senml names "n" in the 17update body. 18routing and group forwarding is done in this class, and resource processing e.g. GET, POST, is done in 19the respective Content Handlers.20resource endpoints are subresource collections with a single item, the item being referenced using the 21name of the collection e.g. /a/b/c is the URI of a resource endpoint. The resource c is a collection 22with a single item that is referenced by the base name and returns representations like this: 23senml { "bn": "/a/b/c", "e": {"sv": "test"} }24collection+senml { "l": {"href": "", "rel": "item"}, "bn": "/a/b/c", "e": {"sv": "test"} }25Items and subresources are created by POSTing representations containing items and optionally links in26the senml+collection content-format. THe location of the created resource will consist of the collection 27uri and the resource name specified in the "href" link attribute or the "n" attribute of the corresponding28senml element.29 30Links that fail to select a resource are returned with a status code of 404 Not Found31"""32import MachineHypermediaToolkit.terms as v33from HypermediaResource import HypermediaResource34from copy import deepcopy35from Items import SenmlItems36from PlainTextHandler import PlainTextHandler37from SenmlHandler import SenmlHandler38from SenmlCollectionHandler import SenmlCollectionHandler39class HypermediaCollection(HypermediaResource):40 def __init__(self, rootResource=None, uriPath=["/"], resourceLink=None, resourceItem=None ):41 HypermediaResource.__init__(self)42 self._uriPath = uriPath43 self._pathString = "/"44 for pathElement in uriPath[1:]:45 self._pathString += (pathElement + "/")46 self._pathLen = len(self._uriPath)47 if ["/"] == uriPath :48 self._rootResource = self49 else:50 self._rootResource = rootResource51 self._unrouted = 052 53 self._itemArray = SenmlItems()54 self._subresources = {}55 56 """ merge the constructor rt link attribute values into the self link """57 if None != resourceLink:58 if v._rt in resourceLink:59 self._linkArray.selectMerge({v._rel:v._self}, {v._rt: resourceLink[v._rt]})60 61 """ if there is an item in the constructor, null the resource name and add it to items """62 if None != resourceItem :63 resourceItem[v._n] = v._null64 self._itemArray.add(resourceItem)65 self._linkArray.selectMerge({v._href:v._null},{ v._rel: v._item})66 PlainTextHandler(self)67 SenmlHandler(self)68 SenmlCollectionHandler(self)69 """ Route requests using hyperlinks. Link relations "item" and "sub" are used to identify 70 local items in the collection and sub resources, respectively.""" 71 def routeRequest(self, request): 72 self._request = request73 self._unrouted = len(request[v.uriPath]) - self._pathLen74 75 if 0 == self._unrouted:76 """ this resource is selected, process content-format """77 self._processGroup(self._request)78 self.handleRequest(self._request)79 else:80 self._resourceName = self._request[v.uriPath][self._pathLen]81 # if there is both sub and item, route sub and ignore item82 if [] != self._linkArray.get({v._href:self._resourceName, v._rel:v._sub}):83 """ route request to subresource item"""84 self._subresources[self._resourceName].routeRequest(self._request)85 elif 1 == self._unrouted and [] != self._linkArray.get({v._href:self._resourceName, v._rel:v._item}) :86 """ item in the local collection is selected, handle content-format in this context"""87 self.handleRequest(self._request)88 else:89 """ nothing to route or process """90 self._request[v.response][v.status] = v.NotFound91 def _processGroup(self, request):92 """invoke a proxy or promise to forward the request to each resource marked with rel=grp """93 self._groupLinks = self._linkArray.get({v._rel:v._grp})94 if [] != self._groupLinks:95 request[v.response][v.payload] = []96 request[v.response][v.code] = []97 """ make request instances """98 self._requests = []99 for self._link in self._groupLinks:100 print "group link: ", self._link101 self._requests.append( deepcopy(request) )102 for self._request in self._requests:103 """ overwrite uriPath """ 104 self._request[v.uriPath] = ["/"]105 for self._pathElement in self._groupLinks.popleft()[v._href].split("/"):106 if len(self._pathElement) > 0:107 self._request[v.uriPath].append(self._pathElement)108 """ route request to root resource if path starts with / """ 109 if "/" == self._request[v.uriPath][0]:110 self._rootResource.routeRequest(self._request)111 else:112 self.routeRequest(self._request)113 """ collect the results """114 for self._request in self._requests:115 request[v.response][v.payload].append(self._request[v.response][v.payload])116 if v.Success != self._request[v.response][v.status] and \117 v.Created != self._request[v.response][v.status]:118 request[v.response][v.status] = v.BadRequest119 request[v.response][v.code].append(self._request[v.response][v.code]) 120 return self._requests121 else:122 return None123 def _createSubresource(self, resourceLink, resourceItem=None):124 resourceName = resourceLink[v._href]125 self._subresources[resourceName] = \126 HypermediaCollection( self._rootResource, self._uriPath + [resourceName], resourceLink, resourceItem) ...

Full Screen

Full Screen

PlainTextHandler.py

Source:PlainTextHandler.py Github

copy

Full Screen

1import MachineHypermediaToolkit.terms as v2from HypermediaResource import ContentHandler3import json4from Links import Links5class PlainTextHandler(ContentHandler):6 7 _contentFormat = v.plainTextType8 def _processRequest(self, request):9 if 0 == self._resource._unrouted:10 """ process collection URI, select by query parameters, 11 require only one resource link, item or subresource, 12 is selected for text/plain format """13 self._itemLinks = Links(self._resource._linkArray.get(request[v.uriQuery])).get({v._rel:v._item})14 self._subLinks = Links(self._resource._linkArray.get(request[v.uriQuery])).get({v._rel:v._sub})15 if 1 == len(self._itemLinks) and 0 == len(self._subLinks) :16 self._resourceName = self._itemLinks[0][v._href]17 elif 1 == len(self._subLinks) and 0 == len(self._itemLinks) :18 self._resourceName = self._subLinks[0][v._href]19 else:20 request[v.response][v.status] = v.NotFound21 """ clear query parameters when consumed at the path endpoint """22 request[v.uriQuery] = {}23 elif 1 == self._resource._unrouted :24 """ a local context item matched the last path element, _resourceName is set in the resource """25 self._resourceName = self._resource._resourceName26 else:27 request[v.response][v.status] = v.ServerError28 29 """ process item, resourceName is from request URI or from query filtering """30 if v.get == request[v.method] :31 if 1 == len(self._itemLinks) : 32 """ get item in local context """33 request[v.response][v.payload] = \34 json.dumps(self._resource._itemArray.getValueByName(self._resourceName) )35 request[v.response][v.status] = v.Success36 elif 1 == len(self._subLinks) :37 """ get subresource item """38 request[v.uriPath] = self._resource._uriPath + [self._resourceName]39 request[v.uriQuery] = {v._href:v._null}40 self._resource._subresources[self._resourceName].routeRequest(request)41 """ send request and wait for response """ 42 else:43 request[v.response][v.status] = v.NotFound44 45 elif v.put == request[v.method] :46 if 1 == len(self._itemLinks) : 47 self._resource._itemArray.updateValueByName(self._resourceName, json.loads(request[v.payload]))48 request[v.response][v.status] = v.Success49 elif 1 == len(self._subLinks) :50 """ route a request URI made from the collection path + resource name """51 request[v.uriPath] = self._resource._uriPath + [self._resourceName]52 request[v.uriQuery] = {v._href:v._null}53 self._resource._subresources[self._resourceName].routeRequest(request)54 else:55 request[v.response][v.status] = v.NotFound56 else:...

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run localstack automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful