{ "info": { "author": "Siu-Kei Muk (David)", "author_email": "muksiukei@gmail.com", "bugtrack_url": null, "classifiers": [], "description": "# Abstract Factory Broker\n\n## Introduction\n\nAbstract Factory Broker (`afb`) is a library that facilitates abstract factory management. It introduces a mechanism for transforming configuration files into Python objects through a network of abstract factories, allowing flexible specification of execution behavior.\n\n## Installation\n\nThis library supports Python 3.3+.\n\n```bash\n$ pip install afb\n```\n\n## Mechanism\n\nThis package consists of two classes:\n\n - `Manufacturer`:\n - Collection of factories of the same class.\n - `Broker`:\n - Collection of `Manufacturer`s.\n\n### `Manufacturer`\n\nA `Manufacturer` is a collection of factories of a class. It is responsible for delegating the object creation requests to the specified factories. The process go as follows:\n\n 1. Retrieves the factory, along with other information, according to the given key.\n 2. Prepares the arguments required by the factory, according to its signature.\n 3. Calls the factory and returns the result.\n\nEach request is done by a call to method `make` with parameters:\n\n - `method`: The key of the factory.\n - `params`: A `dict` of keyword argument values.\n\nIt is not uncommon that a factory depends on objects that are not directly representable in text, such as string or numbers. In this case, the request for the required object could be nested in the current request. The `Manufacturer` would first prepare the arguments by passing the sub-requests to the `Manufacturer` of the required classes through the network established by `Broker` (see below). After that, the factory is called to return the desired result.\n\n### `Broker`\n\nA `Broker` is a collection of `Manufacturer`s. It defines a network of `Manufacturer`s where they are able to pass object creation sub-requests to each other. It consists of a Class-to-Manufacturer mapping to pass the requests to their responsible `Manufacturer` to process.\n\nIt also accepts object creation requests through its `make` method, where an additional `cls` parameter is required to determine the right `Manufacturer` to use.\n\nLet's take a look at an example. Suppose there are two classes, `A` and `B`. `A` has a factory `fa` that depends on a `B` object along with a `float`:\n\n```python\ndef fa(b, x):\n \"\"\"Creates an `A` object.\n\n Args:\n b: An instance of `B` object.\n x: A float.\n \"\"\"\n ...\n return A(...)\n```\n\nAnd `B` has a factory `fb` that depends on a string:\n\n```python\ndef fb(s):\n \"\"\"Creates a `B` object.\n\n Args:\n s: String.\n \"\"\"\n ...\n return B(...)\n```\n\nAn instance of `A` can be created by first creating a `B` object, and passes it to `fa` with a `float`.\n\n```python\n# Create a `B` object\ns = \"some string\"\nb = fb(s)\n\n# Create an `A` object\nx = 3.14\na = fa(b, x)\n```\n\nSuppose the above factories are registered in their respective `Manufacturer`s (`mfr_a`, `mfr_b`) in a network defined by a `Broker` (`bkr`), `a` can be created by the following call:\n\n```python\nparams = {\n \"fa\": {\n \"b\": {\n \"fb\": {\"s\": \"some string\"}\n },\n \"x\": 3.14}}\n\na = bkr.make(cls=A, params=params)\n```\n\nThis allows us to export the object specification to an external configuration file provided by at execution time (or even dynamically generated), giving the program a notable configurability.\n\n---\n\n## Base Usage\n\nIt is best to illustrate how it works with an example. Suppose we have the following classes:\n\n```python\n# Class definitions\nclass A(object):\n ...\n\nclass B(object):\n ...\n\nclass C(object):\n ...\n```\n\nEach class has a factory, say:\n\n```python\n# Factories\ndef fa(x: int, y: float) -> A:\n return A(...)\n\ndef fb(z: str, a: A) -> B:\n return B(...)\n\ndef fc(x: float, b: B) -> C:\n return C(...)\n```\n\n**Note:** Here we are using the type hints available from Python 3.5 for easy illustration. In the actual code they are NOT required.\n\nNow we have three classes, with a factory for each of them. The first thing we need to do is to create a `Manufacturer` for each class, and register their factories.\n\n```python\n# Manufacturer for class B\n# ---------------------------\n# 1.1 Create Manufacturer\nmfr_b = Manufacturer(B)\n\n# 1.2 Register `fb` into `mfr_b`\n# 1.2.1 Provide descriptions for `fa`.\ndescriptions = {\n \"short\": \"Creates B from z, a.\"\n \"long\":\n \"\"\"Creates B from z, a, where ...\"\"\"\n}\n\n# 1.2.2 Provide signature, with descriptions\nsig_b = {\n \"z\": {\n \"type\": str,\n \"description\": \"Input mode of ...\"\n },\n \"a\": {\n \"type\": A,\n \"description\": \"Logic block A which ...\"\n }\n}\n\n# 1.2.3 Register factory.\n# We use the key \"fact_b\" to refer to the factory `fb`\nmfr_a.register(\"fact_b\", fb, sig_b, descriptions=descriptions)\n```\n\nFinally, register all the `Manufacturer`s to a `Broker`:\n\n```python\n# Create a Broker\nbroker = Broker()\n\n# Register Manufacturers\nbroker.register(mfr_a)\nbroker.register(mfr_b)\nbroker.register(mfr_c)\n# Or one can make a single function call:\n# `broker.register_all([mfr_a, mfr_b, mfr_c])\n```\n\nFrom this point, `broker`, as well as the registered `Manufacturer`s, can be used to make objects. For example, an instance of `A` can be created in the following ways:\n\n```python\n# 1. Create by `Manufacturer.make` call\nparams = {\n \"x\": -2,\n \"y\": 3.14\n}\n\na = mfr_a.make(\"fact_a\", params)\n\n# 2. Create by `Broker.make` call\nspec = {\n \"fact_a\": params\n}\n\na = broker.make(A, spec)\n```\n\nThe `Broker.make` method accepts two arguments:\n\n 1. Target class\n 2. Object specification\n\nThe target class (`cls`) is for the `Broker` to retrieve the right `Manufacturer`, while the object speicifcation is a singleton `dict` that specifies:\n\n 1. The factory to use as the key\n 2. The parameters to pass to the factory as the value\n\nThe object specification can be nested. Consider making an object `C`, which uses `fb` for the required `B` in `fc`, and `fa` for the required `A` in `fb`:\n\n```python\nspec = {\n \"fact_c\": {\n \"x\": 2.7183\n \"b\": {\n \"fact_b\": {\n \"z\": \"Some mode\",\n \"a\": {\n \"fact_a\": {\n \"x\": -2,\n \"y\": 3.1416\n }\n }\n }\n }\n }\n}\n\nc = broker.make(C, spec)\n```\n\nThe execution goes as follows:\n\n 1. `Broker` retrieves `Manufacturer` of `C`, `mfr_c`, and calls `mfr_c.make`\n 2. `mfr_c` retrieves factory keyed by `\"fact_c\"`, `fc`, and prepares the arguments `x` and `b` for it.\n 3. As `fc` requires `x` as a `float`, and the given value is itself a `float`, it proceeds to the next parameter.\n 4. `fc` requires `b` as a `B`, and the given value is a singleton `dict`, `spec_b`, it is interpreted as an object specification. `mfr_c` then makes a `Broker.make` call for object instantiation.\n 5. `Broker` retrieves `Manufacturer` of `B`, `mfr_b`, and calls `mfr_b.make` with `spec_b`.\n 6. `mfr_b` retrieves factory keyed by `\"fact_b\"`, `fb`, and prepares the arguments `z` and `a` for it.\n 7. As `fb` requires `z` as a `str`, and the given value is itself a `str`, it proceeds to the next parameter.\n 8. `fb` requires `a` as an `A`, and the given value is a singleton `dict`, `spec_a`, it is interpreted as an object specification. `mfr_b` then makes a `Broker.make` call for object instantiation.\n 9. `Broker` retrieves `Manufacturer` of `A`, `mfr_a`, and calls `mfr_a.make` with `spec_a`.\n 10. `mfr_a` retrieves factory keyed by `\"fact_a\"`, `fa`, and prepares the arguments `x` and `y` for it.\n 11. As `fa` requires `x` as an `int`, and the given value is itself an `int`, it proceeds to the next parameter.\n 12. `fa` requires `y` as a `float`, and the given value is itself a `float`, parameter preparation is done for `fa`.\n 13. `mfr_a` calls `fa` with the prepared `x` and `y`, and returns the result `obj_a` from `fa` to the caller.\n 14. `Broker` returns the `obj_a` to the caller.\n 15. `mfr_b` completes its parameter preparation. It calls `fb` with the prepared `z` and `a`, and returns the result `obj_b` to the caller.\n 16. `Broker` returns the `obj_b` to the caller.\n 17. `mfr_c` completes its parameter preparation. It calls `fc` with the prepared `x` and `b`, and returns the result `obj_c` to the caller.\n 18. `Broker` returns the `obj_c` to the caller.\n\n**Note:** The above is only for illustration purpose. In real applications, the specifications are usually loaded from configuration files, and the classes and factories are defined in dedicated packages and modules with a registry for management.\n\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "https://github.com/dave-msk/broker/archive/v1.3.0.tar.gz", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/dave-msk/afb", "keywords": "afb,factory,abstract factory,config", "license": "", "maintainer": "", "maintainer_email": "", "name": "afb", "package_url": "https://pypi.org/project/afb/", "platform": "", "project_url": "https://pypi.org/project/afb/", "project_urls": { "Download": "https://github.com/dave-msk/broker/archive/v1.3.0.tar.gz", "Homepage": "https://github.com/dave-msk/afb" }, "release_url": "https://pypi.org/project/afb/1.3.0/", "requires_dist": null, "requires_python": "", "summary": "A base for abstract factory in Python", "version": "1.3.0" }, "last_serial": 5248043, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "5a6c2b2a3efe6f9ceb0edbc841e6cba5", "sha256": "5fa94ac062abb2a09a183779cbf5abf6edbb41510b53b432a813ed6f2609e5f6" }, "downloads": -1, "filename": "afb-0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "5a6c2b2a3efe6f9ceb0edbc841e6cba5", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 7331, "upload_time": "2018-06-03T12:59:46", "url": "https://files.pythonhosted.org/packages/d2/fc/5eb7816847a599944f6c639a5af52912d728a43b6d75a4137a9ecfb39f6e/afb-0.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "50ca3a8dd0ca41e47678f855753ac523", "sha256": "df9eae9a6d8b687cd621b8467b7123b0fce82bbb864d7c0cc926175687030c72" }, "downloads": -1, "filename": "afb-0.1.tar.gz", "has_sig": false, "md5_digest": "50ca3a8dd0ca41e47678f855753ac523", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5539, "upload_time": "2018-06-03T12:59:47", "url": "https://files.pythonhosted.org/packages/00/01/2eaffe2f44d1d95ba8220437da11224256c300c4241b44fab3e850cc831c/afb-0.1.tar.gz" } ], "0.2": [ { "comment_text": "", "digests": { "md5": "f1733eaaa738462c3678e0e858d9c8a9", "sha256": "93eec30b4984a4cf46b77972f5a8fb2cdc71d75c8ef29fb1ae5398eaff7032a1" }, "downloads": -1, "filename": "afb-0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "f1733eaaa738462c3678e0e858d9c8a9", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 7340, "upload_time": "2018-06-04T14:28:41", "url": "https://files.pythonhosted.org/packages/08/cc/9a316eb4c35ba6d31660c0cc8c5a2ab22d79484265c6571aaf6609afd89f/afb-0.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "688b3fa6a54bfaac41ef4611bf4af95a", "sha256": "142352c62b7bb86a8624b5f8cf84bab7b529a256a8a94df16dc0598e6acb562a" }, "downloads": -1, "filename": "afb-0.2.tar.gz", "has_sig": false, "md5_digest": "688b3fa6a54bfaac41ef4611bf4af95a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5558, "upload_time": "2018-06-04T14:28:42", "url": "https://files.pythonhosted.org/packages/4d/04/60f218239b934c1113f52c1f24f26330e21edf9b40e2203ebb8d46230371/afb-0.2.tar.gz" } ], "0.3": [ { "comment_text": "", "digests": { "md5": "76117fceaef3aff00c411c30e9b85e6c", "sha256": "3633b73596e2a03f18d774febc4fe2a4b2fa6af84ad89d7b295ddada43c02747" }, "downloads": -1, "filename": "afb-0.3-py3-none-any.whl", "has_sig": false, "md5_digest": "76117fceaef3aff00c411c30e9b85e6c", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 7453, "upload_time": "2018-06-08T15:17:46", "url": "https://files.pythonhosted.org/packages/ec/59/a1c0d39c3eaeef3847b1da454e4ec951435db49613521eb3f9b525fd9f13/afb-0.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ba9d64a344dd8d84742226570607a4d7", "sha256": "0acedd5d382c4ce5f7513c5c36550f1866acdf93e1556afd89bd007ac606a0cc" }, "downloads": -1, "filename": "afb-0.3.tar.gz", "has_sig": false, "md5_digest": "ba9d64a344dd8d84742226570607a4d7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5671, "upload_time": "2018-06-08T15:17:47", "url": "https://files.pythonhosted.org/packages/9d/48/6f8464161c4de444d897236d585ed915ba45c48db8220e6379ecc7b7c06a/afb-0.3.tar.gz" } ], "0.4.1": [ { "comment_text": "", "digests": { "md5": "571d4edc604f191f555e5158f0af2cb5", "sha256": "c66989dc5aadd175772d04d0477310d3133304c265f73c4137b0c45566fcfbba" }, "downloads": -1, "filename": "afb-0.4.1-py3-none-any.whl", "has_sig": false, "md5_digest": "571d4edc604f191f555e5158f0af2cb5", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 8800, "upload_time": "2018-06-09T10:53:26", "url": "https://files.pythonhosted.org/packages/43/d0/9745ac6d72f5f3e8b5272df71d7aed885f3292a9118c068b9fe091d580d1/afb-0.4.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "b33dea9bc33e9c289ed875fbaec00172", "sha256": "c5d9be16a450b85ba1cd5a611d92cf04ee48ee27429ac7134fc5a13fd9d42a17" }, "downloads": -1, "filename": "afb-0.4.1.tar.gz", "has_sig": false, "md5_digest": "b33dea9bc33e9c289ed875fbaec00172", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6680, "upload_time": "2018-06-09T10:53:28", "url": "https://files.pythonhosted.org/packages/f6/ce/22198e8b4d8f7fa53d2e1b4cf8cf855c37c13412275853b69f365007c16a/afb-0.4.1.tar.gz" } ], "0.4.2": [ { "comment_text": "", "digests": { "md5": "22df9f87f9e9bd5bd1141851f087f188", "sha256": "c616baf7aa1f7394460303b8f10d619c597df4d4f55625ed86dccdba3f5d5b9c" }, "downloads": -1, "filename": "afb-0.4.2-py3-none-any.whl", "has_sig": false, "md5_digest": "22df9f87f9e9bd5bd1141851f087f188", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 8777, "upload_time": "2018-06-24T22:42:07", "url": "https://files.pythonhosted.org/packages/be/1d/5686f4e463197c2227921435eb448120ec6576e4bd2df8f5293871dfa4aa/afb-0.4.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "0e871435af5ba5b0a64ac84cb9455167", "sha256": "13c9c9ca0df9e9b8f17ea42ecf69f99a9421e544af1613ddc9e175ce8d9d1800" }, "downloads": -1, "filename": "afb-0.4.2.tar.gz", "has_sig": false, "md5_digest": "0e871435af5ba5b0a64ac84cb9455167", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6691, "upload_time": "2018-06-24T22:42:09", "url": "https://files.pythonhosted.org/packages/25/8c/2dd022aba040ee3735fc85ab8f640a2627ae41742cd37d9f64659f1448d1/afb-0.4.2.tar.gz" } ], "0.4.3": [ { "comment_text": "", "digests": { "md5": "7db95f259a205feb16fa4a3c2a436837", "sha256": "6233fd0dfa25d107bed1cb2dc2f099b190a778f050b4ca8ea9ef17a8d71e2c07" }, "downloads": -1, "filename": "afb-0.4.3-py3-none-any.whl", "has_sig": false, "md5_digest": "7db95f259a205feb16fa4a3c2a436837", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 17171, "upload_time": "2018-07-14T13:59:49", "url": "https://files.pythonhosted.org/packages/eb/29/98dce76a395fd099594ab63fbadca89382f252e5e866a32e072fdf305943/afb-0.4.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "25ddc95e45abe2ad821ac4c0d5b4221f", "sha256": "a190e39bf98fa1203844e69e3133bf1c61f485618b128f4b7048ba6d9f951d5d" }, "downloads": -1, "filename": "afb-0.4.3.tar.gz", "has_sig": false, "md5_digest": "25ddc95e45abe2ad821ac4c0d5b4221f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9536, "upload_time": "2018-07-14T13:59:51", "url": "https://files.pythonhosted.org/packages/82/20/48846065c4fd2b3501fdd8a6660525eb476543c7b1e53e38310867fb82b1/afb-0.4.3.tar.gz" } ], "1.0.0": [ { "comment_text": "", "digests": { "md5": "5e5fa8168f2f4dcde119ccb30d1072c0", "sha256": "714238892a069079692e9de44fff80f2f626f4a813369695b12c78683b80a0b6" }, "downloads": -1, "filename": "afb-1.0.0-py3-none-any.whl", "has_sig": false, "md5_digest": "5e5fa8168f2f4dcde119ccb30d1072c0", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 17859, "upload_time": "2018-08-01T14:38:52", "url": "https://files.pythonhosted.org/packages/10/e7/c7fdaac15f14623d10a546066f2e3218ce209197f11728eb5eed335a6943/afb-1.0.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "8833f60fc0eb7e6be8b2dff988724106", "sha256": "9502cc025e3255a59964cdaae9ac4a6e705bd405c88ab3b555c1cc1b372400c1" }, "downloads": -1, "filename": "afb-1.0.0.tar.gz", "has_sig": false, "md5_digest": "8833f60fc0eb7e6be8b2dff988724106", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10197, "upload_time": "2018-08-01T14:38:53", "url": "https://files.pythonhosted.org/packages/00/ec/175150f504549be62ff734280bedaa5f485f66afa6b0fe8c05388a342c03/afb-1.0.0.tar.gz" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "8d8169eaf59d4da827497c7cdb3271ff", "sha256": "d4abf07724b983ca6c4ffdb4c6f7d408d33727fc1a1950e33bfec8f43e65d19a" }, "downloads": -1, "filename": "afb-1.0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "8d8169eaf59d4da827497c7cdb3271ff", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 17879, "upload_time": "2018-08-11T06:11:55", "url": "https://files.pythonhosted.org/packages/33/59/ddfee99d87315d2911f2086cee2e0a5c35579f91d846ee4566a3f01423b0/afb-1.0.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "6b7c5c6d4a99edb5548421d9e81738b7", "sha256": "93e590bf70f01e951c1801b0a5e85d6fc87f2a3f3ecb32f44612e613e62461db" }, "downloads": -1, "filename": "afb-1.0.1.tar.gz", "has_sig": false, "md5_digest": "6b7c5c6d4a99edb5548421d9e81738b7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10217, "upload_time": "2018-08-11T06:11:56", "url": "https://files.pythonhosted.org/packages/e0/20/0f777f0e24acd151321d465fb5caee3dac4257e8e8880029415426a7017e/afb-1.0.1.tar.gz" } ], "1.0.2": [ { "comment_text": "", "digests": { "md5": "3758e53fdcf69603d9944dd4097871b0", "sha256": "d2461af2c66666de7c37804b5ca3f11563e8acdc2b52f15a6f73bd23ae024848" }, "downloads": -1, "filename": "afb-1.0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "3758e53fdcf69603d9944dd4097871b0", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 17875, "upload_time": "2018-08-21T03:56:28", "url": "https://files.pythonhosted.org/packages/91/ee/36931a075c5f3575e83f72f1d31efd38a19c7e4f84c5b6daa38da7d10b7f/afb-1.0.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "225b718a1f7f34fdab01dc458f3fa047", "sha256": "fd5002d71adc7ce738d108209f94f1b5d79b42558b2ecc2644fe2797812398bd" }, "downloads": -1, "filename": "afb-1.0.2.tar.gz", "has_sig": false, "md5_digest": "225b718a1f7f34fdab01dc458f3fa047", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10213, "upload_time": "2018-08-21T03:56:30", "url": "https://files.pythonhosted.org/packages/9f/14/d2f79a07cc4a8e33e75f0ce2bfee9c7d8545e1e100b7d46a54782bd941ca/afb-1.0.2.tar.gz" } ], "1.1": [ { "comment_text": "", "digests": { "md5": "0b50e1337f9b4701b4d7b773a704ad61", "sha256": "f900aae08791d441688a1c67e21c14906639c7ae7617f2d684a41a409976dade" }, "downloads": -1, "filename": "afb-1.1-py3-none-any.whl", "has_sig": false, "md5_digest": "0b50e1337f9b4701b4d7b773a704ad61", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 21066, "upload_time": "2018-09-29T12:21:17", "url": "https://files.pythonhosted.org/packages/4a/d7/7b11d48316d94d986f6a5fda79368ee3e7ad5964b81bc59be03004551f58/afb-1.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "0ddce2c93906f13713c614ae6bc9250a", "sha256": "97505e52f2b93e8b557b7ced46507718975dfce25b973856d193375aadb0e9e2" }, "downloads": -1, "filename": "afb-1.1.tar.gz", "has_sig": false, "md5_digest": "0ddce2c93906f13713c614ae6bc9250a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11476, "upload_time": "2018-09-29T12:21:18", "url": "https://files.pythonhosted.org/packages/11/03/16370b133c905e444e37d22a01ab08424bb3349ecb197d2dd9e93eba6d25/afb-1.1.tar.gz" } ], "1.1.1": [ { "comment_text": "/home/david/.pypirc", "digests": { "md5": "266b8d454304663e47c79768993ece78", "sha256": "33d291dd9d0b1d97412d8a51a2b1b080b7995c3f5b59ce0eb310fb38c8f863e4" }, "downloads": -1, "filename": "afb-1.1.1-py3-none-any.whl", "has_sig": false, "md5_digest": "266b8d454304663e47c79768993ece78", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 22671, "upload_time": "2018-10-24T12:29:56", "url": "https://files.pythonhosted.org/packages/27/21/2080aa5e2f5fbc476a2b9064abf82b3c196dfb5dfca1335708e97abc3eda/afb-1.1.1-py3-none-any.whl" }, { "comment_text": "/home/david/.pypirc", "digests": { "md5": "3cdba161bf5d5bb097f0c6b00d48678e", "sha256": "4e750dc4dae4501a83b5fff58a8dde08f782fc828d31239c760729f1e4707831" }, "downloads": -1, "filename": "afb-1.1.1.tar.gz", "has_sig": false, "md5_digest": "3cdba161bf5d5bb097f0c6b00d48678e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13700, "upload_time": "2018-10-24T12:29:57", "url": "https://files.pythonhosted.org/packages/42/0e/04c133103bd9f0901596486c7493b06d84a5521836f51553483f2ef24982/afb-1.1.1.tar.gz" } ], "1.2.0": [ { "comment_text": "/home/david/.pypirc", "digests": { "md5": "7b18809a5b58b3e54bb29ab1b31c0bd7", "sha256": "9c3e1aa1209d7236657a720cf0f0b308578eb1386eee5543e921e37c06890ef3" }, "downloads": -1, "filename": "afb-1.2.0-py3-none-any.whl", "has_sig": false, "md5_digest": "7b18809a5b58b3e54bb29ab1b31c0bd7", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 24821, "upload_time": "2018-11-07T12:52:00", "url": "https://files.pythonhosted.org/packages/39/51/a2749dacceff1de25109001b267c037e8acd8f780be026da43e93f654fea/afb-1.2.0-py3-none-any.whl" }, { "comment_text": "/home/david/.pypirc", "digests": { "md5": "96674fee2d624002fe9f18d36aee339e", "sha256": "b757e6c34490ae7add3065bce2f043bd8239b8d6598b7e49f5b05a65fc6c659d" }, "downloads": -1, "filename": "afb-1.2.0.tar.gz", "has_sig": false, "md5_digest": "96674fee2d624002fe9f18d36aee339e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17688, "upload_time": "2018-11-07T12:52:02", "url": "https://files.pythonhosted.org/packages/53/c2/25f49f0841c8ebb63545f8dabaa5ff9334fde4f6123c36a21da50895afc7/afb-1.2.0.tar.gz" } ], "1.2.1": [ { "comment_text": "/home/david/.pypirc", "digests": { "md5": "45c21cb24bbf1ca70694fb1bb6714607", "sha256": "e83e8869d1cc8be4ae7f1b3914bb343f1090629b17d9257df9e500a7d1829db9" }, "downloads": -1, "filename": "afb-1.2.1-py3-none-any.whl", "has_sig": false, "md5_digest": "45c21cb24bbf1ca70694fb1bb6714607", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 24932, "upload_time": "2018-11-12T13:46:21", "url": "https://files.pythonhosted.org/packages/39/a1/7d9d89ce224a8f3ee05bba2d0151b68accea7eeab22915d8d40f4af10f43/afb-1.2.1-py3-none-any.whl" }, { "comment_text": "/home/david/.pypirc", "digests": { "md5": "4a0342eedaece0a05530f2da04afc2ee", "sha256": "7e2403f50068c9e5989861cd817ef6ec503057b24bfc1ad27d8367cceb010b2f" }, "downloads": -1, "filename": "afb-1.2.1.tar.gz", "has_sig": false, "md5_digest": "4a0342eedaece0a05530f2da04afc2ee", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17766, "upload_time": "2018-11-12T13:46:23", "url": "https://files.pythonhosted.org/packages/2f/97/cf4e1dedaac59f6e60d339e368c3da4fde0cec4da171c52bc9bb520f2d28/afb-1.2.1.tar.gz" } ], "1.2.2": [ { "comment_text": "", "digests": { "md5": "4cc7b15e24c6c9088788ac825da349cb", "sha256": "10cfeab5d8e7b03e7646de8ca4b92cc22259206ab8e539a7fd0634aa6039e8b7" }, "downloads": -1, "filename": "afb-1.2.2-py3-none-any.whl", "has_sig": false, "md5_digest": "4cc7b15e24c6c9088788ac825da349cb", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 25546, "upload_time": "2019-02-17T07:53:56", "url": "https://files.pythonhosted.org/packages/21/1f/ff3a141b259e346723f3ef7b99cd5dc59b0783daa936108bed65c16426e2/afb-1.2.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "60ec67a3708ee996a8df37d47b00d6ea", "sha256": "b2d0128ebe8e38967676acae2fe68bf457b34ef4aefc697570af92254a6230f2" }, "downloads": -1, "filename": "afb-1.2.2.tar.gz", "has_sig": false, "md5_digest": "60ec67a3708ee996a8df37d47b00d6ea", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18120, "upload_time": "2019-02-17T07:53:58", "url": "https://files.pythonhosted.org/packages/97/25/563fed6152791f89ccf214a8cfa26efe9ea4a4995ff348b72345d022f166/afb-1.2.2.tar.gz" } ], "1.2.2.1": [ { "comment_text": "", "digests": { "md5": "1460f48bdbc0461b1c6661ce34ac3b72", "sha256": "ef91da4430e8e23aae34594bf8cf3b1e7f7434195e755e77bb50bc069e53a666" }, "downloads": -1, "filename": "afb-1.2.2.1-py3-none-any.whl", "has_sig": false, "md5_digest": "1460f48bdbc0461b1c6661ce34ac3b72", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 25561, "upload_time": "2019-02-17T08:20:59", "url": "https://files.pythonhosted.org/packages/62/61/67ccd8a2790c9668ef13d38102211eaecfff2200383f316a6500de2a2cdd/afb-1.2.2.1-py3-none-any.whl" } ], "1.3.0": [ { "comment_text": "/home/david/.pypirc", "digests": { "md5": "9823c4752c40830fa720e3ca97bab643", "sha256": "9383f421103cc52ca091beff755739be83d679d4e91c735f183cc2bb848e1124" }, "downloads": -1, "filename": "afb-1.3.0-py3-none-any.whl", "has_sig": false, "md5_digest": "9823c4752c40830fa720e3ca97bab643", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 26346, "upload_time": "2019-05-09T15:16:23", "url": "https://files.pythonhosted.org/packages/e0/96/ba5d365d6cfa27f7597c68aa5c34deb09fb1494937441c9308f19eeda9bb/afb-1.3.0-py3-none-any.whl" }, { "comment_text": "/home/david/.pypirc", "digests": { "md5": "6b6da3a60ddd721a838dfc7709202ba6", "sha256": "924c88bf13f6e5ce175f30b0bd2d0ad09d152663d567c3ae2e780c6cb3c5c73d" }, "downloads": -1, "filename": "afb-1.3.0.tar.gz", "has_sig": false, "md5_digest": "6b6da3a60ddd721a838dfc7709202ba6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18760, "upload_time": "2019-05-09T15:16:25", "url": "https://files.pythonhosted.org/packages/88/30/ea2f6dd69f0b46adbd7db250dbb74f8f28b1c92913f12888f89e4db479c2/afb-1.3.0.tar.gz" } ] }, "urls": [ { "comment_text": "/home/david/.pypirc", "digests": { "md5": "9823c4752c40830fa720e3ca97bab643", "sha256": "9383f421103cc52ca091beff755739be83d679d4e91c735f183cc2bb848e1124" }, "downloads": -1, "filename": "afb-1.3.0-py3-none-any.whl", "has_sig": false, "md5_digest": "9823c4752c40830fa720e3ca97bab643", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 26346, "upload_time": "2019-05-09T15:16:23", "url": "https://files.pythonhosted.org/packages/e0/96/ba5d365d6cfa27f7597c68aa5c34deb09fb1494937441c9308f19eeda9bb/afb-1.3.0-py3-none-any.whl" }, { "comment_text": "/home/david/.pypirc", "digests": { "md5": "6b6da3a60ddd721a838dfc7709202ba6", "sha256": "924c88bf13f6e5ce175f30b0bd2d0ad09d152663d567c3ae2e780c6cb3c5c73d" }, "downloads": -1, "filename": "afb-1.3.0.tar.gz", "has_sig": false, "md5_digest": "6b6da3a60ddd721a838dfc7709202ba6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18760, "upload_time": "2019-05-09T15:16:25", "url": "https://files.pythonhosted.org/packages/88/30/ea2f6dd69f0b46adbd7db250dbb74f8f28b1c92913f12888f89e4db479c2/afb-1.3.0.tar.gz" } ] }