API Documentation

This part of the documentation covers the interfaces used to develop with amazon-orders.

Main Interface

amazonorders.orders._parse_order_count(order_count_tag)[source]

Parse the leading number out of an Order history count tag, so the count survives thousands separators (e.g. 1,213 orders) and any trailing copy.

Parameters:

order_count_tag (Optional[Tag]) – The Order history count tag, if one was found.

Return type:

Optional[int]

Returns:

The Order count, or None if it was absent or unparsable.

amazonorders.orders._parse_order_history(parsed, config, start_index)[source]

Select the Order cards from an Order history page, gating an empty page on the page’s own Order count so a spent window can be told apart from a page that failed to render.

Parameters:
  • parsed (Tag) – The parsed Order history page.

  • config (AmazonOrdersConfig) – The config providing the selectors.

  • start_index (int) – The index of the first Order on the page within its window.

Return type:

List[Tag]

Returns:

The Order card tags, or an empty list when the count confirms the window is spent.

amazonorders.orders._parse_order_details(parsed, config, order_number=None, clone=None)[source]

Build an Order from an Order details page, leaving the not-found policy to the caller.

Parameters:
  • parsed (Tag) – The parsed Order details page.

  • config (AmazonOrdersConfig) – The config providing the selectors and entity classes.

  • order_number (Optional[str]) – The Order ID to fall back on when the page does not identify itself.

  • clone (Optional[Order]) – A partially populated version of the Order, if one was already fetched.

Return type:

Optional[Order]

Returns:

The parsed Order, or None if the details entity was not on the page.

class amazonorders.orders.AmazonOrders(amazon_session, debug=None, config=None)[source]

Bases: object

Using an authenticated AmazonSession, can be used to query Amazon for Order details and history.

amazon_session: AmazonSession

The session to use for requests.

config: AmazonOrdersConfig

The config to use.

debug: bool

Setting logger to DEBUG will send output to stderr.

static parse_order_history(html, config, start_index=0)[source]

Parse an already-fetched Amazon Order history page into Orders, without a session driving the fetch. Useful for parsing HTML obtained elsewhere (a browser, a proxy, a fixture) and for network-free testing.

A page with no Orders is returned as an empty list only when the page’s own Order count confirms the window is empty at start_index; otherwise it raises, since that is a page that failed to render.

A page Amazon served with its content encrypted (which can happen to fetches made outside the library’s session) raises rather than being parsed as empty cards.

Parameters:
  • html (str) – The Order history page HTML to parse.

  • config (AmazonOrdersConfig) – The config providing the selectors and entity classes used for parsing.

  • start_index (int) – The index of the first Order on the page within its window, seeding index the way get_order_history() does.

Return type:

List[Order]

Returns:

A list of the parsed Orders.

static parse_order_details(html, config, order_number=None)[source]

Parse an already-fetched Amazon Order details page into an Order, without a session driving the fetch. Useful for parsing HTML obtained elsewhere and for network-free testing.

Parameters:
  • html (str) – The Order details page HTML to parse.

  • config (AmazonOrdersConfig) – The config providing the selectors and entity classes used for parsing.

  • order_number (Optional[str]) – The Order ID the page was fetched for, used as a fallback for order_number when it cannot be parsed from the page.

Return type:

Order

Returns:

The parsed Order.

get_order(order_id, clone=None)[source]

Get the full details for a given Amazon Order ID.

Parameters:
  • order_id (str) – The Amazon Order ID to lookup.

  • clone (Optional[Order]) – If a partially populated version of the Order has already been fetched from history.

Return type:

Order

Returns:

The requested Order.

get_invoice(order_id)[source]

Get the print-friendly invoice page for a given Amazon Order ID, returning the response (including its parsed HTML) so callers can render or print the page.

Parameters:

order_id (str) – The Amazon Order ID to lookup.

Return type:

AmazonSessionResponse

Returns:

The invoice page response.

get_order_history(year=None, start_index=None, full_details=False, keep_paging=True, time_filter=None, order_filter=None)[source]

Get the Amazon Order history for a given time period.

Parameters:
  • year (Optional[int]) – The year for which to get history. Ignored if time_filter is provided. Defaults to the current year if neither year nor time_filter is specified.

  • start_index (Optional[int]) – The index of the Order from which to start fetching in the history. See index to correlate, or if a call to this method previously errored out, see index in the exception’s meta to continue paging where it left off.

  • full_details (bool) – Get the full details for each Order in the history. This will execute an additional request per Order.

  • keep_paging (bool) – False if only one page should be fetched.

  • time_filter (Optional[str]) – The time filter to use. Supported values are "last30" (last 30 days), "months-3" (past 3 months), or "year-YYYY" (specific year). If provided, this takes precedence over the year parameter.

  • order_filter (Optional[str]) – The order type filter to use. If provided, appended alongside the time filter.

Return type:

List[Order]

Returns:

A list of the requested Orders.

async _build_orders_async(next_page, keep_paging, full_details, current_index)[source]
Return type:

List[Order]

_build_order(order_tag, full_details, current_index)[source]
Return type:

Order

_is_whole_foods_details_url(url)[source]
Return type:

bool

_get_whole_foods_order(details_response, order_number=None, clone=None)[source]

Builds an Order from an already-fetched Whole Foods Market details page response.

Return type:

Order

async _async_wrapper(func, *args)[source]
Return type:

Order

amazonorders.transactions._parse_transaction_form_tag(form_tag, config)[source]
Return type:

Tuple[List[Transaction], Optional[Dict[str, str]]]

amazonorders.transactions._parse_transactions_page(parsed, config)[source]
Return type:

Tuple[List[Transaction], Optional[Dict[str, str]]]

class amazonorders.transactions.AmazonTransactions(amazon_session, debug=None, config=None)[source]

Bases: object

Using an authenticated AmazonSession, can be used to query Amazon for Transaction details and history.

amazon_session: AmazonSession

The session to use for requests.

config: AmazonOrdersConfig

The config to use.

debug: bool

Setting logger to DEBUG will send output to stderr.

static parse_transactions(html, config)[source]

Parse an already-fetched Amazon Transactions page into Transactions, without a session driving the fetch. Useful for parsing HTML obtained elsewhere (a browser, a proxy, a fixture) and for network-free testing. Only the Transactions on the given page are returned; paging is a fetch concern.

Parameters:
  • html (str) – The Transactions page HTML to parse.

  • config (AmazonOrdersConfig) – The config providing the selectors used for parsing.

Return type:

List[Transaction]

Returns:

A list of the parsed Transactions.

get_transactions(days=365, next_page_data=None, keep_paging=True, order_id=None)[source]

Get Amazon Transaction history for a given number of days, or for a single Order.

Parameters:
  • days (int) – The number of days worth of Transactions to get. Ignored when order_id is given.

  • next_page_data (Optional[Dict[str, Any]]) – If a call to this method previously errored out, passing the exception’s meta will continue paging where it left off.

  • keep_paging (bool) – False if only one page should be fetched.

  • order_id (Optional[str]) – If given, only Transactions for this Amazon Order ID are returned, scoped server-side via Amazon’s transactionTag filter (the days window does not apply).

Return type:

List[Transaction]

Returns:

A list of the requested Transactions.

Session Management

class amazonorders.session.IODefault[source]

Bases: object

Handles input/output from the application. By default, this uses console commands, but this class exists so that it can be overridden when constructing an AmazonSession if input/output should be handled another way.

echo(msg, **kwargs)[source]

Echo a message to the console.

Parameters:
  • msg (str) – The data to send to output.

  • kwargs (Any) – Unused by the default implementation.

Return type:

None

prompt(msg, type=None, **kwargs)[source]

Prompt to the console for user input.

Parameters:
  • msg (str) – The data to use as the input prompt.

  • type (Optional[Any]) – Unused by the default implementation.

  • kwargs (Any) – Unused by the default implementation.

Return type:

Any

Returns:

The user input result.

class amazonorders.session.AmazonSession(username=None, password=None, debug=False, io=<amazonorders.session.IODefault object>, config=None, auth_forms=None, otp_secret_key=None, domain=None)[source]

Bases: object

An interface for interacting with Amazon and authenticating an underlying requests.Session. Utilizing this class means session data is maintained between requests. Session data may also persisted after each request, so it can also be maintained between separate instantiations of the class or application.

To get started, call the login function.

username: str | None

An Amazon username. Environment variable AMAZON_USERNAME will override passed in or config value.

password: str | None

An Amazon password. Environment variable AMAZON_PASSWORD will override passed in or config value.

otp_secret_key: str | None

The secret key Amazon provides when manually adding a 2FA authenticator app. Setting this will allow one-time password challenges to be auto-solved. Environment variable AMAZON_OTP_SECRET_KEY will override passed in or config value.

debug: bool

Setting logger to DEBUG will send output to stderr and write an HTML file for all requests made on the session.

io: IODefault

The I/O handler for echoes and prompts.

config: AmazonOrdersConfig

The config to use.

auth_forms: List[AuthForm]

The list of form implementations to use with authentication. If a value is passed for this when instantiating an AmazonSession, ensure that list is populated with the default form implementations. default_auth_forms returns the default chain so callers can extend it instead of duplicating it.

session: Session

The shared session to be used across all requests.

is_authenticated: bool

If login has been executed and successfully logged in the session.

static default_auth_forms(config)[source]

Build the default ordered list of AuthForm instances used by AmazonSession. Callers wishing to inject a custom form (e.g. a third-party WAF Captcha solver) can call this and insert their own handler before passing the list as auth_forms.

Parameters:

config (AmazonOrdersConfig) – The config to bind to each form.

Return type:

List[AuthForm]

Returns:

The default ordered list of AuthForm instances.

request(method, url, persist_cookies=False, **kwargs)[source]

Execute the request against Amazon with base headers, parsing and storing the response.

Parameters:
  • method (str) – The request method to execute.

  • url (str) – The URL to execute method on.

  • persist_cookies (bool) – If True, cookies from the response will be persisted to a file.

  • kwargs (Any) – Remaining kwargs will be passed to requests.request.

Return type:

AmazonSessionResponse

Returns:

The response from the executed request.

get(url, **kwargs)[source]

Perform a GET request.

Parameters:
Return type:

AmazonSessionResponse

Returns:

The response from the executed request.

post(url, **kwargs)[source]

Perform a POST request.

Parameters:
Return type:

AmazonSessionResponse

Returns:

The response from the executed request.

auth_cookies_stored()[source]
Return type:

bool

login()[source]

Execute an Amazon login process. This will include the sign-in page, and may also include OTP (if 2FA is enabled for your account), Captcha challenges, and any other forms in auth_forms.

If successful, is_authenticated will be set to True.

If existing session data is already persisted, calling this function will still attempt to reauthenticate to refresh it.

Return type:

None

logout()[source]

Logout and close the existing Amazon session and clear cookies.

Return type:

None

build_response_error(response)[source]

Build an error message from the given response.

Parameters:

response (Response) – The response to check and build a response.

Return type:

str

Returns:

The error message.

check_response(amazon_session_response, meta=None)[source]

Check the response to ensure it appears to be returning a valid response, and that it is still authenticated. We detect if authentication has expired by checking for redirects to the login page. Raise an error if the response is not going to contain the requested data for parsing.

Parameters:
Return type:

None

_get_page_from_url(output_dir, url)[source]
Return type:

str

_raise_auth_error(response)[source]
Return type:

None

_create_session()[source]
Return type:

Session

_process_forms(last_response)[source]
_provision_cookies()[source]
class amazonorders.forms.AuthForm(config, selector, error_selector=None, critical=False)[source]

Bases: ABC

The base class of an authentication <form> that can be submitted.

The base implementation will attempt to auto-solve Captcha when the optional amazoncaptcha dependency is installed (pip install amazon-orders[captcha], available on Python <=3.12 only). If auto-solve is unavailable or fails, it will use the default image view to show the Captcha prompt, and it will also pass the image URL to prompt as img_url.

config: AmazonOrdersConfig

The config to use.

selector: str | None

The CSS selector for the <form>.

error_selector: str

The CSS selector for the error div when form submission fails.

critical: bool

If True, form submission failures will raise AmazonOrdersAuthError.

amazon_session: AmazonSession | None

The AmazonSession on which to submit the form.

form: Tag | None

The selected <form>.

data: Dict[str, Any] | None

The <form> data that will be submitted.

select_form(amazon_session, parsed)[source]

Using the selector defined on this instance, select the <form> for the given Tag.

Parameters:
  • amazon_session (AmazonSession) – The AmazonSession on which to submit the form.

  • parsed (Tag) – The Tag from which to select the <form>.

Return type:

bool

Returns:

Whether the <form> selection was successful.

fill_form(additional_attrs=None)[source]

Populate the data field with values from the <form>, including any additional attributes passed.

Parameters:

additional_attrs (Optional[Dict[str, Any]]) – Additional attributes to add to the <form> data for submission.

Return type:

None

submit(last_response)[source]

Submit the populated <form>.

Parameters:

last_response (Response) – The response of the request that fetched the form.

Return type:

AmazonSessionResponse

Returns:

The response from the executed request.

clear_form()[source]

Clear the populated <form> so this class can be reused.

Return type:

None

_solve_captcha(url)[source]
Return type:

Union[str, Any]

_get_form_action(last_response)[source]
Return type:

str

_handle_errors(form_response)[source]
Return type:

None

_abc_impl = <_abc._abc_data object>
class amazonorders.forms.SignInForm(config, selector=None, solution_attr_key='email')[source]

Bases: AuthForm

fill_form(additional_attrs=None)[source]

Populate the data field with values from the <form>, including any additional attributes passed.

Parameters:

additional_attrs (Optional[Dict[str, Any]]) – Additional attributes to add to the <form> data for submission.

Return type:

None

_abc_impl = <_abc._abc_data object>
class amazonorders.forms.ClaimForm(config, selector=None, solution_attr_key='email')[source]

Bases: AuthForm

fill_form(additional_attrs=None)[source]

Populate the data field with values from the <form>, including any additional attributes passed.

Parameters:

additional_attrs (Optional[Dict[str, Any]]) – Additional attributes to add to the <form> data for submission.

Return type:

None

_abc_impl = <_abc._abc_data object>
class amazonorders.forms.IntentForm(config, selector=None, error_selector=None)[source]

Bases: AuthForm

submit(last_response)[source]

When we encounter this form, we can’t submit it, so we display its contents as the error message, since within the context of this library, it is a termination event for the auth flow.

Parameters:

last_response (Response) – The response of the request that fetched the form.

Return type:

AmazonSessionResponse

Returns:

The response from the executed request.

_abc_impl = <_abc._abc_data object>
class amazonorders.forms.MfaDeviceSelectForm(config, selector=None, solution_attr_key='otpDeviceContext')[source]

Bases: AuthForm

This will first echo the <form> device choices, then it will pass the list of choices to prompt as choices. The value passed to prompt will be a list of the human-readable label of each input tag (falling back to the tag’s value when no label is found), numbered starting at one, and the number entered selects the device of the same number.

fill_form(additional_attrs=None)[source]

Populate the data field with values from the <form>, including any additional attributes passed.

Parameters:

additional_attrs (Optional[Dict[str, Any]]) – Additional attributes to add to the <form> data for submission.

Return type:

None

_get_device_label(field)[source]
Return type:

str

_abc_impl = <_abc._abc_data object>
class amazonorders.forms.MfaForm(config, selector=None, solution_attr_key='otpCode')[source]

Bases: AuthForm

fill_form(additional_attrs=None)[source]

Populate the data field with values from the <form>, including any additional attributes passed.

Parameters:

additional_attrs (Optional[Dict[str, Any]]) – Additional attributes to add to the <form> data for submission.

Return type:

None

_abc_impl = <_abc._abc_data object>
class amazonorders.forms.CaptchaForm(config, selector=None, error_selector=None, solution_attr_key='cvf_captcha_input')[source]

Bases: AuthForm

fill_form(additional_attrs=None)[source]

Populate the data field with values from the <form>, including any additional attributes passed.

Parameters:

additional_attrs (Optional[Dict[str, Any]]) – Additional attributes to add to the <form> data for submission.

Return type:

None

_abc_impl = <_abc._abc_data object>
class amazonorders.forms.AcicAuthBlocker(config)[source]

Bases: AuthForm

select_form(amazon_session, parsed)[source]

Using the selector defined on this instance, select the <form> for the given Tag.

Parameters:
  • amazon_session (AmazonSession) – The AmazonSession on which to submit the form.

  • parsed (Tag) – The Tag from which to select the <form>.

Return type:

bool

Returns:

Whether the <form> selection was successful.

_abc_impl = <_abc._abc_data object>
class amazonorders.forms.JSAuthBlocker(config, regex)[source]

Bases: AuthForm

select_form(amazon_session, parsed)[source]

Using the selector defined on this instance, select the <form> for the given Tag.

Parameters:
  • amazon_session (AmazonSession) – The AmazonSession on which to submit the form.

  • parsed (Tag) – The Tag from which to select the <form>.

Return type:

bool

Returns:

Whether the <form> selection was successful.

_abc_impl = <_abc._abc_data object>

Challenge Solvers

class amazonorders.contrib.waf.base.AwsWafForm(config)[source]

Bases: AuthForm

Shared base for AWS WAF JavaScript challenge solvers. Subclasses implement _solve_token to call a third-party solver and return the aws-waf-token cookie value.

This base class handles detection (the window.gokuProps blob plus the challenge.js script tag), setting the aws-waf-token cookie on the session, and re-fetching the challenged URL.

API_KEY_ENV_VAR: ClassVar[str] = ''

Name of the environment variable from which to read this solver’s API key. Subclasses must override.

PROVIDER_NAME: ClassVar[str] = ''

Display name of the third-party provider, used in the user-visible message emitted on every successful solve. Subclasses must override.

api_key: str

The third-party solver API key. Resolved (in order of precedence) from the API_KEY_ENV_VAR environment variable, then from the lowercase config key of the same name on AmazonOrdersConfig.

select_form(amazon_session, parsed)[source]

Detect an AWS WAF challenge page by matching the window.gokuProps blob and the challenge.js script tag. When both are present, this form will handle the page; otherwise the auth loop continues to the next form.

Parameters:
  • amazon_session (AmazonSession) – The AmazonSession on which to submit the form.

  • parsed (Tag) – The Tag for the page being inspected.

Return type:

bool

Returns:

True if a WAF challenge was detected, False otherwise.

fill_form(additional_attrs=None)[source]

AWS WAF challenge pages have no <form> to populate; no-op override.

Return type:

None

submit(last_response)[source]

Hand the WAF challenge off to _solve_token, set the resulting aws-waf-token cookie on the session, and re-fetch the challenged URL.

Parameters:

last_response (Response) – The response that returned the WAF challenge page.

Return type:

AmazonSessionResponse

Returns:

The AmazonSessionResponse from re-fetching the URL after the cookie is set.

Raises:

AmazonOrdersError – if select_form was not called first.

_solve_token(url, goku, challenge_script)[source]

Subclass hook. Call the third-party solver with the supplied challenge parameters and return the resulting aws-waf-token cookie value to be set on the session.

Parameters:
  • url (str) – The URL of the WAF-challenged page.

  • goku (Dict[str, Any]) – The parsed window.gokuProps payload (typically contains key, iv, and context).

  • challenge_script (str) – The src of the AWS WAF challenge.js script tag from the challenge page.

Return type:

str

Returns:

The aws-waf-token cookie value.

Raises:

NotImplementedError – if a subclass does not override this method.

_solve_visual_captcha(url, image_data, question)[source]

Subclass hook. Solve a visual grid Puzzle (e.g. “Choose all the buckets”) and return the indices of the correct grid cells.

Parameters:
  • url (str) – The URL of the page containing the Puzzle.

  • image_data (list) – List of base64-encoded data URLs, one per grid tile.

  • question (str) – The object to identify (e.g. "the buckets").

Return type:

Optional[list]

Returns:

A list of zero-based grid cell indices to select, or None if this solver does not support Puzzle classification.

_abc_impl = <_abc._abc_data object>
class amazonorders.contrib.waf.capsolver.CapSolverWafForm(config)[source]

Bases: AwsWafForm

Solves AWS WAF JavaScript challenges via CapSolver’s AntiAwsWafTaskProxyLess task.

Reads the API key from the CAPSOLVER_API_KEY environment variable. Requires the capsolver Python package: pip install amazon-orders[capsolver].

API_KEY_ENV_VAR: ClassVar[str] = 'CAPSOLVER_API_KEY'

Name of the environment variable from which to read this solver’s API key. Subclasses must override.

PROVIDER_NAME: ClassVar[str] = 'CapSolver'

Display name of the third-party provider, used in the user-visible message emitted on every successful solve. Subclasses must override.

_solve_token(url, goku, challenge_script)[source]

Solve the AWS WAF challenge via CapSolver’s AntiAwsWafTaskProxyLess task type and return the aws-waf-token cookie value.

Parameters:
  • url (str) – The URL of the WAF-challenged page.

  • goku (Dict[str, Any]) – The parsed window.gokuProps payload.

  • challenge_script (str) – The src of the AWS WAF challenge.js script tag.

Return type:

str

Returns:

The aws-waf-token cookie value.

Raises:

AmazonOrdersError – if the capsolver package is not installed, or if CapSolver’s response does not contain the expected cookie field.

_solve_visual_captcha(url, image_data, question)[source]

Solve a visual grid Puzzle via CapSolver’s AwsWafClassification task type and return the indices of the correct grid cells.

Parameters:
  • url (str) – The URL of the page containing the Puzzle.

  • image_data (List[str]) – List of base64-encoded data URLs, one per grid tile.

  • question (str) – The object to identify (e.g. "the buckets").

Return type:

Optional[List[int]]

Returns:

A list of zero-based grid cell indices to select.

Raises:

AmazonOrdersError – if the capsolver package is not installed, or if CapSolver’s response does not contain the expected fields.

_abc_impl = <_abc._abc_data object>
class amazonorders.contrib.waf.anticaptcha.AntiCaptchaWafForm(config)[source]

Bases: AwsWafForm

Solves AWS WAF JavaScript challenges via Anti-Captcha’s AmazonTaskProxyless task.

Reads the API key from the ANTICAPTCHA_API_KEY environment variable. Requires the anticaptchaofficial Python package: pip install amazon-orders[anticaptcha].

API_KEY_ENV_VAR: ClassVar[str] = 'ANTICAPTCHA_API_KEY'

Name of the environment variable from which to read this solver’s API key. Subclasses must override.

PROVIDER_NAME: ClassVar[str] = 'Anti-Captcha'

Display name of the third-party provider, used in the user-visible message emitted on every successful solve. Subclasses must override.

_solve_token(url, goku, challenge_script)[source]

Solve the AWS WAF challenge via Anti-Captcha’s AmazonTaskProxyless task type and return the aws-waf-token cookie value.

Parameters:
  • url (str) – The URL of the WAF-challenged page.

  • goku (Dict[str, Any]) – The parsed window.gokuProps payload.

  • challenge_script (str) – The src of the AWS WAF challenge.js script tag.

Return type:

str

Returns:

The aws-waf-token cookie value.

Raises:

AmazonOrdersError – if the anticaptchaofficial package is not installed, or if Anti-Captcha returns no token.

_abc_impl = <_abc._abc_data object>
class amazonorders.contrib.waf.twocaptcha.TwoCaptchaWafForm(config)[source]

Bases: AwsWafForm

Solves AWS WAF JavaScript challenges via 2Captcha’s amazon_waf solver method.

Reads the API key from the TWOCAPTCHA_API_KEY environment variable. Requires the 2captcha-python Python package: pip install amazon-orders[2captcha].

API_KEY_ENV_VAR: ClassVar[str] = 'TWOCAPTCHA_API_KEY'

Name of the environment variable from which to read this solver’s API key. Subclasses must override.

PROVIDER_NAME: ClassVar[str] = '2Captcha'

Display name of the third-party provider, used in the user-visible message emitted on every successful solve. Subclasses must override.

_solve_token(url, goku, challenge_script)[source]

Solve the AWS WAF challenge via 2Captcha’s amazon_waf method and return the aws-waf-token cookie value (extracted from the existing_token field in 2Captcha’s response).

Parameters:
  • url (str) – The URL of the WAF-challenged page.

  • goku (Dict[str, Any]) – The parsed window.gokuProps payload.

  • challenge_script (str) – The src of the AWS WAF challenge.js script tag.

Return type:

str

Returns:

The aws-waf-token cookie value.

Raises:

AmazonOrdersError – if the 2captcha-python package is not installed, or if 2Captcha’s response is malformed or missing the expected existing_token field.

_abc_impl = <_abc._abc_data object>
class amazonorders.contrib.browser.playwright.PlaywrightAuthForm(config)[source]

Bases: AuthForm

Shared base for Playwright-based JavaScript challenge solvers. Subclasses implement select_form to detect the challenge page and _is_challenge_url to signal when navigation has completed.

This base class handles the Playwright browser lifecycle, bidirectional cookie bridging between requests and the Playwright browser context, and re-fetching the final URL once the challenge resolves.

Requires the [browser] extra: pip install amazon-orders[browser], then playwright install chromium.

headless: bool

Whether to launch the browser in headless mode. Defaults to True. Set to False in subclasses that require user interaction.

manual: bool

Whether this form solves challenges by handing off to a human in a visible browser window (as opposed to an automated third-party solver). Forms with this set act as the free, manual solver for an embedded ACIC challenge.

fill_form(additional_attrs=None)[source]

JavaScript challenge pages have no <form> to populate; no-op override.

Return type:

None

submit(last_response)[source]

Launch a headless browser, bridge the current session cookies into it, navigate to the challenge URL, wait for the challenge to resolve, harvest the resulting cookies back into the session, and re-fetch the final URL.

Parameters:

last_response (Response) – The response that returned the JavaScript challenge page.

Return type:

AmazonSessionResponse

Returns:

The AmazonSessionResponse from re-fetching the URL after the challenge resolves.

Raises:

AmazonOrdersError – if the playwright package is not installed, if select_form was not called first, or if the challenge does not resolve within the timeout.

_on_challenge_page(page, context, output_dir)[source]

Hook called after navigating to the challenge page and saving the initial snapshot, but before waiting for the challenge URL to resolve. Override in subclasses to take additional action (e.g. solving an embedded Puzzle).

Parameters:
  • page (Any) – The Playwright Page currently on the challenge URL.

  • context (Any) – The Playwright BrowserContext.

  • output_dir (Optional[str]) – Directory for debug snapshots, or None when not in debug mode.

Return type:

None

abstractmethod _is_challenge_url(url, original_url)[source]

Return True if url is still on the challenge page; False once the challenge has resolved and navigation may stop.

Parameters:
  • url (str) – The current browser URL.

  • original_url (str) – The URL of the page that first showed the challenge.

Return type:

bool

Returns:

True while the challenge is active.

_inject_cookies(context, url)[source]
Return type:

None

_harvest_cookies(context)[source]
Return type:

None

_save_debug_snapshot(page, output_dir, name)[source]
Return type:

None

_abc_impl = <_abc._abc_data object>
class amazonorders.contrib.browser.playwright.PlaywrightAcicForm(config)[source]

Bases: PlaywrightAuthForm

Handles Amazon’s ACIC (Amazon Challenge and Identity Component) JavaScript challenge by running it in a headless browser. If an embedded AWS WAF challenge or visual grid Puzzle is present on the ACIC page, it will be solved automatically using the first AwsWafForm found in auth_forms_classes.

If no automated solver is registered but a manual solver (PlaywrightManualWafForm) is, a visible browser window is opened instead so the user can solve the embedded challenge themselves, for free. An automated solver takes precedence when both are registered.

Detects the challenge via the #aa-challenge-page-captcha-container element and waits for navigation away from /ax/aaut/verify/ap/challenge.

Register via auth_forms_classes in AmazonOrdersConfig:

auth_forms_classes:
  - "amazonorders.contrib.browser.playwright.PlaywrightAcicForm"
select_form(amazon_session, parsed)[source]

Detect an ACIC challenge page by the presence of #aa-challenge-page-captcha-container.

Parameters:
  • amazon_session (AmazonSession) – The AmazonSession on which to submit the form.

  • parsed (Tag) – The Tag for the page being inspected.

Return type:

bool

Returns:

True if an ACIC challenge was detected, False otherwise.

_manual_mode()[source]

Return True if the embedded challenge should be handed off to a human in a visible browser window rather than an automated solver. This is the case when a manual solver form is registered and no automated AwsWafForm is; an automated solver takes precedence when both are present, since it is non-interactive.

Return type:

bool

_find_waf_solver()[source]
Return type:

Optional[AwsWafForm]

_find_manual_solver()[source]
Return type:

Optional[PlaywrightAuthForm]

_on_challenge_page(page, context, output_dir)[source]

Hook called after navigating to the challenge page and saving the initial snapshot, but before waiting for the challenge URL to resolve. Override in subclasses to take additional action (e.g. solving an embedded Puzzle).

Parameters:
  • page (Any) – The Playwright Page currently on the challenge URL.

  • context (Any) – The Playwright BrowserContext.

  • output_dir (Optional[str]) – Directory for debug snapshots, or None when not in debug mode.

Return type:

None

_try_solve_embedded_waf(page, context, output_dir)[source]

If the ACIC challenge page contains an embedded AWS WAF challenge, solve it using the first AwsWafForm found in amazon_session.auth_forms, inject the resulting aws-waf-token cookie into the browser context, and reload the page.

Parameters:
  • page (Any) – The Playwright Page on the ACIC challenge URL.

  • context (Any) – The Playwright BrowserContext.

  • output_dir (Optional[str]) – Directory for debug snapshots, or None.

Return type:

bool

Returns:

True if a WAF token was obtained and injected, False otherwise.

_try_solve_visual_captcha(page, context, output_dir)[source]

If the ACIC challenge page contains a visual grid Puzzle rendered by CaptchaScript.renderCaptcha, extract the challenge images and question, solve it via the configured AwsWafForm, and submit the answer.

Parameters:
  • page (Any) – The Playwright Page on the ACIC challenge URL.

  • context (Any) – The Playwright BrowserContext.

  • output_dir (Optional[str]) – Directory for debug snapshots, or None.

Return type:

bool

Returns:

True if the Puzzle was solved and submitted, False otherwise.

_is_challenge_url(url, original_url)[source]

Return True if url is still on the challenge page; False once the challenge has resolved and navigation may stop.

Parameters:
  • url (str) – The current browser URL.

  • original_url (str) – The URL of the page that first showed the challenge.

Return type:

bool

Returns:

True while the challenge is active.

_abc_impl = <_abc._abc_data object>
class amazonorders.contrib.browser.playwright.PlaywrightJSAuthForm(config)[source]

Bases: PlaywrightAuthForm

Handles Amazon’s JavaScript bot-detection challenge page by running it in a headless browser. This is a best-effort form; effectiveness depends on whether the challenge can be resolved by a real browser without a visual puzzle.

Detects the challenge via JS_ROBOT_TEXT_REGEX and waits for navigation away from the original challenge URL path.

Register via auth_forms_classes in AmazonOrdersConfig:

auth_forms_classes:
  - "amazonorders.contrib.browser.playwright.PlaywrightJSAuthForm"
regex: str

The regex used to detect the JavaScript bot-detection page text.

select_form(amazon_session, parsed)[source]

Detect a JavaScript bot-detection page by matching JS_ROBOT_TEXT_REGEX against the page text.

Parameters:
  • amazon_session (AmazonSession) – The AmazonSession on which to submit the form.

  • parsed (Tag) – The Tag for the page being inspected.

Return type:

bool

Returns:

True if a JavaScript bot challenge was detected, False otherwise.

_on_challenge_page(page, context, output_dir)[source]

Hook called after navigating to the challenge page and saving the initial snapshot, but before waiting for the challenge URL to resolve. Override in subclasses to take additional action (e.g. solving an embedded Puzzle).

Parameters:
  • page (Any) – The Playwright Page currently on the challenge URL.

  • context (Any) – The Playwright BrowserContext.

  • output_dir (Optional[str]) – Directory for debug snapshots, or None when not in debug mode.

Return type:

None

_is_challenge_url(url, original_url)[source]

Return True if url is still on the challenge page; False once the challenge has resolved and navigation may stop.

Parameters:
  • url (str) – The current browser URL.

  • original_url (str) – The URL of the page that first showed the challenge.

Return type:

bool

Returns:

True while the challenge is active.

_abc_impl = <_abc._abc_data object>
class amazonorders.contrib.browser.playwright.PlaywrightManualWafForm(config)[source]

Bases: PlaywrightAuthForm

Handles Amazon’s AWS WAF JavaScript challenge by opening a visible browser window so the user can solve the Puzzle manually. Once the challenge resolves and the browser navigates away, cookies are harvested back into the session automatically.

Because it opens a browser window it requires a display and a user at the keyboard, making it suitable for local/interactive use but not for headless servers or CI.

Detects the challenge via the window.gokuProps blob and the challenge.js script tag (same signals as AwsWafForm), and waits for navigation away from the original challenge URL path.

Register via auth_forms_classes in AmazonOrdersConfig:

auth_forms_classes:
  - amazonorders.contrib.browser.playwright.PlaywrightManualWafForm
select_form(amazon_session, parsed)[source]

Detect an AWS WAF challenge page by matching the window.gokuProps blob and the challenge.js script tag.

Parameters:
  • amazon_session (AmazonSession) – The AmazonSession on which to submit the form.

  • parsed (Tag) – The Tag for the page being inspected.

Return type:

bool

Returns:

True if a WAF challenge was detected, False otherwise.

_on_challenge_page(page, context, output_dir)[source]

Hook called after navigating to the challenge page and saving the initial snapshot, but before waiting for the challenge URL to resolve. Override in subclasses to take additional action (e.g. solving an embedded Puzzle).

Parameters:
  • page (Any) – The Playwright Page currently on the challenge URL.

  • context (Any) – The Playwright BrowserContext.

  • output_dir (Optional[str]) – Directory for debug snapshots, or None when not in debug mode.

Return type:

None

_is_challenge_url(url, original_url)[source]

Return True if url is still on the challenge page; False once the challenge has resolved and navigation may stop.

Parameters:
  • url (str) – The current browser URL.

  • original_url (str) – The URL of the page that first showed the challenge.

Return type:

bool

Returns:

True while the challenge is active.

_abc_impl = <_abc._abc_data object>

Configuration

class amazonorders.conf.AmazonOrdersConfig(config_path=None, data=None)[source]

Bases: object

An object containing amazon-orders’s configuration. The state of this object is populated from the config file, if present, when it is instantiated, and it is also persisted back to the config file when save is called.

If overrides are passed in data parameter when this object is instantiated, they will be used to populate the new object, but not persisted to the config file until save is called.

Default values provisioned with the config can be found here.

config_path: str

The path to use for the config file.

constants: Any

The Constants in use, rebuilt when the domain changes.

static _default_data()[source]

Provision the default config values.

Return type:

Dict[str, Any]

Returns:

The default config values.

_load_classes()[source]

Instantiate the constants and selectors, which the auth layer itself uses and so are always needed. The entity and output classes resolve on first use instead.

Return type:

None

_validate_class_paths()[source]

Check the shape of every lazily resolved class path at construction, so a malformed value still fails here rather than at first use, without importing the modules they name.

Raises:

AmazonOrdersError – If a class path is not a dotted path to a class.

Return type:

None

_resolve_class(key)[source]

Resolve and cache the class named by the given config key.

Parameters:

key (str) – The config key naming the class.

Return type:

Any

Returns:

The resolved class.

Raises:

AmazonOrdersError – If the configured class path cannot be imported.

_set_class(key, value)[source]

Override the resolved class for the given config key, so a class can be assigned directly as well as named through its config path.

Parameters:
  • key (str) – The config key naming the class.

  • value (Any) – The class to use.

Return type:

None

property order_cls: Any

The Order class in use.

property shipment_cls: Any

The Shipment class in use.

property item_cls: Any

The Item class in use.

property output_cls: Any

The OutputFormatter class in use.

_validate_bs4_parser()[source]
Return type:

None

_instantiate_constants()[source]
Return type:

Any

set_domain(domain)[source]

Set the active Amazon domain and rebuild constants so URL-derived attributes and region-sensitive headers reflect the change.

Parameters:

domain (str) – The Amazon domain (e.g. amazon.com.au) or full URL.

Return type:

None

update_config(key, value, save=True)[source]

Update the given key/value pair in the config object. By default, this update will also be persisted to the config file. If only the object should be updated without persisting, pass save=False.

Parameters:
  • key (str) – The key to be updated.

  • value (Union[str, int, float]) – The new value.

  • save (bool) – True if the config should be persisted.

Return type:

None

save()[source]

Persist the current state of this config object to the config file.

Return type:

None

amazonorders.constants._BROWSER_PRESETS: Dict[str, Dict[str, str | None]] = {'chromium': {}, 'firefox': {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language': 'en-US,en;q=0.5', 'Sec-Ch-Ua': None, 'Sec-Ch-Ua-Mobile': None, 'Sec-Ch-Ua-Platform': None, 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:146.0) Gecko/20100101 Firefox/146.0'}}

Browser-specific header overrides applied on top of the class-level BASE_HEADERS (which already reflects the Chromium fingerprint). A None value removes the key (used to strip headers absent in that engine). Accept-Language here is the browser default; domain-specific TLD overrides still apply on top via _apply_domain.

amazonorders.constants._REGION_LANGUAGES = {'ca': 'en-CA,en;q=0.9,en-US;q=0.8', 'co.uk': 'en-GB,en;q=0.9,en-US;q=0.8', 'com.au': 'en-AU,en;q=0.9,en-US;q=0.8', 'in': 'en-IN,en;q=0.9,en-US;q=0.8', 'sg': 'en-SG,en;q=0.9,en-US;q=0.8'}

Accept-Language values for English-locale Amazon sites, keyed by the TLD suffix that follows amazon.. Looked up dynamically from the user-supplied domain; unknown TLDs keep the base en-US value. This map only governs the Accept-Language header — it is not a list of supported sites and does not affect any other authentication behavior.

amazonorders.constants._REGION_CURRENCIES = {'co.uk': '£', 'in': '₹', 'sg': 'S$'}

CURRENCY_SYMBOL values for English-locale Amazon sites where the storefront actually prefixes prices with a non-$ symbol. amazon.com.au and amazon.ca render prices as plain $ (single-currency context), so they keep the default and are intentionally omitted here. Skipped when AMAZON_CURRENCY_SYMBOL is set.

amazonorders.constants._normalize_base_url(value)[source]
Return type:

str

class amazonorders.constants.Constants(config=None)[source]

Bases: object

A class containing useful constants. Extend and override with constants_class in the config:

from amazonorders.conf import AmazonOrdersConfig

config = AmazonOrdersConfig(data={"constants_class": "my_module.MyConstants"})

URLs and the URL-shaped headers (Origin, Host, Referer) are derived from the active Amazon domain. Accept-Language and CURRENCY_SYMBOL are adjusted for a small set of English-locale TLDs (CURRENCY_SYMBOL only when AMAZON_CURRENCY_SYMBOL is unset). The domain is resolved in this precedence order:

  1. The domain key on AmazonOrdersConfig.

  2. The AMAZON_BASE_URL environment variable.

  3. The default, amazon.com.

Only the English, .com site is officially supported. Other domains may work, but values like openid.assoc_handle are not adjusted automatically — subclass and set constants_class to override them if a non-.com site requires it.

BASE_URL = 'https://www.amazon.com'
SIGN_IN_URL = 'https://www.amazon.com/ap/signin'
SIGN_IN_QUERY_PARAMS = {'openid.assoc_handle': 'usflex', 'openid.claimed_id': 'http://specs.openid.net/auth/2.0/identifier_select', 'openid.identity': 'http://specs.openid.net/auth/2.0/identifier_select', 'openid.mode': 'checkid_setup', 'openid.ns': 'http://specs.openid.net/auth/2.0', 'openid.pape.max_auth_age': '0', 'openid.return_to': 'https://www.amazon.com/?ref_=nav_custrec_signin'}
SIGN_IN_CLAIM_URL = 'https://www.amazon.com/ax/claim'
SIGN_OUT_URL = 'https://www.amazon.com/gp/flex/sign-out.html'
ORDER_HISTORY_URL = 'https://www.amazon.com/your-orders/orders'
ORDER_DETAILS_URL = 'https://www.amazon.com/gp/your-account/order-details'
ORDER_INVOICE_URL = 'https://www.amazon.com/gp/css/summary/print.html'
HISTORY_FILTER_QUERY_PARAM = 'timeFilter'
ORDER_FILTER_QUERY_PARAM = 'orderFilter'
WHOLE_FOODS_DETAILS_ROUTES = ['/fopo/order-details', '/wholefoodsmarket/receipts/order/']
TRANSACTION_HISTORY_ROUTE = '/cpe/yourpayments/transactions'
TRANSACTION_HISTORY_URL = 'https://www.amazon.com/cpe/yourpayments/transactions'
BASE_HEADERS = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', 'Accept-Encoding': 'gzip, deflate, br, zstd', 'Accept-Language': 'en-US,en;q=0.9', 'Host': 'www.amazon.com', 'Origin': 'https://www.amazon.com', 'Referer': 'https://www.amazon.com/ap/signin?openid.pape.max_auth_age=0&openid.return_to=https%3A%2F%2Fwww.amazon.com%2F%3Fref_%3Dnav_custrec_signin&openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.assoc_handle=usflex&openid.mode=checkid_setup&openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0', 'Sec-Ch-Ua': '"Chromium";v="149", "Google Chrome";v="149", "Not.A/Brand";v="24"', 'Sec-Ch-Ua-Mobile': '?0', 'Sec-Ch-Ua-Platform': '"macOS"', 'Sec-Fetch-Dest': 'document', 'Sec-Fetch-Mode': 'navigate', 'Sec-Fetch-Site': 'none', 'Sec-Fetch-User': '?1', 'Upgrade-Insecure-Requests': '1', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/149.0.0.0 Safari/537.36'}
COOKIES_SET_WHEN_AUTHENTICATED = ['x-main']
JS_ROBOT_TEXT_REGEX = "[.\\s\\S]*verify that you're not a robot[.\\s\\S]*Enable JavaScript[.\\s\\S]*"
GOKU_PROPS_REGEX = 'window\\.gokuProps\\s*=\\s*(\\{.*?\\});'
ACIC_CHALLENGE_PATH = '/ax/aaut/verify/ap/challenge'
CURRENCY_SYMBOL = '$'
_apply_browser(browser)[source]

Apply browser-specific header overrides for the given browser engine.

Parameters:

browser (str) – Browser engine name — "firefox" or "chromium". Unknown values log a warning and leave BASE_HEADERS unchanged.

Return type:

None

_apply_domain(domain)[source]

Override the URL-derived attributes for the given Amazon domain.

Parameters:

domain (str) – The Amazon domain (e.g. amazon.com.au) or full URL (e.g. https://www.amazon.com.au).

Return type:

None

format_currency(amount)[source]
Return type:

str

class amazonorders.output.OutputFormatter(config)[source]

Bases: object

A class that renders entities for output. Extend and override with output_class in the config:

from amazonorders.conf import AmazonOrdersConfig

config = AmazonOrdersConfig(data={"output_class": "my_module.MyOutputFormatter"})

json, yaml, and csv are built from to_dict, so any Parsable can be rendered in them, nested entities included. text is rendered by this class’s per-entity methods, falling back to the entity’s own __str__.

csv renders one row per entity, since a spreadsheet cannot nest: a nested entity becomes parent_child columns (e.g. recipient_name), and a list becomes a <field>_count column alongside its values joined by CSV_LIST_DELIMITER. Columns are the union of the fields present, so an empty result has no columns and renders as an empty document, where json and yaml render as an empty list.

OUTPUT_FORMATS = ['text', 'json', 'yaml', 'csv']

The formats accepted by the CLI’s --output option.

CSV_LIST_DELIMITER = '; '

Joins a list’s values within a single CSV column.

CSV_SUMMARY_FIELDS = ['title', 'name']

Fields tried, in order, to summarize a nested entity in a CSV column.

config: AmazonOrdersConfig

The config to use.

format(entities, output_format)[source]

Render the given entities in the given format.

Parameters:
Return type:

str

Returns:

The rendered output.

text(entity)[source]

Render a single entity as human-readable text.

Parameters:

entity (Parsable) – The entity to render.

Return type:

str

Returns:

The entity as text.

order_text(order)[source]

Render an Order as human-readable text.

Parameters:

order (Order) – The Order to render.

Return type:

str

Returns:

The Order as text.

transaction_text(transaction)[source]

Render a Transaction as human-readable text.

Parameters:

transaction (Transaction) – The Transaction to render.

Return type:

str

Returns:

The Transaction as text.

_csv(entities)[source]
Return type:

str

_flatten_for_csv(entity)[source]
Return type:

Dict[str, Any]

_csv_summary(item)[source]
Return type:

str

_single_line(value)[source]
Return type:

str

class amazonorders.selectors.Selector(css_selector, text=None, text_contains=None)[source]

Bases: object

Can be used to extend the definition of a CSS selector, allowing for programmatic inspection of the selections results before determining if selector matches.

css_selector: str

The CSS selector.

text: str | None

The text within the tag that must match exactly (after stripping).

text_contains: str | None

A substring within the tag’s text that must be present (case-insensitive). Evaluated only when text is not set.

class amazonorders.selectors.Selectors[source]

Bases: object

A class containing CSS selectors. Extend and override with selectors_class in the config:

from amazonorders.conf import AmazonOrdersConfig

config = AmazonOrdersConfig(data={"selectors_class": "my_module.MySelectors"})
BAD_INDEX_SELECTOR = 'html.a-tablet'
ACIC_CHALLENGE_SELECTOR = '#aa-challenge-page-captcha-container'
ACIC_VISUAL_CAPTCHA_MODAL_SELECTOR = '.amzn-captcha-modal'
ACIC_VISUAL_CAPTCHA_CANVAS_SELECTOR = '.amzn-captcha-modal canvas'
ACIC_VISUAL_CAPTCHA_QUESTION_SELECTOR = '.amzn-captcha-modal em'
ACIC_VISUAL_CAPTCHA_VERIFY_SELECTOR = '#amzn-btn-verify-internal'
AWS_WAF_CHALLENGE_SCRIPT_SELECTOR = 'script[src*="awswaf.com"]'
SIGN_IN_FORM_SELECTOR = "form[name='signIn']"
CLAIM_FORM_SELECTOR = "form[name='signIn'].auth-validate-form"
INTENT_FORM_SELECTOR = 'form#intent-confirmation-form'
INTENT_MESSAGE_SELECTOR = 'div#intent-confirmation-container'
MFA_DEVICE_SELECT_FORM_SELECTOR = 'form#auth-select-device-form'
MFA_DEVICE_SELECT_INPUT_SELECTOR = "input[name='otpDeviceContext']"
MFA_DEVICE_SELECT_INPUT_SELECTOR_VALUE = 'value'
MFA_DEVICE_SELECT_LABEL_SELECTOR = 'span.a-label.a-radio-label'
MFA_FORM_SELECTOR = 'form#auth-mfa-form'
CAPTCHA_1_FORM_SELECTOR = 'form.cvf-widget-form-captcha'
CAPTCHA_2_FORM_SELECTOR = ["form:has(input[id^='captchacharacters'])", "form[action$='validateCaptcha']"]
CAPTCHA_OTP_FORM_SELECTOR = 'form#verification-code-form'
DEFAULT_ERROR_TAG_SELECTOR = 'div#auth-error-message-box'
CAPTCHA_1_ERROR_SELECTOR = 'div.cvf-widget-alert'
CAPTCHA_2_ERROR_SELECTOR = 'div.a-alert-info'
ORDER_HISTORY_ENTITY_SELECTOR = ['div.order-card', 'div.order']
ORDER_HISTORY_COUNT_SELECTOR = ['.js-yo-container span.num-orders', 'form.js-time-filter-form label.time-filter__label b']
ORDER_HISTORY_CSD_ENCRYPTED_SELECTOR = <amazonorders.selectors.Selector object>
ORDER_DETAILS_ENTITY_SELECTOR = ['div#orderDetails', 'div#ordersContainer', 'div#odp-main-section']
ITEM_ENTITY_SELECTOR = ["[data-component='purchasedItems'] .a-fixed-left-grid", 'div:has(> div.yohtmlc-item)', '.item-box, .yo-enhanced-flex-card, .yo-enhanced-card', 'div.a-row.a-spacing-base:has(img.ufpo-itemListWidget-image)']
SHIPMENT_ENTITY_SELECTOR = ["[data-component='orderCard'] [data-component='shipments'] .a-box", 'div.shipment', 'div.delivery-box']
ORDER_SKIP_ITEMS = ['.brand-info-box .brand-logo img', "a.yohtmlc-order-details-link[href^='/wholefoodsmarket']", <amazonorders.selectors.Selector object>]
ORDER_WHOLE_FOODS = ["a[href*='/wholefoodsmarket/receipts/order/']", "a[href*='/fopo/order-details']", <amazonorders.selectors.Selector object>, 'img.ufpo-itemListWidget-image']
ORDER_SKIP_TOTALS = [<amazonorders.selectors.Selector object>, <amazonorders.selectors.Selector object>]
FIELD_ITEM_QUANTITY_SELECTOR = ['.od-item-view-qty', 'span.item-view-qty', 'span.product-image__qty']
FIELD_ITEM_WHOLE_FOODS_QUANTITY_SELECTOR = ['span.a-size-small']
FIELD_ITEM_TITLE_SELECTOR = ["[data-component='itemTitle']", '.yohtmlc-item a', '.yohtmlc-product-title', 'div.a-column.a-span10 > a', 'div.a-column.a-span10 > span', '.yo-enhanced-title a']
FIELD_ITEM_TAG_ITERATOR_SELECTOR = ['.yohtmlc-item div']
FIELD_ITEM_PRICE_SELECTOR = ["[data-component='unitPrice'] .a-text-price :not(.a-offscreen)", '.yohtmlc-item .a-color-price', 'div.a-section.a-text-right span.a-size-small']
FIELD_ITEM_SELLER_SELECTOR = ["[data-component='orderedMerchant']", '.yohtmlc-item div']
FIELD_ITEM_RETURN_SELECTOR = ["[data-component='itemReturnEligibility']", '.yo-enhanced-return', '.yohtmlc-item div']
FIELD_ORDER_NUMBER_SELECTOR = ["[data-component='orderId']", "[data-component='briefOrderInfo'] div.a-column", ".order-date-invoice-item :is(bdi, span)[dir='ltr']", ".yohtmlc-order-id :is(bdi, span)[dir='ltr']", ":is(bdi, span)[dir='ltr']"]
FIELD_ORDER_GRAND_TOTAL_SELECTOR = ['div.yohtmlc-order-total span.value', 'div.order-header div.a-column.a-span2', 'div.order-header div.a-col-left .a-span9', '#wfm-grand-total-amount']
FIELD_ORDER_WHOLE_FOODS_SUBTOTAL_SELECTOR = '#wfm-subtotal-amount'
FIELD_ORDER_WHOLE_FOODS_TAX_SELECTOR = '#wfm-tax-total-amount'
FIELD_ORDER_WHOLE_FOODS_PAYMENT_METHOD_SELECTOR = '#wfm-0-card-brand'
FIELD_ORDER_WHOLE_FOODS_PAYMENT_LAST_4_SELECTOR = '#wfm-0-card-tail'
FIELD_ORDER_PLACED_DATE_SELECTOR = ["[data-component='orderDate']", 'span.order-date-invoice-item', "[data-component='briefOrderInfo'] div.a-column", 'div:is(.a-span3, .a-span12)']
FIELD_ORDER_PAYMENT_METHOD_SELECTOR = 'img.pmts-payment-credit-card-instrument-logo'
FIELD_ORDER_PAYMENT_METHOD_LAST_4_SELECTOR = 'span:has(img.pmts-payment-credit-card-instrument-logo):last-child'
FIELD_ORDER_SUBTOTALS_TAG_ITERATOR_SELECTOR = ["[data-component='orderSubtotals'] div.a-row", 'div#od-subtotals div.a-row', "[data-component='chargeSummary'] div.od-line-item-row"]
FIELD_ORDER_SUBTOTALS_TAG_POPOVER_PRELOAD_SELECTOR = '.a-popover-preload'
FIELD_ORDER_SUBTOTALS_INNER_TAG_SELECTOR = 'div.a-span-last'
FIELD_ORDER_ADDRESS_SELECTOR = ['div.displayAddressDiv', "[data-component='shippingAddress']"]
FIELD_ORDER_ADDRESS_FALLBACK_1_SELECTOR = 'div.recipient span.a-declarative'
FIELD_ORDER_ADDRESS_FALLBACK_2_SELECTOR = "script[id^='shipToData']"
FIELD_ORDER_GIFT_CARD_INSTANCE_SELECTOR = '.gift-card-instance'
FIELD_ORDER_ITEM_COUNT_SELECTOR = ['div.a-fixed-left-grid-col.a-col-right span', 'span']
FIELD_SHIPMENT_DELIVERY_STATUS_SELECTOR = ['div.js-shipment-info-container div.a-row', 'span.delivery-box__primary-text', '.yohtmlc-shipment-status-primaryText', '.od-status-message']
FIELD_RECIPIENT_NAME_SELECTOR = ['li.displayAddressFullName', 'div:nth-child(1)', 'li:nth-child(1)']
FIELD_RECIPIENT_ADDRESS1_SELECTOR = 'li.displayAddressAddressLine1'
FIELD_RECIPIENT_ADDRESS2_SELECTOR = 'li.displayAddressAddressLine2'
FIELD_RECIPIENT_ADDRESS_CITY_STATE_POSTAL_SELECTOR = 'li.displayAddressCityStateOrRegionPostalCode'
FIELD_RECIPIENT_ADDRESS_COUNTRY_SELECTOR = 'li.displayAddressCountryName'
FIELD_RECIPIENT_ADDRESS_FALLBACK_SELECTOR = ['div:nth-child(2)', 'li:nth-child(2)']
FIELD_SELLER_NAME_SELECTOR = ['a', 'span']
TRANSACTION_HISTORY_FORM_SELECTOR = "form:has(input[name='ppw-widgetState'])"
TRANSACTION_HISTORY_CONTAINER_SELECTOR = '.pmts-portal-component'
TRANSACTION_DATE_CONTAINERS_SELECTOR = 'div.apx-transaction-date-container'
TRANSACTIONS_CONTAINER_SELECTOR = 'div'
TRANSACTIONS_SELECTOR = 'div.apx-transactions-line-item-component-container:has(*)'
TRANSACTIONS_NEXT_PAGE_INPUT_SELECTOR = ["input[type='submit'][name^='ppw-widgetEvent:DefaultNextPageNavigationEvent']"]
TRANSACTIONS_NEXT_PAGE_INPUT_STATE_SELECTOR = "input[name='ppw-widgetState']"
TRANSACTIONS_NEXT_PAGE_INPUT_IE_SELECTOR = "input[name='ie']"
FIELD_TRANSACTION_COMPLETED_DATE_SELECTOR = 'span'
FIELD_TRANSACTION_PAYMENT_METHOD_SELECTOR = ['div.apx-transactions-line-item-component-container > div:nth-child(1) span.a-size-base']
FIELD_TRANSACTION_GRAND_TOTAL_SELECTOR = ['div.apx-transactions-line-item-component-container > div:nth-child(1) span.a-size-base-plus']
FIELD_TRANSACTION_ORDER_NUMBER_SELECTOR = ['div.apx-transactions-line-item-component-container div .a-span12']
FIELD_TRANSACTION_SELLER_NAME_SELECTOR = ['div.apx-transactions-line-item-component-container :has(a.a-link-normal) + div']

Entities

class amazonorders.entity.parsable.Parsable(parsed, config)[source]

Bases: object

A base class that contains a parsed representation of the entity, which can be extended to build an entity that utilizes the common the helper methods.

parsed: Tag

Parsed HTML data that can be used to populate the fields of the entity.

config: AmazonOrdersConfig

The config to use.

to_dict()[source]

Serialize the entity to a dict of primitives, suitable for JSON, YAML, or CSV output. Nested entities and lists of them are converted recursively, dates become ISO 8601 strings, and the parsed Tag and the config are omitted.

Return type:

Dict[str, Any]

Returns:

The entity’s fields as a dict.

safe_parse(parse_function, **kwargs)[source]

Execute the given parse function on a field, handling any common parse exceptions and passing them as warnings to the logger (suppressing them as exceptions).

Parameters:
  • parse_function (Callable[..., Any]) – The parse function to attempt safe execution.

  • kwargs (Any) – The kwargs will be passed to parse_function.

Return type:

Any

Returns:

The return value from parse_function.

simple_parse(selector, attr_name=None, text_contains=None, required=False, prefix_split=None, wrap_tag=None, parse_date=False, prefix_split_fuzzy=False, suffix_split=None, suffix_split_fuzzy=False)[source]

Will attempt to extract the text value of the given CSS selector(s) for a field, and is suitable for most basic functionality on a well-formed page.

The selector can be either a str or a list. If a list is given, each selector in the list will be tried.

In most cases the selected tag’s text will be returned, but if wrap_tag is given, the tag itself (wrapped in the class) will be returned.

Parameters:
  • selector (Union[str, list]) – The CSS selector(s) for the field.

  • attr_name (Optional[str]) – If provided, return the value of this attribute on the selected field.

  • text_contains (Optional[str]) – Only select the field if this value is found in its text content.

  • required (bool) – If required, an exception will be thrown instead of returning None.

  • prefix_split (Optional[str]) – Only select the field with the given prefix, returning the right side of the split if so.

  • wrap_tag (Optional[Type]) – Wrap the selected tag in this class before returning.

  • parse_date (bool) – True if the resulting value should be fuzzy parsed in to a date (returning None if parsing fails).

  • prefix_split_fuzzy (bool) – True if the value should still be used even if prefix_split is not found.

  • suffix_split (Optional[str]) – Only select the field with the given suffix, returning the left side of the split if so.

  • suffix_split_fuzzy (bool) – True if the value should still be used even if suffix_split is not found.

Return type:

Any

Returns:

The cleaned up return value from the parsed selector.

safe_simple_parse(selector, **kwargs)[source]

A helper function that uses simple_parse as the parse_function() passed to safe_parse.

Parameters:
  • selector (Union[str, list]) – The CSS selector to pass to simple_parse.

  • kwargs (Any) – The kwargs will be passed to parse_function.

Return type:

Any

Returns:

The return value from simple_parse.

with_base_url(url)[source]

If the given URL is relative, the BASE_URL will be prepended.

Parameters:

url (str) – The URL to check.

Return type:

str

Returns:

The fully qualified URL.

to_currency(value)[source]

Clean up a currency, stripping non-numeric values and returning it as a primitive.

Recognizes the $, £, €, and ₹ symbols (and leading currency-code letters such as A$ or CDN$), accepts accounting-style negatives in parentheses (e.g. ($1.99)), and treats a literal FREE as 0.0.

Parameters:

value (Union[str, int, float]) – The currency to parse.

Return type:

Union[int, float, None]

Returns:

The currency as a primitive.

class amazonorders.entity.item.Item(parsed, config)[source]

Bases: Parsable

An Item in an Amazon Order. If desired fields are populated as None, ensure full_details is True when retrieving the Order (for instance, with get_order_history), since by default it is False (it will slow down querying).

title: str

The Item title.

The Item link. None for items without an Amazon detail page (e.g. ASINLESS Whole Foods Market line items).

asin: str | None

The product ASIN, derived from link; None when the link is not a product page.

price: float | None

The Item price.

seller: Seller | None

The Item Seller.

condition: str | None

The Item condition.

return_eligible_date: date | None

The Item return eligible date.

The Item image URL.

quantity: int | None

The Item quantity. None for items sold by weight (e.g. Whole Foods), which have no whole-unit count.

_parse_asin()[source]
Return type:

Optional[str]

_parse_quantity()[source]
Return type:

Optional[int]

class amazonorders.entity.order.Order(parsed, config, full_details=False, clone=None, index=None, order_number=None)[source]

Bases: Parsable

An Amazon Order. If desired fields are populated as None, ensure full_details is True when retrieving the Order (for instance, with get_order_history), since by default it is False (enabling slows down querying).

full_details: bool

If the Orders full details were populated from its details page.

index: int | None

Where the Order appeared in the history when it was queried. This will inevitably change (e.g. when a new Order is placed, all indexes will then be off by one), but is still captured as it may be applicable in various use-cases. Populated when the Order was fetched through get_order_history (use start_index to correlate), or when the clone has its index set.

cancelled: bool

True if the Order was cancelled. When True, fields like grand_total and the totals on the details page may be None because Amazon stops rendering them.

is_whole_foods: bool

True if this is a Whole Foods Market purchase (an in-store/FOPO purchase or a Whole Foods receipt order). Unlike other unsupported order types, these expose a grand_total and (often) an item_count on the history page, so those fields are populated.

shipments: List[Shipment]

The Order Shipments.

items: List[Item]

The Order Items.

order_number: str | None

The Order number. May be None only when the Order is cancelled and Amazon stripped the order number from the details page (the order_number parameter is used as a fallback in that case).

The Order details link.

grand_total: float | None

The Order grand total.

order_placed_date: date

The Order placed date.

recipient: Recipient

The Order Recipients.

item_count: int | None

The number of items in the purchase, when Amazon summarizes the count instead of listing the items (e.g. Whole Foods Market orders show “N items in this purchase”). None when no such summary is shown.

payment_method: str | None

The Order payment method. Only populated when full_details is True. For Whole Foods Market orders this is the card brand of the first payment method on the receipt (e.g. “Visa”).

payment_method_last_4: str | None

The Order payment method’s last 4 digits, preserved verbatim so leading zeros are not lost. Only populated when full_details is True.

subtotal: float | None

The Order subtotal. Only populated when full_details is True.

shipping_total: float | None

The Order shipping total. Only populated when full_details is True.

free_shipping: float | None

The Order free shipping. Only populated when full_details is True.

promotion_applied: float | None

The Order promotion applied. Only populated when full_details is True.

coupon_savings: float | None

The Order coupon savings. Only populated when full_details is True.

reward_points: float | None

The Order reward points. Only populated when full_details is True.

subscription_discount: float | None

The Order Subscribe & Save discount. Only populated when full_details is True.

total_before_tax: float | None

The Order total before tax. Only populated when full_details is True.

estimated_tax: float | None

The Order estimated tax. Only populated when full_details is True. For Whole Foods Market orders this is the “Tax and Fees” total from the receipt.

refund_total: float | None

The Order refund total. Only populated when full_details is True.

multibuy_discount: float | None

The Multibuy discount. Only populated when full_details is True.

amazon_discount: float | None

The Amazon discount. Only populated when full_details is True.

gift_card: float | None

The Gift Card total (rendered as “Gift Card” on digital order details pages). Only populated when full_details is True.

gift_wrap: float | None

The Gift Wrap total. Only populated when full_details is True.

_parse_shipments()[source]
Return type:

List[Shipment]

_parse_items()[source]
Return type:

List[Item]

Return type:

Optional[str]

_parse_grand_total()[source]
Return type:

Optional[float]

_parse_whole_foods_amount(selector)[source]
Return type:

Optional[float]

_parse_payment_method()[source]
Return type:

Optional[str]

_parse_masked_digits(selector, pattern)[source]
Return type:

Optional[str]

_parse_payment_method_last_4()[source]
Return type:

Optional[str]

_parse_subtotal()[source]
Return type:

Optional[float]

_parse_estimated_tax()[source]
Return type:

Optional[float]

_parse_item_count()[source]
Return type:

Optional[int]

_parse_recipient()[source]
Return type:

Optional[Recipient]

_parse_enclosing_ship_to()[source]

Finds this Order’s shipping address when a page renders it alongside the Order instead of within it.

Return type:

Optional[Tag]

_parse_currency(contains, combine_multiple=False)[source]
Return type:

Optional[float]

_if_full_details(value)[source]
Return type:

Optional[Any]

class amazonorders.entity.recipient.Recipient(parsed, config)[source]

Bases: Parsable

The person receiving an Amazon Order.

name: str

The Recipient name.

address: str | None

The Recipient address.

_parse_address()[source]
Return type:

Optional[str]

class amazonorders.entity.seller.Seller(parsed, config)[source]

Bases: Parsable

An Amazon Seller of an Amazon Item.

name: str

The Seller name.

The Seller link.

class amazonorders.entity.shipment.Shipment(parsed, config)[source]

Bases: Parsable

An Amazon Shipment, which should contain one or more Item’s.

items: List[Item]

The Shipment Items.

delivery_status: str | None

The Shipment delivery status.

The Shipment tracking link.

_parse_items()[source]
Return type:

List[Item]

class amazonorders.entity.transaction.Transaction(parsed, config, completed_date)[source]

Bases: Parsable

An Amazon Transaction.

completed_date: date

The Transaction completed date.

payment_method: str

The Transaction payment method.

payment_method_last_4: str | None

The Transaction payment method’s last digits, parsed from payment_method. None if no masked digits.

grand_total: float

The Transaction grand total.

is_refund: bool

The Transaction was a refund or not.

order_number: str

The Transaction Order number.

The Transaction Order details link.

seller: str

The Transaction seller name.

_parse_grand_total()[source]
Return type:

Union[float, int, None]

_parse_order_number()[source]
Return type:

Optional[str]

Return type:

Optional[str]

_parse_payment_method_last_4()[source]
Return type:

Optional[str]

Exceptions

exception amazonorders.exception.AmazonOrdersError(error, meta=None)[source]

Bases: Exception

Raised when a general amazon-orders error has occurred.

meta: Dict[str, Any] | None

Metadata for context around the error was raised.

exception amazonorders.exception.AmazonOrdersNotFoundError(error, meta=None)[source]

Bases: AmazonOrdersError

Raised when an Amazon page is not found.

exception amazonorders.exception.AmazonOrdersAuthError(error, meta=None)[source]

Bases: AmazonOrdersError

Raised when an amazon-orders authentication error has occurred.

exception amazonorders.exception.AmazonOrdersAuthRedirectError(error, meta=None)[source]

Bases: AmazonOrdersAuthError

Raised when an amazon-orders session that was previously authenticated redirects to login, indicating the likely need to reauthenticate.

exception amazonorders.exception.AmazonOrdersEntityError(error, meta=None)[source]

Bases: AmazonOrdersError

Raised when an amazon-orders entity parsing error has occurred.

Utility Functions

class amazonorders.util.AmazonSessionResponse(response, bs4_parser)[source]

Bases: object

A wrapper for the requests.Response object, which also contains the parsed HTML.

response: Response

The request’s response object.

parsed: Tag

The parsed HTML from the response.

amazonorders.util._selector_text_matches(tag, selector)[source]
Return type:

bool

amazonorders.util.select(parsed, selector)[source]

This is a helper function that extends BeautifulSoup’s select() method to allow for multiple selectors. The selector can be either a str or a list. If a list is given, each selector in the list will be tried until one is found to return a populated list of Tag’s, and that value will be returned.

Parameters:
  • parsed (Tag) – The Tag from which to attempt selection.

  • selector (Union[List[Union[str, Selector]], str, Selector]) – The CSS selector(s) for the field.

Return type:

List[Tag]

Returns:

The selected tag.

amazonorders.util.select_one(parsed, selector)[source]

This is a helper function that extends BeautifulSoup’s select_one() method to allow for multiple selectors. The selector can be either a str or a list. If a list is given, each selector in the list will be tried until one is found to return a populated Tag, and that value will be returned.

Parameters:
  • parsed (Tag) – The Tag from which to attempt selection.

  • selector (Union[List[Union[str, Selector]], str, Selector]) – The CSS selector(s) for the field.

Return type:

Optional[Tag]

Returns:

The selection tag.

amazonorders.util.to_type(value)[source]

Attempt to convert value to its primitive type of int, float, or bool.

If value is an empty string, None will be returned.

Parameters:

value (str) – The value to convert.

Return type:

Union[int, float, bool, str, None]

Returns:

The converted value.

amazonorders.util.load_class(package, clazz)[source]

Import the given class from the given package, and return it.

Parameters:
  • package (List[str]) – The package.

  • clazz (str) – The class to import.

Return type:

Union[Callable, Any]

Returns:

The return class.

amazonorders.util.cleanup_html_text(text)[source]

Cleanup excessive whitespace within text that comes from an HTML block.

Parameters:

text (str) – The text to clean up.

Return type:

str

Returns:

The cleaned up text.