pyfxa-mte


Namepyfxa-mte JSON
Version 0.7.9 PyPI version JSON
download
home_pageNone
SummaryFirefox Accounts client library for Python
upload_time2024-09-24 16:28:13
maintainerNone
docs_urlNone
authorNone
requires_python>=3.8
licenseNone
keywords accounts authentication firefox
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage
            ===========================================================
PyFxA: Python library for interacting with Mozilla Accounts
===========================================================

This is python library for interacting with the Mozilla Accounts (formerly known as the Firefox Accounts) ecosystem.

Eventually, it is planned to provide easy support for the following features:

* being a direct mozilla accounts authentication client
* being an FxA OAuth Service Provider
* accessing attached services
* helps interactions with Firefox Account servers with requests Authentication plugins.

But none of that is ready yet; caveat emptor.


Mozilla Accounts
================

Currently, basic auth-server operations should work like so:

.. code-block:: python

    from fxa.core import Client

    client = Client("https://api.accounts.firefox.com")
    client.create_account("test@example.com", "MySecretPassword")

    session = client.login("test@example.com", "MySecretPassword")
    cert = session.sign_certificate(myPublicKey)
    session.change_password("MySecretPassword", "ThisIsEvenMoreSecret")


FxA OAuth Relier
================

Trade the authentication code against a longer lived OAuth token:

.. code-block:: python

    from fxa.oauth import Client

    client = Client()
    token = client.trade_code("client-id", "client-secret", "code-1234")


Verify an OAuth token:

.. code-block:: python

    from fxa.oauth import Client
    from fxa.errors import ClientError

    client = Client()

    try:
        profile = client.verify_token("123456...")
    except ClientError:
        print "Invalid token"

    print("User id", profile["user"])


Testing email addresses
=======================

There's also very basic integration with restmail.net, to allow for
testing with live email addresses.  It works like this:

.. code-block:: python

    from fxa.core import Client
    from fxa.tests.utils import TestEmailAccount

    # Create a testing account using an @restmail.net address.
    acct = TestEmailAccount()
    client = Client("https://api.accounts.firefox.com")
    session = client.create_account(acct.email, "MySecretPassword")

    # Verify the account using the code from email.
    acct.fetch()
    for m in acct.messages:
        if "x-verify-code" in m["headers"]:
            session.verify_email_code(m["headers"]["x-verify-code"])

    ...

    # Destroy the account once you're done with it.
    acct.clear()
    client.destroy_account(acct.email, "MySecretPassword")


Passing tokens and assertions to other applications
===================================================

PyFxA provides a ``fxa-client`` that you can use to export Bearer
Tokens and Browser ID assertions.


Get a Bearer Token for an existing account
------------------------------------------

.. code-block:: bash

    fxa-client --bearer --auth you@domain.tld \
        --account-server https://api.accounts.firefox.com/v1 \
        --oauth-server https://oauth.accounts.firefox.com/v1

    Please enter a password for you@domain.tld:

    # ---- BEARER TOKEN INFO ----
    # User: you@domain.tld
    # Scopes: profile
    # Account: https://api.accounts.firefox.com/v1
    # Oauth: https://oauth.accounts.firefox.com/v1
    # ---------------------------
    export OAUTH_BEARER_TOKEN="3f5106b203c...b728ef93fe29203aad44ee816a45b2f2ff57a6aed7a3"


Create a new account Bearer Token on stage
------------------------------------------

.. code-block:: bash

    fxa-client --bearer --create --prefix hello

    # ---- BEARER TOKEN INFO ----
    # User: hello-89331eba46e970dc1686ba2dc4583fc9@restmail.net
    # Scopes: profile
    # Account: https://api-accounts.stage.mozaws.net/v1
    # Oauth: https://oauth.stage.mozaws.net/v1
    # ---------------------------
    export OAUTH_BEARER_TOKEN="ecb5285d59b28e6768fe60d76e6994877ffb16d3232c...72bdee05ea8a5"


Create a new account BrowserID assertion on stage
-------------------------------------------------

.. code-block:: bash

    fxa-client --browserid --create --audience https://token.stage.mozaws.net/ --prefix syncto
    # ---- BROWSER ID ASSERTION INFO ----
    # User: syncto-5bcf63598bf6026a6833035821742d3e@restmail.net
    # Audience: https://token.stage.mozaws.net/
    # Account: https://api-accounts.stage.mozaws.net/v1
    # ------------------------------------
    export FXA_BROWSERID_ASSERTION="eyJhbGciOiJSUzI1NiJ9.eyJw......VNKcPu6Uc9Y4pCuGcdM0UwaA"
    export FXA_CLIENT_STATE="abaa31cc3b16aaf6759f2cba164a54be"


With Requests
=============

Using Firefox Account BrowserID with Requests
---------------------------------------------

You can use the ``FxABrowserIDAuth`` to build the BrowserID assertion:

.. code-block:: python

    from fxa.core import Client
    from fxa.plugins.requests import FxABrowserIDAuth

    email = acct.email
    password = "MySecretPassword"

    raw_resp = requests.get('https://token.services.mozilla.com/1.0/sync/1.5',
                            auth=FxABrowserIDAuth(email, password,
                                                  with_client_state=True))

    raw_resp.raise_for_status()
    resp = raw_resp.json()
    user_id = resp['uid']


Using Firefox Account Bearer Token with Requests
------------------------------------------------

You can use the ``FxABearerTokenAuth`` to build the Bearer Token:

.. code-block:: python

    from fxa.core import Client
    from fxa.plugins.requests import FxABearerTokenAuth

    email = acct.email
    password = "MySecretPassword"

    raw_resp = requests.get('https://profile.accounts.firefox.com/v1/profile',
                            auth=FxABearerTokenAuth(email, password,
                                                    ['profile'], client_id))

    raw_resp.raise_for_status()
    resp = raw_resp.json()
    user_id = resp['uid']


With HTTPie
===========

Using Firefox Account BrowserID with HTTPie
-------------------------------------------

You can use the httpie plugin provided with PyFxA to build the BrowserID request:

.. code-block:: http

    BID_WITH_CLIENT_STATE=True \
        http GET https://token.services.mozilla.com/1.0/sync/1.5 \
        --auth-type=fxa-browserid --auth "email:password" -v

    GET /1.0/sync/1.5 HTTP/1.1
    Accept: */*
    Accept-Encoding: gzip, deflate
    Authorization: BrowserID eyJhbG..._EqaQ
    Connection: keep-alive
    Host: token.services.mozilla.com
    User-Agent: HTTPie/0.9.2
    X-Client-State: 97b945...920fac4d4d5f0dc6...2992

    HTTP/1.1 200 OK
    Access-Control-Allow-Credentials: true
    Access-Control-Allow-Headers: DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,X-Conditions-Accepted
    Access-Control-Allow-Methods: GET, POST, OPTIONS
    Access-Control-Max-Age: 1728000
    Connection: keep-alive
    Content-Length: 414
    Content-Type: application/json; charset=UTF-8
    Date: Tue, 21 Jul 2015 10:48:42 GMT
    X-Timestamp: 1437475722

    {
        "api_endpoint": "https://sync-230-us-west-2.sync.services.mozilla.com/1.5/99283757",
        "duration": 3600,
        "hashalg": "sha256",
        "id": "eyJub2RlI....FlYzdiMCIsICJ1aWQiOiAyMDIzODc3NX2Bvj5zv..7S2jRaw__-....eh3hiSVWA==",
        "key": "lSw-MvgK....ebu9JsX-yXS70NkiXu....6wWgVzU0Q=",
        "uid": 99283757
    }

.. note::

    You can configure the audience by settings the ``BID_AUDIENCE``
    environment variable.

	You can also compute the Token Server client state using the
	``BID_WITH_CLIENT_STATE`` environment variable.


Using Firefox Account Bearer Tokens with HTTPie
-----------------------------------------------

You can use the httpie plugin provided with PyFxA to build the Bearer
token request:

.. code-block:: http

    $ http GET https://profile.accounts.firefox.com/v1/profile \
        --auth-type fxa-bearer --auth "email:password" -v

    GET /v1/profile HTTP/1.1
    Accept: */*
    Accept-Encoding: gzip, deflate
    Authorization: Bearer 98e05e12ba...0d61231e88daf91
    Connection: keep-alive
    Host: profile.accounts.firefox.com
    User-Agent: HTTPie/0.9.2

    HTTP/1.1 200 OK
    Connection: keep-alive
    Content-Length: 92
    Content-Type: application/json; charset=utf-8
    Date: Tue, 21 Jul 2015 14:47:32 GMT
    Server: nginx
    access-control-allow-headers: Authorization, Content-Type, If-None-Match
    access-control-allow-methods: GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS
    access-control-allow-origin: *
    access-control-expose-headers: WWW-Authenticate, Server-Authorization
    access-control-max-age: 86400
    cache-control: no-cache
    content-encoding: gzip
    etag: "d1cf22901b3e3be527c06e27689be705bb22a172"
    strict-transport-security: max-age=15552000; includeSubdomains
    vary: accept-encoding

    {
        "email": "email@address.com",
        "uid": "63b91ca4ec19ad79f320eaf5815d75e9"
    }

.. note::

    You can configure the following:

      - FXA_CLIENT_ID: To choose the CLIENT_ID (default to Firefox Dev id)
      - FXA_SCOPES: To choose the list of scopes
      - FXA_ACCOUNT_SERVER_URL: To select the account server url
        (default to: https://api.accounts.firefox.com/v1)
      - FXA_OAUTH_SERVER_URL: To select the oauth server url
        (default to: https://oauth.accounts.firefox.com/v1)



=====================
Contributing to PyFxA
=====================

The basic requirements are:

- Python 3.12.2 or higher
- Pip 24.0

To get started:

.. code-block::

    $ pip install '.[dev]'
    $ pip install .

To run tests:

.. code-block::

    $ pytest

If you'd like to run all supported versions of Python, install `hatch` via `pip` or `pipx`:

.. code:: bash

    $ pipx install hatch

Once installed you can run the tests in all supported Python environments with:

.. code:: bash

    $ hatch run test:cov

To run the tests with specific Python version you can specify this with hatch:

.. code:: bash

    $ hatch run +py=3.10 test:cov

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "pyfxa-mte",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "accounts, authentication, firefox",
    "author": null,
    "author_email": "Mozilla Services <services-dev@mozilla.org>",
    "download_url": "https://files.pythonhosted.org/packages/63/2a/51488fe1811e68dde30159c37a7f8fe9197b5907718cc18441c9bd4ccd54/pyfxa_mte-0.7.9.tar.gz",
    "platform": null,
    "description": "===========================================================\nPyFxA: Python library for interacting with Mozilla Accounts\n===========================================================\n\nThis is python library for interacting with the Mozilla Accounts (formerly known as the Firefox Accounts) ecosystem.\n\nEventually, it is planned to provide easy support for the following features:\n\n* being a direct mozilla accounts authentication client\n* being an FxA OAuth Service Provider\n* accessing attached services\n* helps interactions with Firefox Account servers with requests Authentication plugins.\n\nBut none of that is ready yet; caveat emptor.\n\n\nMozilla Accounts\n================\n\nCurrently, basic auth-server operations should work like so:\n\n.. code-block:: python\n\n    from fxa.core import Client\n\n    client = Client(\"https://api.accounts.firefox.com\")\n    client.create_account(\"test@example.com\", \"MySecretPassword\")\n\n    session = client.login(\"test@example.com\", \"MySecretPassword\")\n    cert = session.sign_certificate(myPublicKey)\n    session.change_password(\"MySecretPassword\", \"ThisIsEvenMoreSecret\")\n\n\nFxA OAuth Relier\n================\n\nTrade the authentication code against a longer lived OAuth token:\n\n.. code-block:: python\n\n    from fxa.oauth import Client\n\n    client = Client()\n    token = client.trade_code(\"client-id\", \"client-secret\", \"code-1234\")\n\n\nVerify an OAuth token:\n\n.. code-block:: python\n\n    from fxa.oauth import Client\n    from fxa.errors import ClientError\n\n    client = Client()\n\n    try:\n        profile = client.verify_token(\"123456...\")\n    except ClientError:\n        print \"Invalid token\"\n\n    print(\"User id\", profile[\"user\"])\n\n\nTesting email addresses\n=======================\n\nThere's also very basic integration with restmail.net, to allow for\ntesting with live email addresses.  It works like this:\n\n.. code-block:: python\n\n    from fxa.core import Client\n    from fxa.tests.utils import TestEmailAccount\n\n    # Create a testing account using an @restmail.net address.\n    acct = TestEmailAccount()\n    client = Client(\"https://api.accounts.firefox.com\")\n    session = client.create_account(acct.email, \"MySecretPassword\")\n\n    # Verify the account using the code from email.\n    acct.fetch()\n    for m in acct.messages:\n        if \"x-verify-code\" in m[\"headers\"]:\n            session.verify_email_code(m[\"headers\"][\"x-verify-code\"])\n\n    ...\n\n    # Destroy the account once you're done with it.\n    acct.clear()\n    client.destroy_account(acct.email, \"MySecretPassword\")\n\n\nPassing tokens and assertions to other applications\n===================================================\n\nPyFxA provides a ``fxa-client`` that you can use to export Bearer\nTokens and Browser ID assertions.\n\n\nGet a Bearer Token for an existing account\n------------------------------------------\n\n.. code-block:: bash\n\n    fxa-client --bearer --auth you@domain.tld \\\n        --account-server https://api.accounts.firefox.com/v1 \\\n        --oauth-server https://oauth.accounts.firefox.com/v1\n\n    Please enter a password for you@domain.tld:\n\n    # ---- BEARER TOKEN INFO ----\n    # User: you@domain.tld\n    # Scopes: profile\n    # Account: https://api.accounts.firefox.com/v1\n    # Oauth: https://oauth.accounts.firefox.com/v1\n    # ---------------------------\n    export OAUTH_BEARER_TOKEN=\"3f5106b203c...b728ef93fe29203aad44ee816a45b2f2ff57a6aed7a3\"\n\n\nCreate a new account Bearer Token on stage\n------------------------------------------\n\n.. code-block:: bash\n\n    fxa-client --bearer --create --prefix hello\n\n    # ---- BEARER TOKEN INFO ----\n    # User: hello-89331eba46e970dc1686ba2dc4583fc9@restmail.net\n    # Scopes: profile\n    # Account: https://api-accounts.stage.mozaws.net/v1\n    # Oauth: https://oauth.stage.mozaws.net/v1\n    # ---------------------------\n    export OAUTH_BEARER_TOKEN=\"ecb5285d59b28e6768fe60d76e6994877ffb16d3232c...72bdee05ea8a5\"\n\n\nCreate a new account BrowserID assertion on stage\n-------------------------------------------------\n\n.. code-block:: bash\n\n    fxa-client --browserid --create --audience https://token.stage.mozaws.net/ --prefix syncto\n    # ---- BROWSER ID ASSERTION INFO ----\n    # User: syncto-5bcf63598bf6026a6833035821742d3e@restmail.net\n    # Audience: https://token.stage.mozaws.net/\n    # Account: https://api-accounts.stage.mozaws.net/v1\n    # ------------------------------------\n    export FXA_BROWSERID_ASSERTION=\"eyJhbGciOiJSUzI1NiJ9.eyJw......VNKcPu6Uc9Y4pCuGcdM0UwaA\"\n    export FXA_CLIENT_STATE=\"abaa31cc3b16aaf6759f2cba164a54be\"\n\n\nWith Requests\n=============\n\nUsing Firefox Account BrowserID with Requests\n---------------------------------------------\n\nYou can use the ``FxABrowserIDAuth`` to build the BrowserID assertion:\n\n.. code-block:: python\n\n    from fxa.core import Client\n    from fxa.plugins.requests import FxABrowserIDAuth\n\n    email = acct.email\n    password = \"MySecretPassword\"\n\n    raw_resp = requests.get('https://token.services.mozilla.com/1.0/sync/1.5',\n                            auth=FxABrowserIDAuth(email, password,\n                                                  with_client_state=True))\n\n    raw_resp.raise_for_status()\n    resp = raw_resp.json()\n    user_id = resp['uid']\n\n\nUsing Firefox Account Bearer Token with Requests\n------------------------------------------------\n\nYou can use the ``FxABearerTokenAuth`` to build the Bearer Token:\n\n.. code-block:: python\n\n    from fxa.core import Client\n    from fxa.plugins.requests import FxABearerTokenAuth\n\n    email = acct.email\n    password = \"MySecretPassword\"\n\n    raw_resp = requests.get('https://profile.accounts.firefox.com/v1/profile',\n                            auth=FxABearerTokenAuth(email, password,\n                                                    ['profile'], client_id))\n\n    raw_resp.raise_for_status()\n    resp = raw_resp.json()\n    user_id = resp['uid']\n\n\nWith HTTPie\n===========\n\nUsing Firefox Account BrowserID with HTTPie\n-------------------------------------------\n\nYou can use the httpie plugin provided with PyFxA to build the BrowserID request:\n\n.. code-block:: http\n\n    BID_WITH_CLIENT_STATE=True \\\n        http GET https://token.services.mozilla.com/1.0/sync/1.5 \\\n        --auth-type=fxa-browserid --auth \"email:password\" -v\n\n    GET /1.0/sync/1.5 HTTP/1.1\n    Accept: */*\n    Accept-Encoding: gzip, deflate\n    Authorization: BrowserID eyJhbG..._EqaQ\n    Connection: keep-alive\n    Host: token.services.mozilla.com\n    User-Agent: HTTPie/0.9.2\n    X-Client-State: 97b945...920fac4d4d5f0dc6...2992\n\n    HTTP/1.1 200 OK\n    Access-Control-Allow-Credentials: true\n    Access-Control-Allow-Headers: DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,X-Conditions-Accepted\n    Access-Control-Allow-Methods: GET, POST, OPTIONS\n    Access-Control-Max-Age: 1728000\n    Connection: keep-alive\n    Content-Length: 414\n    Content-Type: application/json; charset=UTF-8\n    Date: Tue, 21 Jul 2015 10:48:42 GMT\n    X-Timestamp: 1437475722\n\n    {\n        \"api_endpoint\": \"https://sync-230-us-west-2.sync.services.mozilla.com/1.5/99283757\",\n        \"duration\": 3600,\n        \"hashalg\": \"sha256\",\n        \"id\": \"eyJub2RlI....FlYzdiMCIsICJ1aWQiOiAyMDIzODc3NX2Bvj5zv..7S2jRaw__-....eh3hiSVWA==\",\n        \"key\": \"lSw-MvgK....ebu9JsX-yXS70NkiXu....6wWgVzU0Q=\",\n        \"uid\": 99283757\n    }\n\n.. note::\n\n    You can configure the audience by settings the ``BID_AUDIENCE``\n    environment variable.\n\n\tYou can also compute the Token Server client state using the\n\t``BID_WITH_CLIENT_STATE`` environment variable.\n\n\nUsing Firefox Account Bearer Tokens with HTTPie\n-----------------------------------------------\n\nYou can use the httpie plugin provided with PyFxA to build the Bearer\ntoken request:\n\n.. code-block:: http\n\n    $ http GET https://profile.accounts.firefox.com/v1/profile \\\n        --auth-type fxa-bearer --auth \"email:password\" -v\n\n    GET /v1/profile HTTP/1.1\n    Accept: */*\n    Accept-Encoding: gzip, deflate\n    Authorization: Bearer 98e05e12ba...0d61231e88daf91\n    Connection: keep-alive\n    Host: profile.accounts.firefox.com\n    User-Agent: HTTPie/0.9.2\n\n    HTTP/1.1 200 OK\n    Connection: keep-alive\n    Content-Length: 92\n    Content-Type: application/json; charset=utf-8\n    Date: Tue, 21 Jul 2015 14:47:32 GMT\n    Server: nginx\n    access-control-allow-headers: Authorization, Content-Type, If-None-Match\n    access-control-allow-methods: GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS\n    access-control-allow-origin: *\n    access-control-expose-headers: WWW-Authenticate, Server-Authorization\n    access-control-max-age: 86400\n    cache-control: no-cache\n    content-encoding: gzip\n    etag: \"d1cf22901b3e3be527c06e27689be705bb22a172\"\n    strict-transport-security: max-age=15552000; includeSubdomains\n    vary: accept-encoding\n\n    {\n        \"email\": \"email@address.com\",\n        \"uid\": \"63b91ca4ec19ad79f320eaf5815d75e9\"\n    }\n\n.. note::\n\n    You can configure the following:\n\n      - FXA_CLIENT_ID: To choose the CLIENT_ID (default to Firefox Dev id)\n      - FXA_SCOPES: To choose the list of scopes\n      - FXA_ACCOUNT_SERVER_URL: To select the account server url\n        (default to: https://api.accounts.firefox.com/v1)\n      - FXA_OAUTH_SERVER_URL: To select the oauth server url\n        (default to: https://oauth.accounts.firefox.com/v1)\n\n\n\n=====================\nContributing to PyFxA\n=====================\n\nThe basic requirements are:\n\n- Python 3.12.2 or higher\n- Pip 24.0\n\nTo get started:\n\n.. code-block::\n\n    $ pip install '.[dev]'\n    $ pip install .\n\nTo run tests:\n\n.. code-block::\n\n    $ pytest\n\nIf you'd like to run all supported versions of Python, install `hatch` via `pip` or `pipx`:\n\n.. code:: bash\n\n    $ pipx install hatch\n\nOnce installed you can run the tests in all supported Python environments with:\n\n.. code:: bash\n\n    $ hatch run test:cov\n\nTo run the tests with specific Python version you can specify this with hatch:\n\n.. code:: bash\n\n    $ hatch run +py=3.10 test:cov\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Firefox Accounts client library for Python",
    "version": "0.7.9",
    "project_urls": {
        "Homepage": "https://github.com/clarmso/PyFxA"
    },
    "split_keywords": [
        "accounts",
        " authentication",
        " firefox"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "ddf942112955d20d79d5ea05f959fc451e917a1b33b213cf7a9bf05753da8163",
                "md5": "5ddc74dcb02d4a8cf8b06eaf12a642ae",
                "sha256": "bd546e4348e389f4f7a68daab4ab895a90df55d241e9e8b96c57590c703bed46"
            },
            "downloads": -1,
            "filename": "pyfxa_mte-0.7.9-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "5ddc74dcb02d4a8cf8b06eaf12a642ae",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 53942,
            "upload_time": "2024-09-24T16:28:12",
            "upload_time_iso_8601": "2024-09-24T16:28:12.323187Z",
            "url": "https://files.pythonhosted.org/packages/dd/f9/42112955d20d79d5ea05f959fc451e917a1b33b213cf7a9bf05753da8163/pyfxa_mte-0.7.9-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "632a51488fe1811e68dde30159c37a7f8fe9197b5907718cc18441c9bd4ccd54",
                "md5": "171335b2d4e69333e6dd534eb211d1ef",
                "sha256": "b06e0f54fb941c90ae0b8303993fdf042be3fc95f6e487c3306676b20978456f"
            },
            "downloads": -1,
            "filename": "pyfxa_mte-0.7.9.tar.gz",
            "has_sig": false,
            "md5_digest": "171335b2d4e69333e6dd534eb211d1ef",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 43675,
            "upload_time": "2024-09-24T16:28:13",
            "upload_time_iso_8601": "2024-09-24T16:28:13.689560Z",
            "url": "https://files.pythonhosted.org/packages/63/2a/51488fe1811e68dde30159c37a7f8fe9197b5907718cc18441c9bd4ccd54/pyfxa_mte-0.7.9.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-09-24 16:28:13",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "clarmso",
    "github_project": "PyFxA",
    "travis_ci": false,
    "coveralls": true,
    "github_actions": true,
    "lcname": "pyfxa-mte"
}
        
Elapsed time: 0.49751s