{ "info": { "author": "Thiago Melo", "author_email": "thiago.lc.melo@gmail.com", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3" ], "description": "dspreview\n=========\n\nTool for merging DSP data from many providers in a single view. There are CLI\ntools for launching the workers responsible for parsing ``.csv`` files and \nstoring them in a MySQL database. There is also a web app where it is possible\nto have a complete report of the operation.\n\nConfiguration\n-------------\n\nYou must specify the following environment variables prior to usage:\n\n- ``DB_HOST`` the url or ip for the mysql server\n- ``DB_PORT`` the port for the mysql server\n- ``DB_NAME`` the name of the database\n- ``DB_USER`` a user with writing permission\n- ``DB_PASS`` the user's password\n\nIf you inted to develop or change something, it is also need:\n\n- ``DB_TEST_NAME`` the name of the database (for testing purposes)\n- ``DB_TEST_USER`` a user with writing permission (for testing purposes)\n- ``DB_TEST_PASS`` the user's password (for testing purposes)\n\nSince this project has support only for GCP (currently), the following \nenvironment variables are also mandatory:\n\n- ``GOOGLE_APPLICATION_CREDENTIALS`` the json file for an account with admin permissions for the `Storage`_ service.\n- ``GCP_BUCKET`` the bucket where the ``.csv`` file will be placed\n\nIt is possible to set the workers to consume a RabbitMQ queue, so it is necessary\nto specify the server info:\n\n- ``MQ_HOST`` the RabbitMQ server ip address\n- ``MQ_PORT`` the RabbitMQ port\n- ``MQ_VHOST`` the RabbitMQ virtual host\n- ``MQ_USER`` the RabbitMQ user\n- ``MQ_PASS`` the RabbitMQ password\n- ``MQ_QUEUE`` the RabbitMQ queue name (we might change for workers operating through exchanges later, so we can have multiple workers operating at the same time, but for now lets use one queue).\n\nA much better option would be to set all these variables in a file named ``.dspreview.csg`` in the users home folder:\n\n::\n\n {\n \"GOOGLE_APPLICATION_CREDENTIALS\": \"/home/user/service_account.json\",\n \"GCP_BUCKET\": \"...\",\n \"DB_HOST\": \"...\",\n \"DB_PORT\": \"3306\",\n \"DB_NAME\": \"...\",\n \"DB_USER\": \"...\",\n \"DB_PASS\": \"...\"\n }\n\nIf the above environment variables are set, you can initialize the system.\nIt will create the database, tables, and so on. It might be donne through:\n\n::\n\n $ dspreview init\n\n\nThere are currently two workers: ``dcm`` and ``dsp``. The ``dcm`` worker expects\nto find a file named ``dcm.csv`` inside the ``GCP_BUCKET``, with the \nfollowing structure:\n\n **[date, campaign_id, campaign, placement_id, placement, impressions, clicks, reach]**\n\nwhere:\n\n- ``date`` should be in format YYYY-MM-DD\n- ``campaign_id`` is an integer\n- ``campaign`` is a string with the information ``brand_subbrand``\n- ``placement_id`` is an integer\n- ``placement`` is a string with the information ``dsp_adtype``\n- ``impressions`` is an integer\n- ``clicks`` is an integer\n- ``reach`` is an float, please take care to not repeat this, since it is a calculated metric\n\nWhile the ``dsp`` worker expect to find a file with the dsp's name (like\n``dbm.csv`` or ``mediamath.csv``) and the following structure:\n\n **[date, campaign_id, campaign, impressions, clicks, cost]**\n\nwhere:\n\n- ``date`` should be in format YYYY-MM-DD\n- ``campaign_id`` is an integer\n- ``campaign`` is a string with the information ``brand_subbrand_adtype``\n- ``impressions`` is an integer\n- ``clicks`` is an integer\n- ``cost`` is a float\n\nIn order to launch a worker, you might use the command:\n\n::\n\n $ dspreview --worker dcm\n\nor:\n\n::\n\n $ dspreview --worker dsp\n\n\nIf the DSP is known in advance, you might run:\n\n::\n\n $ dspreview --worker dsp --dsp dbm\n\nor\n\n::\n\n $ dspreview --worker dsp --dsp mediamath\n\n\nWhen all files are stored in the MySQL database, the following command generates\nthe full report:\n\n::\n\n $ dspreview --generate-report\n\nThe web app might be run through:\n\n::\n\n $ dspreview serve --port 80\n\nThe default port is ``80``\n\nFinally, it is possible to put the worker to run in a loop, in this case, it\nwill consume a queue in the RabbitMQ. The messages must be:\n\n- ``dcm`` for the DCM worker\n- ``dsp`` for running all DSP workers\n- ``dsp.dbm`` for running a specific DSP worker (DBM in this case)\n- ``report`` for generating full report\n\nThe worker might be launched as:\n\n::\n\n $ dspreview operate\n\nIt is possible to add itens to the queue through:\n\n::\n\n $ dspreview --poke \"dsp.dbm\"\n\n\nClassifications\n---------------\n\nBesides the configuration described above, it is also important to understand the\n``classifications``. The classifications might be managed through the webserver\nin the underlying section.\n\nThe idea is that each line in the DCM and DSP files might be classified according\nto a **brand**, a **sub brand**, and a **dsp**. You can create a regex that\nwill be checked against a combination of fields.\n\nFor instance, it is a line in the DBM file:\n\n+------------+-------------+---------------------+-------------+--------+------------+ \n| date | campaign_id | campaign | impressions | clicks | cost | \n+============+=============+=====================+=============+========+============+ \n| 2018-01-01 | 128115 | acme_asprin_youtube | 6011070 | 11889 | 40334.2797 | \n+------------+-------------+---------------------+-------------+--------+------------+ \n\nYou might choose to apply the regex ``.*acme.*`` for classifying the brand as **Acme**, and the only necessary field is ``campaign``.\n\nChances are that you have another brand, say **Umbrella Corp**, and for some reason, you end up with a line like:\n\n+------------+-------------+---------------------+-------------+--------+------------+ \n| date | campaign_id | campaign | impressions | clicks | cost | \n+============+=============+=====================+=============+========+============+ \n| 2018-03-01 | 475987 | acme_solution | 4867867 | 46454 | 87897.4558 | \n+------------+-------------+---------------------+-------------+--------+------------+ \n\nNow, the regex above would classify both this lines as **Acme**. \n\nA solution would be change the regex to ``^128115acme.*`` applied to the \nconcatenation of fields ``campaign_id`` and ``campaign``, in order to identify \nads belonging to the brand **Acme**. \n\nFor identifying ads belonging to **Umbrella Corp** the regex could be ``^475987acme.*``\napplied to the concatenation of fields ``campaign_id`` and ``campaign``.\n\nThe fields that can be used are:\n\n1. campaign_id\n2. campaign\n3. placement_id (form DCM files only)\n4. placement (form DCM files only)\n\nFields will be concatenated in this order.\n\nThe regex patterns will be applied in the order in which they are registered \nin the database. The first matching a combination of fields will define the \nclassification, so it is necessary to avoid ubiquitous regex.\n\nPreparing for Development\n-------------------------\n\n1. Ensure ``pip`` and ``pipenv`` are installed.\n2. Make sure you also have ``default-libmysqlclient-dev`` or ``libmysqlclient-dev`` installed.\n3. Clone repository: ``https://github.com/thiagolcmelo/dspreview``\n4. Fetch development dependencies: ``make install``\n\n\nRunning Tests\n-------------\n\nRun tests locally using ``make`` if virtualenv is active:\n\n::\n\n $ make\n\nIf virtualenv isn't active then use\n\n::\n\n $ pipenv run make\n\n.. _Storage: https://cloud.google.com/storage/\n.. _SQL: https://cloud.google.com/sql/\n\n", "description_content_type": "", "docs_url": null, "download_url": "https://github.com/thiagolcmelo/dspreview/archive/v0.1.9.tar.gz", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/thiagolcmelo/dspreview", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "dspreview", "package_url": "https://pypi.org/project/dspreview/", "platform": "", "project_url": "https://pypi.org/project/dspreview/", "project_urls": { "Download": "https://github.com/thiagolcmelo/dspreview/archive/v0.1.9.tar.gz", "Homepage": "https://github.com/thiagolcmelo/dspreview" }, "release_url": "https://pypi.org/project/dspreview/0.1.9/", "requires_dist": [ "alembic (==1.0.0)", "cachetools (==2.1.0)", "certifi (==2018.8.24)", "chardet (==3.0.4)", "click (==6.7)", "dominate (==2.3.1)", "flask-bootstrap (==3.3.7.1)", "flask-login (==0.4.1)", "flask-migrate (==2.2.1)", "flask-sqlalchemy (==2.3.2)", "flask-testing (==0.7.1)", "flask-wtf (==0.14.2)", "flask (==1.0.2)", "google-api-python-client (==1.6.6)", "google-auth-httplib2 (==0.0.3)", "google-auth (==1.4.1)", "httplib2 (==0.11.3)", "idna (==2.7)", "itsdangerous (==0.24)", "jinja2 (==2.10)", "mako (==1.0.7)", "markupsafe (==1.0)", "mysqlclient (==1.3.13)", "oauth2client (==4.1.2)", "pandas (==0.23.4)", "pika (==0.12.0)", "pkginfo (==1.4.2)", "psycopg2 (==2.7.5)", "pyasn1-modules (==0.2.2)", "pyasn1 (==0.4.4)", "python-dateutil (==2.7.3)", "python-editor (==1.0.3)", "pytz (==2018.5)", "requests (==2.19.1)", "rsa (==3.4.2)", "six (==1.11.0)", "sqlalchemy (==1.2.11)", "twine (==1.11.0)", "uritemplate (==3.0.0)", "visitor (==0.1.3)", "werkzeug (==0.14.1)", "wtforms (==2.2.1)", "urllib3 (==1.23); python_version != \"3.2.*\"", "numpy (==1.15.1); python_version != \"3.3.*\"", "requests-toolbelt (==0.8.0); python_version < \"4\"", "tqdm (==4.25.0); python_version >= \"2.6\"" ], "requires_python": "", "summary": "a simple preview for dsp digital advertising information", "version": "0.1.9" }, "last_serial": 4208794, "releases": { "0.1.2": [ { "comment_text": "", "digests": { "md5": "ba971ebe21b4fe44d07a97ab1196a1a0", "sha256": "e46b83a5527eaed56288ceb85f4d961bedd9a89777f79cce60212959faad588b" }, "downloads": -1, "filename": "dspreview-0.1.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "ba971ebe21b4fe44d07a97ab1196a1a0", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 1102736, "upload_time": "2018-08-24T02:26:41", "url": "https://files.pythonhosted.org/packages/3c/1a/5387e9c6367185a02f569767c3e3ec6cb5c0fb4dd1848481f5ff7d84c35d/dspreview-0.1.2-py2.py3-none-any.whl" } ], "0.1.3": [ { "comment_text": "", "digests": { "md5": "67844c1c6d731cf689133721eea32805", "sha256": "ecadf917a143a8b30a020ffd06e7571c7746b836c1969b6c42c5bd6f2acb3f35" }, "downloads": -1, "filename": "dspreview-0.1.3-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "67844c1c6d731cf689133721eea32805", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 1108677, "upload_time": "2018-08-25T03:53:54", "url": "https://files.pythonhosted.org/packages/f2/02/d83c3929317670a5b4fc84a9fda5c191cd83a9119dd8957accab1f0f60d6/dspreview-0.1.3-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "829c11320dd608e8a63edbd5d326e9b2", "sha256": "6c3835804cfc9101fb37117c9ed14a6262a2533bff98f33ef1c8bb4cb1d21041" }, "downloads": -1, "filename": "dspreview-0.1.3.tar.gz", "has_sig": false, "md5_digest": "829c11320dd608e8a63edbd5d326e9b2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1107292, "upload_time": "2018-08-25T03:53:59", "url": "https://files.pythonhosted.org/packages/4a/69/39acbf9001c1766626093df269d7f1127d00a5edaf1709925a2728507e8b/dspreview-0.1.3.tar.gz" } ], "0.1.3.1": [ { "comment_text": "", "digests": { "md5": "db54729ddb005b3261d5b613d41d8341", "sha256": "740e4533eabc5b8e03922c868d5f74f605b10ef23c7abd2bd6cecc50ab78b9de" }, "downloads": -1, "filename": "dspreview-0.1.3.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "db54729ddb005b3261d5b613d41d8341", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 1108663, "upload_time": "2018-08-25T04:05:35", "url": "https://files.pythonhosted.org/packages/67/52/0cbba4d60b564ac9149ec128f3a71da33d10c9aff884626b57c8c2a3d2b8/dspreview-0.1.3.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "42853c12e65a17975bbac2cf3188dbbc", "sha256": "6d2aec86651a099cbce8f14aade844344b78f14689f904ec34bccb372cda5bc4" }, "downloads": -1, "filename": "dspreview-0.1.3.1.tar.gz", "has_sig": false, "md5_digest": "42853c12e65a17975bbac2cf3188dbbc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1107239, "upload_time": "2018-08-25T04:05:40", "url": "https://files.pythonhosted.org/packages/2b/3d/767ab6317c4df1b9f045e1244e58d152c6f74053b431e7707a602b793b5b/dspreview-0.1.3.1.tar.gz" } ], "0.1.4": [ { "comment_text": "", "digests": { "md5": "a6d0fed995e8b14204da14b65c8ed8af", "sha256": "329feced1c6acf98f355b94253fbebeb018892db1eb5212912e97e3afaf5869a" }, "downloads": -1, "filename": "dspreview-0.1.4-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "a6d0fed995e8b14204da14b65c8ed8af", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 1108640, "upload_time": "2018-08-25T04:13:06", "url": "https://files.pythonhosted.org/packages/73/60/99f7522e08c280de703d2c86903f1a720851172652b9305124122933957a/dspreview-0.1.4-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "3744f91422c9a14c688033346692eb07", "sha256": "9e56e58812a562812692557e189a7059ef98b43e78f157b8a8061e43e8dd1036" }, "downloads": -1, "filename": "dspreview-0.1.4.tar.gz", "has_sig": false, "md5_digest": "3744f91422c9a14c688033346692eb07", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1107251, "upload_time": "2018-08-25T04:13:11", "url": "https://files.pythonhosted.org/packages/3e/e0/87cab4ac8ff401f947c4bad2bd9c758043e3f5f50a43dbde315d343ed18a/dspreview-0.1.4.tar.gz" } ], "0.1.5": [ { "comment_text": "", "digests": { "md5": "01356219021dbd2af2c29961e7aa1042", "sha256": "04e1e6368b6a8c08dbc76351ac881c37650c1f3d5f33d166767746408162df9b" }, "downloads": -1, "filename": "dspreview-0.1.5-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "01356219021dbd2af2c29961e7aa1042", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 1110571, "upload_time": "2018-08-26T05:17:59", "url": "https://files.pythonhosted.org/packages/ce/81/9c6cb465480cf1a95fbacf5bcc96f342be8f16b6e99e9e7d16095cfa9abd/dspreview-0.1.5-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "4750b3fc311a55bb0bb353e68bfcea59", "sha256": "df6f39a4e4120272f03fb858e08fd2926b050a3edb785c0c96cc750b364be002" }, "downloads": -1, "filename": "dspreview-0.1.5.tar.gz", "has_sig": false, "md5_digest": "4750b3fc311a55bb0bb353e68bfcea59", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1110144, "upload_time": "2018-08-26T05:18:04", "url": "https://files.pythonhosted.org/packages/2e/9e/131841de00a459a7f3c0f471600219cd0629b38936b256369857406fe00a/dspreview-0.1.5.tar.gz" } ], "0.1.6": [ { "comment_text": "", "digests": { "md5": "55d5ca47e0b8255b850cf7fb9d93b25e", "sha256": "fa8cc12b23531fe45c6354a978018bc17d326105ac3bde712ad9791c43533073" }, "downloads": -1, "filename": "dspreview-0.1.6-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "55d5ca47e0b8255b850cf7fb9d93b25e", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 1110612, "upload_time": "2018-08-26T06:35:03", "url": "https://files.pythonhosted.org/packages/2e/76/d3ea1c1cc15a2bc35bb1483b2493f2f5db1c89b0a0b5553cd5ca23f4c1f8/dspreview-0.1.6-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "35ef65f07395e43e81433d6e82f0f776", "sha256": "bf7d82e379630b321ba038686c1844aba3df3cbb95ff8201af23c605e8201dbb" }, "downloads": -1, "filename": "dspreview-0.1.6.tar.gz", "has_sig": false, "md5_digest": "35ef65f07395e43e81433d6e82f0f776", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1110219, "upload_time": "2018-08-26T06:35:10", "url": "https://files.pythonhosted.org/packages/27/b5/421be92e7e2d4a8dffd935d5e8b4b0ae2de2e4213af973ca7b2e14c874ff/dspreview-0.1.6.tar.gz" } ], "0.1.7": [ { "comment_text": "", "digests": { "md5": "5c7c9f69dee4d645dee1b8461ae54667", "sha256": "c48b9115b353ad2d57fa5372b9918b9dbf70f9a9e5b7b28b2b7df3a575e303b3" }, "downloads": -1, "filename": "dspreview-0.1.7-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "5c7c9f69dee4d645dee1b8461ae54667", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 1110621, "upload_time": "2018-08-26T07:17:19", "url": "https://files.pythonhosted.org/packages/2d/65/f218d83f08dd0f5650a7ea8f96991a024e4f71fecbdab45624fc090c02c6/dspreview-0.1.7-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "91def58fbd1c3bab9ff85c8a09c4d4a8", "sha256": "f6db00252b9e911eb25b0b0693a675b19df0ce63940992b9d2a7d35d1549e076" }, "downloads": -1, "filename": "dspreview-0.1.7.tar.gz", "has_sig": false, "md5_digest": "91def58fbd1c3bab9ff85c8a09c4d4a8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1110513, "upload_time": "2018-08-26T07:17:24", "url": "https://files.pythonhosted.org/packages/7c/fc/5970644451242a6dca6931eef8c9f91692c67353067d3169e81c9e6b6a6d/dspreview-0.1.7.tar.gz" } ], "0.1.8": [ { "comment_text": "", "digests": { "md5": "b622f824b30223b9046ddb4fef9bc39a", "sha256": "51dca3bed01dc8656b72f5e24b0919f89536b71e3d7ac115e59c04a54492c0dc" }, "downloads": -1, "filename": "dspreview-0.1.8-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "b622f824b30223b9046ddb4fef9bc39a", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 1110631, "upload_time": "2018-08-26T07:28:08", "url": "https://files.pythonhosted.org/packages/94/a9/a24cba63460663f08ac842666ed9287668c0de507185988655fd983367b0/dspreview-0.1.8-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "7a22b95c486fbe6cbcf8b702d21356a1", "sha256": "d590ac81ea01c11b8b139ad9a555d273ada1f9c4a0e2d07d75649b2efa5e9275" }, "downloads": -1, "filename": "dspreview-0.1.8.tar.gz", "has_sig": false, "md5_digest": "7a22b95c486fbe6cbcf8b702d21356a1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1110529, "upload_time": "2018-08-26T07:28:12", "url": "https://files.pythonhosted.org/packages/8c/c4/adfe0ad219d08d83604849399bb6f54f42bae78343706b2fdb32e5c9f3dc/dspreview-0.1.8.tar.gz" } ], "0.1.9": [ { "comment_text": "", "digests": { "md5": "c457b08bc600c4b8253f1b8603410668", "sha256": "65e0a7653ad80cbf736d109ce85b7a28f779fb1d88dda857b92b34c7654c5ecf" }, "downloads": -1, "filename": "dspreview-0.1.9-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "c457b08bc600c4b8253f1b8603410668", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 1110811, "upload_time": "2018-08-26T17:35:39", "url": "https://files.pythonhosted.org/packages/e3/65/749eea02cff661aaff51b1bc35268ab3d51652db4641d0ce8cc37035409e/dspreview-0.1.9-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "e92e46884fdcbc3fa5a1cfe9f6fc1a51", "sha256": "0bbb3582ea4e4074f8432964da39ca7b8737c1b0ba7af9e004d7cab8723b8281" }, "downloads": -1, "filename": "dspreview-0.1.9.tar.gz", "has_sig": false, "md5_digest": "e92e46884fdcbc3fa5a1cfe9f6fc1a51", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1110653, "upload_time": "2018-08-26T17:35:44", "url": "https://files.pythonhosted.org/packages/b5/03/b2ec7951e520a5dc5dd6e52513ac18aabe40453b94d62a5b3170cc300bad/dspreview-0.1.9.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "c457b08bc600c4b8253f1b8603410668", "sha256": "65e0a7653ad80cbf736d109ce85b7a28f779fb1d88dda857b92b34c7654c5ecf" }, "downloads": -1, "filename": "dspreview-0.1.9-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "c457b08bc600c4b8253f1b8603410668", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 1110811, "upload_time": "2018-08-26T17:35:39", "url": "https://files.pythonhosted.org/packages/e3/65/749eea02cff661aaff51b1bc35268ab3d51652db4641d0ce8cc37035409e/dspreview-0.1.9-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "e92e46884fdcbc3fa5a1cfe9f6fc1a51", "sha256": "0bbb3582ea4e4074f8432964da39ca7b8737c1b0ba7af9e004d7cab8723b8281" }, "downloads": -1, "filename": "dspreview-0.1.9.tar.gz", "has_sig": false, "md5_digest": "e92e46884fdcbc3fa5a1cfe9f6fc1a51", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1110653, "upload_time": "2018-08-26T17:35:44", "url": "https://files.pythonhosted.org/packages/b5/03/b2ec7951e520a5dc5dd6e52513ac18aabe40453b94d62a5b3170cc300bad/dspreview-0.1.9.tar.gz" } ] }