GPALRestAPI is a native Windows application that OttoMagic launches. It starts on a local port and exposes browser automation as HTTP endpoints. GPAL uses OttoMagicClient as its typed fluent wrapper, but the endpoints themselves are plain REST -- any language or tool that can make HTTP calls can drive the browser through GPALRestAPI.
// GPAL talks to GPALRestAPI through OttoMagicClient
GPAL
var el = GPAL
GPAL
// The same endpoints are callable from any HTTP client
// POST http://localhost:PORT/GoTo { "url": "https://example
// POST http://localhost:PORT/Query { "css": "
In GPAL workflows you rarely call GPALRestAPI directly -- OttoMagicClient provides a fluent typed interface over the endpoints. MagicHelper wraps the same surface as single-step methods.
GPALRestAPI endpoints cover navigation, element interaction, element queries, script injection (before page load, not arbitrary execution during the workflow), storage operations across all browser storage types, page inspection, and DOM context switching. The full surface is accessible via OttoMagicClient in GPAL or from any HTTP client directly.
// Navigation
GPAL
GPAL
GPAL
// Element interaction
GPAL
GPAL
GPAL
GPAL
GPAL
// Storage and page inspection
GPAL
GPAL
GPAL
GPAL
// Script injection and DOM context
GPAL
GPAL
GPAL
GPALRestAPI includes a parallel set of persistent endpoints -- QueryPersistentSelector, EvaluatePersistent, and their multi-result variants. These are used by GPAL's persistent selector system to check for nag elements between units of work without disrupting the main DOM context.
Because GPALRestAPI is a standard HTTP server, any client that can make REST requests can reach it. GPALRestAPI scans for a free port starting at 3000 and, once bound, broadcasts the port number as a UTF-8 string to UDP 127.0.0.1:47623. GPAL receives this automatically and sets GPAL.OttoMagicRestApiBaseUrl. External code can do the same: open a UdpClient on port 47623 before OttoMagic launches, receive the broadcast, then address GPALRestAPI at the returned port for the duration of the session.
// Open the UDP listener BEFORE OttoMagic
// launches
using var udp = new UdpClient(47623);
udp
var remoteEp = new IPEndPoint(IPAddress
byte[] data = udp
string port = Encoding
// GPALRestAPI is now reachable at this port for the session
string baseUrl = $"http://localhost:{port}/";
// POST {baseUrl}/GoTo { "url": "https://example
// POST {baseUrl}/Query { "css": "
GPAL listens for this broadcast once at startup -- if GPALRestAPI restarts and acquires a different port, the workflow must also restart to pick up the new address.
Showing off some plain text in these paragraphs eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Here you can find different accents and emphasis sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
This is a link and how it could look like bestlinkinthebeautifulworld. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Here's just some classic bold text adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam notBoldSecondbestlinkinthebeautifulworld illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Obcaecati, iste distinctio veritatis eligendi laboriosam adipisicing elit illo nostrum corporis at adipisicing elit libero vel voluptas? Expedita, adipisicing facere dolores voluptatem ad ab rem assumenda soluta!
Other cuple of colors in case we want to emphasize several ways adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam adipisicing elit illo nostrum corporis at voluptatem libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta! Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quod veniam, quam ad expedita laborum sed at voluptates culpa ipsam ut vel. Ullam temporibus a mollitia quod aliquam ratione exercitationem nesciunt.
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta! Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quod veniam, quam ad expedita laborum sed at voluptates culpa ipsam ut vel. Ullam temporibus a mollitia quod aliquam ratione exercitationem nesciunt.
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Repudiandae quas consequuntur illo numquam assumenda autem exercitationem distinctio perspiciatis in natus. Eius dicta similique ipsam ipsa minima, nemo quae enim tempore.
GPAL
.CallIfNotFound(GenericCallIfNotFound)
.WithPublishToConsole();
//System.Drawing.Rectangle windowSize = new System.Drawing.Rectangle(10, 10, 1500, 1024);
// NOTE: we have to set browser = before we execute any steps
// this is due to the 'GenericCallIfNotFound' which might throw an exception, and BankScraper will not have the browser set when it calls scraper.Close()
// until the complete fluent line gets executed (meaning every step, meaning browser is not set until everything else succeeds)
browser = GPAL.Browser
.WithBrowserType(Enums.BrowserType.Chrome)
.WithProfileDataDirectory(ChromeProfileLocation)
.WithUseAutomationEngine(AutomationEngine.Selenium)
.WithWindowSize(new System.Drawing.Rectangle(0,0,1920,1080))
.ToGPALObject();