{ "info": { "author": "CenturyLink Managed Services Team", "author_email": "managedos@ctl.io", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6" ], "description": "=================================================\nCenturyLink Cloud ManagedOS Python Utilities [1]_\n=================================================\n\n***************\nGetting Started\n***************\n\nTo install the ``clc_msa_utils`` package, use the command below.::\n\n pip3 install clc_msa_utils\n\n*******\nKVStore\n*******\n\nThis is a utility class that abstracts loading a configuration from Consul or ETCD. This class supports perodically\nreloading the configuration from the configured key-value store, and notifying a callback method after reloading.\nThe following may be passed into the constructor, or pulled from env variables:\n\n+------------------+-----------------------+--------------------------------------------+-----------+\n| Constructor Arg | Environment Variable | Description | Default |\n+==================+=======================+============================================+===========+\n| consul_host | CONSUL_HOST | Host for Consul | None |\n+------------------+-----------------------+--------------------------------------------+-----------+\n| consul_port | CONSUL_PORT | Port for Consul | 8500 |\n+------------------+-----------------------+--------------------------------------------+-----------+\n| etcd_host | ETCD_HOST | Host for etcd | localhost |\n+------------------+-----------------------+--------------------------------------------+-----------+\n| etcd_port | ETCD_PORT | Port for etcd | 2379 |\n+------------------+-----------------------+--------------------------------------------+-----------+\n| kv_prefix | KV_PREFIX | Prefix for config path | \"\" |\n+------------------+-----------------------+--------------------------------------------+-----------+\n| reload_seconds | RELOAD_CONFIG_PERIOD | Seconds between config reloads | 20 |\n+------------------+-----------------------+--------------------------------------------+-----------+\n| reload_enabled | RELOAD_ENABLED | If true, reloads the config periodically. | False |\n+------------------+-----------------------+--------------------------------------------+-----------+\n\nTODO: Future Features\n~~~~~~~~~~~~~~~~~~~~~~\n* Nested Configurations: Will enable you specify a list of prefixes to use to overlay configuration values.\n\nExample Usage\n~~~~~~~~~~~~~\n\n.. code:: python\n :number-lines: 1\n\n from clc_msa_utils.kv_store import KVStore\n\n # Create config store\n kv_store = KVStore(\n kv_prefix=os.getenv('CONSUL_PREFIX') or os.getenv('ETCD_PREFIX', '/config/retry-listener'),\n reload_enabled=True\n )\n\n # Setup on_reload handler\n def initialize():\n kv_store.on_reload(dynamic_configuration)\n\n # Implement reload handler to check if attributes changed, and then perform some logic.\n def dynamic_configuration(old, new):\n if not old or old.get('exchange_configs') != new.get('exchange_configs') \\\n or kv_store.attribute_changed(\"rabbit_host\",\"rabbit_port\",\"rabbit_user\",\"rabbit_password\",\"rabbit_queue_name\"):\n setup_queue()\n\n # Use kv_store to pull configuration values.\n def setup_queue():\n rabbit_host = kv_store.get('rabbit_host', 'localhost')\n rabbit_port = int(kv_store.get('rabbit_port', 5672))\n\n\n************\nLogManager\n************\n\nThis is a utility class that uses a KVStore to configure the python logging facility. It uses KVStore's dynamic ability\nto reload its configuration to update Python's logging facility.\n\n+------------------+---------------------------------------------+--------------------+\n| Constructor Arg | Description | Default |\n+==================+=============================================+====================+\n| kv_store | Backing KVStore used to configure logging. | None/Required |\n+------------------+---------------------------------------------+--------------------+\n\nKVStore configurations relative to the kv_prefix\n\n+------------------------------+---------------------------------------------+-----------------------------------------------------------------------+\n| Key | Description | Default |\n+==============================+=============================================+=======================================================================+\n| logging_filename | The file where logs are written. | None (Std Out) |\n+------------------------------+---------------------------------------------+-----------------------------------------------------------------------+\n| logging_filemode | The file mode if a filename is specified | None |\n+------------------------------+---------------------------------------------+-----------------------------------------------------------------------+\n| logging_format | The format of the logging line | [%(threadName)s] %(asctime)s - %(levelname)s - %(name)s - %(message)s |\n+------------------------------+---------------------------------------------+-----------------------------------------------------------------------+\n| logging_datefmt | The date format of the date written | %m/%d/%Y %I:%M:%S %p |\n+------------------------------+---------------------------------------------+-----------------------------------------------------------------------+\n| logging_level | Root logging Level | INFO |\n+------------------------------+---------------------------------------------+-----------------------------------------------------------------------+\n| logging_config/log_name_1 | Logging level for | None |\n+------------------------------+---------------------------------------------+-----------------------------------------------------------------------+\n| logging_config/log_name_2 | Logging level for | None |\n+------------------------------+---------------------------------------------+-----------------------------------------------------------------------+\n| logging_config/log_name_n | Logging level for | None |\n+------------------------------+---------------------------------------------+-----------------------------------------------------------------------+\n\n\nExample Usage\n~~~~~~~~~~~~~\nHere are the available configurations for logging provided by KVStore using an example of `/config/local_config`\n\n.. code:: json\n\n {\n \"config\" : {\n \"local_config\" : {\n \"logging_level\": \"INFO\",\n \"logging_config\": {\n \"default\": \"DEBUG\",\n \"KVStore\": \"DEBUG\",\n \"LogManager\": \"DEBUG\"\n }\n }\n }\n }\n\n\n\n.. code:: python\n :number-lines: 1\n\n from clc_msa_utils.kv_store import KVStore\n from clc_msa_utils.log_manager import LogManager\n\n kv_store = KVStore(\n kv_prefix=os.getenv('CONSUL_PREFIX') or\n os.getenv('ETCD_PREFIX') or\n os.getenv('KV_PREFIX', '/config/local_config'),\n reload_enabled=True\n )\n\n log_manager = LogManager(kv_store=kv_store)\n\n\n************\nQueueFactory\n************\n\nThis is a utility class that abstracts the creation of Queue Producers and Queue Consumers/Listeners.\nThe producers and consumers are constructed based on a configuration passed into their respective methods\nas a parameter. The following is an example JSON configuration of a Queue Consumer configuration that\ncould be stored in a key-value store such as ETCD or Consul. Notice that the `queue_config` attribute is\nan array and can be all of the necessary configuration for both your Consumer and Producers.\n\n.. code:: json\n\n {\n \"queue_config\": [\n {\n \"name\": \"make_managed_request\",\n \"type\": \"consumer\",\n \"exchange\": {\n \"name\": \"managed_server\",\n \"type\": \"x-delayed-message\",\n \"arguments\": {\"x-delayed-type\": \"topic\"},\n \"durable\": true\n },\n \"queue\": \"make_managed_mos_cmdb\",\n \"binding_key\": \"requested.make_managed\",\n \"host\": \"rabbitmq.managed-services-dev.skydns.local\",\n \"port\": \"5672\",\n \"auth\": {\n \"user\": \"guest\",\n \"password\": \"guest\"\n }\n }\n ]\n }\n\nExample Usage\n~~~~~~~~~~~~~\n\n.. code:: python\n :number-lines: 1\n\n from clc_msa_utils.queueing import QueueFactory\n\n # Get config (eg. from kv_store)\n queue_config = kv_store.get('queue-config')\n\n # Initialize QueueFactory\n q_factory = QueueFactory()\n\n # Generate Queue Consumers (QueueConsumer)\n consumers = q_factory.create_consumers(queue_config)\n\n # Generate Queue Producers (QueueProducer)\n producers = q_factory.create_producers(queue_config)\n\n # Retrieve and use consumer based on name configured\n consumers['make_managed_request'].listen(callback_function)\n\n # Retrieve and use producer based on name configured\n producers['error'].publish({\"error_details\": \"message about how you messed things up...\"})\n\n\n\n def callback_function(ch, method, properties, body):\n ...\n\n\nMulti-Threaded Example\n~~~~~~~~~~~~~~~~~~~~~~\n.. code:: python\n :number-lines: 1\n\n queue_factory = None\n\n def setup_queue:\n\n # If the queue_factory was already created, stop_consuming.\n # Clean up the existing connections before creating new ones\n # on a configuration change.\n if queue_factory:\n queue_factory.stop_consuming()\n\n # Create one configuration per thread, with a unique name for each.\n queue_factory_config = {\n \"queue_config\": []\n }\n\n amqp_connections = int(kv_store.get('amqp_connections', '10'))\n x = 0\n\n while x < amqp_connections:\n queue_config = {\n \"name\": \"notify_worker_thread_\" + str(x),\n \"type\": \"consumer\",\n \"queue\": \"my_queue\",\n \"host\": \"localhost\",\n \"port\": \"5672\",\n \"exchange\": {\n \"name\": \"managed_server\",\n \"type\": \"x-delayed-message\",\n \"arguments\": {\"x-delayed-type\": \"topic\"},\n \"durable\": true\n },\n \"auth\": {\n \"user\": \"guest\",\n \"password\": \"guest\"\n }\n }\n\n queue_factory_config[\"queue_config\"].append(queue_config)\n x = x + 1\n\n # Create the QueueFactory, and pass in the configuration and worker function.\n queue_factory = QueueFactory()\n queue_factory.create_consumers(queue_factory_config)\n queue_factory.start_consuming(do_work)\n\n # Wait for all threads to stop before stopping the main thread.\n for queue_consumer in queue_factory.consumers():\n queue_consumer.thread().join()\n\n ...\n\n def do_work(ch, method, properties, body):\n # Worker code goes here\n pass\n\n\n************\nQueueWorker\n************\n\nThis is a utility class that creates a KVStore, LogManager, configures exchanges and queues, and starts consuming. This\nclass also supports multi-threaded queue consumers, specified by the amqp connections. It also provides convenience\nmethods to publish success messages, error messages, and will handle catching and reporting exceptionswithout writing\ncode in the callback method, and acknowldge the message when done.\n\nHere are the parameters available when creating a QueueWorker\n\n+------------------------------+--------------------------------------------------------------------------------------------------------------+----------------------+\n| Parameter | Description | Default |\n+==============================+==============================================================================================================+======================+\n| consul_host | Consul host used to initialize the KVStore. | None |\n+------------------------------+--------------------------------------------------------------------------------------------------------------+----------------------+\n| consul_port | Consul port used to initialize the KVStore. | None |\n+------------------------------+--------------------------------------------------------------------------------------------------------------+----------------------+\n| etcd_host | Etcd host used to initialize the KVStore. | None |\n+------------------------------+--------------------------------------------------------------------------------------------------------------+----------------------+\n| etcd_port | Etcd port used to initialize the KVStore. | None |\n+------------------------------+--------------------------------------------------------------------------------------------------------------+----------------------+\n| kv_prefix | The prefix used to initialize the KVStore. | None |\n+------------------------------+--------------------------------------------------------------------------------------------------------------+----------------------+\n| rabbit_host_key | The key in the kv store that contains the RabbitMQ Host. | rabbit_host |\n+------------------------------+--------------------------------------------------------------------------------------------------------------+----------------------+\n| rabbit_port_key | The key in the kv store that contains the RabbitMQ Port | rabbit_port |\n+------------------------------+--------------------------------------------------------------------------------------------------------------+----------------------+\n| rabbit_user_key | The key in the kv store that contains the RabbitMQ User | rabbit_user |\n+------------------------------+--------------------------------------------------------------------------------------------------------------+----------------------+\n| rabbit_password_key | The key in the kv store that contains the RabbitMQ Password | rabbit_password |\n+------------------------------+--------------------------------------------------------------------------------------------------------------+----------------------+\n| amqp_connection_key | The key in the kv store that contains the number of connections to RabbitMQ | amqp_connections |\n+------------------------------+--------------------------------------------------------------------------------------------------------------+----------------------+\n| listen_exchange_key | The key in the kv store that contains the exchange to publish to listen on when consuming messages | exchange |\n+------------------------------+--------------------------------------------------------------------------------------------------------------+----------------------+\n| listen_routing_key_key | The key in the kv store that contains the routing key to bind to when consuming messages. | listen_routing_key |\n+------------------------------+--------------------------------------------------------------------------------------------------------------+----------------------+\n| queue_name_key | The key in the kv store that contains the queue name to listen on when consuming messages | queue |\n+------------------------------+--------------------------------------------------------------------------------------------------------------+----------------------+\n| done_exchange_key | The key in the kv store that contains the exchange to publish to on success | done_exchange |\n+------------------------------+--------------------------------------------------------------------------------------------------------------+----------------------+\n| done_routing_key_key | The key in the kv store that contains the routing key to publish to on success. | done_routing_key |\n+------------------------------+--------------------------------------------------------------------------------------------------------------+----------------------+\n| error_exchange_key | The key in the kv store that contains the exchange to publish to on error | error_exchange |\n+------------------------------+--------------------------------------------------------------------------------------------------------------+----------------------+\n| error_routing_key_key | The key in the kv store that contains the routing key to publish to on error. | error_routing_key |\n+------------------------------+--------------------------------------------------------------------------------------------------------------+----------------------+\n| data_key_on_error_payload | The key in the kv store that contains the key in the error payload when publishing to the error exchange. | data |\n+------------------------------+--------------------------------------------------------------------------------------------------------------+----------------------+\n| initialize_log_manager | When true, creates a LogManager using the kv store created or specified | True |\n+------------------------------+--------------------------------------------------------------------------------------------------------------+----------------------+\n| kv_store | When specigfied, this kv_store is used instead of creating a new one. | None |\n+------------------------------+--------------------------------------------------------------------------------------------------------------+----------------------+\n| rabbit_host_default | The default value of the RabbitMQ Host. | localhost |\n+------------------------------+--------------------------------------------------------------------------------------------------------------+----------------------+\n| rabbit_port_default | The default value of the RabbitMQ Port | 5672 |\n+------------------------------+--------------------------------------------------------------------------------------------------------------+----------------------+\n| rabbit_user_default | The default value of the RabbitMQ User | guest |\n+------------------------------+--------------------------------------------------------------------------------------------------------------+----------------------+\n| rabbit_password_default | The default value of the RabbitMQ Password | guest |\n+------------------------------+--------------------------------------------------------------------------------------------------------------+----------------------+\n| amqp_connection_default | The default value of the number of connections to RabbitMQ | 10 |\n+------------------------------+--------------------------------------------------------------------------------------------------------------+----------------------+\n| listen_exchange_default | The default value of the exchange to publish to listen on when consuming messages | main_exchange |\n+------------------------------+--------------------------------------------------------------------------------------------------------------+----------------------+\n| listen_routing_key_default | The default value of the routing key to bind to when consuming messages. | listen.key |\n+------------------------------+--------------------------------------------------------------------------------------------------------------+----------------------+\n| queue_name_default | The default value of the queue name to listen on when consuming messages | default_queue |\n+------------------------------+--------------------------------------------------------------------------------------------------------------+----------------------+\n| done_exchange_default | The default value of the exchange to publish to on success | main_exchange |\n+------------------------------+--------------------------------------------------------------------------------------------------------------+----------------------+\n| done_routing_key_default | The default value of the routing key to publish to on success. | done.key |\n+------------------------------+--------------------------------------------------------------------------------------------------------------+----------------------+\n| error_exchange_default | The default value ofthe exchange to publish to on error | error_exchange |\n+------------------------------+--------------------------------------------------------------------------------------------------------------+----------------------+\n| error_routing_key_default | The default value of the routing key to publish to on error. | error.key |\n+------------------------------+--------------------------------------------------------------------------------------------------------------+----------------------+\n\n\nExample Usage\n~~~~~~~~~~~~~\n\n*worker.py*\n\n.. code:: python\n :number-lines: 1\n\n import logging\n import time\n\n from clc_msa_utils.queueing import QueueWorker\n\n logger = logging.getLogger(\"default\")\n\n unregister_queue_worker = QueueWorker(\n kv_prefix=os.getenv(\"ETCD_PREFIX\", \"/config/billing-listener\"),\n\n # Rabbit Connection Info\n rabbit_host_key=\"rabbit_host\", rabbit_host_default=\"rabbitmq.rabbitmq\",\n rabbit_port_key=\"rabbit_port\", rabbit_port_default=15672,\n rabbit_user_key=\"rabbit_user\", rabbit_user_default=\"guest\",\n rabbit_password_key=\"rabbit_password\", rabbit_password_default=\"guest\",\n amqp_connection_key=\"amqp_connection_count\", amqp_connection_default=10,\n\n # Listen Config\n listen_exchange_key=\"main_exchange\", listen_exchange_default=\"managed_server\",\n listen_routing_key_key=\"main_exchange_stop_billing_routing_key\", listen_routing_default=\"requested.make_unmanaged\",\n queue_name_key=\"rabbit_stop_billing_queue_name\", queue_name_default=\"stop_billing\",\n\n # Done Config\n done_exchange_key=\"main_exchange\", done_exchange_default=\"managed_server\",\n done_routing_key_key=\"main_exchange_done_stop_billing_routing_key\",\n done_routing_key_default=\"billing.make_unmanaged\",\n\n # Error Config\n error_exchange_key=\"dead_letter_exchange\", error_exchange_default=\"managed_server_error\",\n error_routing_key_key=\"dead_letter_exchange_stop_billing_routing_key\",\n error_routing_key_default=\"monitoring_config.make_managed\",\n data_key_on_error_payload=\"server\")\n\n # Use the same kv_store as above, and don't initialize another log_manager\n register_queue_worker = QueueWorker(\n # Rabbit Connection Info\n rabbit_host_key=\"rabbit_host\", rabbit_host_default=\"rabbitmq.rabbitmq\",\n rabbit_port_key=\"rabbit_port\", rabbit_port_default=15672,\n rabbit_user_key=\"rabbit_user\", rabbit_user_default=\"guest\",\n rabbit_password_key=\"rabbit_password\", rabbit_password_default=\"guest\",\n amqp_connection_key=\"amqp_connection_count\", amqp_connection_default=10,\n\n # Listen Config\n listen_exchange_key=\"main_exchange\", listen_exchange_default=\"managed_server\",\n listen_routing_key_key=\"main_exchange_routing_key\", listen_routing_default=\"requested.make_managed\",\n queue_name_key=\"rabbit_queue_name\", queue_name_default=\"start_billing\",\n\n # Done Config\n done_exchange_key=\"main_exchange\", done_exchange_default=\"managed_server\",\n done_routing_key_key=\"main_exchange_done_routing_key\", done_routing_key_default=\"billing.make_managed\",\n\n # Error Config\n error_exchange_key=\"dead_letter_exchange\", error_exchange_default=\"managed_server_error\",\n error_routing_key_key=\"dead_letter_exchange_routing_key\", error_routing_key_default=\"billing.make_managed\",\n data_key_on_error_payload=\"server\",\n\n # Reuse configs\n initialize_log_manager=False, kv_store=unregister_queue_worker.kv_store())\n\n # Use the same kv_store for my configurations.\n kv_store=unregister_queue_worker.kv_store()\n\n # Use all defaults.\n all_defaults_queue_worker = QueueWorker(rabbit_host_default=\"rabbitmq.rabbitmq\")\n\n\n # Initializes the listener\n def initialize():\n logger.debug(\"Initializing worker...\")\n\n # Register the callbacks with the queue workers, this initializes the worker and starts consuming.\n register_queue_worker.set_callback(register_listener)\n unregister_queue_worker.set_callback(unregister_listener)\n all_defaults_queue_worker.set_callback(all_defaults_listener)\n\n logger.debug(\"Done Initializing worker\")\n\n\n def register_listener(ch, method, properties, body):\n _do_work(ch, method, properties, body, \"register\", register_queue_worker)\n\n\n def unregister_listener(ch, method, properties, body):\n _do_work(ch, method, properties, body, \"unregister\", unregister_queue_worker)\n\n\n def all_defaults_listener(ch, method, properties, body):\n _do_work(ch, method, properties, body, \"all_defaults\", all_defaults_queue_worker)\n\n\n def _do_work(ch, method, properties, body, task_name, queue_worker, sleep_seconds=8):\n logger.info(\"[{0}] Received the following message: {1}\".format(task_name, body.decode(\"utf-8\")))\n logger.info(\"[{0}] Pretending to do something for {1} seconds...\".format(task_name, str(sleep_seconds)))\n\n time.sleep(sleep_seconds)\n\n logger.info(\"[{0}] Done pretending to do something. \".format(task_name, str(sleep_seconds)))\n\n payload = {\n \"task_name\": task_name,\n \"sleep_seconds\": sleep_seconds,\n \"original_message\": body.decode(\"utf-8\"),\n \"properties\": properties,\n \"method\": method\n }\n\n # No need to catch an error, the QueueWorker will publish the error for you.\n # The error message will contain 'Exception: Raising an error.', the error_details and\n # errorDetails will contain the stack trace, and the `data_key_on_error_payload` property will contain the\n # original payload.\n if \"error\" in str(body.decode(\"utf-8\")):\n raise Exception(\"Raising an error.\")\n\n # Publish a success message, propagating the properties\n queue_worker.publish_success(payload, properties)\n\n # If I need to manually publish an error message, there is a method to do so.\n queue_worker.publish_error(payload)\n\n # Queue worker acknowledges the message, so need to do is here!\n logger.info(\"[{0}] Acknowledged that I am done pretending to do something.\".format(task_name))\n\n\n if __name__ == '__main__':\n initialize()\n\n\n*worker_UT.py*\n\n.. code:: python\n :number-lines: 1\n\n import unittest\n import worker\n\n\n class WorkerTests(unittest.TestCase):\n\n def setUp(self):\n pass\n\n def tearDown(self):\n # Stop reloading so the test will end.\n worker.kv_store.disable_reloading()\n\n def test_something(self):\n pass\n\n\n**********************************\nutils.dict_replace_empty_values()\n**********************************\n\nThis utility method removes or replaces empty strings in a dictionary. Optionally, you may also replace None values.\n\n**positional parameters**\n\n#. The dictionary to process\n\n**arguments**\n\n- *process_none_values*: When true, replace or remove attributes that have a value of None/Null, default=False\n- *clone_dict*: When true clones the input dictionary, processes it, and returns the clone leaving the original untouched, default=False\n- *remove_values*: When true, removes attributes that are empty or optionally None, default=False\n- *replace_with*: The replacement value, default=None\n- *replace_float_with_decimal*: The replacement value, default=None\n\n\nExample Usage\n~~~~~~~~~~~~~\n\n.. code:: python\n :number-lines: 1\n\n from utils import dict_replace_empty_values\n\n def process_dict(my_dict):\n # Return a clone of my_dict removing None values and empty strings.\n dict_a = dict_replace_empty_values(my_dict,\n process_none_values=True,\n clone_dict=True,\n remove_values=True)\n\n # Return a clone of my_dict replacing None values and empty strings with \"EMPTY\".\n dict_b = dict_replace_empty_values(my_dict,\n process_none_values=True,\n clone_dict=True,\n replace_with=\"EMPTY\")\n\n # Return a clone of my_dict replacing None values and empty strings with \"EMPTY\", and replace floats with decimal.\n dict_c = dict_replace_empty_values(my_dict,\n process_none_values=True,\n clone_dict=True,\n replace_with=\"EMPTY\",\n replace_float_with_decimal=True)\n\n**********************************\nutils.log_dict_types()\n**********************************\nLogs the type for every attribute in the specified dictionary.\n\n\n**positional parameters**\n\n#. The dictionary for which to log types\n\n**arguments**\n\n- *types*: Which types to show, else show all, default=None,\n- *use_logger*: The logger uto use, default=logger\n\n\n----\n\n\n.. [1] This document is formatted using `reStructuredText `_,\n with `reStructuredText directives `_.", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/CenturyLinkCloud/mos-pyutils", "keywords": "CenturyLink ManagedServices Utilities", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "clc-msa-utils", "package_url": "https://pypi.org/project/clc-msa-utils/", "platform": "", "project_url": "https://pypi.org/project/clc-msa-utils/", "project_urls": { "Homepage": "https://github.com/CenturyLinkCloud/mos-pyutils" }, "release_url": "https://pypi.org/project/clc-msa-utils/0.10.8/", "requires_dist": null, "requires_python": "", "summary": "CenturyLink Managed Services Anywhere Python Utilities", "version": "0.10.8" }, "last_serial": 5359339, "releases": { "0.10.0": [ { "comment_text": "", "digests": { "md5": "a8dc0a146e6fa38e0821703a8bc508eb", "sha256": "0271b66bd036e31f771768918c3d6164897d5c48b02cb6faa8b7831c7e01fe7a" }, "downloads": -1, "filename": "clc_msa_utils-0.10.0.tar.gz", "has_sig": false, "md5_digest": "a8dc0a146e6fa38e0821703a8bc508eb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27269, "upload_time": "2018-04-05T14:40:56", "url": "https://files.pythonhosted.org/packages/91/85/85465a93c35e505a24d06b8a9b63543b82c0d64e5d80c529b8edff00aabe/clc_msa_utils-0.10.0.tar.gz" } ], "0.10.1": [ { "comment_text": "", "digests": { "md5": "e09c9ee64727574e3828838a0e20229e", "sha256": "bc2c748dad74f42332c49507a4d4bcdd18b4e36947abdbfe998e8e1ade00f9dd" }, "downloads": -1, "filename": "clc_msa_utils-0.10.1.tar.gz", "has_sig": false, "md5_digest": "e09c9ee64727574e3828838a0e20229e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27203, "upload_time": "2018-04-05T15:32:33", "url": "https://files.pythonhosted.org/packages/36/99/6edc76852ba3f3c06c0acec5848afff747096db0d98e96a63b7182ffd9fe/clc_msa_utils-0.10.1.tar.gz" } ], "0.10.3": [ { "comment_text": "", "digests": { "md5": "24c6074e15c560435ed0d157c0c18981", "sha256": "f6542bbd0dd73ad85757bc45cd4fa55119ffbfa0e4031990b63ec9759a957cc8" }, "downloads": -1, "filename": "clc_msa_utils-0.10.3.tar.gz", "has_sig": false, "md5_digest": "24c6074e15c560435ed0d157c0c18981", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27219, "upload_time": "2018-04-13T19:51:02", "url": "https://files.pythonhosted.org/packages/b1/32/1e90006a85a1540d6d9ebd49d3b0624ba8fc7be46e80772adb8e72caf9a0/clc_msa_utils-0.10.3.tar.gz" } ], "0.10.3.1": [ { "comment_text": "", "digests": { "md5": "968ef16e832046636d7919795f320db0", "sha256": "92d5be8268f474e05b69f5645a3f465cdecd33a0549c7a0d94b569a85cd5638c" }, "downloads": -1, "filename": "clc_msa_utils-0.10.3.1.tar.gz", "has_sig": false, "md5_digest": "968ef16e832046636d7919795f320db0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27637, "upload_time": "2018-04-26T14:19:25", "url": "https://files.pythonhosted.org/packages/f6/9a/6ce536a8a1730d25ec56c61773607a71c7514c71d36ac3cfc107ef5bbcd6/clc_msa_utils-0.10.3.1.tar.gz" } ], "0.10.3.2": [ { "comment_text": "", "digests": { "md5": "64053744b66b6eb7e88c7d6acce5d4cb", "sha256": "a95fd7b0b65e01810a263766a734c88ff1ebd5eccb3e56f3fea81c5e55f5338a" }, "downloads": -1, "filename": "clc_msa_utils-0.10.3.2.tar.gz", "has_sig": false, "md5_digest": "64053744b66b6eb7e88c7d6acce5d4cb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 28063, "upload_time": "2018-04-26T14:33:00", "url": "https://files.pythonhosted.org/packages/0d/61/1ecc5e6c4dc2d6c83c0797970a7a56ce2662ece3e9112d273fb12f71f688/clc_msa_utils-0.10.3.2.tar.gz" } ], "0.10.3.3": [ { "comment_text": "", "digests": { "md5": "a6d4aa2ee959b17da47c4a92d642bf8f", "sha256": "ec5a3c83155b904dc203c8e3620d792620ef7d642572b18bd9bc4cb474789072" }, "downloads": -1, "filename": "clc_msa_utils-0.10.3.3.tar.gz", "has_sig": false, "md5_digest": "a6d4aa2ee959b17da47c4a92d642bf8f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 28057, "upload_time": "2018-04-26T14:34:46", "url": "https://files.pythonhosted.org/packages/1b/2d/b4faf275caa1440512a8e2baf902f52f744a2cbfc88c456e6afcdef4a1eb/clc_msa_utils-0.10.3.3.tar.gz" } ], "0.10.4": [ { "comment_text": "", "digests": { "md5": "d826f18da3c18ee486df8f4436685efe", "sha256": "b1a01444817e728067741ac7e0f0d19a0b98dd9626934ccadbe633e14b7b3e09" }, "downloads": -1, "filename": "clc_msa_utils-0.10.4.tar.gz", "has_sig": false, "md5_digest": "d826f18da3c18ee486df8f4436685efe", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 28205, "upload_time": "2018-05-21T19:43:08", "url": "https://files.pythonhosted.org/packages/45/15/8c7c53a9e8ef7c6ef95b922e0133432fffd69c43858ac9c2a7876ba323a5/clc_msa_utils-0.10.4.tar.gz" } ], "0.10.5": [ { "comment_text": "", "digests": { "md5": "a025f9222cb55e94725e2fae8d769bc1", "sha256": "8ed81a7a65bdbc9b1c09cf0adec37328984b6677ffcd20b5efb43eca1f98f509" }, "downloads": -1, "filename": "clc_msa_utils-0.10.5.tar.gz", "has_sig": false, "md5_digest": "a025f9222cb55e94725e2fae8d769bc1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 28309, "upload_time": "2018-07-24T17:21:27", "url": "https://files.pythonhosted.org/packages/43/b7/ab51392559e48941c68780961a43d342349f698860fb3c2f7198dac8b8e0/clc_msa_utils-0.10.5.tar.gz" } ], "0.10.6": [ { "comment_text": "", "digests": { "md5": "321522192b94617805f55a3a3c2c1f01", "sha256": "b72ff389f5b566bc072e9466246661c9f13e7c5195f447ccf3e189a4a0600ee0" }, "downloads": -1, "filename": "clc_msa_utils-0.10.6.tar.gz", "has_sig": false, "md5_digest": "321522192b94617805f55a3a3c2c1f01", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 28547, "upload_time": "2018-10-17T19:10:09", "url": "https://files.pythonhosted.org/packages/55/0a/ea4b18ed70e04a8ae4f00440b2ba551dca8280a7fbce2b0b3b10e70443f8/clc_msa_utils-0.10.6.tar.gz" } ], "0.10.8": [ { "comment_text": "", "digests": { "md5": "ecf390ebcd7236370fbf0846dc511d1c", "sha256": "82ab848ef6cb10bf4afa00a1270bc28a029012719470ecee06da11a3680b378a" }, "downloads": -1, "filename": "clc_msa_utils-0.10.8.tar.gz", "has_sig": false, "md5_digest": "ecf390ebcd7236370fbf0846dc511d1c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 28544, "upload_time": "2019-06-04T19:38:27", "url": "https://files.pythonhosted.org/packages/1d/50/7a45c3498a95fb0796abc0468287ad2c2c318277907c90bf1948215aa79c/clc_msa_utils-0.10.8.tar.gz" } ], "0.5.0": [ { "comment_text": "", "digests": { "md5": "25e4d995fa40394cd0490f9b2183bdef", "sha256": "8f7204134ffaa39d468619f72fcfea14df07c529ba66afc0a7fdb3213d034b09" }, "downloads": -1, "filename": "clc_msa_utils-0.5.0.tar.gz", "has_sig": false, "md5_digest": "25e4d995fa40394cd0490f9b2183bdef", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7647, "upload_time": "2018-01-11T17:19:32", "url": "https://files.pythonhosted.org/packages/14/f1/22a2b55d267750216d1d6e9331de1daa4cbb1eae1f55bf6b0f9458074e81/clc_msa_utils-0.5.0.tar.gz" } ], "0.6.1": [ { "comment_text": "", "digests": { "md5": "e91e3c82a016e6ceb54cc95ae8add878", "sha256": "5b5fc8782b2bf1b936ba0c91fbda300e1ecae30fc780b292df7da7fbc5e1ae5f" }, "downloads": -1, "filename": "clc_msa_utils-0.6.1.tar.gz", "has_sig": false, "md5_digest": "e91e3c82a016e6ceb54cc95ae8add878", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8670, "upload_time": "2018-01-19T16:54:03", "url": "https://files.pythonhosted.org/packages/78/20/42af3eb5fc798c373fd7aab97eea6a0c137d90a21137d9f4e6c8a3c38e8c/clc_msa_utils-0.6.1.tar.gz" } ], "0.6.7": [ { "comment_text": "", "digests": { "md5": "6d11ebbdaf3588bd8d5d6a51c9cb7cc8", "sha256": "5d0e0c11ba099294882b78a92c0e1e471d6e2a21a99ae74a9b7e4f49f6d93bee" }, "downloads": -1, "filename": "clc_msa_utils-0.6.7.tar.gz", "has_sig": false, "md5_digest": "6d11ebbdaf3588bd8d5d6a51c9cb7cc8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11222, "upload_time": "2018-01-29T22:37:09", "url": "https://files.pythonhosted.org/packages/7f/aa/d4b0af8df9b45f6219621e3ab48414feca90e557d28e272813b4e2b5af96/clc_msa_utils-0.6.7.tar.gz" } ], "0.6.8": [ { "comment_text": "", "digests": { "md5": "0b82fd9f5ad656e4fb68c04172e4d36a", "sha256": "b6f0393c1d8f081d940741b3e9d60b51e6f392373932d31615feef1703eb8906" }, "downloads": -1, "filename": "clc_msa_utils-0.6.8.tar.gz", "has_sig": false, "md5_digest": "0b82fd9f5ad656e4fb68c04172e4d36a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11199, "upload_time": "2018-01-30T17:07:16", "url": "https://files.pythonhosted.org/packages/74/08/95c10f92c06e48586957874c0ccc7c18a6643948e5b2b704a2c6af2dacac/clc_msa_utils-0.6.8.tar.gz" } ], "0.6.9": [ { "comment_text": "", "digests": { "md5": "5644790eb1e01de6df0b26b086dacabb", "sha256": "598ce53529564fa05effffffdf25fe1773055a04470592ec23d905b170736b9d" }, "downloads": -1, "filename": "clc_msa_utils-0.6.9.tar.gz", "has_sig": false, "md5_digest": "5644790eb1e01de6df0b26b086dacabb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22177, "upload_time": "2018-02-08T20:52:01", "url": "https://files.pythonhosted.org/packages/e0/fb/c1e14d8f0eefaeccdd3e52b0ec1753890ff6c4b1dbe33ec4aba12a2a0ea5/clc_msa_utils-0.6.9.tar.gz" } ], "0.6.9.1": [ { "comment_text": "", "digests": { "md5": "8e1cf567298108d0f450ff72773623ce", "sha256": "70e35253ce75c8c63005fdbcdeb70be67dd74b5cb8096f6c38103ded22ff43f8" }, "downloads": -1, "filename": "clc_msa_utils-0.6.9.1.tar.gz", "has_sig": false, "md5_digest": "8e1cf567298108d0f450ff72773623ce", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22360, "upload_time": "2018-02-12T17:00:15", "url": "https://files.pythonhosted.org/packages/4a/70/2c8175fa3d20d3a8c9138d4bf18555594073932c76fcc22bc7230fdc7695/clc_msa_utils-0.6.9.1.tar.gz" } ], "0.7.0": [ { "comment_text": "", "digests": { "md5": "0ecd74231f61fc10c6d8d8d114c69062", "sha256": "258e1598375289c041eee30a8e13eda73954983483b3c987b590f44d019d4d93" }, "downloads": -1, "filename": "clc_msa_utils-0.7.0.tar.gz", "has_sig": false, "md5_digest": "0ecd74231f61fc10c6d8d8d114c69062", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23964, "upload_time": "2018-02-12T20:14:21", "url": "https://files.pythonhosted.org/packages/5a/9f/87a46dc1e23fdbace56a36f66fb1f1513a55252d6c0d077eff5293ee5238/clc_msa_utils-0.7.0.tar.gz" } ], "0.7.5": [ { "comment_text": "", "digests": { "md5": "b90016792e450208a9183a26502cfad2", "sha256": "d529d47d8cc76a88f90ce4f149285222d00ee58dedbd3e7acf4af20ebe2975fa" }, "downloads": -1, "filename": "clc_msa_utils-0.7.5.tar.gz", "has_sig": false, "md5_digest": "b90016792e450208a9183a26502cfad2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24055, "upload_time": "2018-02-15T17:01:50", "url": "https://files.pythonhosted.org/packages/9f/65/c2068535564caf8c416f7262c0548d735eb7aad5210cba5c3ff054002e89/clc_msa_utils-0.7.5.tar.gz" } ], "0.8.2": [ { "comment_text": "", "digests": { "md5": "b40f120355edde5f36e9b968761e2be0", "sha256": "459c34e3cce01875ea6a3ce3be34df0436e316d82b27247787423940ae6361e0" }, "downloads": -1, "filename": "clc_msa_utils-0.8.2.tar.gz", "has_sig": false, "md5_digest": "b40f120355edde5f36e9b968761e2be0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24190, "upload_time": "2018-02-19T22:38:57", "url": "https://files.pythonhosted.org/packages/aa/56/6b4474eba57be944d096179863fa8fc8ab3736c90b5618a17adf1f3079fe/clc_msa_utils-0.8.2.tar.gz" } ], "0.8.5": [ { "comment_text": "", "digests": { "md5": "2b5135edc0de3b852b05f246b0f6c6f3", "sha256": "51c8ae768b741b730c909100748249305ec21da42e3cf4da9da53389412d8a4b" }, "downloads": -1, "filename": "clc_msa_utils-0.8.5.tar.gz", "has_sig": false, "md5_digest": "2b5135edc0de3b852b05f246b0f6c6f3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24594, "upload_time": "2018-02-21T14:53:36", "url": "https://files.pythonhosted.org/packages/c0/a2/49640374556d9a63956869ea4e69825fed31f17a916f0833753edafd1057/clc_msa_utils-0.8.5.tar.gz" } ], "0.8.5.1": [ { "comment_text": "", "digests": { "md5": "32d8d102b761c1be30011ff686d99b4e", "sha256": "748bd58c265b5197099d1b16c43bd8e5abc7ea793fde0abb83b954315cda6b44" }, "downloads": -1, "filename": "clc_msa_utils-0.8.5.1.tar.gz", "has_sig": false, "md5_digest": "32d8d102b761c1be30011ff686d99b4e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24592, "upload_time": "2018-02-21T20:21:17", "url": "https://files.pythonhosted.org/packages/d0/8f/79b388ff88b06c51addabb5b9f061cb1e434d8aee5236ce28190bfc61d46/clc_msa_utils-0.8.5.1.tar.gz" } ], "0.8.5.2": [ { "comment_text": "", "digests": { "md5": "26ad347514f8dbb1bc01ada9311ab4f8", "sha256": "0a1b8f4e0192d698ea3561da26378a17fcaae48690d583dbb848fa3f0bb2862f" }, "downloads": -1, "filename": "clc_msa_utils-0.8.5.2.tar.gz", "has_sig": false, "md5_digest": "26ad347514f8dbb1bc01ada9311ab4f8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24598, "upload_time": "2018-02-21T21:23:56", "url": "https://files.pythonhosted.org/packages/33/9e/2deb47dd2e4dad9a508ffd4fe5591de9f8ecf6280f5e363f9e2407ac93f7/clc_msa_utils-0.8.5.2.tar.gz" } ], "0.8.6": [ { "comment_text": "", "digests": { "md5": "4af0b78de6bfb785e5f1db277005b593", "sha256": "9aaac37e3b492eca1e2d84e4f47e36c5499deed072526a60faca5f574e1227fd" }, "downloads": -1, "filename": "clc_msa_utils-0.8.6.tar.gz", "has_sig": false, "md5_digest": "4af0b78de6bfb785e5f1db277005b593", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24592, "upload_time": "2018-02-22T18:36:40", "url": "https://files.pythonhosted.org/packages/b6/e0/5f71907c785ce3242b3fb8d962944a10c83236de3824c40eb47d64ad1b42/clc_msa_utils-0.8.6.tar.gz" } ], "0.8.7": [ { "comment_text": "", "digests": { "md5": "4b34f8628200cf09ee6fde72f493cc7e", "sha256": "c0b2d86f5827a07baa229145b2b3e6380f4f32c27ff835878545f8f7218a9f51" }, "downloads": -1, "filename": "clc_msa_utils-0.8.7.tar.gz", "has_sig": false, "md5_digest": "4b34f8628200cf09ee6fde72f493cc7e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24671, "upload_time": "2018-02-22T22:00:48", "url": "https://files.pythonhosted.org/packages/7c/84/9bda746fd97efc44d26d01dd17b8a8ddfa200b5d17b012bce01cfe02b474/clc_msa_utils-0.8.7.tar.gz" } ], "0.8.8": [ { "comment_text": "", "digests": { "md5": "37c6bd00bd75eae0c72e0f1d46413f50", "sha256": "7fc700491a81de83cb47d0ca0a6a4712869b3ce1c1c7a583c5de0b2d3b333267" }, "downloads": -1, "filename": "clc_msa_utils-0.8.8.tar.gz", "has_sig": false, "md5_digest": "37c6bd00bd75eae0c72e0f1d46413f50", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24680, "upload_time": "2018-02-23T20:14:56", "url": "https://files.pythonhosted.org/packages/d8/56/0e01035694eda733b247432c6c43f10dfa0d3ca7a34ad61fa53575e1be38/clc_msa_utils-0.8.8.tar.gz" } ], "0.8.9": [ { "comment_text": "", "digests": { "md5": "a6a544048e31fc903f66e7161f1c2eb8", "sha256": "6bfbc0b978b32dbc0b999fff0167f8d76fc8c7c0960ce74d3f7d7dd3c6f445bf" }, "downloads": -1, "filename": "clc_msa_utils-0.8.9.tar.gz", "has_sig": false, "md5_digest": "a6a544048e31fc903f66e7161f1c2eb8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24697, "upload_time": "2018-02-27T20:39:28", "url": "https://files.pythonhosted.org/packages/f3/1a/97dc0711ee51c5be4681ab38ab2a217571f7103c695428f2436c8cb38ee0/clc_msa_utils-0.8.9.tar.gz" } ], "0.9.3.1": [ { "comment_text": "", "digests": { "md5": "9665bc4ae3b630823e3bb1418a1a3502", "sha256": "fa65aa8fed0dad00b5eadee12d92c8f0668762c236fb8e89b6e38833f60609bd" }, "downloads": -1, "filename": "clc_msa_utils-0.9.3.1.tar.gz", "has_sig": false, "md5_digest": "9665bc4ae3b630823e3bb1418a1a3502", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 26273, "upload_time": "2018-04-04T16:16:26", "url": "https://files.pythonhosted.org/packages/5d/87/2480811a656c2c4db14b8b6a76613b487630a705b14386d8f75d168c5c5b/clc_msa_utils-0.9.3.1.tar.gz" } ], "0.9.4": [ { "comment_text": "", "digests": { "md5": "dcdb498dbfde052629b1b32a473e53a9", "sha256": "fb88787e28337acc6e47f2c41db42eee184e63aa8f55c8f24c47e4782224c112" }, "downloads": -1, "filename": "clc_msa_utils-0.9.4.tar.gz", "has_sig": false, "md5_digest": "dcdb498dbfde052629b1b32a473e53a9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27049, "upload_time": "2018-04-04T21:13:48", "url": "https://files.pythonhosted.org/packages/a1/e5/f70c51310ba679b0b74e4d605d259674a3bc7436261d54136b7693bccde5/clc_msa_utils-0.9.4.tar.gz" } ], "0.9.5": [ { "comment_text": "", "digests": { "md5": "a36c6d3cbec944f130759e16bf79b055", "sha256": "84dc8d99ca53037902597f48290fead7992ad3511d3ae3f80c11066711e058b6" }, "downloads": -1, "filename": "clc_msa_utils-0.9.5.tar.gz", "has_sig": false, "md5_digest": "a36c6d3cbec944f130759e16bf79b055", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27047, "upload_time": "2018-04-05T13:36:59", "url": "https://files.pythonhosted.org/packages/66/fb/f1fac2925a6725a3e7a6c3076015016837ea680833bd077ef0b4347028dc/clc_msa_utils-0.9.5.tar.gz" } ], "0.9.6": [ { "comment_text": "", "digests": { "md5": "cf66706bb5fb6d23abb6ec73d51888a1", "sha256": "991b3d9d77ae40193dcc8e8b3c4473e96278ebe23325c0c302ac4b7697a80afc" }, "downloads": -1, "filename": "clc_msa_utils-0.9.6.tar.gz", "has_sig": false, "md5_digest": "cf66706bb5fb6d23abb6ec73d51888a1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27044, "upload_time": "2018-04-05T13:39:02", "url": "https://files.pythonhosted.org/packages/88/89/e9eacf7921db85cb678085c9542e27470ea3e61ab4ba260e4ee81b1eb565/clc_msa_utils-0.9.6.tar.gz" } ], "0.9.7": [ { "comment_text": "", "digests": { "md5": "bb9944113be26c708766b91cec07da13", "sha256": "5445af9f91934f2bf62357f7fbc5b96eab3f5f2148f5ab1c7cce5735ba7656b0" }, "downloads": -1, "filename": "clc_msa_utils-0.9.7.tar.gz", "has_sig": false, "md5_digest": "bb9944113be26c708766b91cec07da13", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27055, "upload_time": "2018-04-05T13:52:41", "url": "https://files.pythonhosted.org/packages/b8/71/045b3ff5bc08e828a4cd2f508a9de61cf449d233db9bb6d25f5aa8704a05/clc_msa_utils-0.9.7.tar.gz" } ], "0.9.8": [ { "comment_text": "", "digests": { "md5": "d3504ec896e3b9b12e8d03af48d08f61", "sha256": "1739835972d28d8dff5655bd2b995531ae0e47cb7870b4f04cd26c3c5bf875f7" }, "downloads": -1, "filename": "clc_msa_utils-0.9.8.tar.gz", "has_sig": false, "md5_digest": "d3504ec896e3b9b12e8d03af48d08f61", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27072, "upload_time": "2018-04-05T14:05:39", "url": "https://files.pythonhosted.org/packages/f7/4a/d6e5c736ce99f6ebbd06b19a1d94682a6ed7c38b22ca1bf37d69926acf46/clc_msa_utils-0.9.8.tar.gz" } ], "0.9.9": [ { "comment_text": "", "digests": { "md5": "7d77941d348486b3e5f741674d65366d", "sha256": "6ceebf69b6e95633527f8dfee513ec0b2e618c24df583fbef3c5e992d4f29f96" }, "downloads": -1, "filename": "clc_msa_utils-0.9.9.tar.gz", "has_sig": false, "md5_digest": "7d77941d348486b3e5f741674d65366d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27195, "upload_time": "2018-04-05T14:27:45", "url": "https://files.pythonhosted.org/packages/db/38/c9732fbb49e74e216a21a5a428ce01099b650ab24688db6b385515eee814/clc_msa_utils-0.9.9.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "ecf390ebcd7236370fbf0846dc511d1c", "sha256": "82ab848ef6cb10bf4afa00a1270bc28a029012719470ecee06da11a3680b378a" }, "downloads": -1, "filename": "clc_msa_utils-0.10.8.tar.gz", "has_sig": false, "md5_digest": "ecf390ebcd7236370fbf0846dc511d1c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 28544, "upload_time": "2019-06-04T19:38:27", "url": "https://files.pythonhosted.org/packages/1d/50/7a45c3498a95fb0796abc0468287ad2c2c318277907c90bf1948215aa79c/clc_msa_utils-0.10.8.tar.gz" } ] }