# packages

pkgId: fab8b323008e552ebd822dd6baf6158f922e02fdd46b5cb7de1950a18cd2386b
name: python-aind-slims-api
arch: src
version: 0.1.17
epoch: 0
release: 1
summary: Generated from aind-library-template
url: https://pypi.org/project/aind-slims-api/
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aind-slims-api-0.1.17-1.src.rpm
checksum_type: sha256
description:
  [![License](https://img.shields.io/badge/license-MIT-brightgreen)](LICENSE)
  ![Code Style](https://img.shields.io/badge/code%20style-black-black)
  [![semantic-release: angular](https://img.shields.io/badge/semantic--release-angular-e10079?logo=semantic-release)](https://github.com/semantic-release/semantic-release)
  ![Interrogate](https://img.shields.io/badge/interrogate-100.0%25-brightgreen)
  ![Coverage](https://img.shields.io/badge/coverage-100%25-brightgreen?logo=codecov)
  ![Python](https://img.shields.io/badge/python->=3.10-blue?logo=python)

  This library is for pythonic access to data stored in the AIND SLIMS deployment. It is not meant to be a generic way to interact with SLIMS, but rather specific to how data is modeled in AIND's SLIMS instance.


  To use the software, in the root directory, run
  ```bash
  pip install -e .
  ```

  To develop the code, run
  ```bash
  pip install -e .[dev]
  ```




  ![Example usage](example-usage.gif)

  Requires the [pylance extension](https://marketplace.visualstudio.com/items?itemName=ms-python.vscode-pylance) to be installed for similar functionality.





  There are several libraries used to run linters, check documentation, and run tests.

  - Please test your changes using the **coverage** library, which will run the tests and log a coverage report:

  ```bash
  coverage run -m unittest discover && coverage report
  ```

  - Use **interrogate** to check that modules, methods, etc. have been documented thoroughly:

  ```bash
  interrogate .
  ```

  - Use **flake8** to check that code is up to standards (no unused imports, etc.):
  ```bash
  flake8 .
  ```

  - Use **black** to automatically format the code into PEP standards:
  ```bash
  black .
  ```

  - Use **isort** to automatically sort import statements:
  ```bash
  isort .
  ```



  For internal members, please create a branch. For external members, please fork the repository and open a pull request from the fork. We'll primarily use [Angular](https://github.com/angular/angular/blob/main/CONTRIBUTING.md#commit) style for commit messages. Roughly, they should follow the pattern:
  ```text
  <type>(<scope>): <short summary>
  ```

  where scope (optional) describes the packages affected by the code changes and type (mandatory) is one of:

  - **build**: Changes that affect build tools or external dependencies (example scopes: pyproject.toml, setup.py)
  - **ci**: Changes to our CI configuration files and scripts (examples: .github/workflows/ci.yml)
  - **docs**: Documentation only changes
  - **feat**: A new feature
  - **fix**: A bugfix
  - **perf**: A code change that improves performance
  - **refactor**: A code change that neither fixes a bug nor adds a feature
  - **test**: Adding missing tests or correcting existing tests



  The table below, from [semantic release](https://github.com/semantic-release/semantic-release), shows which commit message gets you which release type when `semantic-release` runs (using the default configuration):

  | Commit message                                                                                                                                                                                   | Release type                                                                                                    |
  | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------- |
  | `fix(pencil): stop graphite breaking when too much pressure applied`                                                                                                                             | ~~Patch~~ Fix Release, Default release                                                                          |
  | `feat(pencil): add 'graphiteWidth' option`                                                                                                                                                       | ~~Minor~~ Feature Release                                                                                       |
  | `perf(pencil): remove graphiteWidth option`<br><br>`BREAKING CHANGE: The graphiteWidth option has been removed.`<br>`The default graphite width of 10mm is always used for performance reasons.` | ~~Major~~ Breaking Release <br /> (Note that the `BREAKING CHANGE: ` token must be in the footer of the commit) |


  To generate the rst files source files for documentation, run
  ```bash
  sphinx-apidoc -o doc_template/source/ src
  ```
  Then to create the documentation HTML files, run
  ```bash
  sphinx-build -b html doc_template/source/ doc_template/build/html
  ```
  More info on sphinx installation can be found [here](https://www.sphinx-doc.org/en/master/usage/installation.html).


pkgId: 02df321ee2d94edfc2b06fb2193e14354a677150fd2be428eb040aa73e337c80
name: python-aind-spurious-correlation
arch: src
version: 0.0.3
epoch: 0
release: 1
summary: Generated from aind-library-template
url: https://pypi.org/project/aind-spurious-correlation/
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aind-spurious-correlation-0.0.3-1.src.rpm
checksum_type: sha256
description:
  [![License](https://img.shields.io/badge/license-MIT-brightgreen)](LICENSE)
  ![Code Style](https://img.shields.io/badge/code%20style-black-black)
  [![semantic-release: angular](https://img.shields.io/badge/semantic--release-angular-e10079?logo=semantic-release)](https://github.com/semantic-release/semantic-release)
  ![Interrogate](https://img.shields.io/badge/interrogate-100.0%25-brightgreen)
  ![Coverage](https://img.shields.io/badge/coverage-100%25-brightgreen?logo=codecov)
  ![Python](https://img.shields.io/badge/python->=3.10-blue?logo=python)




   - To use this template, click the green `Use this template` button and `Create new repository`.
   - After github initially creates the new repository, please wait an extra minute for the initialization scripts to finish organizing the repo.
   - To enable the automatic semantic version increments: in the repository go to `Settings` and `Collaborators and teams`. Click the green `Add people` button. Add `svc-aindscicomp` as an admin. Modify the file in `.github/workflows/tag_and_publish.yml` and remove the if statement in line 65. The semantic version will now be incremented every time a code is committed into the main branch.
   - To publish to PyPI, enable semantic versioning and uncomment the publish block in `.github/workflows/tag_and_publish.yml`. The code will now be published to PyPI every time the code is committed into the main branch.
   - The `.github/workflows/test_and_lint.yml` file will run automated tests and style checks every time a Pull Request is opened. If the checks are undesired, the `test_and_lint.yml` can be deleted. The strictness of the code coverage level, etc., can be modified by altering the configurations in the `pyproject.toml` file and the `.flake8` file.


  To use the software, in the root directory, run
  ```bash
  pip install -e .
  ```

  To develop the code, run
  ```bash
  pip install -e .[dev]
  ```





  There are several libraries used to run linters, check documentation, and run tests.

  - Please test your changes using the **coverage** library, which will run the tests and log a coverage report:

  ```bash
  coverage run -m unittest discover && coverage report
  ```

  - Use **interrogate** to check that modules, methods, etc. have been documented thoroughly:

  ```bash
  interrogate .
  ```

  - Use **flake8** to check that code is up to standards (no unused imports, etc.):
  ```bash
  flake8 .
  ```

  - Use **black** to automatically format the code into PEP standards:
  ```bash
  black .
  ```

  - Use **isort** to automatically sort import statements:
  ```bash
  isort .
  ```



  For internal members, please create a branch. For external members, please fork the repository and open a pull request from the fork. We'll primarily use [Angular](https://github.com/angular/angular/blob/main/CONTRIBUTING.md#commit) style for commit messages. Roughly, they should follow the pattern:
  ```text
  <type>(<scope>): <short summary>
  ```

  where scope (optional) describes the packages affected by the code changes and type (mandatory) is one of:

  - **build**: Changes that affect build tools or external dependencies (example scopes: pyproject.toml, setup.py)
  - **ci**: Changes to our CI configuration files and scripts (examples: .github/workflows/ci.yml)
  - **docs**: Documentation only changes
  - **feat**: A new feature
  - **fix**: A bugfix
  - **perf**: A code change that improves performance
  - **refactor**: A code change that neither fixes a bug nor adds a feature
  - **test**: Adding missing tests or correcting existing tests



  The table below, from [semantic release](https://github.com/semantic-release/semantic-release), shows which commit message gets you which release type when `semantic-release` runs (using the default configuration):

  | Commit message                                                                                                                                                                                   | Release type                                                                                                    |
  | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------- |
  | `fix(pencil): stop graphite breaking when too much pressure applied`                                                                                                                             | ~~Patch~~ Fix Release, Default release                                                                          |
  | `feat(pencil): add 'graphiteWidth' option`                                                                                                                                                       | ~~Minor~~ Feature Release                                                                                       |
  | `perf(pencil): remove graphiteWidth option`<br><br>`BREAKING CHANGE: The graphiteWidth option has been removed.`<br>`The default graphite width of 10mm is always used for performance reasons.` | ~~Major~~ Breaking Release <br /> (Note that the `BREAKING CHANGE: ` token must be in the footer of the commit) |


  To generate the rst files source files for documentation, run
  ```bash
  sphinx-apidoc -o docs/source/ src
  ```
  Then to create the documentation HTML files, run
  ```bash
  sphinx-build -b html docs/source/ docs/build/html
  ```
  More info on sphinx installation can be found [here](https://www.sphinx-doc.org/en/master/usage/installation.html).


pkgId: eb947eb1d8589d3b0a15d2b6600a0a779a9bf5865e315d5748c177f588da1ee8
name: python-aino-utkik
arch: src
version: 0.9.1
epoch: 0
release: 1
summary: Small, clean code with a lazy view dispatcher and class based views for Django.
url: https://github.com/aino/aino-utkik
rpm_license: BSD
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aino-utkik-0.9.1-1.src.rpm
checksum_type: sha256
description:
  aino-utkik provides minimalistic class based views for Django focusing on
  common usage, readability and convienience.
  For Django 1.3 or earlier use 0.7.8
  For Django 1.7 or later use 0.8.0 or later
  Example::
      
      from utkik.dispatch import *
      urlpatterns = patterns('',
          (r'^(?P<slug>[-\w]+)/$', 'news.NewsDetailView'),
          (r'^$', 'news.NewsListView'),
      )
      
      from django.shortcuts import get_object_or_404
      from news.models import News
      from utkik import View
      class NewsDetailView(View):
          template_name = 'news/news_detail.html'
          def get(self, slug):
              self.c.news = get_object_or_404(News.objects, slug=slug)
      class NewsListView(View):
          template_name = 'news/news_list.html'
          def get(self):
              self.c.news_list = News.objects.all()


pkgId: 0b0e06fb6124782a7e018507bc6c61de48190ca2a5f0c8c2b5a2e38afc4885d3
name: python-aio-code-editor
arch: src
version: 0.7.2
epoch: 0
release: 1
summary: please add a summary manually as the author left a blank one
url: https://pypi.org/project/aio-code-editor/
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aio-code-editor-0.7.2-1.src.rpm
checksum_type: sha256
description:
  1. Tạo môi trường, python>=3.8
  ```python
  conda create -n aio_editor-env python=3.12

  ```
  2. Cài đặt thư viện

  ```python
  pip install aio-code-editor

  ```


  1. Tạo file st_app.py

  ```python
  from aio_code_editor import app
  app.run()

  ```
  2. Mở terminal --> Kích hoạt môi trường --> Chạy lệnh
  ```python
  streamlit run app.py

  ```


  <img src='https://archive.org/download/aio-demo/aio-demo.png' alt='Image'>


  Made by  [AI VIET NAM]("https://www.facebook.com/aivietnam.edu.vn)


pkgId: 7d6933130828c1ec58a47127d3f0d0e770695489324e904f7b29b1cde5404f8d
name: python-aio-databases
arch: src
version: 0.16.2
epoch: 0
release: 1
summary: Async support for various databases
url: https://github.com/klen/aio-databases
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aio-databases-0.16.2-1.src.rpm
checksum_type: sha256
description:
  The package gives you async support for a range of databases (SQLite,
  PostgreSQL, MySQL).

  [![Tests Status](https://github.com/klen/aio-databases/workflows/tests/badge.svg)](https://github.com/klen/aio-databases/actions)
  [![PYPI Version](https://img.shields.io/pypi/v/aio-databases)](https://pypi.org/project/aio-databases/)
  [![Python Versions](https://img.shields.io/pypi/pyversions/aio-databases)](https://pypi.org/project/aio-databases/)



  * Has no dependencies (except databases drivers)
  * Supports [asyncio](https://docs.python.org/3/library/asyncio.html) and [trio](https://github.com/python-trio/trio)
  * Supports [aiosqlite](https://github.com/omnilib/aiosqlite),
    [aiomysql](https://github.com/aio-libs/aiomysql),
    [aiopg](https://github.com/aio-libs/aiopg),
    [asyncpg](https://github.com/MagicStack/asyncpg),
    [triopg](https://github.com/python-trio/triopg),
    [trio_mysql](https://github.com/python-trio/trio-mysql)
  * Manage pools of connections
  * Manage transactions



  * python >= 3.9



  **aio-databases** should be installed using pip:

  ```shell
  $ pip install aio-databases
  ```

  You have to choose and install the required database drivers with:

  ```shell

  $ pip install aio-databases[aiosqlite]  # asyncio


  $ pip install aio-databases[aiomysql]   # asyncio
  $ pip install aio-databases[trio_mysql] # trio


  $ pip install aio-databases[aiopg]      # asyncio
  $ pip install aio-databases[asyncpg]    # asyncio
  $ pip install aio-databases[triopg]     # trio


  $ pip install aio-databases[aioodbc]    # asyncio
  ```






  ```python
      from aio_databases import Database

      
      db = Database('sqlite:///:memory:')  # with default driver

      
      db = Database('aiosqlite:///:memory:', **driver_params)
  ```



  Setup a pool of connections

  ```python
      
      async def my_app_starts():
          await db.connect()

      
      async def my_app_ends():
          await db.disconnect()

      
      

      async with db:
          await my_main_coroutine()
  ```



  ```python
      
      async with db.connection():
          await my_code()

      
      async with db.connection(False):
          await my_code()
  ```

  If a pool is setup it will be used



  ```python
      await db.execute('select $1', '1')
      await db.executemany('select $1', '1', '2', '3')

      records = await db.fetchall('select (2 * $1) res', 2)
      assert records == [(4,)]

      record = await db.fetchone('select (2 * $1) res', 2)
      assert record == (4,)
      assert record['res'] == 4

      result = await db.fetchval('select 2 * $1', 2)
      assert result == 4
  ```

  * Iterate through rows one by one

  ```python

      async for rec in db.iterate('select name from users'):
          print(rec)

  ```



  By default the database opens and closes a connection for a query.

  ```python
      
      await db.fetchone('select %s', 42)

      
      await db.fetchone('select %s', 77)
  ```

  Manually open and close a connection

  ```python

      
      async with db.connection():
          
          await db.fetchone('select %s', 42)
          await db.fetchone('select %s', 77)
          

      
      async with db.connection(False):
          
  ```

  If there any connection already `db.method` would be using the current one
  ```python
      async with db.connection(): # connection would be acquired here
          await db.fetchone('select %s', 42)  # the connection is used
          await db.fetchone('select %s', 77)  # the connection is used

      
  ```



  ```python
      
      async with db.transaction() as trans1:
          

          async with db.transaction() as trans2:
              
              await trans2.rollback()

          
          

          await trans1.commit()

      
      async with db.tranction(True) as trans:
          
  ```



  If you have any suggestions, bug reports or annoyances please report them to
  the issue tracker at https://github.com/klen/aio-databases/issues




  Development of the project happens at: https://github.com/klen/aio-databases




  Licensed under a [MIT License](http://opensource.org/licenses/MIT)


pkgId: f8d7b8c58e7b0b19a6581153a448765e02e71eee07d8f1ff04e4e4c4c9a94cb1
name: python-aio-databases
arch: src
version: 1.1.1
epoch: 0
release: 1
summary: Async support for various databases
url: https://github.com/klen/aio-databases
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aio-databases-1.1.1-1.src.rpm
checksum_type: sha256
description:
  The package gives you async support for a range of databases (SQLite,
  PostgreSQL, MySQL).

  [![Tests Status](https://github.com/klen/aio-databases/workflows/tests/badge.svg)](https://github.com/klen/aio-databases/actions)
  [![PYPI Version](https://img.shields.io/pypi/v/aio-databases)](https://pypi.org/project/aio-databases/)
  [![Python Versions](https://img.shields.io/pypi/pyversions/aio-databases)](https://pypi.org/project/aio-databases/)



  * Has no dependencies (except databases drivers)
  * Supports [asyncio](https://docs.python.org/3/library/asyncio.html) and [trio](https://github.com/python-trio/trio)
  * Supports [aiosqlite](https://github.com/omnilib/aiosqlite),
    [aiomysql](https://github.com/aio-libs/aiomysql),
    [aiopg](https://github.com/aio-libs/aiopg),
    [asyncpg](https://github.com/MagicStack/asyncpg),
    [triopg](https://github.com/python-trio/triopg),
    [trio_mysql](https://github.com/python-trio/trio-mysql)
  * Manage pools of connections
  * Manage transactions



  * python >= 3.9



  **aio-databases** should be installed using pip:

  ```shell
  $ pip install aio-databases
  ```

  You have to choose and install the required database drivers with:

  ```shell

  $ pip install aio-databases[aiosqlite]  # asyncio


  $ pip install aio-databases[aiomysql]   # asyncio
  $ pip install aio-databases[trio_mysql] # trio


  $ pip install aio-databases[aiopg]      # asyncio
  $ pip install aio-databases[asyncpg]    # asyncio
  $ pip install aio-databases[triopg]     # trio


  $ pip install aio-databases[aioodbc]    # asyncio
  ```






  ```python
      from aio_databases import Database

      
      db = Database('sqlite:///:memory:')  # with default driver

      
      db = Database('asyncpg+pool://test:test@localhost:5432/tests', maxsize=10)
  ```



  - `aiomyql`
  - `aiomyql+pool`
  - `aiopg`
  - `aiopg+pool`
  - `asyncpg`
  - `asyncpg+pool`
  - `aioodbc`
  - `aioodbc+pool`
  - `aiosqlite`
  - `trio-mysql`
  - `triopg`



  Setup a pool of connections

  ```python
      
      async def my_app_starts():
          await db.connect()

      
      async def my_app_ends():
          await db.disconnect()

      
      

      async with db:
          await my_main_coroutine()
  ```



  ```python
      
      async with db.connection():
          await my_code()

      
      async with db.connection(False):
          await my_code()
  ```

  If a pool is setup it will be used



  ```python
      await db.execute('select $1', '1')
      await db.executemany('select $1', '1', '2', '3')

      records = await db.fetchall('select (2 * $1) res', 2)
      assert records == [(4,)]

      record = await db.fetchone('select (2 * $1) res', 2)
      assert record == (4,)
      assert record['res'] == 4

      result = await db.fetchval('select 2 * $1', 2)
      assert result == 4
  ```

  * Iterate through rows one by one

  ```python

      async for rec in db.iterate('select name from users'):
          print(rec)

  ```



  By default the database opens and closes a connection for a query.

  ```python
      
      await db.fetchone('select %s', 42)

      
      await db.fetchone('select %s', 77)
  ```

  Manually open and close a connection

  ```python

      
      async with db.connection():
          
          await db.fetchone('select %s', 42)
          await db.fetchone('select %s', 77)
          

      
      async with db.connection(False):
          
  ```

  If there any connection already `db.method` would be using the current one
  ```python
      async with db.connection(): # connection would be acquired here
          await db.fetchone('select %s', 42)  # the connection is used
          await db.fetchone('select %s', 77)  # the connection is used

      
  ```



  ```python
      
      async with db.transaction() as trans1:
          

          async with db.transaction() as trans2:
              
              await trans2.rollback()

          
          

          await trans1.commit()

      
      async with db.tranction(True) as trans:
          
  ```



  If you have any suggestions, bug reports or annoyances please report them to
  the issue tracker at https://github.com/klen/aio-databases/issues




  Development of the project happens at: https://github.com/klen/aio-databases




  Licensed under a [MIT License](http://opensource.org/licenses/MIT)


pkgId: a7c728e6929ac4af2553bb4f2aca4f0fd414c8c9e0fc6486d640ee02199085a1
name: python-aio-eapi
arch: src
version: 0.6.3
epoch: 0
release: 1
summary: Arista EOS API asyncio client
url: https://pypi.org/project/aio-eapi/
rpm_license: UNKNOWN
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aio-eapi-0.6.3-1.src.rpm
checksum_type: sha256
description:
  This repository contains an Arista EOS asyncio client.



  Thie following shows how to create a Device instance and run a list of
  commands.

  Device will use HTTPS transport by default.  The Device instance supports the
  following initialization parameters:

     * `host` - The device hostname or IP address
     * `username` - The login username
     * `password` - The login password
     * `proto` - *(Optional)* Choose either "https" or "http", defaults to "https"
     * `port` - *(Optional)* Chose the protocol port to override proto default

  The Device class inherits directly from httpx.AsyncClient.  As such, the Caller
  can provide any initialization parameters.  The above specific parameters are
  all optional.

  ```python
  import json
  from aioeapi import Device

  username = 'dummy-user'
  password = 'dummy-password'

  async def run_test(host):
      dev = Device(host=host, username=username, password=password)
      res = await dev.cli(commands=['show hostname', 'show version'])
      json.dumps(res)
  ```



  Arista eAPI documents require an Arista Portal customer login.  Once logged into the
  system you can find the documents in the Software Download area.  Select an EOS release
  and then select the Docs folder.

  You can also take a look at the Arista community client, [here](https://github.com/arista-eosplus/pyeapi).


pkgId: 62c1372bea32d5a90c3496211261168d962f9936fcf56c87afe80845a91008c0
name: python-aio-fluid
arch: src
version: 1.1.3
epoch: 0
release: 1
summary: Tools for backend python services
url: https://pypi.org/project/aio-fluid/
rpm_license: BSD
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aio-fluid-1.1.3-1.src.rpm
checksum_type: sha256
description:
  Aio Fluid

  Async utilities for backend python services developed by [Quantmind](https://quantmind.com).

  [![PyPI version](https://badge.fury.io/py/aio-fluid.svg)](https://badge.fury.io/py/aio-fluid)
  [![Python versions](https://img.shields.io/pypi/pyversions/aio-fluid.svg)](https://pypi.org/project/aio-fluid)
  [![build](https://github.com/quantmind/fluid/workflows/build/badge.svg)](https://github.com/quantmind/aio-fluid/actions?query=workflow%3Abuild)
  [![codecov](https://codecov.io/gh/quantmind/aio-fluid/graph/badge.svg?token=81oWUoyEVp)](https://codecov.io/gh/quantmind/aio-fluid)

  **Documentation**: [https://quantmind.github.io/aio-fluid](https://quantmind.github.io/aio-fluid)

  **Source Code**: [https://github.com/quantmind/aio-fluid](https://github.com/quantmind/aio-fluid)




  This is a simple python package you can install via pip:

  ```
  pip install aio-fluid
  ```

  To install all the dependencies:

  ```
  pip install aio-fluid[cli, db, http, log]
  ```
  this includes the following extra dependencies:

  - `cli` for the command line interface using [click](https://click.palletsprojects.com/) and [rich](https://github.com/Textualize/rich)
  - `db` for database support with [asyncpg](https://github.com/MagicStack/asyncpg) and [sqlalchemy](https://www.sqlalchemy.org/)
  - `http` for http client support with [httpx](https://www.python-httpx.org/) and [aiohttp](https://docs.aiohttp.org/en/stable/)
  - `log` for JSON logging support with [python-json-logger](https://github.com/madzak/python-json-logger)




  You can run the examples via

  ```
  poetry run python -m examples.main
  ```


pkgId: 9b9b2d72f4fda0bfd96c1c9254a32d223b9f913ded237bec683fd0a439d973f1
name: python-aio-geojson-client
arch: src
version: 0.21
epoch: 0
release: 1
summary: An async GeoJSON client library.
url: https://pypi.org/project/aio-geojson-client/
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aio-geojson-client-0.21-1.src.rpm
checksum_type: sha256
description:
  [![Build Status](https://img.shields.io/github/actions/workflow/status/exxamalte/python-aio-geojson-client/ci.yaml)](https://github.com/exxamalte/python-aio-geojson-client/actions/workflows/ci.yaml)
  [![codecov](https://codecov.io/gh/exxamalte/python-aio-geojson-client/branch/master/graph/badge.svg?token=FHM8U3HT33)](https://codecov.io/gh/exxamalte/python-aio-geojson-client)
  [![PyPi](https://img.shields.io/pypi/v/aio-geojson-client.svg)](https://pypi.python.org/pypi/aio-geojson-client)
  [![Version](https://img.shields.io/pypi/pyversions/aio-geojson-client.svg)](https://pypi.python.org/pypi/aio-geojson-client)
  [![Maintainability](https://api.codeclimate.com/v1/badges/4f7b12fe27fc845b5712/maintainability)](https://codeclimate.com/github/exxamalte/python-aio-geojson-client/maintainability)

  This library provides convenient async access to
  [GeoJSON](https://tools.ietf.org/html/rfc7946) Feeds.


  `pip install aio-geojson-client`



  | Library  | Source  | Topic  |
  |----------|---------|--------|
  | [aio_geojson_generic_client](https://github.com/exxamalte/python-aio-geojson-generic-client)       | Generic GeoJSON feeds                             | Any         |
  | [aio_geojson_geonetnz_quakes](https://github.com/exxamalte/python-aio-geojson-geonetnz-quakes)     | GeoNet New Zealand Quakes                         | Earthquakes |
  | [aio_geojson_geonetnz_volcano](https://github.com/exxamalte/python-aio-geojson-geonetnz-volcano)   | GeoNet New Zealand Volcano                        | Volcanoes   |
  | [aio_geojson_nsw_rfs_incidents](https://github.com/exxamalte/python-aio-geojson-nsw-rfs-incidents) | NSW Rural Fire Service                            | Fires       |
  | [aio_geojson_usgs_earthquakes](https://github.com/exxamalte/python-aio-geojson-usgs-earthquakes)   | U.S. Geological Survey Earthquake Hazards Program | Earthquakes |


  Each implementation extracts relevant information from the GeoJSON feed. Not
  all feeds contain the same level of information, or present their information
  in different ways.

  After instantiating a particular class and supply the required parameters, you
  can call `update` to retrieve the feed data. The return value will be a tuple
  of a status code and the actual data in the form of a list of feed entries
  specific to the selected feed.
  Alternatively, calling method `update_override` allows passing in ad-hoc filters
  that override the globally defined filters.

  Status Codes
  * _OK_: Update went fine and data was retrieved. The library may still
    return empty data, for example because no entries fulfilled the filter
    criteria.
  * _OK_NO_DATA_: Update went fine but no data was retrieved, for example
    because the server indicated that there was not update since the last request.
  * _ERROR_: Something went wrong during the update



  The Feed Manager helps managing feed updates over time, by notifying the
  consumer of the feed about new feed entries, updates and removed entries
  compared to the last feed update.

  * If the current feed update is the first one, then all feed entries will be
    reported as new. The feed manager will keep track of all feed entries'
    external IDs that it has successfully processed.
  * If the current feed update is not the first one, then the feed manager will
    produce three sets:
    * Feed entries that were not in the previous feed update but are in the
      current feed update will be reported as new.
    * Feed entries that were in the previous feed update and are still in the
      current feed update will be reported as to be updated.
    * Feed entries that were in the previous feed update but are not in the
      current feed update will be reported to be removed.
  * If the current update fails, then all feed entries processed in the previous
    feed update will be reported to be removed.

  After a successful update from the feed, the feed manager provides two
  different dates:

  * `last_update` will be the timestamp of the last update from the feed
    irrespective of whether it was successful or not.
  * `last_update_successful` will be the timestamp of the last successful update
    from the feed. This date may be useful if the consumer of this library wants
    to treat intermittent errors from feed updates differently.
  * `last_timestamp` (optional, depends on the feed data) will be the latest
    timestamp extracted from the feed data.
    This requires that the underlying feed data actually contains a suitable
    date. This date may be useful if the consumer of this library wants to
    process feed entries differently if they haven't actually been updated.

rpm_license:
[cell repeats an earlier one in this file: 10254 characters]


pkgId: 6c3d5ea0583b67739be55636518c6aee975b5bae22e9fcb22d013b310c7d0a59
name: python-aio-geojson-flightairmap
arch: src
version: 0.4.21
epoch: 0
release: 1
summary: An async GeoJSON client library for planes using information from a Flight Air Map server.
url: https://github.com/kuchel77/python-aio-geojson-flightairmap
rpm_license: Apache Software License
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aio-geojson-flightairmap-0.4.21-1.src.rpm
checksum_type: sha256
description:
  [![Build Status](https://travis-ci.org/kuchel77/python-aio-geojson-flighairmap.svg)](https://travis-ci.org/kuchel77/python-aio-geojson-flightairmap)
  [![Coverage Status](https://coveralls.io/repos/github/kuchel77/python-aio-geojson-flightairmap/badge.svg?branch=master)](https://coveralls.io/github/exxamalte/python-aio-geojson-flightairmap?branch=master)
  [![PyPi](https://img.shields.io/pypi/v/aio-geojson-flightairmap.svg)](https://pypi.python.org/pypi/aio-geojson-flightairmap)
  [![Version](https://img.shields.io/pypi/pyversions/aio-geojson-flightairmap.svg)](https://pypi.python.org/pypi/aio-geojson-flightairmap)

  This library provides convenient async access to local [Flight Air Map](https://www.flightairmap.com/) geojson feed.

  This is an adaption of the [NSW RFS Incidents feed](https://github.com/exxamalte/python-aio-geojson-nsw-rfs-incidents) by Malte Franken.


  `pip install aio-geojson-flightairmap`


  See below for examples of how this library can be used. After instantiating a
  particular class - feed or feed manager - and supply the required parameters,
  you can call `update` to retrieve the feed data. The return value
  will be a tuple of a status code and the actual data in the form of a list of
  feed entries specific to the selected feed.

  Status Codes
  * _OK_: Update went fine and data was retrieved. The library may still
    return empty data, for example because no entries fulfilled the filter
    criteria.
  * _OK_NO_DATA_: Update went fine but no data was retrieved, for example
    because the server indicated that there was not update since the last request.
  * _ERROR_: Something went wrong during the update

  **Parameters**

  | Parameter          | Description                               |
  |--------------------|-------------------------------------------|
  | `home_coordinates` | Coordinates (tuple of latitude/longitude) |

  **Supported Filters**

  | Filter     |                     | Description |
  |------------|---------------------|-------------|
  | Radius     | `filter_radius`     | Radius in kilometers around the home coordinates in which events from feed are included. |

  **Example**
  ```python
  import asyncio
  from aiohttp import ClientSession
  from aio_geojson_flightairmap import FlightAirMapFeed
  async def main() -> None:
      async with ClientSession() as websession:
          
          
          feed = FlightAirMapFeed(websession,
                  (-33.0, 150.0),
                  filter_radius=20000)

          status, entries = await feed.update()
          print(status)
          print(entries)
          for e in entries:
              print(e.publication_date)
              print(e.coordinates)
              print(e.flight_num)
  asyncio.get_event_loop().run_until_complete(main())
  ```


  Each feed entry is populated with the following properties:

  | Name               | Description                                                                                         | Feed attribute |
  |--------------------|-----------------------------------------------------------------------------------------------------|----------------|
  | geometry           | All geometry details of this entry.                                                                 | `geometry`     |
  | coordinates        | Best coordinates (latitude, longitude) of this entry.                                               | `geometry`     |
  | external_id        | The unique public identifier for this incident.                                                     | `guid`         |
  | title              | Title of this entry.                                                                                | `title`        |
  | attribution        | Attribution of the feed.                                                                            | n/a            |
  | distance_to_home   | Distance in km of this entry to the home coordinates.                                               | n/a            |
  | publication_date   | The publication date of the incidents.                                                              | `pubDate`      |




  The Feed Manager helps managing feed updates over time, by notifying the
  consumer of the feed about new feed entries, updates and removed entries
  compared to the last feed update.

  * If the current feed update is the first one, then all feed entries will be
    reported as new. The feed manager will keep track of all feed entries'
    external IDs that it has successfully processed.
  * If the current feed update is not the first one, then the feed manager will
    produce three sets:
    * Feed entries that were not in the previous feed update but are in the
      current feed update will be reported as new.
    * Feed entries that were in the previous feed update and are still in the
      current feed update will be reported as to be updated.
    * Feed entries that were in the previous feed update but are not in the
      current feed update will be reported to be removed.
  * If the current update fails, then all feed entries processed in the previous
    feed update will be reported to be removed.

  After a successful update from the feed, the feed manager provides two
  different dates:

  * `last_update` will be the timestamp of the last update from the feed
    irrespective of whether it was successful or not.
  * `last_update_successful` will be the timestamp of the last successful update
    from the feed. This date may be useful if the consumer of this library wants
    to treat intermittent errors from feed updates differently.
  * `last_timestamp` (optional, depends on the feed data) will be the latest
    timestamp extracted from the feed data.
    This requires that the underlying feed data actually contains a suitable
    date. This date may be useful if the consumer of this library wants to
    process feed entries differently if they haven't actually been updated.


pkgId: de898a3feb96f19c362cc9047f30a40fe77e041446dfecfa6af14869613e2768
name: python-aio-geojson-generic-client
arch: src
version: 0.5
epoch: 0
release: 1
summary: An generic async GeoJSON client library.
url: https://pypi.org/project/aio-geojson-generic-client/
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aio-geojson-generic-client-0.5-1.src.rpm
checksum_type: sha256
description:
  [![Build Status](https://img.shields.io/github/actions/workflow/status/exxamalte/python-aio-geojson-generic-client/ci.yaml)](https://github.com/exxamalte/python-aio-geojson-generic-client/actions/workflows/ci.yaml)
  [![codecov](https://codecov.io/gh/exxamalte/python-aio-geojson-generic-client/graph/badge.svg?token=F5ZEM1UO56)](https://codecov.io/gh/exxamalte/python-aio-geojson-generic-client)
  [![PyPi](https://img.shields.io/pypi/v/aio-geojson-generic-client.svg)](https://pypi.python.org/pypi/aio-geojson-generic-client)
  [![Version](https://img.shields.io/pypi/pyversions/aio-geojson-generic-client.svg)](https://pypi.python.org/pypi/aio-geojson-generic-client)

  This library provides convenient async generic access to [GeoJSON](https://datatracker.ietf.org/doc/html/rfc7946) feeds.


  `pip install aio-geojson-generic-client`


  See below for examples of how this library can be used. After instantiating a
  particular class - feed or feed manager - and supply the required parameters,
  you can call `update` to retrieve the feed data. The return value
  will be a tuple of a status code and the actual data in the form of a list of
  feed entries specific to the selected feed.

  Status Codes
  * _OK_: Update went fine and data was retrieved. The library may still
    return empty data, for example because no entries fulfilled the filter
    criteria.
  * _OK_NO_DATA_: Update went fine but no data was retrieved, for example
    because the server indicated that there was not update since the last request.
  * _ERROR_: Something went wrong during the update

  **Parameters**

  | Parameter          | Description                               |
  |--------------------|-------------------------------------------|
  | `home_coordinates` | Coordinates (tuple of latitude/longitude) |
  | `url`              | URL of the GeoJSON feed                   |

  **Supported Filters**

  | Filter     |                     | Description |
  |------------|---------------------|-------------|
  | Radius     | `filter_radius`     | Radius in kilometers around the home coordinates in which events from feed are included. |

  **Example**
  ```python
  import asyncio
  from aiohttp import ClientSession
  from aio_geojson_generic_client import GenericFeed
  async def main() -> None:
      async with ClientSession() as websession:
          
          
          feed = GenericFeed(websession,
                             (-33.0, 150.0),
                             "https://www.rfs.nsw.gov.au/feeds/majorIncidents.json",
                             filter_radius=50)
          status, entries = await feed.update()
          print(status)
          print(entries)
  asyncio.get_event_loop().run_until_complete(main())
  ```


  Each feed entry is populated with the following properties:

  | Name               | Description                                                                                         | Feed attribute                               |
  |--------------------|-----------------------------------------------------------------------------------------------------|----------------------------------------------|
  | geometries         | All geometry details of this entry.                                                                 | `geometry`                                   |
  | coordinates        | Best coordinates (latitude, longitude) of this entry.                                               | `geometry`                                   |
  | external_id        | The unique public identifier for this incident.                                                     | `id`, `guid`, `title` or hash of coordinates |
  | title              | Title of this entry (if provided).                                                                  | `title`                                      |
  | distance_to_home   | Distance in km of this entry to the home coordinates.                                               | n/a                                          |
  | publication_date   | The publication date of the entry (if provided).                                                    | `pubDate`                                    |
  | properties         | All properties defined for this entry.                                                              | `properties`                                 |




  The Feed Manager helps managing feed updates over time, by notifying the
  consumer of the feed about new feed entries, updates and removed entries
  compared to the last feed update.

  * If the current feed update is the first one, then all feed entries will be
    reported as new. The feed manager will keep track of all feed entries'
    external IDs that it has successfully processed.
  * If the current feed update is not the first one, then the feed manager will
    produce three sets:
    * Feed entries that were not in the previous feed update but are in the
      current feed update will be reported as new.
    * Feed entries that were in the previous feed update and are still in the
      current feed update will be reported as to be updated.
    * Feed entries that were in the previous feed update but are not in the
      current feed update will be reported to be removed.
  * If the current update fails, then all feed entries processed in the previous
    feed update will be reported to be removed.

  After a successful update from the feed, the feed manager provides two
  different dates:

  * `last_update` will be the timestamp of the last update from the feed
    irrespective of whether it was successful or not.
  * `last_update_successful` will be the timestamp of the last successful update
    from the feed. This date may be useful if the consumer of this library wants
    to treat intermittent errors from feed updates differently.
  * `last_timestamp` (optional, depends on the feed data) will be the latest
    timestamp extracted from the feed data.
    This requires that the underlying feed data actually contains a suitable
    date. This date may be useful if the consumer of this library wants to
    process feed entries differently if they haven't actually been updated.

rpm_license:
[cell repeats an earlier one in this file: 10254 characters]


pkgId: a0280ae8737b6f3bf66574fa3ff480850e7389ed4ac2ac2418023d9b011cdece
name: python-aio-geojson-geonetnz-quakes
arch: src
version: 0.17
epoch: 0
release: 1
summary: An async GeoJSON client library for GeoNet NZ Quakes feed.
url: https://pypi.org/project/aio-geojson-geonetnz-quakes/
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aio-geojson-geonetnz-quakes-0.17-1.src.rpm
checksum_type: sha256
description:
  [![Build Status](https://img.shields.io/github/actions/workflow/status/exxamalte/python-aio-geojson-geonetnz-quakes/ci.yaml)](https://github.com/exxamalte/python-aio-geojson-geonetnz-quakes/actions/workflows/ci.yaml)
  [![codecov](https://codecov.io/gh/exxamalte/python-aio-geojson-geonetnz-quakes/branch/master/graph/badge.svg?token=USA5MZU6D5)](https://codecov.io/gh/exxamalte/python-aio-geojson-geonetnz-quakes)
  [![PyPi](https://img.shields.io/pypi/v/aio-geojson-geonetnz-quakes.svg)](https://pypi.python.org/pypi/aio-geojson-geonetnz-quakes)
  [![Version](https://img.shields.io/pypi/pyversions/aio-geojson-geonetnz-quakes.svg)](https://pypi.python.org/pypi/aio-geojson-geonetnz-quakes)

  This library provides convenient async access to the
  [GeoNet NZ Quakes](https://api.geonet.org.nz/#quakes) feed.



  `pip install aio-geojson-geonetnz-quakes`


  See below for examples of how this library can be used. After instantiating a
  particular class - feed or feed manager - and supply the required parameters,
  you can call `update` to retrieve the feed data. The return value
  will be a tuple of a status code and the actual data in the form of a list of
  feed entries specific to the selected feed.

  Status Codes
  * _OK_: Update went fine and data was retrieved. The library may still
    return empty data, for example because no entries fulfilled the filter
    criteria.
  * _OK_NO_DATA_: Update went fine but no data was retrieved, for example
    because the server indicated that there was not update since the last request.
  * _ERROR_: Something went wrong during the update

  **Parameters**

  | Parameter          | Description                               |
  |--------------------|-------------------------------------------|
  | `home_coordinates` | Coordinates (tuple of latitude/longitude) |
  | `mmi`              | Request quakes that may have caused shaking greater than or equal to the [MMI](https://en.wikipedia.org/wiki/Modified_Mercalli_intensity_scale) value in the New Zealand region. Allowable values are -1..8 inclusive. Default: -1 is used for quakes that are too small to calculate a stable MMI value for. |

  **Supported Filters**

  | Filter            |                            | Description |
  |-------------------|----------------------------|-------------|
  | Radius            | `filter_radius`            | Radius in kilometers around the home coordinates in which events from feed are included. |
  | Minimum Magnitude | `filter_minimum_magnitude` | Minimum magnitude as float value. Only events with a magnitude equal or above this value are included. |
  | Time              | `filter_time`              | Time interval; only events with a reported origin time that falls within now and this past time interval are included. |

  **Example**
  ```python
  import asyncio
  from aiohttp import ClientSession
  from aio_geojson_geonetnz_quakes import GeonetnzQuakesFeed
  async def main() -> None:
      async with ClientSession() as websession:
          
          
          
          
          feed = GeonetnzQuakesFeed(websession, (-41.2, 174.7), mmi=2,
                                    filter_radius=200,
                                    filter_minimum_magnitude=2.5)
          status, entries = await feed.update()
          print(status)
          print(entries)
  asyncio.get_event_loop().run_until_complete(main())
  ```


  Each feed entry is populated with the following properties:

  | Name             | Description                                                                   | Feed attribute |
  |------------------|-------------------------------------------------------------------------------|----------------|
  | geometry         | All geometry details of this entry.                                           | `geometry`     |
  | coordinates      | Best coordinates (latitude, longitude) of this entry.                         | `geometry`     |
  | external_id      | The unique public identifier for this quake.                                  | `publicID`     |
  | title            | Title of this entry.                                                          | `locality`     |
  | attribution      | Attribution of the feed.                                                      | n/a            |
  | distance_to_home | Distance in km of this entry to the home coordinates.                         | n/a            |
  | time             | The origin time of the quake.                                                 | `time`         |
  | depth            | The depth of the quake in km.                                                 | `depth`        |
  | magnitude        | The summary magnitude for the quake.                                          | `magnitude`    |
  | locality         | Distance and direction to the nearest locality.                               | `locality`     |
  | mmi              | The calculated MMI shaking at the closest locality in the New Zealand region. | `mmi`          |
  | quality          | The quality of this information: best, good, caution, deleted.                | `quality`      |




  The Feed Manager helps managing feed updates over time, by notifying the
  consumer of the feed about new feed entries, updates and removed entries
  compared to the last feed update.

  * If the current feed update is the first one, then all feed entries will be
    reported as new. The feed manager will keep track of all feed entries'
    external IDs that it has successfully processed.
  * If the current feed update is not the first one, then the feed manager will
    produce three sets:
    * Feed entries that were not in the previous feed update but are in the
      current feed update will be reported as new.
    * Feed entries that were in the previous feed update and are still in the
      current feed update will be reported as to be updated.
    * Feed entries that were in the previous feed update but are not in the
      current feed update will be reported to be removed.
  * If the current update fails, then all feed entries processed in the previous
    feed update will be reported to be removed.

  After a successful update from the feed, the feed manager provides two
  different dates:

  * `last_update` will be the timestamp of the last update from the feed
    irrespective of whether it was successful or not.
  * `last_update_successful` will be the timestamp of the last successful update
    from the feed. This date may be useful if the consumer of this library wants
    to treat intermittent errors from feed updates differently.
  * `last_timestamp` (optional, depends on the feed data) will be the latest
    timestamp extracted from the feed data.
    This requires that the underlying feed data actually contains a suitable
    date. This date may be useful if the consumer of this library wants to
    process feed entries differently if they haven't actually been updated.

rpm_license:
[cell repeats an earlier one in this file: 10254 characters]


pkgId: 9d781ed6df51416567859c93f118ca5ba4f6886bd95334e2dd907c70c381b2ee
name: python-aio-geojson-geonetnz-volcano
arch: src
version: 0.10
epoch: 0
release: 1
summary: An async GeoJSON client library for GeoNet NZ Volcanic Alert Level feed.
url: https://pypi.org/project/aio-geojson-geonetnz-volcano/
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aio-geojson-geonetnz-volcano-0.10-1.src.rpm
checksum_type: sha256
description:
  [![Build Status](https://img.shields.io/github/actions/workflow/status/exxamalte/python-aio-geojson-geonetnz-volcano/ci.yaml)](https://github.com/exxamalte/python-aio-geojson-geonetnz-volcano/actions/workflows/ci.yaml)
  [![codecov](https://codecov.io/gh/exxamalte/python-aio-geojson-geonetnz-volcano/graph/badge.svg?token=RCSVB3QRER)](https://codecov.io/gh/exxamalte/python-aio-geojson-geonetnz-volcano)
  [![PyPi](https://img.shields.io/pypi/v/aio-geojson-geonetnz-volcano.svg)](https://pypi.python.org/pypi/aio-geojson-geonetnz-volcano)
  [![Version](https://img.shields.io/pypi/pyversions/aio-geojson-geonetnz-volcano.svg)](https://pypi.python.org/pypi/aio-geojson-geonetnz-volcano)

  This library for convenient async access to
  [GeoNet NZ Volcanic Alert Level](https://api.geonet.org.nz/#val) feed.



  `pip install aio-geojson-geonetnz-volcano`


  See below for examples of how this library can be used. After instantiating a
  particular class - feed or feed manager - and supply the required parameters,
  you can call `update` to retrieve the feed data. The return value
  will be a tuple of a status code and the actual data in the form of a list of
  feed entries specific to the selected feed.

  Status Codes
  * _OK_: Update went fine and data was retrieved. The library may still
    return empty data, for example because no entries fulfilled the filter
    criteria.
  * _OK_NO_DATA_: Update went fine but no data was retrieved, for example
    because the server indicated that there was not update since the last request.
  * _ERROR_: Something went wrong during the update

  **Parameters**

  | Parameter          | Description                               |
  |--------------------|-------------------------------------------|
  | `home_coordinates` | Coordinates (tuple of latitude/longitude) |

  **Supported Filters**

  | Filter |                 | Description |
  |--------|-----------------|-------------|
  | Radius | `filter_radius` | Radius in kilometers around the home coordinates in which events from feed are included. |

  **Example**
  ```python
  import asyncio
  from aiohttp import ClientSession
  from aio_geojson_geonetnz_volcano import GeonetnzVolcanoFeed
  async def main() -> None:
      async with ClientSession() as websession:
          
          
          feed = GeonetnzVolcanoFeed(websession,
                                     (-41.2, 174.7),
                                     filter_radius=200)
          status, entries = await feed.update()
          print(status)
          print(entries)
  asyncio.get_event_loop().run_until_complete(main())
  ```


  Each feed entry is populated with the following properties:

  | Name             | Description                                           | Feed attribute |
  |------------------|-------------------------------------------------------|----------------|
  | geometry         | All geometry details of this entry.                   | `geometry`     |
  | coordinates      | Best coordinates (latitude, longitude) of this entry. | `geometry`     |
  | external_id      | The unique public identifier for this volcano.        | `volcanoID`    |
  | title            | Volcano title.                                        | `volcanoTitle` |
  | attribution      | Attribution of the feed.                              | n/a            |
  | distance_to_home | Distance in km of this entry to the home coordinates. | n/a            |
  | alert_level      | Volcanic alert level (0-5).                           | `level`        |
  | activity         | Volcanic activity.                                    | `activity`     |
  | hazards          | Most likely hazards.                                  | `hazards`      |




  The Feed Manager helps managing feed updates over time, by notifying the
  consumer of the feed about new feed entries, updates and removed entries
  compared to the last feed update.

  * If the current feed update is the first one, then all feed entries will be
    reported as new. The feed manager will keep track of all feed entries'
    external IDs that it has successfully processed.
  * If the current feed update is not the first one, then the feed manager will
    produce three sets:
    * Feed entries that were not in the previous feed update but are in the
      current feed update will be reported as new.
    * Feed entries that were in the previous feed update and are still in the
      current feed update will be reported as to be updated.
    * Feed entries that were in the previous feed update but are not in the
      current feed update will be reported to be removed.
  * If the current update fails, then all feed entries processed in the previous
    feed update will be reported to be removed.

  After a successful update from the feed, the feed manager provides two
  different dates:

  * `last_update` will be the timestamp of the last update from the feed
    irrespective of whether it was successful or not.
  * `last_update_successful` will be the timestamp of the last successful update
    from the feed. This date may be useful if the consumer of this library wants
    to treat intermittent errors from feed updates differently.
  * `last_timestamp` is not available for this feed.

rpm_license:
[cell repeats an earlier one in this file: 10254 characters]


pkgId: e00f0cc6b29dc361b96ee2c8850f82a6efd6031740d7fd1181fb3549d2929642
name: python-aio-geojson-nsw-rfs-incidents
arch: src
version: 0.8
epoch: 0
release: 1
summary: An async GeoJSON client library for NSW Rural Fire Service Incidents.
url: https://pypi.org/project/aio-geojson-nsw-rfs-incidents/
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aio-geojson-nsw-rfs-incidents-0.8-1.src.rpm
checksum_type: sha256
description:
  [![Build Status](https://img.shields.io/github/actions/workflow/status/exxamalte/python-aio-geojson-nsw-rfs-incidents/ci.yaml)](https://github.com/exxamalte/python-aio-geojson-nsw-rfs-incidents/actions/workflows/ci.yaml)
  [![codecov](https://codecov.io/gh/exxamalte/python-aio-geojson-nsw-rfs-incidents/branch/master/graph/badge.svg?token=7G2BWWSYRZ)](https://codecov.io/gh/exxamalte/python-aio-geojson-nsw-rfs-incidents)
  [![PyPi](https://img.shields.io/pypi/v/aio-geojson-nsw-rfs-incidents.svg)](https://pypi.python.org/pypi/aio-geojson-nsw-rfs-incidents)
  [![Version](https://img.shields.io/pypi/pyversions/aio-geojson-nsw-rfs-incidents.svg)](https://pypi.python.org/pypi/aio-geojson-nsw-rfs-incidents)

  This library provides convenient async access to the [NSW Rural Fire Service](https://www.rfs.nsw.gov.au/fire-information/fires-near-me) incidents feed.


  `pip install aio-geojson-nsw-rfs-incidents`


  See below for examples of how this library can be used. After instantiating a
  particular class - feed or feed manager - and supply the required parameters,
  you can call `update` to retrieve the feed data. The return value
  will be a tuple of a status code and the actual data in the form of a list of
  feed entries specific to the selected feed.

  Status Codes
  * _OK_: Update went fine and data was retrieved. The library may still
    return empty data, for example because no entries fulfilled the filter
    criteria.
  * _OK_NO_DATA_: Update went fine but no data was retrieved, for example
    because the server indicated that there was not update since the last request.
  * _ERROR_: Something went wrong during the update

  **Parameters**

  | Parameter          | Description                               |
  |--------------------|-------------------------------------------|
  | `home_coordinates` | Coordinates (tuple of latitude/longitude) |

  **Supported Filters**

  | Filter     |                     | Description |
  |------------|---------------------|-------------|
  | Radius     | `filter_radius`     | Radius in kilometers around the home coordinates in which events from feed are included. |
  | Categories | `filter_categories` | Array of category names. Only events with a category matching any of these is included. |

  **Example**
  ```python
  import asyncio
  from aiohttp import ClientSession
  from aio_geojson_nsw_rfs_incidents import NswRuralFireServiceIncidentsFeed
  async def main() -> None:
      async with ClientSession() as websession:
          
          
          
          feed = NswRuralFireServiceIncidentsFeed(websession,
                                                  (-33.0, 150.0),
                                                  filter_radius=50,
                                                  filter_categories=['Advice'])
          status, entries = await feed.update()
          print(status)
          print(entries)
  asyncio.get_event_loop().run_until_complete(main())
  ```


  Each feed entry is populated with the following properties:

  | Name               | Description                                                                                         | Feed attribute |
  |--------------------|-----------------------------------------------------------------------------------------------------|----------------|
  | geometry           | All geometry details of this entry.                                                                 | `geometry`     |
  | coordinates        | Best coordinates (latitude, longitude) of this entry.                                               | `geometry`     |
  | external_id        | The unique public identifier for this incident.                                                     | `guid`         |
  | title              | Title of this entry.                                                                                | `title`        |
  | attribution        | Attribution of the feed.                                                                            | n/a            |
  | distance_to_home   | Distance in km of this entry to the home coordinates.                                               | n/a            |
  | category           | The alert level of the incident ('Emergency Warning', 'Watch and Act', 'Advice','Not Applicable').  | `category`     |
  | publication_date   | The publication date of the incidents.                                                              | `pubDate`      |
  | description        | The description of the incident.                                                                    | `description`  |
  | location           | Location description of the incident.                                                               | `description` -> `LOCATION`            |
  | council_area       | Council are this incident falls into.                                                               | `description` -> `COUNCIL AREA`        |
  | status             | Status of the incident.                                                                             | `description` -> `STATUS`              |
  | type               | Type of the incident (e.g. Bush Fire, Grass Fire, Hazard Reduction).                                | `description` -> `TYPE`                |
  | fire               | Indicated if this incident is a fire or not (`True`/`False`).                                       | `description` -> `FIRE`                |
  | size               | Size in ha.                                                                                         | `description` -> `SIZE`                |
  | responsible_agency | Agency responsible for this incident.                                                               | `description` -> `RESPONSIBLE AGENCY`  |




  The Feed Manager helps managing feed updates over time, by notifying the
  consumer of the feed about new feed entries, updates and removed entries
  compared to the last feed update.

  * If the current feed update is the first one, then all feed entries will be
    reported as new. The feed manager will keep track of all feed entries'
    external IDs that it has successfully processed.
  * If the current feed update is not the first one, then the feed manager will
    produce three sets:
    * Feed entries that were not in the previous feed update but are in the
      current feed update will be reported as new.
    * Feed entries that were in the previous feed update and are still in the
      current feed update will be reported as to be updated.
    * Feed entries that were in the previous feed update but are not in the
      current feed update will be reported to be removed.
  * If the current update fails, then all feed entries processed in the previous
    feed update will be reported to be removed.

  After a successful update from the feed, the feed manager provides two
  different dates:

  * `last_update` will be the timestamp of the last update from the feed
    irrespective of whether it was successful or not.
  * `last_update_successful` will be the timestamp of the last successful update
    from the feed. This date may be useful if the consumer of this library wants
    to treat intermittent errors from feed updates differently.
  * `last_timestamp` (optional, depends on the feed data) will be the latest
    timestamp extracted from the feed data.
    This requires that the underlying feed data actually contains a suitable
    date. This date may be useful if the consumer of this library wants to
    process feed entries differently if they haven't actually been updated.

rpm_license:
[cell repeats an earlier one in this file: 10254 characters]


pkgId: 428f2af40f78ac51c9da6deb71e5d8baf6c19689f834049f6333145a0da4a44d
name: python-aio-geojson-usgs-earthquakes
arch: src
version: 0.4
epoch: 0
release: 1
summary: An async GeoJSON client library for the U.S. Geological Survey Earthquake Hazards Program.
url: https://pypi.org/project/aio-geojson-usgs-earthquakes/
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aio-geojson-usgs-earthquakes-0.4-1.src.rpm
checksum_type: sha256
description:
  [![Build Status](https://img.shields.io/github/actions/workflow/status/exxamalte/python-aio-geojson-usgs-earthquakes/ci.yaml)](https://github.com/exxamalte/python-aio-geojson-usgs-earthquakes/actions/workflows/ci.yaml)
  [![codecov](https://codecov.io/gh/exxamalte/python-aio-geojson-usgs-earthquakes/branch/main/graph/badge.svg?token=91DC4HHZQJ)](https://codecov.io/gh/exxamalte/python-aio-geojson-usgs-earthquakes)
  [![PyPi](https://img.shields.io/pypi/v/aio-geojson-usgs-earthquakes.svg)](https://pypi.python.org/pypi/aio-geojson-usgs-earthquakes)
  [![Version](https://img.shields.io/pypi/pyversions/aio-geojson-usgs-earthquakes.svg)](https://pypi.python.org/pypi/aio-geojson-usgs-earthquakes)

  This library provides convenient async access to U.S. Geological Survey Earthquake Hazards Program feeds.


  `pip install aio-geojson-usgs-earthquakes`


  See below for examples of how this library can be used. After instantiating a
  particular class - feed or feed manager - and supply the required parameters,
  you can call `update` to retrieve the feed data. The return value
  will be a tuple of a status code and the actual data in the form of a list of
  feed entries specific to the selected feed.

  Status Codes
  * _OK_: Update went fine and data was retrieved. The library may still
    return empty data, for example because no entries fulfilled the filter
    criteria.
  * _OK_NO_DATA_: Update went fine but no data was retrieved, for example
    because the server indicated that there was not update since the last request.
  * _ERROR_: Something went wrong during the update

  **Parameters**

  | Parameter          | Description                               |
  |--------------------|-------------------------------------------|
  | `home_coordinates` | Coordinates (tuple of latitude/longitude) |

  **Supported Feeds**

  | Category                               | Feed                                 |
  |----------------------------------------|--------------------------------------|
  | Past Hour - Significant Earthquakes    | `past_hour_significant_earthquakes`  |
  | Past Hour - M4.5+ Earthquakes          | `past_hour_m45_earthquakes`          |
  | Past Hour - M2.5+ Earthquakes          | `past_hour_m25_earthquakes`          |
  | Past Hour - M1.0+ Earthquakes          | `past_hour_m10_earthquakes`          |
  | Past Hour - All Earthquakes            | `past_hour_all_earthquakes`          |
  | Past Day - Significant Earthquakes     | `past_day_significant_earthquakes`   |
  | Past Day - M4.5+ Earthquakes           | `past_day_m45_earthquakes`           |
  | Past Day - M2.5+ Earthquakes           | `past_day_m25_earthquakes`           |
  | Past Day - M1.0+ Earthquakes           | `past_day_m10_earthquakes`           |
  | Past Day - All Earthquakes             | `past_day_all_earthquakes`           |
  | Past 7 Days - Significant Earthquakes  | `past_week_significant_earthquakes`  |
  | Past 7 Days - M4.5+ Earthquakes        | `past_week_m45_earthquakes`          |
  | Past 7 Days - M2.5+ Earthquakes        | `past_week_m25_earthquakes`          |
  | Past 7 Days - M1.0+ Earthquakes        | `past_week_m10_earthquakes`          |
  | Past 7 Days - All Earthquakes          | `past_week_all_earthquakes`          |
  | Past 30 Days - Significant Earthquakes | `past_month_significant_earthquakes` |
  | Past 30 Days - M4.5+ Earthquakes       | `past_month_m45_earthquakes`         |
  | Past 30 Days - M2.5+ Earthquakes       | `past_month_m25_earthquakes`         |
  | Past 30 Days - M1.0+ Earthquakes       | `past_month_m10_earthquakes`         |
  | Past 30 Days - All Earthquakes         | `past_month_all_earthquakes`         |

  **Supported Filters**

  | Filter            |                            | Description |
  |-------------------|----------------------------|-------------|
  | Radius            | `filter_radius`            | Radius in kilometers around the home coordinates in which events from feed are included. |
  | Minimum Magnitude | `filter_minimum_magnitude` | Minimum magnitude as float value. Only event with a magnitude equal or above this value are included. |


  **Example**
  ```python
  import asyncio
  from aiohttp import ClientSession
  from aio_geojson_usgs_earthquakes import UsgsEarthquakeHazardsProgramFeed
  async def main() -> None:
      async with ClientSession() as websession:
          
          
          
          
          feed = UsgsEarthquakeHazardsProgramFeed(websession,
                                                  (21.3, -157.8),
                                                  'past_day_all_earthquakes',
                                                  filter_radius=5000,
                                                  filter_minimum_magnitude=4.0)
          status, entries = await feed.update()
          print(status)
          print(entries)
  asyncio.get_event_loop().run_until_complete(main())
  ```


  Each feed entry is populated with the following properties:

  | Name               | Description                                                                                         | Feed attribute |
  |--------------------|-----------------------------------------------------------------------------------------------------|----------------|
  | geometries         | All geometry details of this entry.                                                                 | `geometry`     |
  | coordinates        | Best coordinates (latitude, longitude) of this entry.                                               | `geometry`     |
  | distance_to_home   | Distance in km of this entry to the home coordinates.                                               | n/a            |
  | attribution        | Attribution of the feed.                                                                            | n/a            |
  | external_id        | The unique public identifier for this entry.                                                        | `id`           |
  | title              | Title of this entry.                                                                                | `title`        |
  | place              | Description of the place where this earthquakes occurred.                                           | `place`        |
  | magnitude          | Magnitude of this earthquake.                                                                       | `mag`          |
  | time               | Date and time when this event occurred.                                                             | `time`         |
  | updated            | Date and time when this entry was last updated.                                                     | `updated`      |
  | alert              | Alert level of this entry ("green", "yellow", "orange", "red").                                     | `alert`        |
  | type               | Type of this seismic event ("earthquake", "quarry").                                                | `type`         |
  | status             | Indicates whether the event has been reviewed by a human ("automatic", "reviewed", "deleted").      | `status`       |




  The Feed Manager helps managing feed updates over time, by notifying the
  consumer of the feed about new feed entries, updates and removed entries
  compared to the last feed update.

  * If the current feed update is the first one, then all feed entries will be
    reported as new. The feed manager will keep track of all feed entries'
    external IDs that it has successfully processed.
  * If the current feed update is not the first one, then the feed manager will
    produce three sets:
    * Feed entries that were not in the previous feed update but are in the
      current feed update will be reported as new.
    * Feed entries that were in the previous feed update and are still in the
      current feed update will be reported as to be updated.
    * Feed entries that were in the previous feed update but are not in the
      current feed update will be reported to be removed.
  * If the current update fails, then all feed entries processed in the previous
    feed update will be reported to be removed.

  After a successful update from the feed, the feed manager provides two
  different dates:

  * `last_update` will be the timestamp of the last update from the feed
    irrespective of whether it was successful or not.
  * `last_update_successful` will be the timestamp of the last successful update
    from the feed. This date may be useful if the consumer of this library wants
    to treat intermittent errors from feed updates differently.
  * `last_timestamp` (optional, depends on the feed data) will be the latest
    timestamp extracted from the feed data.
    This requires that the underlying feed data actually contains a suitable
    date. This date may be useful if the consumer of this library wants to
    process feed entries differently if they haven't actually been updated.

rpm_license:
[cell repeats an earlier one in this file: 10254 characters]


pkgId: 48531c8c1cacb8f82e0b249417ec048b1ef3e8c0c87c6f886b233775eeec2969
name: python-aio-georss-client
arch: src
version: 0.14
epoch: 0
release: 1
summary: An async GeoRSS client library.
url: https://pypi.org/project/aio-georss-client/
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aio-georss-client-0.14-1.src.rpm
checksum_type: sha256
description:
  [![Build Status](https://img.shields.io/github/actions/workflow/status/exxamalte/python-aio-georss-client/ci.yaml)](https://github.com/exxamalte/python-aio-georss-client/actions/workflows/ci.yaml)
  [![codecov](https://codecov.io/gh/exxamalte/python-aio-georss-client/branch/master/graph/badge.svg?token=JHET53MLPC)](https://codecov.io/gh/exxamalte/python-aio-georss-client)
  [![PyPi](https://img.shields.io/pypi/v/aio-georss-client.svg)](https://pypi.python.org/pypi/aio-georss-client)
  [![Version](https://img.shields.io/pypi/pyversions/aio-georss-client.svg)](https://pypi.python.org/pypi/aio-georss-client)
  [![Maintainability](https://api.codeclimate.com/v1/badges/29d6a4a8caeac24a91bd/maintainability)](https://codeclimate.com/github/exxamalte/python-aio-georss-client/maintainability)

  This library provides convenient async access to [GeoRSS](http://www.georss.org/) Feeds.


  `pip install aio-georss-client`



  | Library  | Source  | Topic  |
  |----------|---------|--------|
  | [aio_georss_gdacs](https://github.com/exxamalte/python-aio-georss-gdacs) | Global Disaster Alert and Coordination System (GDACS) | Natural Disasters |


  Each implementation extracts relevant information from the GeoJSON feed. Not
  all feeds contain the same level of information, or present their information
  in different ways.

  After instantiating a particular class and supply the required parameters, you
  can call `update` to retrieve the feed data. The return value will be a tuple
  of a status code and the actual data in the form of a list of feed entries
  specific to the selected feed.

  Status Codes
  * _OK_: Update went fine and data was retrieved. The library may still
    return empty data, for example because no entries fulfilled the filter
    criteria.
  * _OK_NO_DATA_: Update went fine but no data was retrieved, for example
    because the server indicated that there was not update since the last request.
  * _ERROR_: Something went wrong during the update


  This library supports 3 different types of geometries:
  * Point
  * Polygon
  * Bounding Box

  By default each feed entry is using all available geometries from the external
  feed. If required however, you can exclude geometries by overriding
  FeedEntry#features and only return the geometries you want to support in your
  specific implementation.




  The Feed Manager helps managing feed updates over time, by notifying the
  consumer of the feed about new feed entries, updates and removed entries
  compared to the last feed update.

  * If the current feed update is the first one, then all feed entries will be
    reported as new. The feed manager will keep track of all feed entries'
    external IDs that it has successfully processed.
  * If the current feed update is not the first one, then the feed manager will
    produce three sets:
    * Feed entries that were not in the previous feed update but are in the
      current feed update will be reported as new.
    * Feed entries that were in the previous feed update and are still in the
      current feed update will be reported as to be updated.
    * Feed entries that were in the previous feed update but are not in the
      current feed update will be reported to be removed.
  * If the current update fails, then all feed entries processed in the previous
    feed update will be reported to be removed.

  After a successful update from the feed, the feed manager provides two
  different dates:

  * `last_update` will be the timestamp of the last update from the feed
    irrespective of whether it was successful or not.
  * `last_update_successful` will be the timestamp of the last successful update
    from the feed. This date may be useful if the consumer of this library wants
    to treat intermittent errors from feed updates differently.
  * `last_timestamp` (optional, depends on the feed data) will be the latest
    timestamp extracted from the feed data.
    This requires that the underlying feed data actually contains a suitable
    date. This date may be useful if the consumer of this library wants to
    process feed entries differently if they haven't actually been updated.

rpm_license:
[cell repeats an earlier one in this file: 10254 characters]


pkgId: f18675045ff864a81bcf41d36e429eafde237ab172be0c198f4020a9daed295c
name: python-aio-insight
arch: src
version: 1.0.6
epoch: 0
release: 1
summary: A Python library for asynchronous querying of Jira Insight API.
url: https://github.com/g-rd/aio_insight
rpm_license: Apache License 2.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aio-insight-1.0.6-1.src.rpm
checksum_type: sha256
description:
  `AIOInsight` is an asynchronous Python library for interacting with Jira Insight's API. It leverages `asyncio` and `httpx` for high-performance data retrieval and management, supporting complex data models, schema processing, and concurrent requests.

  This project is based on the Atlassian Python API, with methods rewritten to support asynchronous operations, providing improved performance and scalability.



  - **Asynchronous Operations:** Uses `asyncio` and `httpx` for concurrent HTTP requests, ensuring high throughput.
  - **Comprehensive API Interaction:** Retrieve schemas, manage objects, and handle data models.
  - **Error Handling:** Includes custom exceptions for robust error handling.
  - **Configurable Parameters:** Allows customization of settings for optimized performance.
  - **Schema Processing:** Automates schema processing for detailed data models in Insight.



  Install dependencies:

  ```bash
  pip install httpx aiohttp anyio
  ```



  ```python
  import asyncio
  import logging
  from aio_insight.aio_insight import AsyncInsight
  from creds import assets_token, assets_url, assets_username

  logging.basicConfig(level=logging.ERROR, format='s - s - s')
  logger = logging.getLogger(__name__)

  async def use_aio_insight():
      async with AsyncInsight(
              url=assets_url,
              username=assets_username,
              password=assets_token,
              cloud=True
      ) as session:
          object_schemas = await session.get_object_schemas()
          print(object_schemas)

  if __name__ == "__main__":
      asyncio.run(use_aio_insight())
  ```



  1. **`get_object_schemas()`**
     - **Description:** Retrieves all object schemas available in Jira Insight.
     - **Returns:** A list of object schemas, each including details such as schema ID, name, and object types within the schema.

  2. **`get_object_schema(schema_id)`**
     - **Description:** Fetches detailed information about a specific object schema by its ID.
     - **Parameters:**
       - `schema_id` (int): The ID of the object schema.
     - **Returns:** A dictionary with information about the specified schema, including name, attributes, and associated object types.

  3. **`create_object_schema(name, description)`**
     - **Description:** Creates a new object schema in Jira Insight.
     - **Parameters:**
       - `name` (str): Name for the new schema.
       - `description` (str): Description for the new schema.
     - **Returns:** A dictionary containing the created schema's details, such as schema ID, name, and description.

  4. **`update_object_schema(schema_id, name, description)`**
     - **Description:** Updates an existing schema’s name and description.
     - **Parameters:**
       - `schema_id` (int): ID of the schema to update.
       - `name` (str): New name for the schema.
       - `description` (str): New description for the schema.
     - **Returns:** A dictionary with updated schema information.

  5. **`get_object_schema_object_types(schema_id)`**
     - **Description:** Lists all object types within a given schema.
     - **Parameters:**
       - `schema_id` (int): ID of the object schema.
     - **Returns:** A list of object types, each including details like type ID, name, and attributes.

  6. **`get_object_schema_object_types_flat(schema_id)`**
     - **Description:** Retrieves object types in a flat structure for a given schema.
     - **Parameters:**
       - `schema_id` (int): ID of the object schema.
     - **Returns:** A list of object types without hierarchical organization, including type details.

  7. **`get_object_schema_object_attributes(schema_id, ...)`**
     - **Description:** Retrieves all attributes for the specified schema, with options for filtering and sorting.
     - **Parameters:** Additional filters such as `only_value_editable`, `order_by_name`, etc.
     - **Returns:** A list of attributes associated with the schema, with details like attribute ID, name, type, and editability.

  8. **`get_object(object_id)`**
     - **Description:** Retrieves information about a specific object by its ID.
     - **Parameters:**
       - `object_id` (int): The ID of the object.
     - **Returns:** A dictionary with object details, including attributes, relationships, and type.

  9. **`get_objects_by_aql(schema_id, object_type_id, aql_query, ...)`**
     - **Description:** Searches for objects based on an AQL (Asset Query Language) query.
     - **Parameters:**
       - `schema_id` (int): ID of the schema.
       - `object_type_id` (int): ID of the object type.
       - `aql_query` (str): The AQL query string.
     - **Returns:** A paginated dictionary of matching objects, including object attributes and type details.

  10. **`get_object_type_attributes(object_type_id, ...)`**
      - **Description:** Retrieves attributes for a specific object type, with options to filter or sort results.
      - **Parameters:** Filters like `only_value_editable`, `order_by_name`, etc.
      - **Returns:** A list of attributes associated with the object type, including details like attribute ID, type, and default values.

  11. **`create_object(object_type_id, attributes, ...)`**
      - **Description:** Creates a new object with specified attributes.
      - **Parameters:**
        - `object_type_id` (int): ID of the object type.
        - `attributes` (list): List of attribute dictionaries for the new object.
      - **Returns:** A dictionary containing details of the created object, including object ID, type, and attributes.

  12. **`update_object(object_id, object_type_id, attributes, ...)`**
      - **Description:** Updates an existing object with new attributes.
      - **Parameters:** Similar to `create_object`, with an additional `object_id` for identifying the object.
      - **Returns:** A dictionary with updated object details.

  13. **`delete_object(object_id)`**
      - **Description:** Deletes an object by its ID.
      - **Parameters:**
        - `object_id` (int): The ID of the object to delete.
      - **Returns:** A confirmation message or status indicating successful deletion.

  14. **`get_object_attributes(object_id)`**
      - **Description:** Retrieves attributes of a specific object.
      - **Parameters:**
        - `object_id` (int): ID of the object.
      - **Returns:** A dictionary with attribute details, including values, types, and other metadata.

  15. **`get_object_history(object_id, ...)`**
      - **Description:** Retrieves the history of changes for a specified object.
      - **Parameters:** Options to filter by ascending order or abbreviation.
      - **Returns:** A list of historical changes, including date, author, and attribute modifications.

  16. **`get_object_reference_info(object_id)`**
      - **Description:** Gets references to and from a specified object.
      - **Parameters:**
        - `object_id` (int): ID of the object.
      - **Returns:** A dictionary of related objects and their reference types.

  17. **`get_status_types(object_schema_id)`**
      - **Description:** Retrieves available status types for a schema.
      - **Parameters:**
        - `object_schema_id` (int): Optional schema ID for filtering status types.
      - **Returns:** A list of status types, including status ID, name, and description.

  18. **`get_attachments_of_objects(object_id)`** *(Data Center only)*
      - **Description:** Fetches attachment details for an object (not supported in Cloud).
      - **Parameters:**
        - `object_id` (int): ID of the object.
      - **Returns:** A list of attachment details like attachment ID, name, and URL.

  19. **`upload_attachment_to_object(object_id, filename)`** *(Data Center only)*
      - **Description:** Uploads an attachment to an object (not supported in Cloud).
      - **Parameters:**
        - `object_id` (int): ID of the object.
        - `filename` (str): Path of the file to upload.
      - **Returns:** Details of the uploaded attachment, such as attachment ID and URL.

  20. **`delete_attachment(attachment_id)`** *(Data Center only)*
      - **Description:** Deletes an attachment by its ID (not supported in Cloud).
      - **Parameters:**
        - `attachment_id` (int): ID of the attachment.
      - **Returns:** A confirmation of successful deletion.

  21. **`add_comment_to_object(comment, object_id, role)`** *(Data Center only)*
      - **Description:** Adds a comment to an object (not supported in Cloud).
      - **Parameters:** Comment text, object ID, and role.
      - **Returns:** Details of the added comment.

  22. **`get_comment_of_object(object_id)`** *(Data Center only)*
      - **Description:** Retrieves comments for an object (not supported in Cloud).
      - **Parameters:** Object ID.
      - **Returns:** A list of comments associated with the object.

  23. **`get_icon_by_id(icon_id)`**
      - **Description:** Retrieves an icon's details by its ID.
      - **Parameters:**
        - `icon_id` (int): ID of the icon.
      - **Returns:** Icon information including ID, name, and image data or URL.

  24. **`get_all_global_icons()`**
      - **Description:** Retrieves all global icons.

      - **Returns:** list of all icons available globally, including details like icon ID, name, and URL.

  26. **`start_import_configuration(import_id)`**
      - **Description:** Starts an import based on a configuration ID.
      - **Parameters:**
        - `import_id` (int): ID of the import configuration.
      - **Returns:** Status or confirmation of the import initiation.

  27. **`reindex_insight()`** *(Data Center only)*
      - **Description:** Initiates a full reindex of Insight (not supported in Cloud).
      - **Returns:** Confirmation of the reindex operation.

  28. **`reindex_current_node_insight()`** *(Data Center only)*
      - **Description:** Reindexes the current node in Insight (not supported in Cloud).
      - **Returns:** Confirmation of the reindex operation for the current node.


pkgId: cb2b30bfb068fa040094beb62eac5e5bd2795e1bf1e1a8b657dd85e88505ce0e
name: python-aio-intex-spa
arch: src
version: 0.9.1
epoch: 0
release: 1
summary: Python client for Intex Spa wifi interface
url: https://github.com/mathieu-mp/aio-intex-spa
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aio-intex-spa-0.9.1-1.src.rpm
checksum_type: sha256
description:
  <!-- badges start -->

  [![PyPI version][pypibadge]][pypilink]
  ![Project Maintenance][maintenance-shield]
  [![Open in Remote - Containers][devcontainer-badge]][devcontainer]

  <!-- badges end -->

  _An AsyncIO-compatible Python client for Intex Spa wifi interface_



  This python package aims to provide an interface with the Intex Spa wifi module.

  It is compatible with Intex wifi-enabled spas without any specific hardware, as it uses the built-in Intex wifi module.

  It uses direct TCP connection to the spa, and does not require access to the Intex cloud. The built-in Intex wifi module only has to be connected to a wifi Access Point.

  It is written with asyncio network functions. It only supports asyncio usage.



  ```bash
  python3 -m pip install -U aio-intex-spa
  ```



  Below are some examples, see `examples` directory for more delight.


  ```python
  from aio_intex_spa import IntexSpa

  async def get_spa_status():
      spa = IntexSpa(SPA_ADDRESS)
      await spa.async_update_status()

  asyncio.run(get_spa_status())
  ```


  ```python
  from aio_intex_spa import IntexSpa

  async def set_spa_heater_state():
      spa = IntexSpa(SPA_ADDRESS)
      await spa.async_set_heater(True)

  asyncio.run(set_spa_heater_state())
  ```



  The versioning of this python package follows Semantic Versioning 2.0.0

  ***Reminder**: Major version zero (0.y.z) is for initial development. Anything MAY change at any time. The public API SHOULD NOT be considered stable.*

  For Changelog, please read [releases].

  <!-- links start -->

  [pypilink]: https://pypi.org/project/aio-intex-spa/
  [pypibadge]: https://badge.fury.io/py/aio-intex-spa.svg
  [releases]: https://github.com/mathieu-mp/aio-intex-spa/releases
  [maintenance-shield]: https://img.shields.io/maintenance/yes/2024.svg
  [devcontainer]: https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/mathieu-mp/aio-intex-spa
  [devcontainer-badge]: https://img.shields.io/static/v1?label=Remote%20-%20Containers&message=Open&color=blue&logo=visualstudiocode

  <!-- links end -->


pkgId: 8517d9bc6d9a50933bc45882235ef93d8972ece8461825d57a52bdb9c16cae68
name: python-aio-ipfabric
arch: src
version: 1.0.0
epoch: 0
release: 1
summary: IP Fabric asyncio client
url: https://pypi.org/project/aio-ipfabric/
rpm_license: UNKNOWN
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aio-ipfabric-1.0.0-1.src.rpm
checksum_type: sha256
description:
  This package contains a Python 3.8+ asyncio client for use wih the IP Fabric product.

     * About IP Fabric: https://ipfabric.io/
     * About IP Fabric API: https://docs.ipfabric.io/api/


  [![Downloads](https://pepy.tech/badge/aio-ipfabric)](https://pepy.tech/project/aio-ipfabric)
  ![Supported Python Version](https://img.shields.io/pypi/pyversions/aio-ipfabric)
  ![Contributors](https://img.shields.io/github/contributors/jeremyschulman/aio-ipfabric)
  [![License](https://img.shields.io/github/license/jeremyschulman/aio-ipfabric)](https://github.com/jeremyschulman/aio-ipfabric/blob/main/LICENSE)




  aio-ipfabric is available on [PyPI](https://pypi.org/project/aio-ipfabric/):

  ```shell script
  pip install aio-ipfabric
  ```

  Direct installation
  ```shell script
  pip install git+https://github.com/jeremyschulman/aio-ipfabric@master#egg=aio-ipfabric
  ```

  Requests officially supports Python 3.8+.




  ````python
  from aioipfabric import IPFabricClient

  async def demo_1_devices_list():
      """
      Example code that uses IPFabricClient without contextmanager
      """

      
      ipf = IPFabricClient()

      
      
      

      
      await ipf.login()

      
      device_list = await ipf.fetch_devices()

      
      await ipf.logout()

      return device_list

  async def demo_2_devices_list():
      """
      Example code that uses IPFabricClient as contextmanager
      """

      
      async with IPFabricClient() as ipf:
          return await ipf.fetch_devices()
  ````




  The following environment variable can be used so that you do no need to
  provide them in your program:

     * `IPF_ADDR` - IP Fabric server URL, for example "https://my-ipfabric-server.com/"
     * `IPF_USERNAME` - Login username
     * `IPF_PASSWORD` - Login password
     * `IPF_TOKEN` - A persistent API token

  You can use either the login credentials or the token to login.

  If you prefer not to use environment variables, the call to `IPFabricClient()` accepts
  parameters; refer to the `help(IPFabricClient)` for details.



  See the [docs](docs) directory.


pkgId: a2d5c42a290a6d501a7c05a6f1a0cc38180387c3958b91700871a59282ca8b57
name: python-aio-kong
arch: src
version: 3.4.0
epoch: 0
release: 1
summary: Asynchronous Kong Client
url: https://pypi.org/project/aio-kong/
rpm_license: BSD-3-Clause
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aio-kong-3.4.0-1.src.rpm
checksum_type: sha256
description:
  [![PyPI version](https://badge.fury.io/py/aio-kong.svg)](https://badge.fury.io/py/aio-kong)
  [![Python versions](https://img.shields.io/pypi/pyversions/aio-kong.svg)](https://pypi.org/project/aio-kong)
  [![Build](https://github.com/quantmind/aio-kong/workflows/build/badge.svg)](https://github.com/quantmind/aio-kong/actions?query=workflow%3Abuild)
  [![codecov](https://codecov.io/gh/quantmind/aio-kong/branch/main/graph/badge.svg?token=JF5L0PEkW6)](https://codecov.io/gh/quantmind/aio-kong)
  [![Downloads](https://img.shields.io/pypi/dd/aio-kong.svg)](https://pypi.org/project/aio-kong/)


  Tested with [kong][] v3.7



  To install the package

  ```
  pip install aio-kong
  ```

  To run tests, clone and

  ```
  make test
  ```

  :warning: If you don't have Kong or postgres running locally, run the services first

  ```bash
  make services
  ```

  test certificates were generated using the command

  ```
  openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -nodes -subj '/CN=localhost'
  ```



  The client can be imported via

  ```python
  from kong.client import Kong
  ```

  In a coroutine:

  ```python
  async with Kong() as cli:
      services = await cli.services.get_list()
      print(json.dumps([s.data for s in services], indent=2))
  ```

  By default the url is obtained from the "KONG_ADMIN_URL" environment variable which defaults to http://127.0.0.1:8001.

  The client has handlers for all Kong objects

  - [cli.services](./kong/services.py) CRUD operations on services
  - [cli.routes](./kong/routes.py) CRUD operations on routes
  - [cli.plugins](./kong/plugins.py) CRUD operations on plugins
  - [cli.consumers](./kong/consumers.py) CRUD operations on consumers
  - [cli.certificates](./kong/certificates.py) CRUD operations on TLS certificates
  - [cli.snis](./kong/snis.py) CRUD operations on SNIs
  - `cli.acls` To list all ACLs



  The client allow to apply a configuration object to kong:

  ```python
  await cli.apply_json(config)
  ```



  The library install the `kongfig` command line tool for uploading kong configuration files.

  ```
  kongfig --yaml config.yaml
  ```

  [kong]: https://github.com/Kong/kong


pkgId: 30e30530137f3b14a136723f3b848073661ca06fec699cbaed01fb8a0606fa7c
name: python-aio-kong
arch: src
version: 3.5.0
epoch: 0
release: 1
summary: Asynchronous Kong Client
url: https://pypi.org/project/aio-kong/
rpm_license: BSD-3-Clause
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aio-kong-3.5.0-1.src.rpm
checksum_type: sha256
description:
  [![PyPI version](https://badge.fury.io/py/aio-kong.svg)](https://badge.fury.io/py/aio-kong)
  [![Python versions](https://img.shields.io/pypi/pyversions/aio-kong.svg)](https://pypi.org/project/aio-kong)
  [![Build](https://github.com/quantmind/aio-kong/workflows/build/badge.svg)](https://github.com/quantmind/aio-kong/actions?query=workflow%3Abuild)
  [![codecov](https://codecov.io/gh/quantmind/aio-kong/branch/main/graph/badge.svg?token=JF5L0PEkW6)](https://codecov.io/gh/quantmind/aio-kong)
  [![Downloads](https://img.shields.io/pypi/dd/aio-kong.svg)](https://pypi.org/project/aio-kong/)


  Tested with [kong][] v3.8



  To install the package

  ```
  pip install aio-kong
  ```

  To run tests, clone and

  ```
  make test
  ```

  :warning: If you don't have Kong or postgres running locally, run the services first

  ```bash
  make services
  ```

  test certificates were generated using the command

  ```
  openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -nodes -subj '/CN=localhost'
  ```



  The client can be imported via

  ```python
  from kong.client import Kong
  ```

  In a coroutine:

  ```python
  async with Kong() as cli:
      services = await cli.services.get_list()
      print(json.dumps([s.data for s in services], indent=2))
  ```

  By default the url is obtained from the "KONG_ADMIN_URL" environment variable which defaults to http://127.0.0.1:8001.

  The client has handlers for all Kong objects

  - [cli.services](./kong/services.py) CRUD operations on services
  - [cli.routes](./kong/routes.py) CRUD operations on routes
  - [cli.plugins](./kong/plugins.py) CRUD operations on plugins
  - [cli.consumers](./kong/consumers.py) CRUD operations on consumers
  - [cli.certificates](./kong/certificates.py) CRUD operations on TLS certificates
  - [cli.snis](./kong/snis.py) CRUD operations on SNIs
  - `cli.acls` To list all ACLs



  The client allow to apply a configuration object to kong:

  ```python
  await cli.apply_json(config)
  ```



  The library install the `kongfig` command line tool for uploading kong configuration files.

  ```
  kongfig --yaml config.yaml
  ```

  [kong]: https://github.com/Kong/kong


pkgId: fbbc36b79bc1d8964e0f1e8abceffcb67b344ecd154354116d68bdb843fd6c41
name: python-aio-net-events
arch: src
version: 7.0.0
epoch: 0
release: 1
summary: Asynchronous network configuration event detector for Python 3.7 and above
url: https://github.com/ntamas/aio-net-events/
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aio-net-events-7.0.0-1.src.rpm
checksum_type: sha256
description:
  `aio-net-events` is a Python library that provides asynchronous generators
  yielding events when the network configuration of the machine changes.
  Currently only network interface additions / removals and IP address additions /
  removals are supported; more events may be added later.

  Supports Windows, Linux and macOS at the moment.

  Requires Python >= 3.8.

  Works with [`asyncio`](https://docs.python.org/3/library/asyncio.html) and
  [`trio`](https://trio.readthedocs.io/en/stable/).



  Use the package manager [pip](https://pip.pypa.io/en/stable/) to install
  `aio-net-events`.

  ```bash
  pip install aio-net-events
  ```





  Pull requests are welcome. For major changes, please open an issue first to
  discuss what you would like to change.

  Please make sure to update tests as appropriate.



  [MIT](https://choosealicense.com/licenses/mit/)


pkgId: 2861c7435ea2c0d09edc06e5620022d509947f6182e7f268bff8baa85ba9dc45
name: python-aio-odoorpc-base
arch: src
version: 3.0.4
epoch: 0
release: 1
url: https://github.com/mbello/aio-odoorpc-base
rpm_license: CC0-1.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aio-odoorpc-base-3.0.4-1.src.rpm
checksum_type: sha256
summary:
  Fast, simple Odoo RPC package with sync and async functions to pilot Odoo's jsonrpc API. Check aio-odoorpc for a higher-level, friendlier interface.

description:
  This python package implements a **complete** set of methods to access
  Odoo's external API (using jsonrpc rather than xmlrpc).

  It offers an almost-exact mirror of Odoo's external API, even parameter names are the same.
  It is 'almost-exact' because 'execute' is skipped in favor of 'execute_kw' only and the
  It is 'almost-exact' because 'execute' is skipped in favor of 'execute_kw' only and the
  API methods from the 'db' service: 'list', 'drop', 'dump', 'rename', 'restore' are here
  implemented with names 'list_databases', 'drop_database', 'dump_database', 'rename_database'
  and 'restore_database' respectively.

  The 'documentation' offered by this package is mostly in the form of proper type
  annotations so that you have a better idea of what kind of data each API method expects.
  Other than that, developers are recommended to go study Odoo's external API by reading the
  source code at (https://github.com/odoo/odoo/tree/master/odoo/service). The three API services
  'object', 'common' and 'db' are implemented there in files model.py, common.py and db.py
  respectively. On each of these python files, a 'dispatch' method is implemented for the service
  in question. The methods available on the external service api are usually those prefixed with
  'exp_' in the method name, with the exception of the 'object' service which only exposes
  'execute' and 'execute_kw'.

  All functions offered by this package are available in both async and sync versions.

  Odoo's API methods implemented:
  - about
  - authenticate
  - change_admin_password
  - create_database
  - db_exist
  - drop_database
  - dump_database
  - duplicate_database
  - execute_kw
  - list_countries
  - list_databases
  - list_lang
  - login
  - migrate_databases
  - rename_database
  - restore_database
  - server_version
  - version

  All methods take as first 2 parameters:
  - **http_client**: a callable or an instance of a compatible http_client (it must implement a 'post'
    method that accepts a 'url' and a 'json' parameter. Packages 'requests', 'httpx' and 'aiohttp' are
    compatible).
    If http_client is a callable, it will be called with a dict as the post payload and must return a
    response object with a '.json()' method that may be synchronous or asynchronous (when using the async
    functions). It must return a dict or dict-like object representing the reponse.

  - **url**: the complete URL of your Odoo's jsonrpc endpoint. Usually something like
    'https://odoo.acme.com/jsonrpc' or 'https://odoo.acme.com:8443/jsonrpc'.

  Remaining parameters on each method are those expected by Odoo's external API, with identical names
  as you will find on Odoo's source code. The method 'jsonrpc' is the low-level method in this package that
  actually does all the HTTP calls for all implemented methods.

  By default, when you issue 'from aio_odoorpc_base import ...' you will be importing the async methods.
  If you want the sync methods you must import from 'aio_odoorpc_base.sync'. You may also use
  'aio_odoorpc_base.aio' if you prefer to be explicit on whether you are importing sync or async code.




  In practice, you may notice that 99% of the time you will be calling the 'execute_kw' method
  which is what allows you to deal with Odoo's models, reading and writing actual business data
  via the model methods 'search', 'read', 'search_read', 'search_count', 'write', 'create', etc.
  While this package only offers you a bare 'execute_kw' method and a helper 'execute_kwargs',
  the higher-level package 'aio-odoorpc' expands over this one adding higher-level objects and methods
  (such as 'search', 'read', 'search_read', 'search_count', 'write', 'create', etc) to consume those
  model methods through calls to 'execute_kw' external API method.



  No dependency is not a promise, just a preference. It may change in the future, but only if for very
  good reason. Here, are free to use whatever HTTP Client library you want.

  I am willing to make modifications in the code in order to support other http client solutions,
  just get in touch (use the project's github repository for that).

  While it would be easier if this package shipped with a specific http client dependency, it should be
  noted that having the possibility to reuse HTTP sessions is a great opportunity to improve the
  speed of your running code. Also, it is possible that your project is already using some http client
  library and here you have the opportunity to use it.

  Remember that you must use an async http client library if you are going to use the async functions,
  or use a synchronous http client library if you are going to use the sync function.


  - sync-only: 'requests'
  - async-only: 'aiohttp'
  - sync and async: 'httpx'


  The package 'odoorpc' is the most used and better maintained package to let you easily consume Odoo's
  external API. It has lots of functionality, good documentation, a large user base and was developed
  by people that are very experienced with Odoo in general and big contributors to the Odoo Community.
  In other words, if you are taking your first steps and do not need an async interface now, start with
  odoorpc.

  However, for my needs, once I was developing Odoo integrations that needed to make hundreds of calls
  to the Odoo API to complete a single job, I began to sorely miss an async interface as well as more
  control over the HTTP client used (I wished for HTTP2 support and connection polling/reuse).

  Also, as I understood Odoo's external API, it started to sound like 'odoorpc' was too big for a task
  too simple. For instance, most of the time (like 99,99% of the time), you will be calling to a single
  jsonrpc method called 'execute_kw'. It is the same call over and over just changing the payload which
  itself is a simple json.

  So I decided to develop a new package myself, made it async-first and tryed to keep it as simple as
  possible. Also, I decided to split it in two, a very simple base package (this one) with only methods
  that mirror those in Odoo's external API and another one 'aio-odoorpc' that adds another layer to
  implement Odoo's model methods like 'search', 'search_read', 'read', etc. as well as an object model
  to instantiate a class once and then make simple method invocation with few parameters to access
  what you need.




  - The 'login' call is really only a lookup of the user_id (an int) of a user given a
    database name, user/login name and password. If you are using this RPC client over and over in your
    code, maybe even calling from a stateless cloud service, you should consider finding out the
    user id (uid) of the user and pass the uid instead of the username to the constructor of AsyncOdooRPC.
    This way, you do not need to call the login() RPC method to retrieve the uid, saving a RPC call;

  - The uid mentioned above is not a session-like id. It is really only the database id of the user
    and it never expires. There is really no 'login' or 'session initiation' step required to access
    Odoo's external API if you know the uid from the beginning;



  - It ships will a good suite of tests that run against an OCA runbot instance;

  - Asyncio is a python3 thing, so no python2 support;

  - Type hints are used everywhere;

  - This package uses jsonrpc only (no xmlrpc). There is a lack of async xmlrpc tooling and
    jsonrpc is considered the best RPC protocol in Odoo (faster, more widely used);

  - The synchronous version of the code is generated automatically from the asynchronous code, so at
    least for now the effort to maintain both is minimal.

  - I am willing to take patches and to add other contributors to this project. Feel free to get in touch,
    the github page is the best place to interact with the project and the project's author;

  - I only develop and run code in Linux environments, if you find a bug under other OS I am happy
    to take patches but I will not myself spend time looking into these eventual bugs;




  Ok, so let's start with some examples. I will omit the event_loop logic, I assume that if you want
  to use an async module you already have that sorted out yourself or through a framework like FastAPI.

  All examples below could also be called using the synchronous OdooRPC object, but without the
  'await' syntax.

  I recommend that you check the tests folder for many more examples. Also, the codebase is very very short,
  do refer to it as well.

  ```
  from aio_odoorpc_base.aio import login, execute_kw
  from aio_odoorpc_base.helpers import execute_kwargs
  import httpx

  url = 'https://odoo.acme.com/jsonrpc'

  async with httpx.AsyncClient() as client:
      uid = await login(http_client=client, url=url, db='acme', login='demo', password='demo')
      kwargs = execute_kwargs(fields=['partner_id', 'date_order', 'amount_total'],
                              limit=1000, offset=0, order='amount_total DESC')
      data = await execute_kw(http_client=client,
                              url=url,
                              db='acme',
                              uid=uid,
                              password='demo',
                              obj='sale.order',
                              method='search_read',
                              args=[],
                              kw=kwargs)
  ```


pkgId: 9ffada8d74ea080a35c641295fbd1c4d40be2b8b9e5945fa12e0d7d516c446dd
name: python-aio-pika
arch: src
version: 9.4.3
epoch: 0
release: 1
summary: Wrapper around the aiormq for asyncio and humans
url: https://github.com/mosquito/aio-pika
rpm_license: Apache-2.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aio-pika-9.4.3-1.src.rpm
checksum_type: sha256
description:
  A wrapper around `aiormq`_ for asyncio and humans.
  Check out the examples and the tutorial in the `documentation`_.
  If you are a newcomer to RabbitMQ, please start with the `adopted official RabbitMQ tutorial`_.
     Since version ``5.0.0`` this library doesn't use ``pika`` as AMQP connector.
     Versions below ``5.0.0`` contains or requires ``pika``'s source code.
     The version 7.0.0 has breaking API changes, see CHANGELOG.md
     for migration hints.


pkgId: 4c101aa546d783e7bdc1203d7f35ea2f303bd0c820421d0623be0002bc3e6e92
name: python-aio-quakeml-client
arch: src
version: 0.8
epoch: 0
release: 1
summary: An async QuakeML client library.
url: https://github.com/exxamalte/python-aio-quakeml-client
rpm_license: Apache-2.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aio-quakeml-client-0.8-1.src.rpm
checksum_type: sha256
description:
  [![Build Status](https://github.com/exxamalte/python-aio-quakeml-client/actions/workflows/ci.yaml/badge.svg?branch=main)](https://github.com/exxamalte/python-aio-quakeml-client/actions?workflow=ci)
  [![codecov](https://codecov.io/gh/exxamalte/python-aio-quakeml-client/graph/badge.svg?token=97PBJ93VGE)](https://codecov.io/gh/exxamalte/python-aio-quakeml-client)
  [![PyPi](https://img.shields.io/pypi/v/aio-quakeml-client.svg)](https://pypi.python.org/pypi/aio-quakeml-client)
  [![Version](https://img.shields.io/pypi/pyversions/aio-quakeml-client.svg)](https://pypi.python.org/pypi/aio-quakeml-client)

  This library provides convenient async access to QuakeML feeds.


pkgId: 5048ba3b06e844d54de85ece8de64748eb6dc606f3053ce37d4765faf4d824f0
name: python-aio-quakeml-ingv-centro-nazionale-terremoti-client
arch: src
version: 0.4
epoch: 0
release: 1
summary: An async INGV Centro Nazionale Terremoti (Earthquakes) QuakeML client library.
url: https://github.com/exxamalte/python-aio-quakeml-ingv-centro-nazionale-terremoti-client
rpm_license: Apache-2.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aio-quakeml-ingv-centro-nazionale-terremoti-client-0.4-1.src.rpm
checksum_type: sha256
description:
  [![Build Status](https://github.com/exxamalte/python-aio-quakeml-ingv-centro-nazionale-terremoti-client/workflows/CI/badge.svg?branch=main)](https://github.com/exxamalte/python-aio-quakeml-ingv-centro-nazionale-terremoti-client/actions?workflow=CI)
  [![codecov](https://codecov.io/gh/exxamalte/python-aio-quakeml-ingv-centro-nazionale-terremoti-client/branch/main/graph/badge.svg?token=15DT06IN30)](https://codecov.io/gh/exxamalte/python-aio-quakeml-ingv-centro-nazionale-terremoti-client)
  [![PyPi](https://img.shields.io/pypi/v/aio-quakeml-ingv-centro-nazionale-terremoti-client.svg)](https://pypi.python.org/pypi/aio-quakeml-ingv-centro-nazionale-terremoti-client)
  [![Version](https://img.shields.io/pypi/pyversions/aio-quakeml-ingv-centro-nazionale-terremoti-client.svg)](https://pypi.python.org/pypi/aio-quakeml-ingv-centro-nazionale-terremoti-client)

  This library provides convenient async access to the INGV Centro Nazionale Terremoti (Earthquakes) QuakeML feeds.


  **Examples**

  Retrieve all events from the last 24 hours (default timeframe):
  ```python
  import asyncio
  from aiohttp import ClientSession
  from aio_quakeml_ingv_centro_nazionale_terremoti_client import IngvCentroNazionaleTerremotiQuakeMLFeed
  async def main() -> None:
      async with ClientSession() as websession:
          
          feed = IngvCentroNazionaleTerremotiQuakeMLFeed(websession,
                                                         (43.7, 11.2))
          status, entries = await feed.update()
          print(status)
          if entries:
              for entry in entries:
                  print(f"- ID: {entry.external_id} - Magnitude: {entry.magnitude.mag} - Distance: {entry.distance_to_home:.2f}")
  asyncio.get_event_loop().run_until_complete(main())
  ```

  Retrieve all events from the last 24 hours (default timeframe) and within a radius of
  100km around the provided home coordinates:
  ```python
  import asyncio
  from aiohttp import ClientSession
  from aio_quakeml_ingv_centro_nazionale_terremoti_client import IngvCentroNazionaleTerremotiQuakeMLFeed
  async def main() -> None:
      async with ClientSession() as websession:
          
          
          feed = IngvCentroNazionaleTerremotiQuakeMLFeed(websession,
                                                         (43.7, 11.2),
                                                         filter_radius=100)
          status, entries = await feed.update()
          print(status)
          if entries:
              for entry in entries:
                  print(f"- ID: {entry.external_id} - Magnitude: {entry.magnitude.mag} - Distance: {entry.distance_to_home:.2f}")
  asyncio.get_event_loop().run_until_complete(main())
  ```

  Retrieve all events from the last 24 hours (default timeframe), within a radius of
  100km around the provided home coordinates, and with a magnitude of 2.0 or higher:
  ```python
  import asyncio
  from aiohttp import ClientSession
  from aio_quakeml_ingv_centro_nazionale_terremoti_client import IngvCentroNazionaleTerremotiQuakeMLFeed
  async def main() -> None:
      async with ClientSession() as websession:
          
          
          
          feed = IngvCentroNazionaleTerremotiQuakeMLFeed(websession,
                                                         (43.7, 11.2),
                                                         filter_radius=100,
                                                         filter_minimum_magnitude=2.0)
          status, entries = await feed.update()
          print(status)
          if entries:
              for entry in entries:
                  print(f"- ID: {entry.external_id} - Magnitude: {entry.magnitude.mag} - Distance: {entry.distance_to_home:.2f}")
  asyncio.get_event_loop().run_until_complete(main())
  ```


pkgId: 331aa6e294938a56fc15e2381ad3f770e378655ad759874c3590a65f243b5a95
name: python-aio-rom
arch: src
version: 0.1.7
epoch: 0
release: 1
summary: asyncio based Redis object mapper
url: https://pypi.org/project/aio-rom/
rpm_license: MIT License
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aio-rom-0.1.7-1.src.rpm
checksum_type: sha256
description:
  asyncio based Redis object mapper

  - [Installation](#installation)
  - [Usage](#usage)
  - [Features](#usage)
  - [TODO](#todo)
  - [Limitations](#limitations)

  TODO

  ```python
  import asyncio
  from dataclasses import field
  from typing import Set, Dict
  from aio_rom import Model
  from aio_rom.fields import Metadata
  from aio_rom.session import redis_pool
  class Foo(Model):
      bar: int
      foobar: Set[int] = field(default_factory=set)
      my_boolean: bool = False
      transient_field: Dict = field(metadata=Metadata(transient=True))
  class OtherFoo(Model):
      foo: Foo
  async def main():
      async with redis_pool("redis://localhost"):
          foo = Foo(123, {1,2,3}, True)
          await foo.save()
          foo2 = await Foo.get(321)
          other_foo = OtherFoo(303, foo2)
          await other_foo.save()
  asyncio.run(main())
  ```

  TODO

  1. Docs
  1. Tests

  1. `configure` must be called before other calls to Redis can succeed, no defaults to localhost atm.
  1. You cannot use `from __future__ import annotations` in the same file you define your models. See https://bugs.python.org/issue39442
  1. TODO Supported datatypes
  1. Probably more ...


pkgId: 6a46e568c7df76538a2f4e8d3f1b95ea78a5054c726a7ce3ad73f5c9663f3827
name: python-aio-scrapy
arch: src
version: 2.1.4
epoch: 0
release: 1
summary: A high-level Web Crawling and Web Scraping framework based on Asyncio
url: https://github.com/conlin-huang/aio-scrapy.git
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aio-scrapy-2.1.4-1.src.rpm
checksum_type: sha256
description:
  <!--
  ![aio-scrapy](./doc/images/aio-scrapy.png)
  -->


  An asyncio + aiolibs crawler  imitate scrapy framework

  English | [中文](./doc/README_ZH.md)


  - aio-scrapy framework is base on opensource project Scrapy & scrapy_redis.
  - aio-scrapy implements compatibility with scrapyd.
  - aio-scrapy implements redis queue and rabbitmq queue.
  - aio-scrapy is a fast high-level web crawling and web scraping framework, used to crawl websites and extract structured data from their pages.
  - Distributed crawling/scraping.


  - Python 3.9+
  - Works on Linux, Windows, macOS, BSD



  The quick way:

  ```shell

  pip install git+https://github.com/ConlinH/aio-scrapy


  pip install aio-scrapy


  pip install aio-scrapy[all]


  pip install aio-scrapy[aiomysql,httpx,aio-pika,mongo]
  ```





  ```shell
  aioscrapy startproject project_quotes
  ```

  ```
  cd project_quotes
  aioscrapy genspider quotes
  ```

  quotes.py

  ```python
  from aioscrapy.spiders import Spider


  class QuotesMemorySpider(Spider):
      name = 'QuotesMemorySpider'

      start_urls = ['https://quotes.toscrape.com']

      async def parse(self, response):
          for quote in response.css('div.quote'):
              yield {
                  'author': quote.xpath('span/small/text()').get(),
                  'text': quote.css('span.text::text').get(),
              }

          next_page = response.css('li.next a::attr("href")').get()
          if next_page is not None:
              yield response.follow(next_page, self.parse)


  if __name__ == '__main__':
      QuotesMemorySpider.start()

  ```

  run the spider:

  ```shell
  aioscrapy crawl quotes
  ```



  ```shell
  aioscrapy genspider single_quotes -t single
  ```

  single_quotes.py:

  ```python
  from aioscrapy.spiders import Spider


  class QuotesMemorySpider(Spider):
      name = 'QuotesMemorySpider'
      custom_settings = {
          "USER_AGENT": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36",
          'CLOSE_SPIDER_ON_IDLE': True,
          
          
          
          
      }

      start_urls = ['https://quotes.toscrape.com']

      @staticmethod
      async def process_request(request, spider):
          """ request middleware """
          pass

      @staticmethod
      async def process_response(request, response, spider):
          """ response middleware """
          return response

      @staticmethod
      async def process_exception(request, exception, spider):
          """ exception middleware """
          pass

      async def parse(self, response):
          for quote in response.css('div.quote'):
              yield {
                  'author': quote.xpath('span/small/text()').get(),
                  'text': quote.css('span.text::text').get(),
              }

          next_page = response.css('li.next a::attr("href")').get()
          if next_page is not None:
              yield response.follow(next_page, self.parse)

      async def process_item(self, item):
          print(item)


  if __name__ == '__main__':
      QuotesMemorySpider.start()

  ```

  run the spider:

  ```shell
  aioscrapy runspider quotes.py
  ```




  ```shell
  aioscrapy -h
  ```




  [doc](./doc/documentation.md)



  please submit your sugguestion to owner by issue



  [aiohttp](https://github.com/aio-libs/aiohttp/)

  [scrapy](https://github.com/scrapy/scrapy)


pkgId: 2b9dbce7345e3ac603855abd49876f617cf2bf053679eaf6500aa22faafda953
name: python-aio-sf-streaming
arch: src
version: 0.3.7
epoch: 0
release: 1
url: https://github.com/papernest-public/aio_sf_streaming
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aio-sf-streaming-0.3.7-1.src.rpm
checksum_type: sha256
summary:
  aio_sf_streaming is a simple Python 3.6 asyncio library allowing to connect and receive live notifications from Salesforce.

description:
  *aio-sf-streaming* is a simple Python 3.6 asyncio library allowing to connect
  and receive live notifications from Salesforce. This library is provided to
  you by `papernest <http://www.papernest.com>`_.
  See `The Force.com streaming API developer guide <https://developer.salesforce.com/docs/atlas.en-us.api_streaming.meta/api_streaming/intro_stream.htm>`_
  for more information about the different uses cases and how configure your
  Salesforce organization.


pkgId: 560ebbe812417f41e38d7c965a15c7c38da44f84906f071fe3e0cf4f3b9c86f8
name: python-aio-statsd
arch: src
version: 0.2.9
epoch: 0
release: 1
summary: an asyncio-based client for send metric to StatsD, Graphite.carbon, TelegrafStatsD and DogStatsD.
url: https://github.com/so1n/aiostatsd
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aio-statsd-0.2.9-1.src.rpm
checksum_type: sha256
description:
  an asyncio-based client for send metric to `StatsD`, `Graphite.carbon`, `TelegrafStatsD` and `DogStatsD`.


  ```Bash
  pip install aio_statsd
  ```


  Create connection and send gauge metric.
  aiostatsd client will automatically send messages in the background when the loop is running
  ```Python
  import asyncio

  from aio_statsd import StatsdClient

  loop = asyncio.get_event_loop()
  client = StatsdClient()
  loop.run_until_complete(client.connect())
  client.gauge('test.key', 1)
  loop.run_forever()
  ```
  Use context manager
  ```Python
  import asyncio

  from aio_statsd import StatsdClient


  async def main():
      async with StatsdClient() as client:
          client.gauge('test.key', 1)

  loop = asyncio.get_event_loop()
  loop.run_until_complete(main())
  ```

  - host: default value 'localhost', Statsd Server ip
  - port: default value 8125, Statsd Server port
  - protocol: default value ProtocolFlag.udp, Transport Layer Prrotocol, Select Tcp:`ProtocolFlag.udp` or Udp:`ProtocolFlag.tcp`
  - timeout: default value 0, send msg timeout, if timeout==0, not enable timeout
  - debug: default value False, enable debug
  - close_timeout: default value 9, Within a few seconds after the client is closed, continue to send messages which in the queue
  - create_timeout: default value 9, Create connection timeout
  - max_len: default value 10000, deque length
  - sample_rate(Use in StatsD Client, DogStatsD Client): default value 1, use sample rate in Statsd or DogStatsD

  ```Python
  import asyncio

  from aio_statsd import StatsdClient


  async def main():
      async with StatsdClient() as client:
          client.gauge('test.key', 1)
          client.counter('test.key', 1)
          client.sets('test.key', 1)
          client.timer('test.key', 1)
          with client.timeit('test'):
              pass  # run your code

          
          client.gauge('test1.key', 1, sample_rate=0.5)

          
          from aio_statsd import StatsdProtocol
          metric = StatsdProtocol()
          metric.gauge('test2.key', 1)
          metric.sets('test2.key', 1)
          client.send_statsd(metric)

  loop = asyncio.get_event_loop()
  loop.run_until_complete(main())
  ```


  ```python
  import asyncio

  from aio_statsd import GraphiteClient

  loop = asyncio.get_event_loop()
  client = GraphiteClient()
  loop.run_until_complete(client.connect())
  client.send_graphite('test.key', 1) # Multiple clients timestamp interval synchronization
  loop.run_forever()
  ```

  >Note: Not tested in production
  ```python
  import asyncio

  from aio_statsd import DogStatsdClient


  async def main():
      async with DogStatsdClient() as client:
          client.gauge('test.key', 1)
          client.distribution('test.key', 1)
          client.increment('test.key',1)
          client.histogram('test.key', 1)
          client.timer('test.key', 1)
          with client.timeit('test'):
              pass  # run your code

          
          client.gauge('test1.key', 1, sample_rate=0.5, tag_dict={'tag': 'tag1'})

          
          
          
          
          from aio_statsd import DogStatsdProtocol
          metric = DogStatsdProtocol()
          metric.gauge('test2.key', 1, tag_dict={'tag': 'tag1'})
          metric.histogram('test2.key', 1)
          client.send_dog_statsd(metric, sample_rate=0.5)

  loop = asyncio.get_event_loop()
  loop.run_until_complete(main())
  ```

  >Note: Not tested in production
  ```python
  import asyncio

  from aio_statsd import TelegrafStatsdClient


  async def main():
      async with TelegrafStatsdClient() as client:
          client.gauge('test.key', 1)
          client.distribution('test.key', 1)
          client.increment('test.key',1)
          client.histogram('test.key', 1)
          client.timer('test.key', 1)
          with client.timeit('test'):
              pass  # run your code

          
          client.gauge('test1.key', 1, sample_rate=0.5, tag_dict={'tag': 'tag1'})

          
          
          
          
          from aio_statsd import TelegrafStatsdProtocol
          metric = TelegrafStatsdProtocol()
          metric.gauge('test2.key', 1, tag_dict={'tag': 'tag1'})
          metric.histogram('test2.key', 1)
          client.send_telegraf_statsd(metric, sample_rate=0.5)

  loop = asyncio.get_event_loop()
  loop.run_until_complete(main())
  ```

  >Note: Not tested in production
  ```Python
  import asyncio

  from aio_statsd import TelegrafClient


  async def main():
      async with TelegrafClient() as client:
          client.send_telegraf('test.key', {"field1": 100}, user_server_time=True)
  ```

  [fast_tools example](https://github.com/so1n/fast-tools/blob/master/example/statsd_middleware.py)


pkgId: 70d43b023af6ccfdb77032c55c475e249869c142113326b4574d4585e846c0b1
name: python-aio-straico
arch: src
version: 0.0.10
epoch: 0
release: 1
summary: An unofficial async/sync client library for Straico API
url: https://github.com/jayrinaldime/aio-straico
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aio-straico-0.0.10-1.src.rpm
checksum_type: sha256
description:
  A client side implementation of Straico API.



  ```commandline

  pip install aio-straico
  ```



  Please see the official Straico API documentation
  https://documenter.getpostman.com/view/5900072/2s9YyzddrR



  ```python
  from aio_straico import straico_client
  from aio_straico.utils import cheapest_model

  def main():
      with straico_client(API_KEY="ko-11111111111111111111111111") as client:
          user_info = client.user()
          print(user_info)
          """
          {'coins': 100000.00,
            'first_name': 'User',
            'last_name': 'Name',
            'plan': 'License Tier 1'}
          """

          models = client.models()
          cheapest_chat_model = cheapest_model(models)
          print(cheapest_chat_model)
          """
          {'name': 'Google: Gemma 2 27B',
           'model': 'google/gemma-2-27b-it',
           'word_limit': 3072,
           'pricing': {'coins': 0.4,
                       'words': 100}}
          """

          reply = client.prompt_completion(cheapest_chat_model, "Hello there")
          print(reply["completion"]["choices"][0]["message"]["content"])
          """
          General Kenobi! 👋

          What can I do for you today? 😊
          """
  if __name__=="__main__":
      main()
  ```


  ```python
  from aio_straico import aio_straico_client
  from aio_straico.utils import cheapest_model

  async def main():
      async with aio_straico_client(API_KEY="ko-11111111111111111111111111") as client:
          user_info = await client.user()
          print(user_info)
          """
          {'coins': 100000.00,
            'first_name': 'User',
            'last_name': 'Name',
            'plan': 'License Tier 1'}
          """

          models = await client.models()
          cheapest_chat_model = cheapest_model(models)
          print(cheapest_chat_model)
          """
          {'name': 'Google: Gemma 2 27B',
           'model': 'google/gemma-2-27b-it',
           'word_limit': 3072,
           'pricing': {'coins': 0.4,
                       'words': 100}}
          """

          reply = await client.prompt_completion(cheapest_chat_model, "Hello there")
          print(reply["completion"]["choices"][0]["message"]["content"])
          """
          General Kenobi! 👋

          What can I do for you today? 😊
          """
  asyncio.run(main())
  ```

  when `API_KEY` is not set in aio_straico_client, it will use the value from environment variable `STRAICO_API_KEY`.
  If no environment variable is found the program will raise an error.

  You can also set the model name manually

  ```python
  reply = await client.prompt_completion("openai/gpt-4o-mini", "Hello there")
  print(reply["completion"]["choices"][0]["message"]["content"])
  """
  General Kenobi! 👋

  What can I do for you today? 😊
  """
  ```



  While the code below is async code, it can also be executed in a non-async mode by removing "await" and using the code with `straico_client` as shown in the "Basic Prompt Completion" section.

  ```python
  mp3_files = [*Path("test_data/audio/").glob("*.mp3")]
  response = await client.prompt_completion(
      "openai/gpt-4o-mini",
      "summarize the main points",
      files=mp3_files,
      display_transcripts=True,
  )

  print("## Summary")
  print(
      response["completions"]["openai/gpt-4o-mini"]["completion"]["choices"][0][
          "message"
      ]["content"]
  )

  print("## Transcript")
  for transcript in response["transcripts"]:
      print("Name:", transcript["name"])
      print("Transcript:", transcript["text"])
      print()

  """

  The . . .


  Name:  . . .
  Transcript: . . .
  """
  ```


  ```python
  youtube_url = "https://www.youtube.com/watch?v=zWPe_CUR4yU"

  response = await client.prompt_completion(
      "openai/gpt-4o-mini",
      "summarize the main points",
      youtube_urls=youtube_url,
      display_transcripts=True,
  )

  print("## Summary")
  print(
      response["completions"]["openai/gpt-4o-mini"]["completion"]["choices"][0][
          "message"
      ]["content"]
  )

  print("## Transcript")
  for transcript in response["transcripts"]:
      print("Name:", transcript["name"])
      print("Transcript:", youtube_trasncript_to_plain_text(transcript["text"]))
      print()

  """

  The . . .


  Name:  . . .
  Transcript: . . .
  """
  ```





  ```python
  model ="openai/dall-e-3"
  directory = Path(".")
  zip_file_path = await client.image_generation_as_zipfile(
      model=model,
      description="A cute cat",
      size=ImageSize.square,
      variations=4,
      destination_zip_path=directory,
  )
  ```


  ```python
  model ="openai/dall-e-3"
  directory = Path(".")
  image_paths = await client.image_generation_as_images(
      model=model,
      description="A cute cat",
      size=ImageSize.landscape,
      variations=4,
      destination_zip_path=directory,
  )
  ```


pkgId: b21b19660c32ba09f70e76ef20f1c7e2d8d5e926c5672bc1f1c307f599ebc5b7
name: python-aio-straico
arch: src
version: 0.1.1
epoch: 0
release: 1
summary: An unofficial async/sync client library for Straico API
url: https://github.com/jayrinaldime/aio-straico
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aio-straico-0.1.1-1.src.rpm
checksum_type: sha256
description:
  A client side implementation of Straico API.



  ```commandline

  pip install aio-straico
  ```



  Please see the official Straico API documentation
  https://documenter.getpostman.com/view/5900072/2s9YyzddrR



  ```python
  from aio_straico import straico_client
  from aio_straico.utils import cheapest_model

  def main():
      with straico_client(API_KEY="ko-11111111111111111111111111") as client:
          user_info = client.user()
          print(user_info)
          """
          {'coins': 100000.00,
            'first_name': 'User',
            'last_name': 'Name',
            'plan': 'License Tier 1'}
          """

          models = client.models()
          cheapest_chat_model = cheapest_model(models)
          print(cheapest_chat_model)
          """
          {'name': 'Google: Gemma 2 27B',
           'model': 'google/gemma-2-27b-it',
           'word_limit': 3072,
           'pricing': {'coins': 0.4,
                       'words': 100}}
          """

          reply = client.prompt_completion(cheapest_chat_model, "Hello there")
          print(reply["completion"]["choices"][0]["message"]["content"])
          """
          General Kenobi! 👋

          What can I do for you today? 😊
          """
  if __name__=="__main__":
      main()
  ```


  ```python
  from aio_straico import aio_straico_client
  from aio_straico.utils import cheapest_model

  async def main():
      async with aio_straico_client(API_KEY="ko-11111111111111111111111111") as client:
          user_info = await client.user()
          print(user_info)
          """
          {'coins': 100000.00,
            'first_name': 'User',
            'last_name': 'Name',
            'plan': 'License Tier 1'}
          """

          models = await client.models()
          cheapest_chat_model = cheapest_model(models)
          print(cheapest_chat_model)
          """
          {'name': 'Google: Gemma 2 27B',
           'model': 'google/gemma-2-27b-it',
           'word_limit': 3072,
           'pricing': {'coins': 0.4,
                       'words': 100}}
          """

          reply = await client.prompt_completion(cheapest_chat_model, "Hello there")
          print(reply["completion"]["choices"][0]["message"]["content"])
          """
          General Kenobi! 👋

          What can I do for you today? 😊
          """
  asyncio.run(main())
  ```

  when `API_KEY` is not set in aio_straico_client, it will use the value from environment variable `STRAICO_API_KEY`.
  If no environment variable is found the program will raise an error.

  You can also set the model name manually

  ```python
  reply = await client.prompt_completion("openai/gpt-4o-mini", "Hello there")
  print(reply["completion"]["choices"][0]["message"]["content"])
  """
  General Kenobi! 👋

  What can I do for you today? 😊
  """
  ```



  While the code below is async code, it can also be executed in a non-async mode by removing "await" and using the code with `straico_client` as shown in the "Basic Prompt Completion" section.


  ```python
  mp3_files = [*Path("test_data/audio/").glob("*.mp3")]
  response = await client.prompt_completion(
      "openai/gpt-4o-mini",
      "summarize the main points",
      files=mp3_files,
      display_transcripts=True,
  )

  print("## Summary")
  print(
      response["completions"]["openai/gpt-4o-mini"]["completion"]["choices"][0][
          "message"
      ]["content"]
  )

  print("## Transcript")
  for transcript in response["transcripts"]:
      print("Name:", transcript["name"])
      print("Transcript:", transcript["text"])
      print()

  """

  The . . .


  Name:  . . .
  Transcript: . . .
  """
  ```


  ```python
  youtube_url = "https://www.youtube.com/watch?v=zWPe_CUR4yU"

  response = await client.prompt_completion(
      "openai/gpt-4o-mini",
      "summarize the main points",
      youtube_urls=youtube_url,
      display_transcripts=True,
  )

  print("## Summary")
  print(
      response["completions"]["openai/gpt-4o-mini"]["completion"]["choices"][0][
          "message"
      ]["content"]
  )

  print("## Transcript")
  for transcript in response["transcripts"]:
      print("Name:", transcript["name"])
      print("Transcript:", youtube_trasncript_to_plain_text(transcript["text"]))
      print()

  """

  The . . .


  Name:  . . .
  Transcript: . . .
  """
  ```




  ```python
  model ="openai/dall-e-3"
  directory = Path(".")
  zip_file_path = await client.image_generation_as_zipfile(
      model=model,
      description="A cute cat",
      size=ImageSize.square,
      variations=4,
      destination_zip_path=directory,
  )
  ```


  ```python
  model ="openai/dall-e-3"
  directory = Path(".")
  image_paths = await client.image_generation_as_images(
      model=model,
      description="A cute cat",
      size=ImageSize.landscape,
      variations=4,
      destination_zip_path=directory,
  )
  ```







  ```python
  from aio_straico import aio_straico_client
  from pathlib import Path

  async def main():
      async with aio_straico_client() as client:
          
          rag = await client.create_rag(
              "My Code RAG",
              "RAG for my project files",
              Path("./my_project/utils.py"),
              Path("./my_project/main.py")
          )
          print(rag)  # Print RAG details

          
          rag_obj = await client.new_rag(
              "My Code RAG",
              "RAG for my project files",
              Path("./my_project/utils.py"),
              Path("./my_project/main.py")
          )
          print(rag_obj.data)
  ```


  ```python
  from aio_straico import straico_client
  from pathlib import Path

  def main():
      with straico_client() as client:
          
          rag = client.create_rag(
              "My Code RAG",
              "RAG for my project files",
              Path("./my_project/utils.py"),
              Path("./my_project/main.py")
          )
          print(rag)  # Print RAG details

          
          rag_obj = client.new_rag(
              "My Code RAG",
              "RAG for my project files",
              Path("./my_project/utils.py"),
              Path("./my_project/main.py")
          )
          print(rag_obj.data)
  ```




  ```python
  async def delete_rag():
      async with aio_straico_client() as client:
          
          rags = await client.rags()
          rag_id = rags[0]['_id']  # Get ID of first RAG

          
          await client.rag_delete(rag_id)

          
          rag_obj = await client.rag(rag_id)
          await rag_obj.delete()
  ```


  ```python
  def delete_rag():
      with straico_client() as client:
          
          rags = client.rags()
          rag_id = rags[0]['_id']  # Get ID of first RAG

          
          client.rag_delete(rag_id)

          
          rag_obj = client.rag(rag_id)
          rag_obj.delete()
  ```




  ```python
  async def rag_prompt():
      async with aio_straico_client() as client:
          
          rags = await client.rags()
          rag_id = rags[0]['_id']  # Get ID of first RAG

          
          models = await client.models()
          cheapest_model = cheapest_model(models)

          
          response = await client.rag_prompt_completion(
              rag_id,
              cheapest_model,
              "Explain the main functionality of my project"
          )
          print(response)

          
          rag_obj = await client.rag(rag_id)
          response = await rag_obj.prompt_completion(
              cheapest_model,
              "Explain the main functionality of my project"
          )
          print(response)
  ```


  ```python
  def rag_prompt():
      with straico_client() as client:
          
          rags = client.rags()
          rag_id = rags[0]['_id']  # Get ID of first RAG

          
          models = client.models()
          cheapest_model = cheapest_model(models)

          
          response = client.rag_prompt_completion(
              rag_id,
              cheapest_model,
              "Explain the main functionality of my project"
          )
          print(response)

          
          rag_obj = client.rag(rag_id)
          response = rag_obj.prompt_completion(
              cheapest_model,
              "Explain the main functionality of my project"
          )
          print(response)
  ```







  ```python
  from aio_straico import aio_straico_client
  from aio_straico.utils import cheapest_model

  async def create_agent():
      async with aio_straico_client() as client:
          
          models = await client.models()
          cheapest_chat_model = cheapest_model(models)

          
          agent = await client.create_agent(
              "My Project Agent",
              "An agent to help with my project",
              cheapest_chat_model,
              "You are a helpful assistant for my project.",
              ["Python", "Project"]
          )
          print(agent)  # Print agent details

          
          agent_obj = await client.new_agent(
              "My Project Agent",
              "An agent to help with my project",
              cheapest_chat_model,
              "You are a helpful assistant for my project.",
              ["Python", "Project"]
          )
          print(agent_obj.data)
  ```


  ```python
  from aio_straico import straico_client
  from aio_straico.utils import cheapest_model

  def create_agent():
      with straico_client() as client:
          
          models = client.models()
          cheapest_chat_model = cheapest_model(models)

          
          agent = client.create_agent(
              "My Project Agent",
              "An agent to help with my project",
              cheapest_chat_model,
              "You are a helpful assistant for my project.",
              ["Python", "Project"]
          )
          print(agent)  # Print agent details

          
          agent_obj = client.new_agent(
              "My Project Agent",
              "An agent to help with my project",
              cheapest_chat_model,
              "You are a helpful assistant for my project.",
              ["Python", "Project"]
          )
          print(agent_obj.data)
  ```




  ```python
  async def add_rag_to_agent():
      async with aio_straico_client() as client:
          
          rags = await client.rags()
          rag_id = rags[0]['_id']  # Get ID of first RAG

          agents = await client.agents()
          agent_id = agents[0]['_id']  # Get ID of first agent

          
          await client.agent_add_rag(agent_id, rag_id)

          
          agent_obj = await client.agent(agent_id)
          await agent_obj.update(rag=rag_id)
  ```


  ```python
  def add_rag_to_agent():
      with straico_client() as client:
          
          rags = client.rags()
          rag_id = rags[0]['_id']  # Get ID of first RAG

          agents = client.agents()
          agent_id = agents[0]['_id']  # Get ID of first agent

          
          client.agent_add_rag(agent_id, rag_id)

          
          agent_obj = client.agent(agent_id)
          agent_obj.update(rag=rag_id)
  ```




  ```python
  async def update_agent():
      async with aio_straico_client() as client:
          
          agents = await client.agents()
          agent_id = agents[0]['_id']

          
          await client.agent_update(
              agent_id,
              name="Updated Agent Name",
              description="Updated description",
              system_prompt="You are an updated helpful assistant."
          )

          
          agent_obj = await client.agent(agent_id)
          await agent_obj.update(
              name="Updated Agent Name",
              description="Updated description",
              system_prompt="You are an updated helpful assistant."
          )
  ```


  ```python
  def update_agent():
      with straico_client() as client:
          
          agents = client.agents()
          agent_id = agents[0]['_id']

          
          client.agent_update(
              agent_id,
              name="Updated Agent Name",
              description="Updated description",
              system_prompt="You are an updated helpful assistant."
          )

          
          agent_obj = client.agent(agent_id)
          agent_obj.update(
              name="Updated Agent Name",
              description="Updated description",
              system_prompt="You are an updated helpful assistant."
          )
  ```




  ```python
  async def agent_prompt():
      async with aio_straico_client() as client:
          
          agents = await client.agents()
          agent_id = agents[0]['_id']  # Get ID of first agent

          
          response = await client.agent_prompt_completion(
              agent_id,
              "Explain the main functionality of my project"
          )
          print(response)

          
          agent_obj = await client.agent(agent_id)
          response = await agent_obj.prompt_completion(
              "Explain the main functionality of my project"
          )
          print(response)
  ```


  ```python
  def agent_prompt():
      with straico_client() as client:
          
          agents = client.agents()
          agent_id = agents[0]['_id']  # Get ID of first agent

          
          response = client.agent_prompt_completion(
              agent_id,
              "Explain the main functionality of my project"
          )
          print(response)

          
          agent_obj = client.agent(agent_id)
          response = agent_obj.prompt_completion(
              "Explain the main functionality of my project"
          )
          print(response)
  ```




  ```python
  async def delete_agent():
      async with aio_straico_client() as client:
          
          agents = await client.agents()
          agent_id = agents[0]['_id']  # Get ID of first agent

          
          await client.agent_delete(agent_id)

          
          agent_obj = await client.agent(agent_id)
          await agent_obj.delete()
  ```


  ```python
  def delete_agent():
      with straico_client() as client:
          
          agents = client.agents()
          agent_id = agents[0]['_id']  # Get ID of first agent

          
          client.agent_delete(agent_id)

          
          agent_obj = client.agent(agent_id)
          agent_obj.delete()
  ```


pkgId: 7fb33efd42c2e9ab0a8ad13809ea4807443a34a7c2342157913a557e00026252
name: python-aio-throttle
arch: src
version: 1.7.0
epoch: 0
release: 1
summary: A simple throttling package
url: https://github.com/Pliner/aio-throttle
rpm_license: UNKNOWN
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aio-throttle-1.7.0-1.src.rpm
checksum_type: sha256
description:
  This library is inspired by [this book](https://landing.google.com/sre/sre-book/chapters/handling-overload/) and this implementation https://github.com/vostok/throttling.

  Features:
  1. Set capacity(max parallel requests) and queue(max queued requests) limits.
  1. Per-consumer limits. For instance, to not allow any consumer to use more than 70% of service's capacity.
  1. Per-request priorities. For instance, to not allow requests with lowest priority to be queued or to now allow requests with normal priority to use more than 90% of service's capacity.

  Example:
  ```python
  from aio_throttle import Throttler, MaxFractionCapacityQuota, ThrottlePriority, ThrottleResult

  capacity_limit = 100
  queue_limit = 200
  consumer_quotas = [MaxFractionCapacityQuota(0.7)]
  priority_quotas = [MaxFractionCapacityQuota(0.9, ThrottlePriority.NORMAL)]
  throttler = Throttler(capacity_limit, queue_limit, consumer_quotas, priority_quotas)


  consumer, priority = "yet another consumer", ThrottlePriority.HIGH
  async with throttler.throttle(consumer=consumer, priority=priority) as result:
      ... # check if result is ThrottleResult.ACCEPTED or not
  ```

  Example of an integration with aiohttp and prometheus_client()
  ```python
  import aiohttp
  import aiohttp.web
  import aiohttp.web_request
  import aiohttp.web_response

  import aio_throttle


  @aio_throttle.aiohttp_ignore() # do not throttle this handler
  async def healthcheck(_: aiohttp.web_request.Request) -> aiohttp.web_response.Response:
      return aiohttp.web_response.Response()


  async def authorize(_: aiohttp.web_request.Request) -> aiohttp.web_response.Response:
      return aiohttp.web_response.Response()


  async def create_app() -> aiohttp.web.Application:
      app = aiohttp.web.Application(middlewares=[
          aio_throttle.aiohttp_middleware_factory(
                  capacity_limit=20,
                  queue_limit=100,
                  consumer_quotas=[aio_throttle.MaxFractionCapacityQuota[str](0.7)],
                  priority_quotas=[
                      aio_throttle.MaxFractionCapacityQuota[aio_throttle.ThrottlePriority](
                          0.9, aio_throttle.ThrottlePriority.NORMAL
                      )
                  ],
                  metrics_provider=aio_throttle.PROMETHEUS_METRICS_PROVIDER,
              ),
      ])
      app.router.add_get("/healthcheck", healthcheck)
      app.router.add_post("/authorize", authorize)
      return app


  aiohttp.web.run_app(create_app(), port=8080, access_log=None)
  ```


pkgId: 3a66009e5d1513cede6aeeed0d72d755049febf69c6a193e68eff54c3a2727c7
name: python-aio-tiny-healthcheck
arch: src
version: 1.1.2
epoch: 0
release: 1
summary: Tiny asynchronous implementation of healthcheck provider and http-server
url: https://github.com/nabrosimoff/aio_tiny_healthcheck
rpm_license: Apache Software License
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aio-tiny-healthcheck-1.1.2-1.src.rpm
checksum_type: sha256
description:
  [![PyPI](https://img.shields.io/pypi/v/aio_tiny_healthcheck.svg)](https://github.com/nabrosimoff/aio_tiny_healthcheck)
  [![Build Status](https://travis-ci.org/nabrosimoff/aio_tiny_healthcheck.svg?branch=master)](https://travis-ci.org/nabrosimoff/aio_tiny_healthcheck)
  [![Build Status](https://travis-ci.org/nabrosimoff/aio_tiny_healthcheck.svg?branch=develop)](https://travis-ci.org/nabrosimoff/aio_tiny_healthcheck)

  Tiny asynchronous implementation of healthcheck provider and server



  ```bash
  pip install aio-tiny-healthcheck
  ```


  By default, the Checker returns 200 if all checks successfully finish or 500 in opposite case.


  ```python
  from aiohttp import web

  from aio_tiny_healthcheck.checker import Checker

  def some_sync_check():
      return True

  async def some_async_check():
      return False

  healthcheck_provider = Checker()
  healthcheck_provider.add_check('sync_check_true', some_async_check)
  healthcheck_provider.add_check('async_check_false', some_async_check)


  app = web.Application()
  app.router.add_get('/healthcheck', healthcheck_provider.aiohttp_handler)
  web.run_app(app)
  ```


  ```python
  from sanic import Sanic
  from sanic.response import json
  from aio_tiny_healthcheck.checker import Checker

  app = Sanic()

  def some_sync_check():
      return True

  async def some_async_check():
      return False

  healthcheck_provider = Checker(success_code=201, fail_code=400)
  healthcheck_provider.add_check('sync_check_true', some_async_check)
  healthcheck_provider.add_check('async_check_false', some_async_check)

  @app.route("/healthcheck")
  async def test(request):
      hc_response = healthcheck_provider.check_handler()
      return json(hc_response.body, status=hc_response.code)

  if __name__ == "__main__":
      app.run(host="0.0.0.0", port=8000)
  ```


  You should want to run healthcheck in background if you already have some blocking operation in your execution flow.
  So, you can just use built-in server for this.

  ```python
  from aio_tiny_healthcheck.checker import Checker
  from aio_tiny_healthcheck.http_server import HttpServer
  import asyncio


  async def some_long_task():
      await asyncio.sleep(3600)


  def some_sync_check():
      return True


  async def some_async_check():
      return True


  aio_thc = Checker()
  hc_server = HttpServer(
      aio_thc,
      path='/health',
      host='localhost',
      port=9090
  )

  aio_thc.add_check('sync_check_true', some_async_check)
  aio_thc.add_check('async_check_false', some_async_check)


  async def main():
      
      asyncio.create_task(hc_server.run())

      
      await some_long_task()


  if __name__ == '__main__':
      loop = asyncio.get_event_loop()
      loop.run_until_complete(main())

  ```



  ```
  python -m aio_tiny_healthcheck http://localhost:9192/healthcheck
  ```

  Useful for running health check without external dependencies like curl.

  By default, concurrent server and health checking utility are working
  with a port and query path `http://localhost:8000/healthcheck`.
  So, if you run concurrent server with no using arguments, you can also run the utility
  with without arguments `python -m aio_tiny_healthcheck`.


pkgId: 237aaa13855c06da4b47812f6e6f84cc7b48301f44a40ebae5ad5d37e2fe86d2
name: python-aio-usb-hotplug
arch: src
version: 6.0.0
epoch: 0
release: 1
summary: Asynchronous generators yielding detected hotplug events on the USB buses
url: https://github.com/ntamas/aio-usb-hotplug/
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aio-usb-hotplug-6.0.0-1.src.rpm
checksum_type: sha256
description:
  `aio-usb-hotplug` is a Python library that provides asynchronous generators
  yielding detected hotplug events on the USB buses.

  Requires Python >= 3.8.

  Works with [`asyncio`](https://docs.python.org/3/library/asyncio.html)
  and [`trio`](https://trio.readthedocs.io/en/stable/).



  Use the package manager [pip](https://pip.pypa.io/en/stable/) to install
  `aio-usb-hotplug`.

  ```bash
  pip install aio-usb-hotplug
  ```

  `aio-usb-hotplug` depends on [PyUSB](https://pypi.org/pypi/pyusb), which
  in turn requires [libusb](https://libusb.info) or
  [openusb](https://sourceforge.net/projects/openusb/). An easy way to satisfy
  this requirement is to install
  [libusb-package](https://pypi.org/pypi/libusb-package), which supplies
  pre-compiled binaries for most platforms:

  ```bash
  pip install libusb-package
  ```

  `aio-usb-hotplug` will make use of
  [libusb-package](https://pypi.org/pypi/libusb-package) if it is installed in
  the current Python environment.





  ```python
  from aio_usb_hotplug import HotplugDetector
  from trio import run  # ...or asyncio

  async def dump_events():
      detector = HotplugDetector.for_device(vid="1050", pid="0407")
      async for event in detector.events():
          print(repr(event))

  trio.run(dump_events)
  ```



  ```python
  from aio_usb_hotplug import HotplugDetector
  from trio import sleep_forever


  async def handle_device(device):
      print("Handling device:", repr(device))
      try:
          
          
          await sleep_forever()
      finally:
          
          print("Stopped handling device:", repr(device))


  async def handle_detected_devices():
      detector = HotplugDetector.for_device(vid="1050", pid="0407")
      await detector.run_for_each_device(handle_device)


  trio.run(handle_detected_devices)
  ```



  Pull requests are welcome. For major changes, please open an issue first to
  discuss what you would like to change.

  Please make sure to update tests as appropriate.



  [MIT](https://choosealicense.com/licenses/mit/)


pkgId: a3eb5d1f71f771e4efeaaa7f5935f596f4a27f58768089eb9ce448d23962af6b
name: python-aioWiserHeatAPI
arch: src
version: 1.5.16
epoch: 0
release: 1
summary: An AsyncIO API for controlling the Drayton Wiser Heating system
url: https://github.com/msp1974/aioWiserHeatAPI
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aioWiserHeatAPI-1.5.16-1.src.rpm
checksum_type: sha256
description:
  This repository contains a simple API which queries the Drayton Wiser Heating sysystem used in the UK.

  The API functionality provides the following functionality to control the wiser heating system for 1,2 and 3 channel heat hubs
  The API also supports Smart Plugs and initial basic functionality for Shutter and Lights



  Requires a minimum of Python v3.10





  Reference [https://it.knightnet.org.uk/kb/nr-qa/drayton-wiser-heating-control/#controlling-the-system](https://it.knightnet.org.uk/kb/nr-qa/drayton-wiser-heating-control/#controlling-the-system)

  1. Press the setup button on your HeatHub, the light will start flashing
  Look for the Wi-Fi network (SSID) called **‘WiserHeatXXXXXX’** where XXXXXX is last 6 digits of the MAC address
  2. Connect to the network from a Windows/Linux/Mac/Android/iPhone machine
  3. Execute the secret url :-)
     * Open a browser to url `http://192.168.8.1/secret`

     This will return a string which is your system secret, store this somewhere. If you are running the test script simply put this value , with the ip address of the hub, in your wiserkeys.params

  4. Press the setup button on the HeatHub again and it will go back to normal operations
  5. Copy the secret and save it somewhere.



  Using your router, or something else, identify the IP address of your HeatHub, it usually identifies itself as the same ID as the ``WiserHeatXXXXXX``

  Alternatively see the test_api_discovery.py file for how to use the api to discover your hub



  Create a file called params.py and place two lines, one with the wiser IP or hostname and the other with the secret key.
  e.g.

  ```code
  HOST="192.168.0.22"
  KEY="ABCDCDCDCCCDCDC"
  ```



  To help understand the api simply look at the test sample code ```tests/test_api_properties.py```, ```tests/test_api_methods.py``` or ```tests/test_api_discovery.py``` and the fully commented code.



  Documentation available in [info.md](https://github.com/msp1974/wiserHeatAPIv2/blob/master/docs/info.md) in the docs directory and within comments in the code





  * Added support for v2 opentherm endpoint for fw above 4.32.46



  * Added additonal functions for v2 hub lights, equipments etc
  * Added support for WindowDoor sensors
  * Added support for Boiler Interface device



  * Fix presets not using defined boost temp
  * Set return value of energy sensors to None if not provided by hub
  * Updated headers for hub query



  * Updates to support v2 hub functions - @LGO44
  * Add connection timeout to new retry function
  * Increase http timeout from 10s to 20s



  * Improve performance of hub read and retries
  * Fix error is no status endpoint



  * Improve error management
  * Add additional debug logging



  * Add retry routine to prevent hub response errors



  * Force schedules endpoint to use http/1.0



  * Handle chunked encoding if sent by the hub



  * Fixed issue whereby lower target temp for passive mode was not being set correctly
  * Added support for smoke alarm



  * Added improved error handling for json decode errors



  * Added addtional v2 hub attributes and switches



  * Fixed issue whereby json conversion errors due to control characters in string



  * Revert to aiohttp and fix errors with v3.9.x that caused move to httpx



  * Fix nuances with httpx



  * Move to httpx instead of aiohttp



  * Add PowerTagE support
  * Add new v2 hub cloud parameters
  * Add new v2 hub capabilities info
  * Add v2 hub equipment data to relevant devices
  * Add tilt support for shutters
  * Fix issue where non ASCII chars removed



  * Fix for hub firmware bug whereby Away Mode Affects HotWater is turned off when cancelling overrides if no overrides exist.



  * Correct relative modulation level opentherm parameter magnitude



  * Amend battery to return None for voltage and percent if battery data not present



  * Add new status class
  * Fix error if passive mode room device offline



  * Correct async error in extra_config



  * Current temperature now returns none for room if TRV signal lost.



  * Fixed issue in passive mode so that it works with 3 channel hub and different rooms on different channels



  * Fixed issue ot maintaining some parameters after hub update
  * Improved handling of extra config json errors
  * Amended current_target_temp to use DisplayedSetPoint instead of CurrentSetPoint as this displays incorrectly in Eco mode



  * Away mode overrides passive mode functions



  * Rework passive mode functionality (may break previous code if using passive mode)



  * Improve logic defining is_passive_mode property



  * Code refactoring
  * Added is_passive_mode property
  * Corrected bug in passive mode automation to determine target temp



  * Breaking Change - changes to passive mode from on or off to disabled, passive manual and passive follow schedule
  * Support boost in passive mode
  * Add additional opentherm parameters
  * Fix not clearing overrides when enabling passive mode



  * Fix issue setting on/off schedule - issue #349



  * Added room passive mode automation control



  * Fixed error in boost_all_rooms using old temp validation type (no longer supported)
  * Fixed error in validating temps from yaml file



  * Added endpoint parameter to set_opentherm_parameter



  * Moved to stable build version
  * Amended timeout error text
  * Improved error handling for setting schedules
  * Added temp sensor support for heating actuator
  * Added support for network diagnostics
  * Added support for non standard port
  * Add boiler parameters to opentherm
  * Support setting opentherm parameters



  * Add url to exception messages
  * Fix for unicode decode error



  * Fixed error intiallising WiserUFHController class
  * Made python3.9 compatible



  * Remove debuggin print lines
  * Remove session close on endpoint error



  * Add ALL as special day option in schedule file for setting schedules from file



  * Fix incorrect id used for schedule assignment in electrical devices



  * Fixed issue in schedule.get_by_name



  * Fixed calling wrong enpoint id for lights and shutters



  * Initial asyncio release


pkgId: ee757153775fd6a840dd6896d928ce73760d6f0b6c28b308b3d83438cb5acf76
name: python-aioWiserHeatAPI
arch: src
version: 1.5.17
epoch: 0
release: 1
summary: An AsyncIO API for controlling the Drayton Wiser Heating system
url: https://github.com/msp1974/aioWiserHeatAPI
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aioWiserHeatAPI-1.5.17-1.src.rpm
checksum_type: sha256
description:
  This repository contains a simple API which queries the Drayton Wiser Heating sysystem used in the UK.

  The API functionality provides the following functionality to control the wiser heating system for 1,2 and 3 channel heat hubs
  The API also supports Smart Plugs and initial basic functionality for Shutter and Lights



  Requires a minimum of Python v3.10





  Reference [https://it.knightnet.org.uk/kb/nr-qa/drayton-wiser-heating-control/#controlling-the-system](https://it.knightnet.org.uk/kb/nr-qa/drayton-wiser-heating-control/#controlling-the-system)

  1. Press the setup button on your HeatHub, the light will start flashing
  Look for the Wi-Fi network (SSID) called **‘WiserHeatXXXXXX’** where XXXXXX is last 6 digits of the MAC address
  2. Connect to the network from a Windows/Linux/Mac/Android/iPhone machine
  3. Execute the secret url :-)
     * Open a browser to url `http://192.168.8.1/secret`

     This will return a string which is your system secret, store this somewhere. If you are running the test script simply put this value , with the ip address of the hub, in your wiserkeys.params

  4. Press the setup button on the HeatHub again and it will go back to normal operations
  5. Copy the secret and save it somewhere.



  Using your router, or something else, identify the IP address of your HeatHub, it usually identifies itself as the same ID as the ``WiserHeatXXXXXX``

  Alternatively see the test_api_discovery.py file for how to use the api to discover your hub



  Create a file called params.py and place two lines, one with the wiser IP or hostname and the other with the secret key.
  e.g.

  ```code
  HOST="192.168.0.22"
  KEY="ABCDCDCDCCCDCDC"
  ```



  To help understand the api simply look at the test sample code ```tests/test_api_properties.py```, ```tests/test_api_methods.py``` or ```tests/test_api_discovery.py``` and the fully commented code.



  Documentation available in [info.md](https://github.com/msp1974/wiserHeatAPIv2/blob/master/docs/info.md) in the docs directory and within comments in the code





  * Fixed error setting opentherm endpoint for fw above 4.32.46
  * Added support for CFMT devices



  * Added support for v2 opentherm endpoint for fw above 4.32.46



  * Added additonal functions for v2 hub lights, equipments etc
  * Added support for WindowDoor sensors
  * Added support for Boiler Interface device



  * Fix presets not using defined boost temp
  * Set return value of energy sensors to None if not provided by hub
  * Updated headers for hub query



  * Updates to support v2 hub functions - @LGO44
  * Add connection timeout to new retry function
  * Increase http timeout from 10s to 20s



  * Improve performance of hub read and retries
  * Fix error is no status endpoint



  * Improve error management
  * Add additional debug logging



  * Add retry routine to prevent hub response errors



  * Force schedules endpoint to use http/1.0



  * Handle chunked encoding if sent by the hub



  * Fixed issue whereby lower target temp for passive mode was not being set correctly
  * Added support for smoke alarm



  * Added improved error handling for json decode errors



  * Added addtional v2 hub attributes and switches



  * Fixed issue whereby json conversion errors due to control characters in string



  * Revert to aiohttp and fix errors with v3.9.x that caused move to httpx



  * Fix nuances with httpx



  * Move to httpx instead of aiohttp



  * Add PowerTagE support
  * Add new v2 hub cloud parameters
  * Add new v2 hub capabilities info
  * Add v2 hub equipment data to relevant devices
  * Add tilt support for shutters
  * Fix issue where non ASCII chars removed



  * Fix for hub firmware bug whereby Away Mode Affects HotWater is turned off when cancelling overrides if no overrides exist.



  * Correct relative modulation level opentherm parameter magnitude



  * Amend battery to return None for voltage and percent if battery data not present



  * Add new status class
  * Fix error if passive mode room device offline



  * Correct async error in extra_config



  * Current temperature now returns none for room if TRV signal lost.



  * Fixed issue in passive mode so that it works with 3 channel hub and different rooms on different channels



  * Fixed issue ot maintaining some parameters after hub update
  * Improved handling of extra config json errors
  * Amended current_target_temp to use DisplayedSetPoint instead of CurrentSetPoint as this displays incorrectly in Eco mode



  * Away mode overrides passive mode functions



  * Rework passive mode functionality (may break previous code if using passive mode)



  * Improve logic defining is_passive_mode property



  * Code refactoring
  * Added is_passive_mode property
  * Corrected bug in passive mode automation to determine target temp



  * Breaking Change - changes to passive mode from on or off to disabled, passive manual and passive follow schedule
  * Support boost in passive mode
  * Add additional opentherm parameters
  * Fix not clearing overrides when enabling passive mode



  * Fix issue setting on/off schedule - issue #349



  * Added room passive mode automation control



  * Fixed error in boost_all_rooms using old temp validation type (no longer supported)
  * Fixed error in validating temps from yaml file



  * Added endpoint parameter to set_opentherm_parameter



  * Moved to stable build version
  * Amended timeout error text
  * Improved error handling for setting schedules
  * Added temp sensor support for heating actuator
  * Added support for network diagnostics
  * Added support for non standard port
  * Add boiler parameters to opentherm
  * Support setting opentherm parameters



  * Add url to exception messages
  * Fix for unicode decode error



  * Fixed error intiallising WiserUFHController class
  * Made python3.9 compatible



  * Remove debuggin print lines
  * Remove session close on endpoint error



  * Add ALL as special day option in schedule file for setting schedules from file



  * Fix incorrect id used for schedule assignment in electrical devices



  * Fixed issue in schedule.get_by_name



  * Fixed calling wrong enpoint id for lights and shutters



  * Initial asyncio release


pkgId: fe5a16e98713cb125c1ebc31b3fb660eef0502cfcf5702b2a16ad542dc0c1b1b
name: python-aio_etcd
arch: src
version: 0.4.6.1
epoch: 0
release: 1
summary: An asynchronous python client for etcd
url: http://github.com/M-o-a-T/aio-etcd
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aio_etcd-0.4.6.1-1.src.rpm
checksum_type: sha256
description:
  A python client for Etcd https://github.com/coreos/etcd
  Official documentation: http://python-aio-etcd.readthedocs.org/


pkgId: 41ecf657b9c0882e7fabfc89b181272395c37d74270b3d1725099347753e4ccc
name: python-aioabcpapi
arch: src
version: 2.1.2
epoch: 0
release: 1
summary: Async library for ABCP API
url: https://github.com/bl4ckm45k/aioabcpapi
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aioabcpapi-2.1.2-1.src.rpm
checksum_type: sha256
description:
  Все методы максимально приближены к древовидному оформлению [официальной документации](https://www.abcp.ru/wiki/ABCP.API).
  Разделяются на `cp` и `ts`, они в свою очередь разделяются на `client` и `admin`, далее для поиска нужного вам метода
  отталкивайтесь от документации [API ABCP](https://www.abcp.ru/wiki/ABCP.API).
  Для примера, из документации **TS.Client**, [Обновление позиции в корзине](https://www.abcp.ru/wiki/API.TS.Client#.D0.9E.D0.B1.D0.BD.D0.BE.D0.B2.D0.BB.D0.B5.D0.BD.D0.B8.D0.B5_.D0.BF.D0.BE.D0.B7.D0.B8.D1.86.D0.B8.D0.B8_.D0.B2_.D0.BA.D0.BE.D1.80.D0.B7.D0.B8.D0.BD.D0.B5)
  описание операции следующее:
  >  Операция: POST /ts/cart/update
  Для использования этого метода нам нужно будет обратиться к `await api.ts.client.cart.update()`


pkgId: 6bec69073cf3b63e8dfc38b4f2a062054ae882b5fa3614565f02f5316bc15cda
name: python-aioacaia
arch: src
version: 0.1.4
epoch: 0
release: 1
summary: An async implementation of PyAcaia
url: https://github.com/zweckj/aioacaia
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aioacaia-0.1.4-1.src.rpm
checksum_type: sha256
description:
  Async implementation of [pyacaia](https://github.com/lucapinello/pyacaia/tree/master/pyacaia), based on `asyncio` and `bleak`



  ```python
  import asyncio
  from aioacaia import AcaiaScale
  from aioacaia.helpers import find_acaia_devices

  async def main()
    addresses = await find_acaia_devices()
    address = addresses[0]
    scale = await AcaiaScale.create(mac=address, is_new_style_scale=False)
    await scale.tare()
    await scale.startStopTimer()
    await scale.resetTimer()

  asyncio.run(main())
  ```



  Weight and settings are available, if you pass a callback function to the constructor.
  In that callback you will either receive objects of type `Message` or `Settings`. A sample notification handler can look like this and can also be found in `decode.py`

  ```python
  def notification_handler(sender, data) -> None:
      msg = decode(data)[0]
      if isinstance(msg, Settings):
          print(f"Battery: {msg.battery}")
          print(f"Unit: {msg.units}")
      elif isinstance(msg, Message):
          print(f"Weight: {msg.value}")

  scale = await AcaiaScale.create(mac=address, callback=notification_handler)
  ```


pkgId: 7f938e8b10dca9ca5b63ad03b2a58ee9048684e51f75c45003f15ef02e01e8d9
name: python-aioairq
arch: src
version: 0.4.2
epoch: 0
release: 1
summary: Asynchronous library to retrieve data from air-Q devices.
url: https://github.com/CorantGmbH/aioairq
rpm_license: Apache License, Version 2.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aioairq-0.4.2-1.src.rpm
checksum_type: sha256
description:
  [![PyPI pyversions](https://img.shields.io/pypi/pyversions/aioairq.svg)](https://pypi.org/project/aioairq/0.3.0/)
  [![PyPI downloads](https://pepy.tech/badge/aioairq)](https://pypi.org/project/aioairq/0.3.0/)


  Python library for asynchronous data access to local air-Q devices.



  At its present state, `AirQ` requires an `aiohttp` session to be provided by the user:

  ```python
  import asyncio
  import aiohttp
  from aioairq import AirQ

  ADDRESS = "123ab_air-q.local"
  PASSWORD = "airqsetup"

  async def main():
      async with aiohttp.ClientSession() as session:
          airq = AirQ(ADDRESS, PASSWORD, session)

          config = await airq.config
          print(f"Available sensors: {config['sensors']}")

          data = await airq.data
          print(f"Momentary data: {data}")

  asyncio.run(main())
  ```



  Example script for Linux how to run everything.

  ```sh

  git clone https://github.com/CorantGmbH/aioairq
  cd aioairq







  python3 -m venv .venv
  source .venv/bin/activate


  pip install -e .


  pip install -e ".[dev]" # if errors, see below


  vim hello-air-q.py
  python hello-air-q.py
  ```



  ```sh








  cat <<EOF >.env
  export AIRQ_IP=192.168.168.42
  export AIRQ_PASS=12345678
  export AIRQ_MDNS=abcde_air-q.local
  export AIRQ_HOSTNAME=air-q-livingroom
  EOF


  source .env
  pytest
  ```



  This repository uses [pre-commit](https://pre-commit.com/) primarily to ensure linting and formatting using [Ruff](https://github.com/astral-sh/ruff) (besides codespell and yamlling). If you want to commit changes to this repository, make sure you have `pre-commit` installed (included among the `dev` extras). Then initialise the git hooks by running

  ```sh
  pre-commit install
  ```

  Once successfully installed, `ruff` git hook will be triggered upon `git commit` and it will lint and try to fix the code you are about to commit. Should any changes be made, the commit will be aborted and you will need to address the lints and stage the modified files to your commit before trying again.




  Ruff's rule list is far less exhaustive than that of `pylint`, so if you want, you can gain additional insight by running `pylint` (not installed as a part of the `dev` extras).

  ```sh
  pip install pylint
  pylint aioairq/*.py
  ```

  Once done, you may leave the virtual environment

  ```sh
  deactivate
  ```


pkgId: d53c4d2d42650060311be3a49fc1739ae277d66fca27e7dc770e3c7bb0d99626
name: python-aioairzone
arch: src
version: 0.9.5
epoch: 0
release: 1
summary: Library to control Airzone devices
url: https://github.com/Noltari/aioairzone
rpm_license: Apache-2.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aioairzone-0.9.5-1.src.rpm
checksum_type: sha256
description:
  [![Latest Version][mdversion-button]][md-pypi]
  [![Python Versions][pyversion-button]][md-pypi]
  [![License: Apache 2.0][apache-button]](LICENSE)

  [apache-button]: https://img.shields.io/badge/License-Apache%202.0-blue.svg
  [md-pypi]: https://pypi.org/project/aioairzone
  [mdversion-button]: https://img.shields.io/pypi/v/aioairzone.svg
  [pyversion-button]: https://img.shields.io/pypi/pyversions/aioairzone.svg

  Python library to control Airzone devices.


  - Python >= 3.11


  ```bash
  pip install aioairzone
  ```


  Run the following command inside this folder
  ```bash
  pip install --upgrade .
  ```


  Examples can be found in the `examples` folder


  Run the following command to list all your Airzone Zones:
  ```
  curl -s --location --request POST "http://192.168.1.25:3000/api/v1/hvac" -d '{"systemID": 0, "zoneID": 0}' | jq
  ```

  Run the following command to list all your Airzone Systems:
  ```
  curl -s --location --request POST "http://192.168.1.25:3000/api/v1/hvac" -d '{"systemID": 127}' | jq
  ```

  Run the following command to fetch your Airzone Altherma parameters:
  ```
  curl -s --location --request POST "http://192.168.1.25:3000/api/v1/hvac" -d '{"systemID": 0}' | jq
  ```

  Run the following command to fetch your Airzone WebServer parameters:
  ```
  curl -s --location --request POST "http://192.168.1.25:3000/api/v1/webserver" | jq
  ```

  Run the following command to fetch a demo Airzone Zone:
  ```
  curl -s --location --request POST "http://192.168.1.25:3000/api/v1/demo" | jq
  ```

  Run the following command to fetch your Airzone LocalAPI version:
  ```
  curl -s --location --request POST "http://192.168.1.25:3000/api/v1/version" | jq
  ```

  Run the following command to fetch your Airzone LocalAPI integration driver:
  ```
  curl -s --location --request POST "http://192.168.1.25:3000/api/v1/integration" -d '{}' | jq
  ```


pkgId: 7b898cabbd22a7ca5267693b8be62b3b4db8bd6cbe01405e032db80cf28e5a3a
name: python-aioairzone-cloud
arch: src
version: 0.6.10
epoch: 0
release: 1
summary: Library to control Airzone Cloud devices
url: https://github.com/Noltari/aioairzone-cloud
rpm_license: Apache-2.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aioairzone-cloud-0.6.10-1.src.rpm
checksum_type: sha256
description:
  [![Latest Version][mdversion-button]][md-pypi]
  [![Python Versions][pyversion-button]][md-pypi]
  [![License: Apache 2.0][apache-button]](LICENSE)

  [apache-button]: https://img.shields.io/badge/License-Apache%202.0-blue.svg
  [md-pypi]: https://pypi.org/project/aioairzone-cloud
  [mdversion-button]: https://img.shields.io/pypi/v/aioairzone-cloud.svg
  [pyversion-button]: https://img.shields.io/pypi/pyversions/aioairzone-cloud.svg

  Python library to control Airzone Cloud devices.


  - Python >= 3.11


  ```bash
  pip install aioairzone-cloud
  ```


  Run the following command inside this folder
  ```bash
  pip install --upgrade .
  ```


  Examples can be found in the `examples` folder


pkgId: 7bef969aca1d3db6422a86e2a204207dc7a15d32a1a8a26038c9194ec325eaa2
name: python-aioalfacrm
arch: src
version: 0.3.2
epoch: 0
release: 1
summary: Is an asynchronous implementation for AlfaCRM API
url: https://github.com/stas12312/aioalfacrm
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aioalfacrm-0.3.2-1.src.rpm
checksum_type: sha256
description:
  [![PyPi Package Version](https://img.shields.io/pypi/v/aioalfacrm.svg?style=flat-square)](https://pypi.python.org/pypi/aioalfacrm)
  [![Supported python versions](https://img.shields.io/pypi/pyversions/aioalfacrm.svg?style=flat-square)](https://pypi.python.org/pypi/aioalfacrm)
  [![MIT License](https://img.shields.io/pypi/l/aioalfacrm.svg?style=flat-blue)](https://opensource.org/licenses/MIT)
  [![Downloads](https://img.shields.io/pypi/dm/aioalfacrm.svg?style=flat-square)](https://pypi.python.org/pypi/aioalfacrm)
  [![Codecov](https://img.shields.io/codecov/c/github/stas12312/aioalfacrm?style=flat-square)](https://app.codecov.io/gh/stas12312/aioalfacrm)
  [![Tests](https://github.com/stas12312/aioalfacrm/actions/workflows/tests.yml/badge.svg)]( https://github.com/stas12312/aioalfacrm/actions)

  **aioalfacrm** - is an asynchronous implementation for the [AlfaCRM API](https://alfacrm.pro/rest-api)





  ```
  $ pip install aioalfacrm
  ```

  *Example:*

  ```python
  import asyncio
  from aioalfacrm import AlfaClient
  from aioalfacrm.entities import Location

  HOSTNAME = 'demo.s20.online'
  EMAIL = 'api-email@email.example'
  API_KEY = 'user-api-token'
  BRANCH_ID = 1


  async def main():
      alfa_client = AlfaClient(
          hostname=HOSTNAME,
          email=EMAIL,
          api_key=API_KEY,
          branch_id=BRANCH_ID,
      )
      try:
          
          if not await alfa_client.check_auth():
              print('Authentification error')
              return
          
          branches = await alfa_client.branch.list(page=0, count=20)

          
          for branch in branches:
              branch.name = f'{branch.name} - Edited'
              
              await alfa_client.branch.save(branch)

          
          location = Location(
              branch_id=1,
              is_active=True,
              name='New location',
          )
          await alfa_client.location.save(location)

      finally:
          
          await alfa_client.close()


  asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())  # For Windows
  asyncio.run(main())


  ```



  ```python

  for page in alfa_client. < object >.get_paginator():
      objects = page.items
  ```



  To work with custom fields, do the following

  ```python
  from aioalfacrm import entities
  from aioalfacrm import fields
  from typing import Optional



  class CustomCustomer(entities.Customer):
      custom_field: Optional[int] = fields.Integer()

      
      def __init__(
              self,
              custom_field: Optional[int] = None,
              *args,
              **kwargs,
      ):
          super(CustomCustomer, self).__init__(custom_field=custom_field, *args, **kwargs)



  from aioalfacrm import AlfaClient
  from aioalfacrm import managers


  class CustomAlfaClient(AlfaClient):

      def __init__(self, *args, **kwargs):
          super(CustomAlfaClient, self).__init__(*args, **kwargs)

          self.customer = managers.Customer(
              api_client=self.api_client,
              entity_class=CustomCustomer,
          )



  import asyncio

  HOSTNAME = 'demo.s20.online'
  EMAIL = 'api-email@email.example'
  API_KEY = 'user-api-token'
  BRANCH_ID = 1


  async def main():
      alfa_client = CustomAlfaClient(hostname=HOSTNAME, email=EMAIL, api_key=API_KEY, branch_id=BRANCH_ID)
      try:
          customers = await alfa_client.customer.list()
          for customer in customers:
              print(customer.custom_field)
      finally:
          await alfa_client.close()


  asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())  # For Windows
  asyncio.run(main())
  ```


pkgId: 7391214d1dcfd637f8e02b0b04c2463edbd416075cac1d0e47c83b098c088323
name: python-aioambient
arch: src
version: 2024.8.0
epoch: 0
release: 1
summary: A clean, async-friendly library for the Ambient Weather API
url: https://github.com/bachya/aioambient
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aioambient-2024.8.0-1.src.rpm
checksum_type: sha256
description:
  [![CI][ci-badge]][ci]
  [![PyPI][pypi-badge]][pypi]
  [![Version][version-badge]][version]
  [![License][license-badge]][license]
  [![Code Coverage][codecov-badge]][codecov]
  [![Maintainability][maintainability-badge]][maintainability]

  <a href="https://www.buymeacoffee.com/bachya1208P" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy Me A Coffee" height="41" width="174"></a>

  `aioambient` is a Python3, asyncio-driven library that interfaces with both the REST and
  Websocket APIs provided by [Ambient Weather][ambient-weather].

  - [Installation](#installation)
  - [Python Versions](#python-versions)
  - [API and Application Keys](#api-and-application-keys)
  - [Usage](#usage)
  - [Contributing](#contributing)



  ```bash
  pip install aioambient
  ```



  `aioambient` is currently supported on:

  - Python 3.10
  - Python 3.11
  - Python 3.12



  Utilizing `aioambient` requires both an Application Key and an API Key from Ambient
  Weather. You can generate both from the Profile page in your
  [Ambient Weather Dashboard][ambient-weather-dashboard].





  ```python
  import asyncio
  from datetime import date

  from aiohttp import ClientSession

  from aioambient import API


  async def main() -> None:
      """Create the aiohttp session and run the example."""
      api = API("<YOUR APPLICATION KEY>", "<YOUR API KEY>")

      
      await api.get_devices()

      
      await api.get_device_details("<DEVICE MAC ADDRESS>")

      
      await api.get_device_details("<DEVICE MAC ADDRESS>", end_date=date(2019, 1, 16))


  asyncio.run(main())
  ```

  By default, the library creates a new connection to Ambient Weather with each coroutine.
  If you are calling a large number of coroutines (or merely want to squeeze out every
  second of runtime savings possible), an [`aiohttp`][aiohttp] `ClientSession` can be used for
  connection pooling:

  ```python
  import asyncio
  from datetime import date

  from aiohttp import ClientSession

  from aioambient import API


  async def main() -> None:
      """Create the aiohttp session and run the example."""
      async with ClientSession() as session:
          api = API("<YOUR APPLICATION KEY>", "<YOUR API KEY>")

          
          await api.get_devices()

          
          await api.get_device_details("<DEVICE MAC ADDRESS>")

          
          await api.get_device_details("<DEVICE MAC ADDRESS>", end_date=date(2019, 1, 16))


  asyncio.run(main())
  ```

  Please be aware of Ambient Weather's
  [rate limiting policies][ambient-weather-rate-limiting].



  ```python
  import asyncio

  from aiohttp import ClientSession

  from aioambient import Websocket


  async def main() -> None:
      """Create the aiohttp session and run the example."""
      websocket = Websocket("<YOUR APPLICATION KEY>", "<YOUR API KEY>")

      
      websocket = Websocket("YOUR APPLICATION KEY", ["<API KEY 1>", "<API KEY 2>"])

      
      
      def connect_method():
          """Print a simple "hello" message."""
          print("Client has connected to the websocket")

      websocket.on_connect(connect_method)

      
      async def connect_coroutine():
          """Waits for 3 seconds, then print a simple "hello" message."""
          await asyncio.sleep(3)
          print("Client has connected to the websocket")

      websocket.async_on_connect(connect_coroutine)

      
      
      def subscribed_method(data):
          """Print the data received upon subscribing."""
          print(f"Subscription data received: {data}")

      websocket.on_subscribed(subscribed_method)

      
      async def subscribed_coroutine(data):
          """Waits for 3 seconds, then print the incoming data."""
          await asyncio.sleep(3)
          print(f"Subscription data received: {data}")

      websocket.async_on_subscribed(subscribed_coroutine)

      
      def data_method(data):
          """Print the data received."""
          print(f"Data received: {data}")

      websocket.on_data(data_method)

      
      async def data_coroutine(data):
          """Wait for 3 seconds, then print the data received."""
          await asyncio.sleep(3)
          print(f"Data received: {data}")

      websocket.async_on_data(data_coroutine)

      
      
      def disconnect_method(data):
          """Print a simple "goodbye" message."""
          print("Client has disconnected from the websocket")

      websocket.on_disconnect(disconnect_method)

      
      async def disconnect_coroutine(data):
          """Wait for 3 seconds, then print a simple "goodbye" message."""
          await asyncio.sleep(3)
          print("Client has disconnected from the websocket")

      websocket.async_on_disconnect(disconnect_coroutine)

      
      await websocket.connect()

      
      await websocket.disconnect()


  asyncio.run(main())
  ```



  The official REST API and Websocket API require an API and application key to access
  data for the devices you own. This API cannot be used if you do not own a personal
  weather station.

  However, there is a second, undocumented API that is used by the https://ambientweather.net
  web application that does not require an API and application key. You can use the
  `OpenAPI` class to retrieve weather station data from this API:

  ```python
  import asyncio
  from datetime import date
  from aiohttp import ClientSession
  from aioambient import OpenAPI


  async def main() -> None:
      """Create the aiohttp session and run the example."""
      api = OpenAPI()

      
      
      
      await api.get_devices_by_location(32.5, -97.3, 3.0)

      
      await api.get_device_details("<DEVICE MAC ADDRESS>")


  asyncio.run(main())
  ```



  Thanks to all of [our contributors][contributors] so far!

  1. [Check for open features/bugs][issues] or [initiate a discussion on one][new-issue].
  2. [Fork the repository][fork].
  3. (_optional, but highly recommended_) Create a virtual environment: `python3 -m venv .venv`
  4. (_optional, but highly recommended_) Enter the virtual environment: `source ./.venv/bin/activate`
  5. Install the dev environment: `script/setup`
  6. Code your new feature or bug fix on a new branch.
  7. Write tests that cover your new functionality.
  8. Run tests and ensure 100% code coverage: `poetry run pytest --cov aioambient tests`
  9. Update `README.md` with any new documentation.
  10. Submit a pull request!

  [aiohttp]: https://github.com/aio-libs/aiohttp
  [ambient-weather-dashboard]: https://dashboard.ambientweather.net
  [ambient-weather-rate-limiting]: https://ambientweather.docs.apiary.io/#introduction/rate-limiting
  [ambient-weather]: https://ambientweather.net
  [ci-badge]: https://img.shields.io/github/actions/workflow/status/bachya/aioambient/test.yml
  [ci]: https://github.com/bachya/aioambient/actions
  [codecov-badge]: https://codecov.io/gh/bachya/aioambient/branch/dev/graph/badge.svg
  [codecov]: https://codecov.io/gh/bachya/aioambient
  [contributors]: https://github.com/bachya/aioambient/graphs/contributors
  [fork]: https://github.com/bachya/aioambient/fork
  [issues]: https://github.com/bachya/aioambient/issues
  [license-badge]: https://img.shields.io/pypi/l/aioambient.svg
  [license]: https://github.com/bachya/aioambient/blob/main/LICENSE
  [maintainability-badge]: https://api.codeclimate.com/v1/badges/81a9f8274abf325b2fa4/maintainability
  [maintainability]: https://codeclimate.com/github/bachya/aioambient/maintainability
  [new-issue]: https://github.com/bachya/aioambient/issues/new
  [new-issue]: https://github.com/bachya/aioambient/issues/new
  [pypi-badge]: https://img.shields.io/pypi/v/aioambient.svg
  [pypi]: https://pypi.python.org/pypi/aioambient
  [version-badge]: https://img.shields.io/pypi/pyversions/aioambient.svg
  [version]: https://pypi.python.org/pypi/aioambient


pkgId: d75f7302dfda2ff25f55cb5aa77bb410e0eb65845495368e154a84aa84f7c372
name: python-aioamqp
arch: src
version: 0.15.0
epoch: 0
release: 1
summary: AMQP implementation using asyncio
url: https://github.com/polyconseil/aioamqp
rpm_license: BSD
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aioamqp-0.15.0-1.src.rpm
checksum_type: sha256
description:
  ``aioamqp`` library is a pure-Python implementation of the `AMQP 0.9.1 protocol`_.
  Built on top on Python's asynchronous I/O support introduced in `PEP 3156`_, it provides an API based on coroutines, making it easy to write highly concurrent applications.
  Bug reports, patches and suggestions welcome! Just open an issue_ or send a `pull request`_.


pkgId: 7524cf59dd544a926cf094d0f525a654bec32a2c62922fc9b87e69857d550984
name: python-aioamqp-consumer-best
arch: src
version: 2.4.0
epoch: 0
release: 1
summary: Consumer utility for AMQP
url: https://github.com/tkukushkin/aioamqp-consumer-best
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aioamqp-consumer-best-2.4.0-1.src.rpm
checksum_type: sha256
description:
  [![PyPI version](https://badge.fury.io/py/aioamqp-consumer-best.svg)](https://pypi.org/project/aioamqp-consumer-best/)
  ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/aioamqp-consumer-best.svg?color=green)
  [![Build Status](https://github.com/tkukushkin/aioamqp-consumer-best/workflows/build/badge.svg?branch=master)](https://github.com/tkukushkin/aioamqp-consumer-best/actions?query=workflow%3Abuild+branch%3Amaster)
  [![codecov](https://codecov.io/gh/tkukushkin/aioamqp-consumer-best/branch/master/graph/badge.svg)](https://codecov.io/gh/tkukushkin/aioamqp-consumer-best)



  ```python
  import asyncio
  from typing import List

  from aioamqp_consumer_best import (
      ConnectionParams,
      Consumer,
      Exchange,
      Message,
      ProcessBulk,
      Queue,
      QueueBinding,
      ToBulks,
      load_json,
  )


  async def callback(messages: List[Message]) -> None:
      print(messages)


  consumer = Consumer(
      middleware=(
          load_json
          | ToBulks(max_bulk_size=10, bulk_timeout=3.0)
          | ProcessBulk(callback)
      ),
      prefetch_count=10,
      queue=Queue(
          name='test-queue',
          bindings=[
              QueueBinding(
                  exchange=Exchange('test-exchange'),
                  routing_key='test-routing-key',
              ),
          ],
      ),
      connection_params=[  # Round robin
          ConnectionParams(),
          ConnectionParams.from_string('amqp://user@rmq-host:5672/'),
      ],
  )

  asyncio.run(consumer.start())
  ```


pkgId: 861d29e8663b2bdf4719466f0aa4aaba82899b0b0bcc5cb6c86ff20a8342f34a
name: python-aioapcaccess
arch: src
version: 0.5.0
epoch: 0
release: 1
summary: Async version of apcaccess library implemented in python.
url: https://pypi.org/project/aioapcaccess/
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aioapcaccess-0.5.0-1.src.rpm
checksum_type: sha256
description:
  [![build](https://github.com/yuxincs/aioapcaccess/actions/workflows/build.yaml/badge.svg)](https://github.com/yuxincs/aioapcaccess/actions/workflows/build.yaml?query=branch%3Amain)
  [![codecov](https://codecov.io/github/yuxincs/aioapcaccess/branch/main/graph/badge.svg?token=8zhys5YAk9)](https://codecov.io/github/yuxincs/aioapcaccess)
  [![PyPI](https://img.shields.io/pypi/v/aioapcaccess)](https://pypi.org/project/aioapcaccess/)
  [![GitHub](https://img.shields.io/github/license/yuxincs/aioapcaccess)](https://github.com/yuxincs/aioapcaccess/blob/main/LICENSE)

  An async implementation of [apcaccess](https://linux.die.net/man/8/apcaccess). This
  library provides programmatic access to the status information provided by
  [apcupsd](http://www.apcupsd.org/) over its Network Information Server (NIS) which
  usually listens on TCP port 3551.

  This project is a re-implementation of the synchronous version
  [flyte/apcaccess](https://github.com/flyte/apcaccess) using
  [asyncio](https://docs.python.org/3/library/asyncio.html), where a lot of the logic is
  borrowed and improved.



  Install with pip:

  ```
  $ pip install aioapcaccess
  ```



  The primary API for getting the status from APCUPS is `aioapcaccess.request_status`.
  It returns a `collections.OrderedDict` mapping from field names (e.g., "SERIALNO") to
  their values in string format. What fields are available will depend on the model of
  your APC UPS, see [APCUPSD manual](http://www.apcupsd.org/manual/) for details.

  The following example shows a typical usage of `aioapcaccess`

  ```python
  import asyncio
  import aioapcaccess

  async def main():
      result = await aioapcaccess.request_status(host='localhost', port=3551)
      print(result)

  if __name__ == '__main__':
      asyncio.run(main())
  ```

  The example above will print the following (prettified and simplified):

  ```
  OrderedDict([
    ('APC', '001,036,0879'),
    ...,
    ('BATTV', '13.7 Volts'),
    ('CUMONBATT', '0 Seconds')
  ))])
  ```

  In addition to `request_status`, we offer the following functions for advanced uses:

  - `aioapcaccess.request_raw_status` for getting raw (unparsed) status in `bytes`.
  - `aioapcaccess.parse_raw_status` for parsing the `bytes` to the dict shown above.
  - `aioapcaccess.split_unit` for splitting the supported unit suffix from the value
    strings, returning a tuple `(value, unit)`. You can check `aioapcaccess.UNITS` for
    the set of supported units. Note that units are also in the forms of strings
    (e.g., "Seconds", "Volts"). If no valid units are found in the value strings, `unit`
    will be `None`.


pkgId: ad1f873ce82efa6926e34665a878272df80e17ecc99a98a040cf44d16b622603
name: python-aioapns
arch: src
version: 3.3.1
epoch: 0
release: 1
summary: An efficient APNs Client Library for Python/asyncio
url: https://github.com/Fatal1ty/aioapns
rpm_license: Apache License, Version 2.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aioapns-3.3.1-1.src.rpm
checksum_type: sha256
description:
  **aioapns** is a library designed specifically for sending push-notifications to iOS devices
  via Apple Push Notification Service. aioapns provides an efficient client through
  asynchronous HTTP2 protocol for use with Python's ``asyncio``
  framework.
  aioapns requires Python 3.8 or later.


pkgId: 2642f7056301ca21ade82d9bcfe26cc9d398464d34d86733e50391e106227191
name: python-aioaquacell
arch: src
version: 0.2.0
epoch: 0
release: 1
summary: Asynchronous library to retrieve details of your Aquacell water softener device
url: https://github.com/Jordi1990/aioaquacell
rpm_license: Apache License 2.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aioaquacell-0.2.0-1.src.rpm
checksum_type: sha256
description:
  Asynchronous library to retrieve details of your Aquacell water softener device.
  This API is reverse engineered from the official Android application.



  - aiohttp
  - aiobotocore
  - requests_aws4auth
  - pycognito
  - aws_request_signer
  - botocore
  - botocore3



  ```python
  userName = "<email address>"
  password = "<password>"


  async def main():
      api = AquacellApi()
      await api.authenticate(userName, password)
      
      print(api.refresh_token)

      softeners = await api.get_all_softeners()
      for softener in softeners:
          print(softener.name)


  if __name__ == "__main__":
      loop = asyncio.get_event_loop()
      loop.run_until_complete(main())
  ```

  ```python
  refresh_token = "<refresh token>"
  api = AquacellApi()
  await api.authenticate(refresh_token)
  ```


pkgId: b1640c625be14d7bd87c318b7c48b596e3cfbc8c62803fa25ab63c512e8ca7a3
name: python-aioaquarea
arch: src
version: 0.7.2
epoch: 0
release: 1
summary: Asynchronous library to control Panasonic Aquarea devices
url: https://github.com/cjaliaga/aioaquarea
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aioaquarea-0.7.2-1.src.rpm
checksum_type: sha256
description:
  Asynchronous library to control Panasonic Aquarea devices

  This library requires:
  - Python >= 3.9
  - asyncio
  - aiohttp

  The library supports the production environment of the Panasonic Aquarea Smart Cloud API and also the Demo environment. One of the main usages of this library is to integrate the Panasonic Aquarea Smart Cloud API with Home Assistant via [home-assistant-aquarea](https://github.com/cjaliaga/home-assistant-aquarea)
  Here is a simple example of how to use the library via getting a device object to interact with it:
  ```python
  from aioaquarea import (
      Client,
      AquareaEnvironment,
      UpdateOperationMode
  )
  import aiohttp
  import asyncio
  import logging
  from datetime import timedelta
  async def main():
      async with aiohttp.ClientSession() as session:
          client = Client(
              username="USERNAME",
              password="PASSWORD",
              session=session,
              device_direct=True,
              refresh_login=True,
              environment=AquareaEnvironment.PRODUCTION,
          )
          
          devices = await client.get_devices(include_long_id=True)
          
          device_info = devices[0]
          device = await client.get_device(
              device_info=device_info, consumption_refresh_interval=timedelta(minutes=1)
          )
          
          device = await client.get_device(
              device_id="LONG ID", consumption_refresh_interval=timedelta(minutes=1)
          )
          
          await device.set_mode(UpdateOperationMode.HEAT)
          
          await device.refresh_data()
  ```

  Big thanks to [ronhks](https://github.com/ronhks) for his awesome work on the [Panasonic Aquaera Smart Cloud integration with MQTT](https://github.com/ronhks/panasonic-aquarea-smart-cloud-mqtt).

rpm_license:
  MIT License  Copyright (c) 2022 Carlos J. Aliaga  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


pkgId: db0fde0bd20352b7323f81751e32a13b96695094f7db90c01d49214573eda8ae
name: python-aioarp
arch: src
version: 0.0.12
epoch: 0
release: 1
url: https://pypi.org/project/aioarp/
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aioarp-0.0.12-1.src.rpm
checksum_type: sha256
summary:
  Aioarp is a ARP protocol implementation that provides synchronous and asynchronous interfaces and gives you complete control over how ARP packets are sent.

description:
  **Table of Contents**
  - [Installation](#installation)
  - [Documentation](#documentation)
  - [ARP Spoofing](#arp-spoofing)
  - [ARP requests](#how-to-send-arp-requests)
  - [License](#license)

  ```console
  pip install aioarp
  ```

  [Click here](https://karosis88.github.io/aioarp/)

  Using this command, you can disable internet access for any device on your local network.
  ```shell
  $ aioarp disable 192.168.0.81 192.168.0.1 enp0s3 --seconds 10
  ```
  or
  ```shell
  $ aioarp spoof 192.168.0.81 192.168.0.1 11:11:11:11:11:11  enp0s3 --seconds 10
  ```
  `spoof` can be used to specify the fake mac address.
  Where...
  - `192.168.0.81` is a target IP address for which we are blocking internet access.
  - `192.168.0.1` is a gateway for our target IP address.
  - `enp0s3` is an optional interface used to send ARP requests. if not specified, the default interface is used.
  - `seconds` is an option that specifies how long we want to disable internet access for the target IP address.


  ```py
  import aioarp
  response = aioarp.request('10.0.2.2', 'enp0s3')
  print(response.sender_mac)

  ```

  ```py
  import trio
  import aioarp
  response = trio.run(aioarp.arequest, '10.0.2.2', 'enp0s3')
  ```
  ```py
  import asyncio
  import aioarp
  response = asyncio.run(aioarp.arequest('10.0.2.2', 'enp0s3'))
  ```
  Or without specifying an `interface` parameter
  ```
  response = aioarp.request('10.0.2.2')
  ```

  `aioarp` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.


  - Use `getmac` package for mac address detecting.
  - Add `send`, `disable` and `spoof` commands for the CLI. (#33)
  - Make the `interface` argument for the `build_arp_packet` function optional. (#32)

  - Add `Packet` base class. (#28)
  - Change `Protocol` to `ProtocolType`. (#30)
  - Validate `sender_ip` of the ARP response packet.

  - Make `interface` argument optional. (#23)
  - Move `Stream` creation from `request` to `sync_send_arp`. (#24)

  - Add `wait_response` argument to `sync_send_arp` and `async_send_arp`. (#13)

  - Add basic API documentation. (#7)

  - Add simple cli.

  - Add `sock` argument to `request` and `arequest` functions.
  - Add `timeout` argument to `request` and `arequest` functions.
  - Add `MockSocket` class for better unit testing.
  - Change signature of `sync_send_arp` and `async_send_arp` functions, now they accept the `stream` argument.


pkgId: 2a7d062808ae1f58183af6201c498d031e00e3be3c8c70afcf711d169c64cc96
name: python-aioarxiv
arch: src
version: 0.1.1
epoch: 0
release: 1
summary: arxiv Parse library
url: https://pypi.org/project/aioarxiv/
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aioarxiv-0.1.1-1.src.rpm
checksum_type: sha256
description:
  An async Python client for the arXiv API with enhanced performance and flexible configuration options.

  > ⚠️ Warning: This project is currently in beta. Not recommended for production use.



  - Asynchronous API calls for better performance
  - Flexible search and download capabilities
  - Customizable rate limiting and concurrent requests
  - Simple error handling



  ```bash
  pip install aioarxiv
  ```



  ```python
  import asyncio
  from aioarxiv import ArxivClient

  async def main():
      async with ArxivClient() as client:
          async for paper in client.search("quantum computing", max_results=1):
              print(f"Title: {paper.title}")
              print(f"Authors: {', '.join(a.name for a in paper.authors)}")
              print(f"Summary: {paper.summary[:200]}...")

              
              file_path = await client.download_paper(paper)
              print(f"Downloaded to: {file_path}")

  if __name__ == "__main__":
      asyncio.run(main())
  ```



  ```python
  from aioarxiv import ArxivConfig, ArxivClient

  config = ArxivConfig(
      rate_limit_calls=3,      # Rate limit per window
      rate_limit_period=1.0,   # Window period in seconds
      max_concurrent_requests=3 # Max concurrent requests
  )

  client = ArxivClient(config=config)
  ```



  ```python
  try:
      async for paper in client.search("quantum computing"):
          print(paper.title)
  except SearchCompleteException:
      print("Search complete")
  ```


  * Python 3.9 or higher


  [MIT License (c) 2024 BalconyJH ](LICENSE)


  * Documentation for aioarxiv is WIP
  * [ArXiv API](https://info.arxiv.org/help/api/index.html)


pkgId: 35bb470a83cd57ee7ee0224a0256f67cbbff12a2dc1645819cc34f15bf2e56b8
name: python-aioaseko
arch: src
version: 1.0.0
epoch: 0
release: 1
summary: Async Python package for the Aseko Pool Live API
url: https://github.com/milanmeu/aioaseko
rpm_license: LGPLv3+
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aioaseko-1.0.0-1.src.rpm
checksum_type: sha256
description:
  [![PyPI](https://img.shields.io/pypi/v/aioaseko)](https://pypi.org/project/aioaseko/) ![PyPI - Downloads](https://img.shields.io/pypi/dm/aioaseko) [![PyPI - License](https://img.shields.io/pypi/l/aioaseko?color=blue)](https://github.com/milanmeu/aioaseko/blob/main/COPYING)

  An async Python wrapper for the Aseko Pool Live API.

  The library supports Aseko ASIN AQUA devices.
  The Aseko ASIN Pool is partially supported.
  The library is currently limited to a selection of features available on aseko.cloud.



  ```bash
  pip install aioaseko
  ```



  ```python
  from aioaseko import Aseko
  ```


  ```python
  api = Aseko("aioAseko@example.com", "passw0rd")
  await api.login()
  ```


  ```python
  from asyncio import run

  from aioaseko import Aseko, InvalidCredentials, Unit

  async def main():
      api = Aseko("aioAseko@example.com", "passw0rd")
      try:
          await api.login()
      except InvalidCredentials:
          print("The username or password is wrong.")
          return
      units = await api.get_units()
      for unit in units:
          if isinstance(unit, Unit):
              print(f"Unit: {unit.name} ({unit.serial_number})")
              print(f"Air temperature: {unit.air_temperature}")
              print(f"Water flow to probes: {unit.water_flow_to_probes}")
  run(main())
  ```


pkgId: d37ad21ac23991cb68bb3bd4452d358aef5ef3a84bc9b07352b5c1ba2b81d296
name: python-aioasuswrt
arch: src
version: 1.4.0
epoch: 0
release: 1
summary: Api wrapper for Asuswrt https://www.asus.com/ASUSWRT/
url: https://github.com/kennedyshead/aioasuswrt
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aioasuswrt-1.4.0-1.src.rpm
checksum_type: sha256
description:
  Small wrapper for asuswrt. ![Python package](https://github.com/kennedyshead/aioasuswrt/workflows/Python%20package/badge.svg)



  `python setup.py test`


  [@mvn23](https://github.com/mvn23)
  [@halkeye](https://github.com/halkeye)
  [@maweki](https://github.com/maweki)
  [@quarcko](https://github.com/quarcko)
  [@wdullaer](https://github.com/wdullaer)


  There are many different versions of asuswrt and sometimes they just dont work in current implementation.
  If you have a problem with your specific router open an issue, but please add as much info as you can and atleast:

  * Version of router
  * Version of Asuswrt




  You can always create an issue in this tracker.
  To test and give us the information needed you could run:
  ```python

  import asyncio
  import logging

  import sys

  from aioasuswrt.asuswrt import AsusWrt

  component = AsusWrt('192.168.1.1', 22, username='****', password='****')
  logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
  logger = logging.getLogger(__name__)


  async def print_data():
      logger.debug("wl")
      logger.debug(await component.connection.async_run_command('for dev in `nvram get wl_ifnames`; do wl -i $dev assoclist; done'))
      dev = await component.async_get_wl()
      logger.debug(dev)
      logger.debug("arp")
      logger.debug(await component.connection.async_run_command('arp -n'))
      dev.update(await component.async_get_arp())
      logger.debug(dev)
      logger.debug("neigh")
      logger.debug(await component.connection.async_run_command('ip neigh'))
      dev.update(await component.async_get_neigh(dev))
      logger.debug(dev)
      logger.debug("leases")
      logger.debug(await component.connection.async_run_command('cat /var/lib/misc/dnsmasq.leases'))
      dev.update(await component.async_get_leases(dev))
      logger.debug(dev)


  loop = asyncio.get_event_loop()

  loop.run_until_complete(print_data())
  loop.close()

  ```
  Coffeefund: 1Huz6vNN6drX3Fq1sU98wPqNSdMPvkMBJG


pkgId: 4531c772a4031bbf6e6a726fe72c4d79f32086fd5c48030e08e873176eee391d
name: python-aioauth
arch: src
version: 1.7.0
epoch: 0
release: 1
summary: Asynchronous OAuth 2.0 framework for Python 3.
url: https://github.com/aliev/aioauth
rpm_license: The MIT License (MIT)
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aioauth-1.7.0-1.src.rpm
checksum_type: sha256
description:
  [![Build Status](https://github.com/aliev/aioauth/workflows/CI/badge.svg?branch=master)](https://github.com/aliev/aioauth/actions/workflows/ci.yml?query=branch%3Amaster)
  [![Coverage](https://badgen.net/codecov/c/github/aliev/aioauth)](https://app.codecov.io/gh/aliev/aioauth)
  [![License](https://img.shields.io/github/license/aliev/aioauth)](https://github.com/aliev/aioauth/blob/master/LICENSE)
  [![PyPi](https://badgen.net/pypi/v/aioauth)](https://pypi.org/project/aioauth/)
  [![Python 3.7](https://img.shields.io/badge/python-3.7-blue.svg)](https://www.python.org/downloads/release/python-370/)

  `aioauth` implements [OAuth 2.0 protocol](https://tools.ietf.org/html/rfc6749) and can be used in asynchronous frameworks like [FastAPI / Starlette](https://github.com/tiangolo/fastapi), [aiohttp](https://github.com/aio-libs/aiohttp). It can work with any databases like `MongoDB`, `PostgreSQL`, `MySQL` and ORMs like [gino](https://python-gino.org/), [sqlalchemy](https://www.sqlalchemy.org/) or [databases](https://pypi.org/project/databases/) over simple [BaseStorage](aioauth/storage.py) interface.



  There are few great OAuth frameworks for Python like [oauthlib](https://github.com/oauthlib/oauthlib) and [authlib](https://github.com/lepture/authlib), but they do not support asyncio and rewriting these libraries to asyncio is a significant challenge (see issues [here](https://github.com/lepture/authlib/issues/63) and [here](https://github.com/oauthlib/oauthlib/issues/415)).



  - [x] [The OAuth 2.0 Authorization Framework](https://tools.ietf.org/html/rfc6749)
  - [X] [OAuth 2.0 Token Introspection](https://tools.ietf.org/html/rfc7662)
  - [X] [Proof Key for Code Exchange by OAuth Public Clients](https://tools.ietf.org/html/rfc7636)
  - [x] OpenID support



  ```
  python -m pip install aioauth
  ```



  FastAPI integration stored on separated [aioauth-fastapi](https://github.com/aliev/aioauth-fastapi) repository and can be installed via the command:

  ```
  python -m pip install aioauth[fastapi]
  ```

  [aioauth-fastapi](https://github.com/aliev/aioauth-fastapi) repository contains demo example which I recommend to look.


pkgId: eba5b6ee053f3df5006f586fd08d5746d8964dc252f112d5b59f7b384c9452b4
name: python-aioauth-fastapi
arch: src
version: 0.1.2
epoch: 0
release: 1
summary: aioauth integration for FastAPI.
url: https://github.com/aliev/aioauth-fastapi
rpm_license: The MIT License (MIT)
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aioauth-fastapi-0.1.2-1.src.rpm
checksum_type: sha256
description:
  - [aioauth_fastapi](https://github.com/aliev/aioauth-fastapi/tree/master/aioauth_fastapi): the core of FastAPI integration
  - [aioauth_fastapi_demo](https://github.com/aliev/aioauth-fastapi/tree/master/aioauth_fastapi_demo): the demo project with [SQLAlchemy](https://www.sqlalchemy.org/) as an ORM and [sqlmodel](https://github.com/tiangolo/sqlmodel)


pkgId: 97b64ca8424cefec0da4fe3c91ae97a549aa5acd672e987ea965d6f793d9b40f
name: python-aioautomower
arch: src
version: 2024.10.0
epoch: 0
release: 1
summary: MPython module to talk to Husqvarna Automower.
url: https://github.com/Thomas55555/aioautomower
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aioautomower-2024.10.0-1.src.rpm
checksum_type: sha256
description:
  [![codecov](https://codecov.io/gh/Thomas55555/aioautomower/graph/badge.svg?token=2BG3S61T6K)](https://codecov.io/gh/Thomas55555/aioautomower)
  [![Python Versions](https://img.shields.io/pypi/pyversions/aioautomower)](https://pypi.org/project/aioautomower/)
  [![License](https://img.shields.io/github/license/Thomas55555/aioautomower.svg)](LICENSE.md)

  Asynchronous library to communicate with the Automower Connect API
  To use this library, you need to register on the [Husqvarna Developers Portal](https://developer.husqvarnagroup.cloud/).
  And connect your account to the `Authentication API` and the `Automower Connect API`.



  In order to use the library, you'll need to do some work yourself to get authentication
  credentials. This depends a lot on the context (e.g. redirecting to use OAuth via web)
  but should be easy to incorporate using Husqvarna's authentication examples. See
  Husqvarna's [Authentication API](https://developer.husqvarnagroup.cloud/apis/authentication-api) for details.

  You will implement `AbstractAuth` to provide an access token. Your implementation
  will handle any necessary refreshes. You can invoke the service with your auth implementation
  to access the API.

  You need at least:

  - Python 3.11+
  - [Poetry][poetry-install]

  For a first start you can run the `example.py`, by doing the following steps

  - `git clone https://github.com/Thomas55555/aioautomower.git`
  - `cd aioautomower`
  - `poetry install`
  - Enter your personal `client_id` and `client_secret` in the `_secrets.yaml` and rename it to `secrets.yaml`
  - Run with `poetry run ./example.py`



  This is an active open-source project. We are always open to people who want to use the code or contribute to it.
  This Python project is fully managed using the [Poetry][poetry] dependency manager.

  As this repository uses the [pre-commit][pre-commit] framework, all changes
  are linted and tested with each commit. You can run all checks and tests
  manually, using the following command:

  ```bash
  poetry run pre-commit run --all-files
  ```

  To run just the Python tests:

  ```bash
  poetry run pytest
  ```

  To update snapshots:

  ```bash
  poetry run pytest --snapshot-update
  ```

  [poetry-install]: https://python-poetry.org/docs/#installation
  [poetry]: https://python-poetry.org
  [pre-commit]: https://pre-commit.com/


pkgId: de8d80e4cd5186776137a66f0acead5378385a5dc530d55e96d075e235b00647
name: python-aioaws
arch: src
version: 0.15.1
epoch: 0
release: 1
summary: Asyncio SDK for some AWS services.
url: https://github.com/samuelcolvin/aioaws
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aioaws-0.15.1-1.src.rpm
checksum_type: sha256
description:
  [![CI](https://github.com/samuelcolvin/aioaws/actions/workflows/ci.yml/badge.svg?event=push)](https://github.com/samuelcolvin/aioaws/actions?query=event%3Apush+branch%3Amain+workflow%3ACI)
  [![Coverage](https://codecov.io/gh/samuelcolvin/aioaws/branch/main/graph/badge.svg)](https://codecov.io/gh/samuelcolvin/aioaws)
  [![pypi](https://img.shields.io/pypi/v/aioaws.svg)](https://pypi.python.org/pypi/aioaws)
  [![versions](https://img.shields.io/pypi/pyversions/aioaws.svg)](https://github.com/samuelcolvin/aioaws)
  [![license](https://img.shields.io/github/license/samuelcolvin/aioaws.svg)](https://github.com/samuelcolvin/aioaws/blob/main/LICENSE)

  Asyncio SDK for some AWS services.

  This library does not depend on boto, boto3 or any of the other bloated, opaque and mind thumbing AWS SDKs. Instead, it
  is written from scratch to provide clean, secure and easily debuggable access to AWS services I want to use.

  The library is formatted with black and includes complete type hints (mypy passes in strict-mode).

  It currently supports:
  * **S3** - list, delete, recursive delete, generating signed upload URLs, generating signed download URLs
  * **SES** - sending emails including with attachments and multipart
  * **SNS** - enough to get notifications about mail delivery from SES
  * [AWS Signature Version 4](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-auth-using-authorization-header.html)
    authentication for any AWS service (this is the only clean & modern implementation of AWS4 I know of in python, see
    [`core.py`](https://github.com/samuelcolvin/aioaws/blob/main/aioaws/core.py#L120-L175))

  The only dependencies of **aioaws**, are:
  * **aiofiles** - for asynchronous reading of files
  * **cryptography** - for verifying SNS signatures
  * **httpx** - for HTTP requests
  * **pydantic** - for validating responses



  ```bash
  pip install aioaws
  ```




  ```py
  import asyncio
  from aioaws.s3 import S3Client, S3Config
  from httpx import AsyncClient


  from devtools import debug

  async def s3_demo(client: AsyncClient):
      s3 = S3Client(client, S3Config('<access key>', '<secret key>', '<region>', 'my_bucket_name.com'))

      
      await s3.upload('path/to/upload-to.txt', b'this the content')

      
      files = [f async for f in s3.list()]
      debug(files)
      """
      [
          S3File(
              key='path/to/upload-to.txt',
              last_modified=datetime.datetime(...),
              size=16,
              e_tag='...',
              storage_class='STANDARD',
          ),
      ]
      """
      
      files = [f async for f in s3.list('path/to/')]
      debug(files)

      
      
      
      
      
      await s3.delete_recursive('path/to/')

      
      
      upload_data = s3.signed_upload_url(
          path='path/to/',
          filename='demo.png',
          content_type='image/png',
          size=123,
      )
      debug(upload_data)
      """
      {
          'url': 'https://my_bucket_name.com/',
          'fields': {
              'Key': 'path/to/demo.png',
              'Content-Type': 'image/png',
              'AWSAccessKeyId': '<access key>',
              'Content-Disposition': 'attachment; filename="demo.png"',
              'Policy': '...',
              'Signature': '...',
          },
      }
      """

      
      download_url = s3.signed_download_url('path/to/demo.png', max_age=60)
      print(download_url)
      

  async def main():
      async with AsyncClient(timeout=30) as client:
          await s3_demo(client)

  asyncio.run(main())
  ```

  `upload_data` shown in the above example can be used in JS with something like this:

  ```js
  const formData = new FormData()
  for (let [name, value] of Object.entries(upload_data.fields)) {
    formData.append(name, value)
  }
  const fileField = document.querySelector('input[type="file"]')
  formData.append('file', fileField.files[0])

  const response = await fetch(upload_data.url, {method: 'POST', body: formData})
  ```

  (in the request to get `upload_data` you would need to provide the file size and content-type in order
  for them for the upload shown here to succeed)




  To send an email with SES:

  ```py
  import asyncio
  from pathlib import Path
  from httpx import AsyncClient
  from aioaws.ses import SesConfig, SesClient, SesRecipient, SesAttachment

  async def ses_demo(client: AsyncClient):
      ses_client = SesClient(client, SesConfig('<access key>', '<secret key>', '<region>'))

      message_id = await ses_client.send_email(
          SesRecipient('sende@example.com', 'Sender', 'Name'),
          'This is the subject',
          [SesRecipient('recipient@eample.com', 'John', 'Doe')],
          'this is the plain text body',
          html_body='<b>This is the HTML body.<b>',
          bcc=[SesRecipient(...)],
          attachments=[
              SesAttachment(b'this is content', 'attachment-name.txt', 'text/plain'),
              SesAttachment(Path('foobar.png')),
          ],
          unsubscribe_link='https:://example.com/unsubscribe',
          configuration_set='SES configuration set',
          message_tags={'ses': 'tags', 'go': 'here'},
      )
      print('SES message ID:', message_id)

  async def main():
      async with AsyncClient() as client:
          await ses_demo(client)

  asyncio.run(main())
  ```



  Receiving data about SES webhooks from SNS (assuming you're using FastAPI)

  ```py
  from aioaws.ses import SesWebhookInfo
  from aioaws.sns import SnsWebhookError
  from fastapi import Request
  from httpx import AsyncClient

  async_client = AsyncClient...

  @app.post('/ses-webhook/', include_in_schema=False)
  async def ses_webhook(request: Request):
      request_body = await request.body()
      try:
          webhook_info = await SesWebhookInfo.build(request_body, async_client)
      except SnsWebhookError as e:
          debug(message=e.message, details=e.details, headers=e.headers)
          raise ...

      debug(webhook_info)
      ...
  ```

  See [here](https://github.com/samuelcolvin/aioaws/blob/main/aioaws/ses.py#L196-L204)
  for more information about what's provided in a `SesWebhookInfo`.


pkgId: fe56e7060f4529aae8cf499d99882f3396c5ddd646eaefae8f38d34213ef0abf
name: python-aiobafi6
arch: src
version: 0.9.0
epoch: 0
release: 1
summary: Big Ass Fans i6/Haiku protocol asynchronous Python library
url: https://github.com/jfroy/aiobafi6
rpm_license: Apache-2.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aiobafi6-0.9.0-1.src.rpm
checksum_type: sha256
description:
  [![PyPI version](https://badge.fury.io/py/aiobafi6.svg)](https://badge.fury.io/py/aiobafi6)
  [![Downloads](https://pepy.tech/badge/aiobafi6)](https://pepy.tech/project/aiobafi6)

  aiobafi6 is a python library to discovery, query and control
  [Big Ass Fans](https://bigassfans.com) products that use the i6 protocol, which
  includes i6 fans and Haiku fans with the 3.0 firmware.

  It supports almost all the features of the previous protocol ("SenseMe"), with
  the exception of rooms, and sleep mode. Occupancy support was added in the 3.1 firmware.



  The aiobafi6 package comes with a minimal command line (`aiobafi6`) that uses
  either the library or direct communication with a target device. It is useful
  for debugging and interacting with the firmware. Run with `--help` for usage.



  The BAF i6 protocol uses
  [protocol buffers](https://developers.google.com/protocol-buffers) for message
  wire serialization. This library maintains a
  [single proto file](proto/aiobafi6.proto) with all known messages and constants.

  The generated Python client for this proto file is checked in the repo to avoid
  depending on the protocol buffer compiler for installation. Whenever the source
  proto file is changed, the Python client files must be re-generated.

  `poe protoc`



  [@bdraco](https://github.com/bdraco) for writing the HASS integration, helping with
  Python, and suggesting BAF is using protobufs.

  [@oogje](https://github.com/oogje) for a reference homebridge implementation.

  [Big Ass Fans](https://www.bigassfans.com) for making great products.


pkgId: ad28fd1087a006441891fefae49327f765b93b5ad4da1fe6637a107efb29fd6a
name: python-aiobastion
arch: src
version: 0.1.8
epoch: 0
release: 1
summary: Manage your Cyberark implementation
url: https://github.com/labanquepostale/aiobastion
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aiobastion-0.1.8-1.src.rpm
checksum_type: sha256
description:
  **aiobastion** is a simple and fully asynchronous framework for [Cyberark API](https://docs.cyberark.com/Product-Doc/OnlineHelp/PAS/Latest/en/Content/WebServices/Implementing%20Privileged%20Account%20Security%20Web%20Services%20.htm) written in Python 3.11 with [asyncio](https://docs.python.org/3/library/asyncio.html) and [aiohttp](https://github.com/aio-libs/aiohttp).
  It helps you to manage your Cyberark implementation faster and in an intuitive way.



  See [examples of usage](https://aiobastion.readthedocs.io/en/latest/started.html#examples) in the [documentation](https://aiobastion.readthedocs.io/en/latest/index.html)




  Here's a minimal python snippet to list safes

  ```python
  import aiobastion
  import asyncio

  from aiobastion import GetTokenException


  async def main():
      
      pvwa_host = "pvwa.mycompany.fr"
      vault = aiobastion.EPV(serialized={'api_host': pvwa_host})

      
      login = input("Login: ")
      password = input("Password: ")

      
      try:
          await vault.login(login, password)
      except GetTokenException as err:
          print(f"An error occured while login : {err}")
          await vault.close_session()
          exit(0)

      
      async with vault as epv:
          
          safes = await epv.safe.list()
          for s in safes:
              print(s)

  if __name__ == '__main__':
      asyncio.run(main())

  ```




  [Define a config file](https://aiobastion.readthedocs.io/en/latest/login.html#define-a-configuration-file), and start using functions to avoid spending hours in annoying tasks in the PVWA :

  * [Accounts manipulation](https://aiobastion.readthedocs.io/en/latest/accounts.html)
  * [Safe manipulation](https://aiobastion.readthedocs.io/en/latest/safe.html)
  * [User manipulation](https://aiobastion.readthedocs.io/en/latest/users.html)
  * Check the documentation for more



  The documention is hosted on readthedocs : https://aiobastion.readthedocs.io/en/latest/index.html



  I've been working on Cyberark projects for years and I see everywhere a profusion of scripts, very often complicated and long to execute for very simple tasks (sometimes even with a "do not turn off" post-it on the screen).
  This package makes it quick and easy to accomplish without having to deal with the specifics of the Cyberark API.
  The acquisition time may be longer than for other well-known libraries, but, believe me, you will save this time very quickly.

rpm_license:
  Copyright (c) 2018 The Python Packaging Authority  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


pkgId: 8b58001e6017d677a4da4eefe69d8fef61a3017b58b8d38b3441f3b46661a660
name: python-aiobitrix24
arch: src
version: 0.4.3
epoch: 0
release: 1
summary: Simple async bitrix-24 rest client
url: https://github.com/prin-it/bitrix24-tools
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aiobitrix24-0.4.3-1.src.rpm
checksum_type: sha256
description:
  <h2 align="center">AIOBitrix24</h2>

  <p align="center">
  <a href="https://github.com/psf/black"><img alt="Code style: black" src="https://img.shields.io/badge/code%20style-black-000000.svg"></a>
  </p>


pkgId: 076c6c96078c9d81161e3c74cb693c1d60dad18addff24d80635eab79bf9d620
name: python-aioblescan
arch: src
version: 0.2.14
epoch: 0
release: 1
summary: Scanning Bluetooth for advertised info with asyncio.
url: http://github.com/frawau/aioblescan
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aioblescan-0.2.14-1.src.rpm
checksum_type: sha256
description:
  aioblescan is a Python 3/asyncio library to listen for BLE advertized
  packets.
  |PyPI version fury.io| |MIT license| |GITHUB-BADGE| |Downloads|


pkgId: dcefd8d0c84688811fdc057dced03c20fe88ad02a53d8747da6a8dcf7bf6e206
name: python-aiobml
arch: src
version: 1.0.4
epoch: 0
release: 1
summary: Asynchronous Python wrapper around Bank of Maldives (BML) API
url: https://github.com/quillfires/aioBML
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aiobml-1.0.4-1.src.rpm
checksum_type: sha256
description:
  This is an asynchronous wrapper around Bank of Maldives API.



  Currently you can use this library to get the transaction history of all your Bank of Maldives accounts, details of all you BML accounts & contacts and add & remove contacts.
  If you want to check for new transactions; save the transactions to a db, check, alert and add any transactions that's not currently saved to the db *check the basic example below*.


  [![Python Version](https://img.shields.io/badge/Python-3.7%20%7C%203.8%20%7C%203.9-blue.svg)](https://www.python.org)  [![aiobml Â· PyPI](https://img.shields.io/pypi/v/aiobml.svg?color=4CBB17)](https://pypi.python.org/pypi/aiobml/)  [![PyPI - Status](https://img.shields.io/pypi/status/aiobml)](https://pypi.python.org/pypi/aiobml/)  [![Maintenance](https://img.shields.io/maintenance/yes/2022)](https://pypi.python.org/pypi/aiobml/)  [![LICENSE](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)

  [![ViewCount](https://views.whatilearened.today/views/github/quillfires/aioBML.svg)](https://views.whatilearened.today/views/github/quillfires/aioBML.svg)  [![GitHub forks](https://img.shields.io/github/forks/quillfires/aioBML)](https://github.com/quillfires/aioBML/network)  [![GitHub stars](https://img.shields.io/github/stars/quillfires/aioBML.svg?color=ffd40c)](https://github.com/quillfires/aioBML/stargazers)  [![PyPI - Downloads](https://img.shields.io/pypi/dm/aiobml?color=orange&label=PIP%20-%20Installs)](https://pypi.python.org/pypi/aiobml/) [![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/quillfires/aioBML/issues)  [![GitHub issues](https://img.shields.io/github/issues/quillfires/aioBML.svg?color=808080)](https://github.com/quillfires/aioBML/issues)

  This library is not fully completed yet. As of now it can be used to get the transactions done within the last 24 - 48 hours, get all the information about your Accounts and your contacts and add & remove contacts. *scroll to the end to see the to do list of this library*


  You must have python 3 installed



  ```$ pip install -U aiobml```



  ```$ git clone https://github.com/quillfires/aioBML.git```

  ```$ cd aioBML```

  ```$ python setup.py install```



  ```python
  import asyncio

  from aiobml import asyncBML

  loop = asyncio.get_event_loop()
  bank = asyncBML(username="your_user_name",password="your_password")

  async def start_bank_client():
      await bank.start()

  @bank.event('new_transaction')
  async def on_new_transaction(transaction):
      print(transaction)
      
      
      
      

  async def contacts():
      data = await bank.get_contacts()
      print(data)
      

  async def accounts():
      data = await bank.get_accounts()
      print(data)
      

  async def add_cont(account, name):
      added_acc = await bank.add_contact(account, name)
      print(added_acc)
      
      

  async def delete_cont(account):
      await bank.delete_contact(account)
      
      

  if __name__ == '__main__':
      try:
          loop.run_until_complete(start_bank_client())
      except (KeyboardInterrupt, SystemExit):
          pass
      finally:
          loop.run_until_complete(bank.close())
  ```


  [See the change log here](https://github.com/quillfires/aioBML/blob/development/CHANGELOG.md)



  - [x] Get todays history
  - [x] Get Account details
  - [x] Get contacts
  - [x] Add contacts
  - [x] Delete contacts
  - [ ] Get history from a date range
  - [ ] Make Transfer to a given account number
  - [ ] Make transfers to contacts.


pkgId: 283849cc74c90d122157a5677836019da59b4b602706430f9aa5d8eb5657f6b3
name: python-aiobotocore
arch: src
version: 2.15.0
epoch: 0
release: 1
summary: Async client for aws services using botocore and aiohttp
url: https://pypi.org/project/aiobotocore/
rpm_license: Apache License 2.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aiobotocore-2.15.0-1.src.rpm
checksum_type: sha256
description:
  |ci badge| |pre-commit badge| |coverage badge| |docs badge| |pypi badge| |gitter badge| |pypi downloads badge| |conda badge| |stackoverflow badge|
  Async client for amazon services using botocore_ and aiohttp_/asyncio_.
  This library is a mostly full featured asynchronous version of botocore.


pkgId: af4ca1370840c00553bfbb8c397de569cfa8762677cc185fd4d3b83c408c75e1
name: python-aiobrultech-serial
arch: src
version: 0.9.0
epoch: 0
release: 1
summary: A Python client library to talk with Brultech Devices over a serial connection
url: https://pypi.org/project/aiobrultech-serial/
rpm_license: MIT License
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aiobrultech-serial-0.9.0-1.src.rpm
checksum_type: sha256
description:
  ![Lint](https://github.com/sdwilsh/aiobrultech-serial/workflows/Lint/badge.svg)
  ![Build](https://github.com/sdwilsh/aiobrultech-serial/workflows/Build/badge.svg)
  ![PyPI](https://img.shields.io/pypi/v/aiobrultech_serial)
  ![Supported Python Versions](https://img.shields.io/pypi/pyversions/aiobrultech_serial)



  This library talks to devices from [Brultech Research](https://www.brultech.com/)
  over their serial port, using
  [siobrultech-protocols](https://github.com/sdwilsh/siobrultech-protocols) to
  decode the data.



  ```
  pip install aiobrultech-serial
  ```



  ```python
  from aiobrultech_serial import connect


  async with connect("/dev/ttyUSB0") as connection:
      async for packet in connection.packets():
          print(f"{packet}")
  ```

  Look at [`scripts/dump.py`](https://github.com/sdwilsh/aiobrultech-serial/blob/main/scripts/dump.py)
  for a fuller example.



  This library also supports getting and setting information on the attached
  device. It supports all of the API calls available in
  [siobrultech-protocols](https://github.com/sdwilsh/siobrultech-protocols).





  ```
  python3.11 -m venv .venv
  source .venv/bin/activate


  pip install -r requirements.txt


  pip install -r requirements-dev.txt


  pre-commit install
  ```



  Tests are run with `pytest`.


pkgId: 9c8564936fbe9acc4209defbded884185f115622fcf7d11c35c369da468a0df7
name: python-aiobungie
arch: src
version: 0.3.1
epoch: 0
release: 1
summary: A Python and Asyncio API wrapper for Bungie's API.
url: https://github.com/nxtlo/aiobungie
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aiobungie-0.3.1-1.src.rpm
checksum_type: sha256
description:
  A statically typed, asynchronous API wrapper that supports Bungie's REST API for Python 3.



  Currently Python 3.10, 3.11 and 3.12 are supported.

  Latest Release using `pip`.

  ```sh
  pip install aiobungie
  ```

  Development via github master.

  ```sh
  pip install git+https://github.com/nxtlo/aiobungie@master
  ```



  See [Examples for advance usage](https://github.com/nxtlo/aiobungie/tree/master/examples)

  ```py
  import aiobungie
  import asyncio

  client = aiobungie.Client('YOUR_API_KEY')

  async def main() -> None:
      
      async with client.rest:
          users = await client.search_users("Fate")
          for user in users:
              
              print(user.memberships)


  asyncio.run(main())
  ```



  aiobungie also provides a stand-alone `RESTClient` / `RESTPool` which's what `Client` built on top of, These clients just provide a lower-level abstraction.

  A key note is that any `Client` based user can access the `RESTClient` instance bound to it with `.rest` property.



  * Lower level, allows to read and deserialize the JSON objects yourself.
  * `RESTClient`s do not turn response payloads into one of `aiobungie.crates` object.
  * RESTful, You can use this as your REST API client in backend directly.
  * Both manifest and OAuth2 methods are usable directly.



  ```py
  import aiobungie
  import asyncio


  client = aiobungie.RESTClient("YOUR_API_KEY")

  async def main() -> None:
      async with client:
          
          manifest = await client.download_json_manifest(name="latest_manifest")
          with manifest.open("r") as file:
              data = file.read()

          
          tokens = await client.fetch_oauth2_tokens('code')
          refreshed_tokens = await client.refresh_access_token(tokens.refresh_token)

          
          response = await client.static_request(
              "GET", # Method.
              "Destiny2/path/to/route", # Route.
              auth="optional_access_token", # If the method requires OAuth2.
              json={"some_key": "some_value"} # If you need to pass JSON data.
          )

  asyncio.run(main())
  ```



  * aiohttp
  * attrs
  * [`sain`](https://github.com/nxtlo/sain), this is a dependency free utility package.
  * `backports.datetime_fromisoformat`, required for `Python 3.10` only.



  aiobungie features are extra dependencies that replaces the standard library with either faster/neater pkgs.

  * `speedup`
  This will include and uses [orjson](https://github.com/ijl/orjson) or [ujson](https://github.com/ultrajson/ultrajson)
  as the default `json` parser. They provide faster json serialization and de-serialization than the standard Python JSON pkg.
  * `full`: This will include all of the features above.

  For installing the specified feature, type `pip install aiobungie[feature-name]`



  Please read this [manual](https://github.com/nxtlo/aiobungie/blob/master/CONTRIBUTING.md)



  If you have used aiobungie and want to show your work, Feel free to Open a PR including it.

  * [Fated](https://github.com/nxtlo/Fated/blob/master/core/components/destiny.py): A Discord BOT that uses aiobungie.



  * Discord Username: `vfate`
  * aiobungie Documentation: [Here](https://nxtlo.github.io/aiobungie/).
  * BungieAPI Discord: [Here](https://discord.gg/vP7VC7TKUG)
  * Official Bungie Documentation: [Here](https://bungie-net.github.io/multi/index.html)
  * Bungie Developer Portal: [Here](https://www.bungie.net/en/Application)



  * I need help with something related to this project: Consider opening a blank issue, discussion or checkout the `useful resources` above.
  * aiobungie doesn't support `fetch_xxx` route, what now? aiobungie's REST client exposes a method called `static_request` which allows you
  to make your own requests, check out `examples/custom_client` example.


pkgId: 61e6b191ca0a211bdcee52b92d290e9efa2391fcf59dce1081557c0fb76b7f69
name: python-aioca
arch: src
version: 1.8
epoch: 0
release: 1
summary: Asynchronous Channel Access client for asyncio and Python using libca via ctypes
url: https://pypi.org/project/aioca/
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aioca-1.8-1.src.rpm
checksum_type: sha256
description:
  [![CI](https://github.com/DiamondLightSource/aioca/actions/workflows/ci.yml/badge.svg)](https://github.com/DiamondLightSource/aioca/actions/workflows/ci.yml)
  [![Coverage](https://codecov.io/gh/DiamondLightSource/aioca/branch/main/graph/badge.svg)](https://codecov.io/gh/DiamondLightSource/aioca)
  [![PyPI](https://img.shields.io/pypi/v/aioca.svg)](https://pypi.org/project/aioca)
  [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)



  aioca is an asynchronous EPICS Channel Access client for asyncio and Python
  using libca via ctypes.

  |    Source     |     <https://github.com/DiamondLightSource/aioca>      |
  | :-----------: | :----------------------------------------------------: |
  |     PyPI      |                  `pip install aioca`                   |
  | Documentation |      <https://DiamondLightSource.github.io/aioca>      |
  |   Releases    | <https://github.com/DiamondLightSource/aioca/releases> |

  <!-- README only content. Anything below this line won't be included in index.md -->

  It exposes a high level interface similar to the commandline tools::

      caget(pvs, ...)
          Returns a single snapshot of the current value of each PV.

      caput(pvs, values, ...)
          Writes values to one or more PVs.

      camonitor(pvs, callback, ...)
          Receive notification each time any of the listed PVs changes.

      connect(pvs, ...)
          Optionally can be used to establish PV connection before using the PV.

  See https://DiamondLightSource.github.io/aioca for more detailed documentation.

rpm_license:
  Apache License Version 2.0, January 2004 http://www.apache.org/licenses/  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION  1. Definitions.  "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.  "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.  "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.  "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.  "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.  "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.  "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).  "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.  "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."  "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:  (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and  (b) You must cause any modified files to carry prominent notices stating that You changed the files; and  (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and  (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.  You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.  END OF TERMS AND CONDITIONS  APPENDIX: How to apply the Apache License to your work.  To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!)  The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.  Copyright {yyyy} {name of copyright owner}  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at  http://www.apache.org/licenses/LICENSE-2.0  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.


pkgId: 8be438f87a54c4c0cdd44b9d83bf083cadc3a7c6b5ef4ca126b49df3995ce6f5
name: python-aioca
arch: src
version: 1.8.1
epoch: 0
release: 1
summary: Asynchronous Channel Access client for asyncio and Python using libca via ctypes
url: https://pypi.org/project/aioca/
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aioca-1.8.1-1.src.rpm
checksum_type: sha256
description:
  [![CI](https://github.com/DiamondLightSource/aioca/actions/workflows/ci.yml/badge.svg)](https://github.com/DiamondLightSource/aioca/actions/workflows/ci.yml)
  [![Coverage](https://codecov.io/gh/DiamondLightSource/aioca/branch/main/graph/badge.svg)](https://codecov.io/gh/DiamondLightSource/aioca)
  [![PyPI](https://img.shields.io/pypi/v/aioca.svg)](https://pypi.org/project/aioca)
  [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)



  aioca is an asynchronous EPICS Channel Access client for asyncio and Python
  using libca via ctypes.

  |    Source     |     <https://github.com/DiamondLightSource/aioca>      |
  | :-----------: | :----------------------------------------------------: |
  |     PyPI      |                  `pip install aioca`                   |
  | Documentation |      <https://DiamondLightSource.github.io/aioca>      |
  |   Releases    | <https://github.com/DiamondLightSource/aioca/releases> |

  <!-- README only content. Anything below this line won't be included in index.md -->

  It exposes a high level interface similar to the commandline tools::

      caget(pvs, ...)
          Returns a single snapshot of the current value of each PV.

      caput(pvs, values, ...)
          Writes values to one or more PVs.

      camonitor(pvs, callback, ...)
          Receive notification each time any of the listed PVs changes.

      connect(pvs, ...)
          Optionally can be used to establish PV connection before using the PV.

  See https://DiamondLightSource.github.io/aioca for more detailed documentation.

rpm_license:
  Apache License Version 2.0, January 2004 http://www.apache.org/licenses/  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION  1. Definitions.  "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.  "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.  "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.  "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.  "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.  "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.  "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).  "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.  "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."  "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:  (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and  (b) You must cause any modified files to carry prominent notices stating that You changed the files; and  (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and  (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.  You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.  END OF TERMS AND CONDITIONS  APPENDIX: How to apply the Apache License to your work.  To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!)  The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.  Copyright {yyyy} {name of copyright owner}  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at  http://www.apache.org/licenses/LICENSE-2.0  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.


pkgId: 3249f661bd508505bd3cc8f37af22fa7265498a933d99a690325264f361ec960
name: python-aiocache
arch: src
version: 0.12.3
epoch: 0
release: 1
summary: multi backend asyncio cache
url: https://github.com/aio-libs/aiocache
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aiocache-0.12.3-1.src.rpm
checksum_type: sha256
description:
  - ``pip install aiocache``
  - ``pip install aiocache[redis]``
  - ``pip install aiocache[memcached]``
  - ``pip install aiocache[redis,memcached]``
  - ``pip install aiocache[msgpack]``


pkgId: 2be0028ead9b228abe327a51cab42759892b3e81a970cac4e878e8e2b33e32fb
name: python-aiocarrot
arch: src
version: 1.0.4
epoch: 0
release: 1
summary: Asynchronous framework for working with RabbitMQ
url: https://pypi.org/project/aiocarrot/
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aiocarrot-1.0.4-1.src.rpm
checksum_type: sha256
description:
  **aiocarrot** is a fully asynchronous framework for working with the <a href="https://www.rabbitmq.com/">RabbitMQ</a> message broker

  <a href="https://github.com/d3nbr0/aiocarrot/actions?query=branch%3Amain+event%3Apush">
      <img src="https://github.com/d3nbr0/aiocarrot/workflows/tests/badge.svg" alt="Tests">
  </a>

  <a href="https://pypi.org/project/aiocarrot">
      <img src="https://img.shields.io/pypi/v/aiocarrot?color=%2334D058&label=pypi%20package" alt="Version">
  </a>

  ___

  **Source Code: https://github.com/d3nbr0/aiocarrot**

  ___

  The key features are:

  * **Completely asynchronous** - aiocarrot has the <a href="https://pypi.org/project/aio-pika/">aiopika</a> library running under the hood
  * **Fast to code** - the framework allows you to reduce the amount of code in your project, as well as speed up its development
  * **Fields validation** - aiocarrot supports field validation using <a href="https://pypi.org/project/pydantic/">pydantic</a>



  The following dependencies are required for **aiocarrot** to work:

  * <a href="https://pypi.org/project/aio-pika/">aio-pika</a> for working with RabbitMQ
  * <a href="https://pypi.org/project/pydantic/">pydantic</a> for fields validation
  * <a href="https://pypi.org/project/ujson/">ujson</a> for sending and receiving messages
  * <a href="https://pypi.org/project/loguru/">loguru</a> for logging :)



  Create and activate virtual environment and then install **aiocarrot**:

  ```commandline
  pip install aiocarrot
  ```



  Create a file `main.py` with:

  ```python
  from aiocarrot import Carrot, Consumer

  import asyncio


  consumer = Consumer()


  @consumer.message(name='multiply')
  async def multiply(first_number: int, second_number: int) -> None:
      print('Result is:', first_number * second_number)


  async def main() -> None:
      carrot = Carrot(url='amqp://guest:guest@127.0.0.1/', queue_name='sample')
      carrot.setup_consumer(consumer)
      await carrot.run()


  if __name__ == '__main__':
      asyncio.run(main())
  ```

  Then run it with:

  ```commandline
  python main.py
  ```

  Now you have created a consumer with the ability to receive a **"multiply"** task



  If you want to send a message, use this:

  ```python
  from aiocarrot import Carrot

  import asyncio


  async def main() -> None:
      carrot = Carrot(url='amqp://guest:guest@127.0.0.1:5672/', queue_name='sample')

      await carrot.send('multiply', first_number=10, second_number=20)


  if __name__ == '__main__':
      asyncio.run(main())
  ```

  **You can find more examples <a href="https://github.com/d3nbr0/aiocarrot/tree/main/examples">here</a>**

  It's very simple to use. Enjoy!


pkgId: fcbe708f56ce663df2264b4f4b123ab2374e96a8f689e2b1b5b9818253588b3d
name: python-aiocdp
arch: src
version: 1.1.8
epoch: 0
release: 1
summary: Asynchronous python module for programatic access to Chrome DevTools Protocol.
url: https://github.com/amirsharapov/aiocdp
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aiocdp-1.1.8-1.src.rpm
checksum_type: sha256
description:
  This library provides an async wrapper around the Chrome DevTools Protocol.



  To be the underlying engine for any projects using Chrome DevTools Protocol. This library should embody the following:

  1. **Flexibility**: Allow for any use case that the CDP supports.
  2. **Minimal external dependencies**: Opt for built-in python libraries where possible.
  3. **Clean code**: No hacks, workarounds, or spaghetti code.





  The following will launch chrome through the command line.

  ```python
  import asyncio

  from aiocdp import Chrome


  async def setup_chrome():
      chrome = Chrome.init(
          host="localhost",
          port=9222,
      )

      chrome.start()

      


  if __name__ == "__main__":
      asyncio.run(setup_chrome())
  ```

  _**NOTE:** If you had chrome open previously, you may run into connection issues.
  If this is the case, close your tabs, run the script to relaunch chrome, and then reopen your tabs._



  ```python
  import asyncio

  from aiocdp import Chrome


  async def setup_tabs():
      chrome = Chrome.init(
          host="localhost",
          port=9222,
      )

      chrome.start()

      
      target = chrome.new_tab("https://www.google.com")
      target = chrome.new_tab("https://www.yahoo.com")
      target = chrome.new_tab("https://www.github.com/amirdevstudio/aiocdp")

      
      target = chrome.new_tab()


  if __name__ == "__main__":
      asyncio.run(setup_tabs())
  ```



  You can find the AIOCDP package published to pypi.org/project/aiocdp





  This library is built to be "one and done" except for performance optimizations or design changes.
  This library should limit the dependencies it has on the CDP unless it's a core feature (opening sessions, etc.).



  - Built-in `dataclasses` module for classes
  - Built-in `typing` module for type hints, enum literals, and other goodies
  - Built-in `json` module for JSON serialization
  - Built-in `asyncio` module for async functionality
  - External `requests` module for HTTP communication
  - External `websockets` module for websocket communication




  - `aiocdp` - Root package. Contains core and utility modules
  - `aiocdp.core` - Core functionality for communicating with the Chrome DevTools Protocol
  - `aiocdp.core.chrome.Chrome` -> Represents the Chrome instance / process.
  - `aiocdp.core.target.Target` -> Represents a chrome devtools protocol target (Page, Frame, Worker, etc)
  - `aiocdp.core.connection.Connection` -> Represents a websocket connection to a target
  - `aiocdp.core.session.TargetSession` -> Represents a session to a specific target.
  - `aiocdp.core.stream.EventStream` -> Represents a stream of events from a connection.
  - `aiocdp.core.stream.EventStreamReader` -> Readonly reader to an event stream.



  - Setup proper typehints for setting subclasses. (use a type var in a shared module)
  - documentation



  1. Update the version in `pyproject.toml`
  2. Run `python -m pip install build twine`
  3. Run `python -m build`
  4. Run `twine check dist/*`
  5. Run `twine upload dist/aiocdp-<MAJOR>.<MINOR>.<PATCH>*`


pkgId: 70b253e91654ccd876ccf02b1640e517a5493d9ca68e23a0102e60d7da7f7694
name: python-aiocfscrape
arch: src
version: 1.0.0
epoch: 0
release: 1
url: https://github.com/pavlodvornikov/aiocfscrape
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aiocfscrape-1.0.0-1.src.rpm
checksum_type: sha256
summary:
  A simple async Python module to bypass Cloudflare's anti-bot page. See https://github.com/pavlodvornikov/aiocfscrape for more information.


pkgId: eed0a835153fbc4588476f982da3f4db08166f64fd23afd8ce87fae04c993ce3
name: python-aioch
arch: src
version: 0.0.2
epoch: 0
release: 1
summary: Library for accessing a ClickHouse database over native interface from the asyncio
url: https://github.com/mymarilyn/aioch
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aioch-0.0.2-1.src.rpm
checksum_type: sha256
description:
  **aioch** is a library for accessing a ClickHouse database over native interface from the asyncio.
  It wraps features of [clickhouse-driver](https://github.com/mymarilyn/clickhouse-driver) for asynchronous usage.

  [![Coverage Status](https://coveralls.io/repos/github/mymarilyn/aioch/badge.svg?branch=master)](https://coveralls.io/github/mymarilyn/aioch?branch=master)
  [![Build Status](https://travis-ci.org/mymarilyn/aioch.svg?branch=master)](https://travis-ci.org/mymarilyn/aioch)




  The package can be installed using `pip`:

  ```bash
  pip install aioch
  ```

  To install from source:

  ```bash
  git clone https://github.com/mymarilyn/aioch
  cd aioch
  python setup.py install
  ```


  ```python
  from datetime import datetime

  import asyncio
  from aioch import Client


  async def exec_progress():
      client = Client('localhost')

      progress = await client.execute_with_progress('LONG AND COMPLICATED QUERY')
      timeout = 20
      started_at = datetime.now()

      async for num_rows, total_rows in progress:
          done = num_rows / total_rows if total_rows else total_rows
          now = datetime.now()
          
          if (now - started_at).total_seconds() > timeout and done < 0.5:
              await client.cancel()
              break
      else:
          rv = await progress.get_result()
          print(rv)


  async def exec_no_progress():
      client = Client('localhost')
      rv = await client.execute('LONG AND COMPLICATED QUERY')
      print(rv)


  loop = asyncio.get_event_loop()
  loop.run_until_complete(asyncio.wait([exec_progress(), exec_no_progress()]))
  ```

  For more information see **clickhouse-driver** usage examples.



  * `executor` - instance of custom Executor, if not supplied default executor will be used
  * `loop` - asyncio compatible event loop

  Other parameters are passing to wrapped clickhouse-driver's Client.



  aioch is distributed under the [MIT license](http://www.opensource.org/licenses/mit-license.php).


pkgId: df9bb170e275208f26f7b4237443b136b9e1a860f6c78d0ac476ac51cdb29b7e
name: python-aiochan
arch: src
version: 0.2.7
epoch: 0
release: 1
summary: CSP-style concurrency for Python
url: https://github.com/zh217/aiochan
rpm_license: Apache
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aiochan-0.2.7-1.src.rpm
checksum_type: sha256
description:
  [![Build Status](https://travis-ci.com/zh217/aiochan.svg?branch=master)](https://travis-ci.com/zh217/aiochan)
  [![Documentation Status](https://readthedocs.org/projects/aiochan/badge/?version=latest)](https://aiochan.readthedocs.io/en/latest/?badge=latest)
  [![codecov](https://codecov.io/gh/zh217/aiochan/branch/master/graph/badge.svg)](https://codecov.io/gh/zh217/aiochan)
  [![PyPI version](https://img.shields.io/pypi/v/aiochan.svg)](https://pypi.python.org/pypi/aiochan/)
  [![PyPI version](https://img.shields.io/pypi/pyversions/aiochan.svg)](https://pypi.python.org/pypi/aiochan/)
  [![PyPI status](https://img.shields.io/pypi/status/aiochan.svg)](https://pypi.python.org/pypi/aiochan/)
  [![GitHub license](https://img.shields.io/github/license/zh217/aiochan.svg)](https://github.com/zh217/aiochan/blob/master/LICENSE)

  ![logo](logo.gif "aiochan logo")

  Aiochan is a library written to bring the wonderful idiom of
  [CSP-style](https://en.wikipedia.org/wiki/Communicating_sequential_processes) concurrency to python. The implementation
  is based on the battle-tested Clojure library [core.async](https://github.com/clojure/core.async), while the API is
  carefully crafted to feel as pythonic as possible.



  * Doing concurrency in Python was painful
  * asyncio sometimes feels too low-level
  * I am constantly missing capabilities from [golang](https://golang.org) and
    [core.async](https://github.com/clojure/core.async)
  * It is much easier to port [core.async](https://github.com/clojure/core.async) to Python than to port all those
    [wonderful](http://www.numpy.org/) [python](https://pytorch.org/) [packages](https://scrapy.org/) to some other
    language.



  * Pythonic [API](https://aiochan.readthedocs.io/en/latest/api.html) that includes everything you'd need for CSP-style
    concurrency programming
  * Works seamlessly with existing asyncio-based libraries
  * Fully [tested](aiochan/test)
  * Fully [documented](https://aiochan.readthedocs.io/en/latest/index.html)
  * Guaranteed to work with Python 3.5.2 or above and PyPy 3.5 or above
  * Depends only on python's core libraries, zero external dependencies
  * Proven, efficient implementation based on Clojure's battle-tested [core.async](https://github.com/clojure/core.async)
  * Familiar semantics for users of [golang](https://golang.org)'s channels and Clojure's core.async channels
  * Flexible implementation that does not depend on the inner workings of asyncio at all
  * Permissively [licensed](LICENSE)
  * A [beginner-friendly tutorial](https://aiochan.readthedocs.io/en/latest/tutorial.html) to get newcomers onboard as
  quickly as possible



  ```bash
  pip3 install aiochan
  ```



  Read the [beginner-friendly tutorial](https://aiochan.readthedocs.io/en/latest/tutorial.html) that starts from the
  basics. Or if you are already experienced with [golang](https://golang.org) or Clojure's
  [core.async](https://github.com/clojure/core.async), start with the
  [quick introduction](https://aiochan.readthedocs.io/en/latest/quick.html) and then dive into the
  [API documentation](https://aiochan.readthedocs.io/en/latest/api.html).



  The [quick introduction](https://aiochan.readthedocs.io/en/latest/quick.html) and the
  [beginner-friendly tutorial](https://aiochan.readthedocs.io/en/latest/tutorial.html) can both be run in jupyter
  notebooks, online in binders if you want (just look for ![the binder link](https://mybinder.org/static/images/badge.svg)
  at the top of each tutorial).



  In addition to the [introduction](https://aiochan.readthedocs.io/en/latest/quick.html) and the
  [tutorial](https://aiochan.readthedocs.io/en/latest/tutorial.html), we have the
  [complete set of examples](examples/concurrency_patterns) from Rob Pike's
  [Go concurrency patterns](https://www.youtube.com/watch?v=f6kdp27TYZs) translated into aiochan. Also, here is a
  [solution](examples/dining_philosophers.py) to the classical
  [dining philosophers problem](https://en.wikipedia.org/wiki/Dining_philosophers_problem).



  We are just starting out, but we will try to answer aiochan-related questions on
  [stackoverflow](https://stackoverflow.com/questions/ask?tags=python+python-aiochan) as quickly as possible.



  File an [issue](https://github.com/zh217/aiochan/issues/new), or if you think you can solve it, a pull request is even
  better.



  `aiochan` is definitely not a toy and we do use it in production, mainly in the two following scenarios:

  * Complex data-flow in routing.  We integrate aiochan with an asyncio-based web server.
    This should be easy to understand.
  * Data-preparation piplelines.  We prepare and pre-process data to feed into our machine learning
    algorithms as fast as possible so that our algorithms spend no time waiting for data
    to come in, but no faster than necessary so that we don't have a memory explosion due to
    data coming in faster than they can be consumed.  For this we make heavy use of
    [parallel_pipe](https://aiochan.readthedocs.io/en/latest/api.html#aiochan.channel.Chan.parallel_pipe)
    and [parallel_pipe_unordered](https://aiochan.readthedocs.io/en/latest/api.html#aiochan.channel.Chan.parallel_pipe_unordered).
    Currently we are not aware of any other library that can completely satisfy this need of ours.



  It is our 'hello world' example:

  ```python
  import aiochan as ac

  async def blue_python(c):
      while True:
          
          product = "a product made by the blue python"
          await c.put(product)

  async def yellow_python(c):
      while True:
          result = await c.get()
          
          print("A yellow python has received", result)

  async def main():
      c = ac.Chan()

      for _ in range(3):
          ac.go(blue_python(c))

      for _ in range(3):
          ac.go(yellow_python(c))
  ```

  in other words, it is a 3-fan-in on top of a 3-fan-out. If you run it, you will have an endless stream of
  `A yellow python has received a product made by the blue python`.

  If you have no idea what this is, read the [tutorial](https://aiochan.readthedocs.io/en/latest/tutorial.html).


pkgId: 01b268dd923529bb779f0d401c8e2bf22516d880b280c598ec95c33dae226941
name: python-aiochannel
arch: src
version: 1.2.1
epoch: 0
release: 1
summary: asyncio Channels (closable queues) inspired by golang
url: https://github.com/tbug/aiochannel
rpm_license: Apache-2.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aiochannel-1.2.1-1.src.rpm
checksum_type: sha256
description:
  [![Build Status](https://github.com/tbug/aiochannel/actions/workflows/test.yml/badge.svg)][Build Status]
  [![Stable Version](https://img.shields.io/pypi/v/aiochannel?label=stable)][PyPI Releases]
  [![Python Versions](https://img.shields.io/pypi/pyversions/aiochannel)][PyPI]
  [![Download Stats](https://img.shields.io/pypi/dm/aiochannel)](https://pypistats.org/packages/aiochannel)

  Channel concept for asyncio.




  ```
  pip install aiochannel
  ```



  [Changelog]





  `Channel` has a very similar API to `asyncio.Queue`.
  The key difference is that a channel is only considered
  "done" when it has been both closed and drained, so calling `.join()`
  on a channel will wait for it to be both closed and drained (Unlike
  `Queue` which will return from `.join()` once the queue is empty).

  **NOTE:** Closing a channel is permanent. You cannot open it again.

  ```python
  import asyncio
  from aiochannel import Channel



  async def main():
      
      
      
      my_channel: Channel[str] = Channel(100)

      
      await my_channel.put("my item")
      
      
      
      


      
      my_item = await my_channel.get()
      
      
      

      
      
      
      
      asyncio.get_event_loop().call_later(0.1, my_channel.close)

      
      await my_channel.join()

      
      
      
      if my_channel.closed():
          print ("Channel is closed")

  asyncio.run(main())
  ```

  Like the `asyncio.Queue` you can also call non-async get and put:

  <!--pytest.mark.skip-->

  ```python
      
      my_channel.put_nowait(item)
      
      

      
      my_channel.get_nowait()
      
      
      
      
  ```

  As of `0.2.0` `Channel` also implements the async iterator protocol.
  You can now use `async for` to iterate over the channel until it
  closes, without having to deal with `ChannelClosed` exceptions.

  <!--pytest.mark.skip-->

  ```python
      
      async for item in channel:
          print(item)
      
  ```

  which is functionally equivalent to

  <!--pytest.mark.skip-->

  ```python
      while True:
          try:
              data = yield from channel.get()
          except ChannelClosed:
              break
          
  ```

    [PyPI]: https://pypi.org/project/aiochannel
    [PyPI Releases]: https://pypi.org/project/aiochannel/#history
    [Github]: https://github.com/tbug/aiochannel
    [Changelog]: https://github.com/tbug/aiochannel/blob/master/CHANGELOG.md
    [Issue Tracker]: https://github.com/tbug/aiochannel/issues
    [Build Status]: https://github.com/tbug/aiochannel/actions/workflows/test.yml


pkgId: 3d8c437912a5f05dfd0e1b60317a8af133ffce2c19a4f2e141aee892a2ca3719
name: python-aiocircuitbreaker
arch: src
version: 2.0.0
epoch: 0
release: 1
description:
  This is an async Python implementation of the `circuitbreaker`__ library.
  __ circuitbreaker_

url: https://github.com/GenyaSol/aiocircuitbreaker
rpm_license: UNKNOWN
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aiocircuitbreaker-2.0.0-1.src.rpm
checksum_type: sha256
summary:
  This is an async Python implementation of the circuitbreaker library https://github.com/fabfuel/circuitbreaker.


pkgId: fe05c55d2a8168148b68cb7944b9f287ffcde9bb57d25eb9bd344653a67edf72
name: python-aiocli
arch: src
version: 1.10.0
epoch: 0
release: 1
summary: Simple and lightweight async console runner.
url: https://pypi.org/project/aiocli/
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aiocli-1.10.0-1.src.rpm
checksum_type: sha256
description:
  [![PyPI version](https://badge.fury.io/py/aiocli.svg)](https://badge.fury.io/py/aiocli)
  [![PyPIDownloads](https://static.pepy.tech/badge/aiocli)](https://pepy.tech/project/aiocli)
  [![CI](https://github.com/aiopy/python-aiocli/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/aiopy/python-aiocli/actions/workflows/ci.yml)

  aiocli is a Python library for simple and lightweight async console runner.

  Full compatibility with argparse module and highly inspired by aiohttp module.



  Use the package manager [pip](https://pypi.org/project/aiocli/) to install aiocli.

  ```bash
  pip install aiocli
  ```



  - Visit [aiocli docs](https://aiopy.github.io/python-aiocli/).



  ```python
  from logging import getLogger, Logger, StreamHandler
  from os import getenv

  from aiocli.commander import run_app, Application, Depends, State

  app = Application(state={
      'envs': {
          'LOGGER_NAME': str(getenv('LOGGER_NAME', 'example_app')),
          'LOGGER_LEVEL': str(getenv('LOGGER_LEVEL', 'INFO')),
      }
  })

  def _get_logger(state: State) -> Logger:
      logger = getLogger(state.get('envs')['LOGGER_NAME'])
      logger.setLevel(state.get('envs')['LOGGER_LEVEL'])
      handler = StreamHandler()
      logger.addHandler(handler)
      return logger

  @app.command(name='greet:to', positionals=[('name', {'default': 'World!'})])
  async def handle_greeting(name: str, logger: Logger = Depends(_get_logger)) -> int:
      logger.info(f'Hello {name}')
      return 0

  @app.command(name='div', optionals=[('--a', {'type': float}), ('--b', {'type': float})])
  async def handle_division(a: float, b: float, logger: Logger = Depends(_get_logger)) -> int:
      try:
          logger.info(f'Result {a} / {b} = {(a / b)}')
          return 0
      except BaseException as err:
          logger.error(f'Error: {err}')
          return 1


  if __name__ == '__main__':
      run_app(app)
  ```



  - Python >= 3.9



  Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

  Please make sure to update tests as appropriate.



  [MIT](https://github.com/aiopy/python-aiocli/blob/master/LICENSE)


pkgId: 39a2bcdec5b1935ec4ca97170bef535061c5291768015c8bb21e910bb8a2c858
name: python-aiocloudpayments
arch: src
version: 0.1.1
epoch: 0
release: 1
summary: CloudPayments Python Async Library
url: https://github.com/drforse/aiocloudpayments
rpm_license: UNKNOWN
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aiocloudpayments-0.1.1-1.src.rpm
checksum_type: sha256
description:
  Python Async [CloudPayments](https://developers.cloudpayments.ru/#api) Library

  ```
  from datetime import date

  from aiocloudpayments import AioCpClient


  async def main():
      client = AioCpClient(PUBLIC_ID, API_SECRET)

      await client.test()

      await client.charge_card(
          amount=10,
          currency="RUB",
          invoice_id="1234567",
          ip_address="123.123.123.123",
          description="Payment for goods in example.com",
          account_id="user_x",
          name="CARDHOLDER NAME",
          card_cryptogram_packet="01492500008719030128SMfLeYdKp5dSQVIiO5l6ZCJiPdel4uDjdFTTz1UnXY+3QaZcNOW8lmXg0H670MclS4lI+qLkujKF4pR5Ri+T/E04Ufq3t5ntMUVLuZ998DLm+OVHV7FxIGR7snckpg47A73v7/y88Q5dxxvVZtDVi0qCcJAiZrgKLyLCqypnMfhjsgCEPF6d4OMzkgNQiynZvKysI2q+xc9cL0+CMmQTUPytnxX52k9qLNZ55cnE8kuLvqSK+TOG7Fz03moGcVvbb9XTg1oTDL4pl9rgkG3XvvTJOwol3JDxL1i6x+VpaRxpLJg0Zd9/9xRJOBMGmwAxo8/xyvGuAj85sxLJL6fA==",
          payer=Person(
              first_name="Test",
              last_name="Test",
              middle_name="Test",
              birth=date(1998, 1, 16),
              address="12A, 123",
              street="Test Avenue",
              city="LosTestels, City of Test Angels",
              country="Testland",
              phone="+1 111 11 11",
              post_code="101011010"
          )
      )

      await client.disconnect()
  ```

  ```
  from aiocloudpayments import AiohttpDispatcher, Result
  from aiocloudpayments.types import PayNotification, CancelNotification, CheckNotification


  CERT_FILE = "cert.pem"
  CERT_FILE = "pkey.pem"


  def main():
      dp = AiohttpDispatcher()

      
      router = Router()

      
      @router.cancel(lambda n: 5 > n.amount > 1)
      async def foo(notification: CancelNotification):
          print(f"{notification=}")
          
          return Result.OK

      
      @router.pay(lambda n: n.amount <= 1)
      async def foo(notification: PayNotification):
          print(f"{notification.amount=}")
          
          return Result.OK

     
      @router.check()
      async def foo(notification: CheckNotification):
          print(f"{notification.amount=}")
          
          return Result.WRONG_AMOUNT

      
      @dp.cancel(lambda n: n.amount > 5)
      async def foo(notification: CancelNotification):
          print(f"{notification.amount=}, > 5")
          

      dp.include_router(router)

      ssl_context = SSLContext()
      ssl_context.load_cert_chain(CERT_FILE, KEY_FILE)

      dp.run_app(
          AioCpClient(PUBLIC_ID, API_SECRET),
          "/test",
          pay_path="/pay",
          cancel_path="/cancel",
          ssl_context=ssl_context,
          check_hmac=False  # disable hmac check, only use in development environments
      )
  ```

  architecture inspired by [aiogram](https://github.com/aiogram/aiogram)


pkgId: 9da8e4c89f2d07fdc4a565f5b6a758b547e0b6fdeaed7991865363777cb7faab
name: python-aiocoap
arch: src
version: 0.4.11
epoch: 0
release: 1
summary: Python CoAP library
url: https://pypi.org/project/aiocoap/
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aiocoap-0.4.11-1.src.rpm
checksum_type: sha256
description:
  The aiocoap package is an implementation of CoAP, the `Constrained Application
  Protocol`_.
  It is written in Python 3 using its `native asyncio`_ methods to facilitate
  concurrent operations while maintaining an easy to use interface.


pkgId: d373d06d4d58baa27fce7255f57b9b2e669ead946de40e3a5a67859c6e55f879
name: python-aiocomelit
arch: src
version: 0.9.1
epoch: 0
release: 1
summary: Python library to control Comelit Simplehome
url: https://github.com/chemelli74/aiocomelit
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aiocomelit-0.9.1-1.src.rpm
checksum_type: sha256
description:
  <p align="center">
    <a href="https://github.com/chemelli74/aiocomelit/actions/workflows/ci.yml?query=branch%3Amain">
      <img src="https://img.shields.io/github/actions/workflow/status/chemelli74/aiocomelit/ci.yml?branch=main&label=CI&logo=github&style=flat-square" alt="CI Status" >
    </a>
    <a href="https://codecov.io/gh/chemelli74/aiocomelit">
      <img src="https://img.shields.io/codecov/c/github/chemelli74/aiocomelit.svg?logo=codecov&logoColor=fff&style=flat-square" alt="Test coverage percentage">
    </a>
  </p>
  <p align="center">
    <a href="https://python-poetry.org/">
      <img src="https://img.shields.io/badge/packaging-poetry-299bd7?style=flat-square&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAASCAYAAABrXO8xAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAJJSURBVHgBfZLPa1NBEMe/s7tNXoxW1KJQKaUHkXhQvHgW6UHQQ09CBS/6V3hKc/AP8CqCrUcpmop3Cx48eDB4yEECjVQrlZb80CRN8t6OM/teagVxYZi38+Yz853dJbzoMV3MM8cJUcLMSUKIE8AzQ2PieZzFxEJOHMOgMQQ+dUgSAckNXhapU/NMhDSWLs1B24A8sO1xrN4NECkcAC9ASkiIJc6k5TRiUDPhnyMMdhKc+Zx19l6SgyeW76BEONY9exVQMzKExGKwwPsCzza7KGSSWRWEQhyEaDXp6ZHEr416ygbiKYOd7TEWvvcQIeusHYMJGhTwF9y7sGnSwaWyFAiyoxzqW0PM/RjghPxF2pWReAowTEXnDh0xgcLs8l2YQmOrj3N7ByiqEoH0cARs4u78WgAVkoEDIDoOi3AkcLOHU60RIg5wC4ZuTC7FaHKQm8Hq1fQuSOBvX/sodmNJSB5geaF5CPIkUeecdMxieoRO5jz9bheL6/tXjrwCyX/UYBUcjCaWHljx1xiX6z9xEjkYAzbGVnB8pvLmyXm9ep+W8CmsSHQQY77Zx1zboxAV0w7ybMhQmfqdmmw3nEp1I0Z+FGO6M8LZdoyZnuzzBdjISicKRnpxzI9fPb+0oYXsNdyi+d3h9bm9MWYHFtPeIZfLwzmFDKy1ai3p+PDls1Llz4yyFpferxjnyjJDSEy9CaCx5m2cJPerq6Xm34eTrZt3PqxYO1XOwDYZrFlH1fWnpU38Y9HRze3lj0vOujZcXKuuXm3jP+s3KbZVra7y2EAAAAAASUVORK5CYII=" alt="Poetry">
    </a>
    <a href="https://github.com/ambv/black">
      <img src="https://img.shields.io/badge/code%20style-black-000000.svg?style=flat-square" alt="black">
    </a>
    <a href="https://github.com/pre-commit/pre-commit">
      <img src="https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white&style=flat-square" alt="pre-commit">
    </a>
  </p>
  <p align="center">
    <a href="https://pypi.org/project/aiocomelit/">
      <img src="https://img.shields.io/pypi/v/aiocomelit.svg?logo=python&logoColor=fff&style=flat-square" alt="PyPI Version">
    </a>
    <img src="https://img.shields.io/pypi/pyversions/aiocomelit.svg?style=flat-square&logo=python&amp;logoColor=fff" alt="Supported Python versions">
    <img src="https://img.shields.io/pypi/l/aiocomelit.svg?style=flat-square" alt="License">
  </p>

  Python library to control Comelit Simplehome



  Install this via pip (or your favourite package manager):

  `pip install aiocomelit`



  Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):

  <!-- prettier-ignore-start -->
  <!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
  <!-- markdownlint-disable -->
  <!-- markdownlint-enable -->
  <!-- ALL-CONTRIBUTORS-LIST:END -->
  <!-- prettier-ignore-end -->

  This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!



  This package was created with
  [Copier](https://copier.readthedocs.io/) and the
  [browniebroke/pypackage-template](https://github.com/browniebroke/pypackage-template)
  project template.


pkgId: 7311ea28f757cf11f975dd586f4763425628b8062e30e739e83ff55a4e955ea6
name: python-aiocometd
arch: src
version: 0.4.5
epoch: 0
release: 1
summary: CometD client for asyncio
url: https://github.com/robertmrk/aiocometd
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aiocometd-0.4.5-1.src.rpm
checksum_type: sha256
description:
  aiocometd is a CometD_ client built using asyncio_, implementing the Bayeux_
  protocol.
  CometD_ is a scalable WebSocket and HTTP based event and message routing bus.
  CometD_ makes use of WebSocket and HTTP push technologies known as Comet_ to
  provide low-latency data from the server to browsers and client applications.


pkgId: e68a592615dd2d4c5f700922c2ef417a072bbf19649e13bf2c4d4a21d5e1d3ca
name: python-aiocomfoconnect
arch: src
version: 0.1.13
epoch: 0
release: 1
url: https://github.com/michaelarnauts/aiocomfoconnect
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aiocomfoconnect-0.1.13-1.src.rpm
checksum_type: sha256
summary:
  aiocomfoconnect is an asyncio Python 3 library for communicating with a Zehnder ComfoAir Q350/450/600 ventilation system

description:
  `aiocomfoconnect` is an asyncio Python 3 library for communicating with a Zehnder ComfoAir Q350/450/600 ventilation system. It's the successor of
  [comfoconnect](https://github.com/michaelarnauts/comfoconnect).

  It's compatible with Python 3.10 and higher.



  ```shell
  pip3 install aiocomfoconnect
  ```



  ```shell
  $ python -m aiocomfoconnect --help

  $ python -m aiocomfoconnect discover

  $ python -m aiocomfoconnect register --host 192.168.1.213

  $ python -m aiocomfoconnect set-speed away --host 192.168.1.213
  $ python -m aiocomfoconnect set-speed low --host 192.168.1.213
  $ python -m aiocomfoconnect set-mode auto --host 192.168.1.213
  $ python -m aiocomfoconnect set-speed medium --host 192.168.1.213
  $ python -m aiocomfoconnect set-speed high --host 192.168.1.213
  $ python -m aiocomfoconnect set-boost on --host 192.168.1.213 --timeout 1200

  $ python -m aiocomfoconnect set-comfocool auto --host 192.168.1.213
  $ python -m aiocomfoconnect set-comfocool off --host 192.168.1.213

  $ python -m aiocomfoconnect show-sensors --host 192.168.1.213
  $ python -m aiocomfoconnect show-sensor 276 --host 192.168.1.213
  $ python -m aiocomfoconnect show-sensor 276 --host 192.168.1.213 -f

  $ python -m aiocomfoconnect get-property --host 192.168.1.213 1 1 8 9  # Unit 0x01, SubUnit 0x01, Property 0x08, Type STRING. See PROTOCOL-RMI.md
  ```



  - `async connect()`: Connect to the bridge.
  - `async disconnect()`: Disconnect from the bridge.
  - `async register_sensor(sensor)`: Register a sensor.
  - `async deregister_sensor(sensor)`: Deregister a sensor.
  - `async get_mode()`: Get the ventilation mode.
  - `async set_mode(mode)`: Set the ventilation mode. (auto / manual)
  - `async get_comfocool_mode()`: Get Comfocool mode
  - `async set_comfocool_mode()`: Set Comfocool mode. (auto / off)
  - `async get_speed()`: Get the ventilation speed.
  - `async set_speed(speed)`: Set the ventilation speed. (away / low / medium / high)
  - `async get_bypass()`: Get the bypass mode.
  - `async set_bypass(mode, timeout=-1)`: Set the bypass mode. (auto / on / off)
  - `async get_balance_mode()`: Get the balance mode.
  - `async set_balance_mode(mode, timeout=-1)`: Set the balance mode. (balance / supply only / exhaust only)
  - `async get_boost()`: Get the boost mode.
  - `async set_boost(mode, timeout=-1)`: Set the boost mode. (boolean)
  - `async get_away()`: Get the away mode.
  - `async set_away(mode, timeout=-1)`: Set the away mode. (boolean)
  - `async get_temperature_profile()`: Get the temperature profile.
  - `async set_temperature_profile(profile)`: Set the temperature profile. (warm / normal / cool)
  - `async get_sensor_ventmode_temperature_passive()`: Get the sensor based ventilation passive temperature control setting.
  - `async set_sensor_ventmode_temperature_passive(mode)`: Set the sensor based ventilation passive temperature control setting. (auto / on / off)
  - `async get_sensor_ventmode_humidity_comfort()`: Get the sensor based ventilation humidity comfort setting.
  - `async set_sensor_ventmode_humidity_comfort(mode)`: Set the sensor based ventilation humidity comfort setting. (auto / on / off)
  - `async get_sensor_ventmode_humidity_protection()`: Get the sensor based ventilation humidity protection setting.
  - `async set_sensor_ventmode_humidity_protection(mode)`: Set the sensor based ventilation humidity protection setting. (auto / on / off)



  - `async cmd_start_session()`: Start a session.
  - `async cmd_close_session()`: Close a session.
  - `async cmd_list_registered_apps()`: List registered apps.
  - `async cmd_register_app(uuid, device_name, pin)`: Register an app.
  - `async cmd_deregister_app(uuid)`: Deregister an app.
  - `async cmd_version_request()`: Request the bridge's version.
  - `async cmd_time_request()`: Request the bridge's time.
  - `async cmd_rmi_request(message, node_id)`: Send a RMI request.
  - `async cmd_rpdo_request(pdid, type, zone, timeout)`: Send a RPDO request.
  - `async cmd_keepalive()`: Send a keepalive message.





  ```python
  import asyncio

  from aiocomfoconnect import discover_bridges


  async def main():
      """ ComfoConnect LAN C Bridge discovery example."""

      
      bridges = await discover_bridges()
      print(bridges)


  if __name__ == "__main__":
      asyncio.run(main())
  ```



  ```python
  import asyncio

  from aiocomfoconnect import ComfoConnect
  from aiocomfoconnect.const import VentilationSpeed
  from aiocomfoconnect.sensors import SENSORS


  async def main(local_uuid, host, uuid):
      """ Basic example."""

      def sensor_callback(sensor, value):
          """ Print sensor updates. """
          print(f"{sensor.name} = {value}")

      
      comfoconnect = ComfoConnect(host, uuid, sensor_callback=sensor_callback)
      await comfoconnect.connect(local_uuid)

      
      for key in SENSORS:
          await comfoconnect.register_sensor(SENSORS[key])

      
      await comfoconnect.set_speed(VentilationSpeed.LOW)

      
      await asyncio.sleep(120)

      
      await comfoconnect.disconnect()


  if __name__ == "__main__":
      asyncio.run(main(local_uuid='00000000000000000000000000001337', host='192.168.1.20', uuid='00000000000000000000000000000055'))  # Replace with your bridge's IP and UUID
  ```





  - [ComfoConnect LAN C Protocol](docs/PROTOCOL.md)
  - [PDO Sensors](docs/PROTOCOL-PDO.md)
  - [RMI commands](docs/PROTOCOL-RMI.md)



  You can use the `scripts/decode_pcap.py` file to decode network traffic between the Mobile App and the ComfoConnect LAN C.
  Make sure that the first TCP session in the capture is the connection between the bridge and the app. It's therefore recommended to start the capture before you open the app.

  ```shell
  $ sudo tcpdump -i any -s 0 -w /tmp/capture.pcap tcp and port 56747
  $ python3 script/decode_pcap.py /tmp/capture.pcap
  ```



  ```shell
  python3 -m pip install grpcio-tools==1.62.3
  python3 -m grpc_tools.protoc -Iprotobuf --python_out=aiocomfoconnect/protobuf protobuf/*.proto
  ```



  You can build a Docker image to make it easier to develop and experiment on your local machine. You can use the `docker build -t aiocomfoconnect .` or the shortcut `make build` command to create a docker image.

  Next, you can run this image by running `docker run aiocomfoconnect`. Any args from `aiocomfoconnect` can be passed into this command, just like the `python3 -m aiocomfoconnect` command.



  * https://github.com/oysteing/comfoconnect-mqtt-bridge


pkgId: 25c8df62eca8d14f16d84a4e5fda935c1f1e041f63477332dfab23412b435cf9
name: python-aiocomfoconnect
arch: src
version: 0.1.14
epoch: 0
release: 1
url: https://github.com/michaelarnauts/aiocomfoconnect
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aiocomfoconnect-0.1.14-1.src.rpm
checksum_type: sha256
summary:
  aiocomfoconnect is an asyncio Python 3 library for communicating with a Zehnder ComfoAir Q350/450/600 ventilation system

description:
  `aiocomfoconnect` is an asyncio Python 3 library for communicating with a Zehnder ComfoAir Q350/450/600 ventilation system. It's the successor of
  [comfoconnect](https://github.com/michaelarnauts/comfoconnect).

  It's compatible with Python 3.10 and higher.



  ```shell
  pip3 install aiocomfoconnect
  ```



  ```shell
  $ python -m aiocomfoconnect --help

  $ python -m aiocomfoconnect discover

  $ python -m aiocomfoconnect register --host 192.168.1.213

  $ python -m aiocomfoconnect set-speed away --host 192.168.1.213
  $ python -m aiocomfoconnect set-speed low --host 192.168.1.213
  $ python -m aiocomfoconnect set-mode auto --host 192.168.1.213
  $ python -m aiocomfoconnect set-speed medium --host 192.168.1.213
  $ python -m aiocomfoconnect set-speed high --host 192.168.1.213
  $ python -m aiocomfoconnect set-boost on --host 192.168.1.213 --timeout 1200

  $ python -m aiocomfoconnect set-comfocool auto --host 192.168.1.213
  $ python -m aiocomfoconnect set-comfocool off --host 192.168.1.213

  $ python -m aiocomfoconnect show-sensors --host 192.168.1.213
  $ python -m aiocomfoconnect show-sensor 276 --host 192.168.1.213
  $ python -m aiocomfoconnect show-sensor 276 --host 192.168.1.213 -f

  $ python -m aiocomfoconnect get-property --host 192.168.1.213 1 1 8 9  # Unit 0x01, SubUnit 0x01, Property 0x08, Type STRING. See PROTOCOL-RMI.md
  ```



  - `async connect()`: Connect to the bridge.
  - `async disconnect()`: Disconnect from the bridge.
  - `async register_sensor(sensor)`: Register a sensor.
  - `async deregister_sensor(sensor)`: Deregister a sensor.
  - `async get_mode()`: Get the ventilation mode.
  - `async set_mode(mode)`: Set the ventilation mode. (auto / manual)
  - `async get_comfocool_mode()`: Get Comfocool mode
  - `async set_comfocool_mode()`: Set Comfocool mode. (auto / off)
  - `async get_speed()`: Get the ventilation speed.
  - `async set_speed(speed)`: Set the ventilation speed. (away / low / medium / high)
  - `async get_bypass()`: Get the bypass mode.
  - `async set_bypass(mode, timeout=-1)`: Set the bypass mode. (auto / on / off)
  - `async get_balance_mode()`: Get the balance mode.
  - `async set_balance_mode(mode, timeout=-1)`: Set the balance mode. (balance / supply only / exhaust only)
  - `async get_boost()`: Get the boost mode.
  - `async set_boost(mode, timeout=-1)`: Set the boost mode. (boolean)
  - `async get_away()`: Get the away mode.
  - `async set_away(mode, timeout=-1)`: Set the away mode. (boolean)
  - `async get_temperature_profile()`: Get the temperature profile.
  - `async set_temperature_profile(profile)`: Set the temperature profile. (warm / normal / cool)
  - `async get_sensor_ventmode_temperature_passive()`: Get the sensor based ventilation passive temperature control setting.
  - `async set_sensor_ventmode_temperature_passive(mode)`: Set the sensor based ventilation passive temperature control setting. (auto / on / off)
  - `async get_sensor_ventmode_humidity_comfort()`: Get the sensor based ventilation humidity comfort setting.
  - `async set_sensor_ventmode_humidity_comfort(mode)`: Set the sensor based ventilation humidity comfort setting. (auto / on / off)
  - `async get_sensor_ventmode_humidity_protection()`: Get the sensor based ventilation humidity protection setting.
  - `async set_sensor_ventmode_humidity_protection(mode)`: Set the sensor based ventilation humidity protection setting. (auto / on / off)



  - `async cmd_start_session()`: Start a session.
  - `async cmd_close_session()`: Close a session.
  - `async cmd_list_registered_apps()`: List registered apps.
  - `async cmd_register_app(uuid, device_name, pin)`: Register an app.
  - `async cmd_deregister_app(uuid)`: Deregister an app.
  - `async cmd_version_request()`: Request the bridge's version.
  - `async cmd_time_request()`: Request the bridge's time.
  - `async cmd_rmi_request(message, node_id)`: Send a RMI request.
  - `async cmd_rpdo_request(pdid, type, zone, timeout)`: Send a RPDO request.
  - `async cmd_keepalive()`: Send a keepalive message.





  ```python
  import asyncio

  from aiocomfoconnect import discover_bridges


  async def main():
      """ ComfoConnect LAN C Bridge discovery example."""

      
      bridges = await discover_bridges()
      print(bridges)


  if __name__ == "__main__":
      asyncio.run(main())
  ```



  ```python
  import asyncio

  from aiocomfoconnect import ComfoConnect
  from aiocomfoconnect.const import VentilationSpeed
  from aiocomfoconnect.sensors import SENSORS


  async def main(local_uuid, host, uuid):
      """ Basic example."""

      def sensor_callback(sensor, value):
          """ Print sensor updates. """
          print(f"{sensor.name} = {value}")

      
      comfoconnect = ComfoConnect(host, uuid, sensor_callback=sensor_callback)
      await comfoconnect.connect(local_uuid)

      
      for key in SENSORS:
          await comfoconnect.register_sensor(SENSORS[key])

      
      await comfoconnect.set_speed(VentilationSpeed.LOW)

      
      await asyncio.sleep(120)

      
      await comfoconnect.disconnect()


  if __name__ == "__main__":
      asyncio.run(main(local_uuid='00000000000000000000000000001337', host='192.168.1.20', uuid='00000000000000000000000000000055'))  # Replace with your bridge's IP and UUID
  ```





  - [ComfoConnect LAN C Protocol](docs/PROTOCOL.md)
  - [PDO Sensors](docs/PROTOCOL-PDO.md)
  - [RMI commands](docs/PROTOCOL-RMI.md)



  You can use the `scripts/decode_pcap.py` file to decode network traffic between the Mobile App and the ComfoConnect LAN C.
  Make sure that the first TCP session in the capture is the connection between the bridge and the app. It's therefore recommended to start the capture before you open the app.

  ```shell
  $ sudo tcpdump -i any -s 0 -w /tmp/capture.pcap tcp and port 56747
  $ python3 script/decode_pcap.py /tmp/capture.pcap
  ```



  ```shell
  python3 -m pip install grpcio-tools==1.67.1
  python3 -m grpc_tools.protoc -Iprotobuf --python_out=aiocomfoconnect/protobuf protobuf/*.proto
  ```



  You can build a Docker image to make it easier to develop and experiment on your local machine. You can use the `docker build -t aiocomfoconnect .` or the shortcut `make build` command to create a docker image.

  Next, you can run this image by running `docker run aiocomfoconnect`. Any args from `aiocomfoconnect` can be passed into this command, just like the `python3 -m aiocomfoconnect` command.



  * https://github.com/oysteing/comfoconnect-mqtt-bridge


pkgId: 669455815af5f2ee880fad23bd5e8feebd2a61abc765b69677cc4a57667837cc
name: python-aioconnectors
arch: src
version: 1.6.3
epoch: 0
release: 1
summary: Simple secure asynchronous message queue
url: https://github.com/mori-b/aioconnectors
rpm_license: Apache Software License
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aioconnectors-1.6.3-1.src.rpm
checksum_type: sha256
description:
  [![PyPI version](https://badge.fury.io/py/aioconnectors.svg)](https://badge.fury.io/py/aioconnectors) [![Downloads](https://static.pepy.tech/personalized-badge/aioconnectors?period=total&units=international_system&left_color=grey&right_color=blue&left_text=downloads)](https://pepy.tech/project/aioconnectors)

             _                                 __
       ___ _(_)__  _______  ___  ___  ___ ____/ /____  _______
      / _ `/ / _ \/ __/ _ \/ _ \/ _ \/ -_) __/ __/ _ \/ __(_-<
      \_,_/_/\___/\__/\___/_//_/_//_/\__/\__/\__/\___/_/ /___/




  **Simple secure asynchronous message queue**

  *<a href="#features">Features</a>*
  *<a href="#installation">Installation</a>*
  *<a href="#exampleptp">Example Point to point : Server and Client</a>*
  *<a href="#exampleps">Example publish/subscribe : Broker, Subscriber, and Publisher</a>*
  *<a href="#hld">High Level Design</a>*
  *<a href="#usecases">Use Cases</a>*
  *<a href="#usage">Usage</a>*
  *<a href="#enc">1.Encryption</a>*
  *<a href="#run">2.Run a connector</a>*
  *<a href="#sendreceive">3.Send/receive messages</a>*
  *<a href="#classes">4.ConnectorManager and ConnectorAPI</a>*
  *<a href="#send">5.send_message</a>*
  *<a href="#management">6.Programmatic management tools</a>*
  *<a href="#cli">7.Command line interface management tools</a>*
  *<a href="#testing">8.Testing tools</a>*
  *<a href="#chat">9.Embedded chat</a>*
  *<a href="#containers">Containers</a>*
  *<a href="#windows">Windows</a>*


  <a name="features"></a>


  aioconnectors is an easy to set up message queue and broker that works on Unix like systems. Requirements are : Python >= 3.6, and openssl installed.
  It provides bidirectional transfer of messages and files, optional authentication and encryption, persistence and reconnection in case of connection loss, proxy support, client filtering.
  It is a point to point broker built on the client/server model, but both peers can push messages. It can also be easily configured as a publish/subscribe broker.
  Based on asyncio, message sending and receiving are asynchronous, with the option to wait asynchronously for a response.
  A connector can be configured with a short json file.
  An embedded command line tool enables to easily run a connector and manage it with shell commands.
  A simple Python API provides functions like starting/stopping a connector, sending a message, receiving messages, and other management capabilities. To support other languages for the API, the file standalone\_api.py only should be transpiled.


  <a name="installation"></a>


      pip3 install aioconnectors


  <a name="exampleptp"></a>


  You can run a connector with a single shell command

      python3 -m aioconnectors create_connector <config_json_path>

  This is covered in <a href="#run">2-</a>, but this example shows the programmatic way to run connectors.
  This is a basic example of a server and a client sending messages to each other. For more interesting examples, please refer to applications.py or aioconnectors\_test.py.
  For both server and client, connector\_manager is running the connector, and connector\_api is sending/receiving messages.
  In this example, connector\_manager and connector\_api are running in the same process for convenience. They can obviously run in different processes, as shown in the other examples.
  In this example we are running server and client on the same machine since server_sockaddr is set to "127.0.0.1".
  To run server and client on different machines, you should modify server_sockaddr value in both server and client code, with the ip address of the server.
  You can run multiple clients, just set a different client\_name for each client.

  1.No encryption
  You can run the following example code directly, the encryption is disabled.
  In case you want to use this example with encryption, you should read 2. and 3. after the examples.



      import asyncio
      import aioconnectors

      loop = asyncio.get_event_loop()
      server_sockaddr = ('127.0.0.1',10673)
      connector_files_dirpath = '/var/tmp/aioconnectors'

      
      connector_manager = aioconnectors.ConnectorManager(is_server=True, server_sockaddr=server_sockaddr, use_ssl=False, use_token=False,
                                                         ssl_allow_all=True, connector_files_dirpath=connector_files_dirpath,
                                                         certificates_directory_path=connector_files_dirpath,
                                                         send_message_types=['any'], recv_message_types=['any'],
                                                         file_recv_config={'any': {'target_directory':connector_files_dirpath}},
                                                         reuse_server_sockaddr=True)

      task_manager =  loop.create_task(connector_manager.start_connector())
      loop.run_until_complete(task_manager)

      
      connector_api = aioconnectors.ConnectorAPI(is_server=True, server_sockaddr=server_sockaddr,
                                                 connector_files_dirpath=connector_files_dirpath,
                                                 send_message_types=['any'], recv_message_types=['any'],
                                                 default_logger_log_level='INFO')

      
      async def message_received_cb(logger, transport_json , data, binary):
          print('SERVER : message received', transport_json , data.decode())
      loop.create_task(connector_api.start_waiting_for_messages(message_type='any', message_received_cb=message_received_cb))

      
      async def send_messages(destination):
          await asyncio.sleep(2)
          index = 0
          while True:
              index += 1
              await connector_api.send_message(data={'application message': f'SERVER MESSAGE {index}'},
                                               message_type='any', destination_id=destination)
              await asyncio.sleep(1)

      loop.create_task(send_messages(destination='client1'))

      try:
          print(f'Connector is running, check log at {connector_files_dirpath+"/aioconnectors.log"}'
                f', type Ctrl+C to stop')
          loop.run_forever()
      except:
          print('Connector stopped !')

      
      connector_api.stop_waiting_for_messages(message_type='any')

      
      task_stop = loop.create_task(connector_manager.stop_connector(delay=None, hard=False, shutdown=True))
      loop.run_until_complete(task_stop)




      import asyncio
      import aioconnectors

      loop = asyncio.get_event_loop()
      server_sockaddr = ('127.0.0.1',10673)
      connector_files_dirpath = '/var/tmp/aioconnectors'
      client_name = 'client1'

      
      connector_manager = aioconnectors.ConnectorManager(is_server=False, server_sockaddr=server_sockaddr,
                                                         use_ssl=False, ssl_allow_all=True, use_token=False,
                                                         connector_files_dirpath=connector_files_dirpath,
                                                         certificates_directory_path=connector_files_dirpath,
                                                         send_message_types=['any'], recv_message_types=['any'],
                                                         file_recv_config={'any': {'target_directory':connector_files_dirpath}},
                                                         client_name=client_name)

      task_manager =  loop.create_task(connector_manager.start_connector())
      loop.run_until_complete(task_manager)

      
      connector_api = aioconnectors.ConnectorAPI(is_server=False, server_sockaddr=server_sockaddr,
                                                 connector_files_dirpath=connector_files_dirpath, client_name=client_name,
                                                 send_message_types=['any'], recv_message_types=['any'],
                                                 default_logger_log_level='INFO')

      
      async def message_received_cb(logger, transport_json , data, binary):
          print('CLIENT : message received', transport_json , data.decode())
      loop.create_task(connector_api.start_waiting_for_messages(message_type='any', message_received_cb=message_received_cb))

      
      async def send_messages():
          await asyncio.sleep(1)
          index = 0
          while True:
              index += 1
              await connector_api.send_message(data={'application message': f'CLIENT MESSAGE {index}'}, message_type='any')
              await asyncio.sleep(1)

      loop.create_task(send_messages())

      try:
          print(f'Connector is running, check log at {connector_files_dirpath+"/aioconnectors.log"}'
                f', type Ctrl+C to stop')
          loop.run_forever()
      except:
          print('Connector stopped !')

      
      connector_api.stop_waiting_for_messages(message_type='any')

      
      task_stop = loop.create_task(connector_manager.stop_connector(delay=None, hard=False, shutdown=True))
      loop.run_until_complete(task_stop)


  <a name="exampleps"></a>


  You can run the following code of a broker, a publisher and a subscriber in 3 different shells on the same machine out of the box.
  You should modify some values as explained in the previous example in order to run on different machines, and with encryption.



  Just a server with pubsub\_central\_broker=True

      import asyncio
      import aioconnectors

      loop = asyncio.get_event_loop()
      server_sockaddr = ('127.0.0.1',10673)
      connector_files_dirpath = '/var/tmp/aioconnectors'

      
      connector_manager = aioconnectors.ConnectorManager(is_server=True, server_sockaddr=server_sockaddr, use_ssl=False, use_token=False,
                                                         ssl_allow_all=True, connector_files_dirpath=connector_files_dirpath,
                                                         certificates_directory_path=connector_files_dirpath,
                                                         send_message_types=['any'], recv_message_types=['any'],
                                                         file_recv_config={'any': {'target_directory':connector_files_dirpath}},
                                                         pubsub_central_broker=True, reuse_server_sockaddr=True)

      task_manager =  loop.create_task(connector_manager.start_connector())
      loop.run_until_complete(task_manager)

      
      connector_api = aioconnectors.ConnectorAPI(is_server=True, server_sockaddr=server_sockaddr,
                                                 connector_files_dirpath=connector_files_dirpath,
                                                 send_message_types=['any'], recv_message_types=['any'],
                                                 default_logger_log_level='INFO')

      
      async def message_received_cb(logger, transport_json , data, binary):
          print('SERVER : message received', transport_json , data.decode())
      loop.create_task(connector_api.start_waiting_for_messages(message_type='any', message_received_cb=message_received_cb))

      try:
          print(f'Connector is running, check log at {connector_files_dirpath+"/aioconnectors.log"}'
                f', type Ctrl+C to stop')
          loop.run_forever()
      except:
          print('Connector stopped !')

      
      connector_api.stop_waiting_for_messages(message_type='any')

      
      task_stop = loop.create_task(connector_manager.stop_connector(delay=None, hard=False, shutdown=True))
      loop.run_until_complete(task_stop)




  Just a client with subscribe\_message\_types = [topic1, topic2, ...]

      import asyncio
      import aioconnectors

      loop = asyncio.get_event_loop()
      server_sockaddr = ('127.0.0.1',10673)
      connector_files_dirpath = '/var/tmp/aioconnectors'
      client_name = 'client2'

      
      connector_manager = aioconnectors.ConnectorManager(is_server=False, server_sockaddr=server_sockaddr,
                                                         use_ssl=False, ssl_allow_all=True, use_token=False,
                                                         connector_files_dirpath=connector_files_dirpath,
                                                         certificates_directory_path=connector_files_dirpath,
                                                         send_message_types=['any'], recv_message_types=['type1'],
                                                         file_recv_config={'type1': {'target_directory':connector_files_dirpath}},
                                                         client_name=client_name, subscribe_message_types=["type1"])

      task_manager =  loop.create_task(connector_manager.start_connector())
      loop.run_until_complete(task_manager)

      
      connector_api = aioconnectors.ConnectorAPI(is_server=False, server_sockaddr=server_sockaddr,
                                                 connector_files_dirpath=connector_files_dirpath, client_name=client_name,
                                                 send_message_types=['any'], recv_message_types=['type1'],
                                                 default_logger_log_level='INFO')

      
      async def message_received_cb(logger, transport_json , data, binary):
          print('CLIENT : message received', transport_json , data.decode())
      loop.create_task(connector_api.start_waiting_for_messages(message_type='type1', message_received_cb=message_received_cb))

      '''
      
      async def send_messages():
          await asyncio.sleep(1)
          index = 0
          while True:
              index += 1
              await connector_api.send_message(data={'application message': f'CLIENT MESSAGE {index}'}, message_type='any')
              await asyncio.sleep(1)

      loop.create_task(send_messages())
      '''

      try:
          print(f'Connector is running, check log at {connector_files_dirpath+"/aioconnectors.log"}'
                f', type Ctrl+C to stop')
          loop.run_forever()
      except:
          print('Connector stopped !')

      
      connector_api.stop_waiting_for_messages(message_type='type1')

      
      task_stop = loop.create_task(connector_manager.stop_connector(delay=None, hard=False, shutdown=True))
      loop.run_until_complete(task_stop)




  Just a client which uses publish\_message instead of send\_message

      import asyncio
      import aioconnectors

      loop = asyncio.get_event_loop()
      server_sockaddr = ('127.0.0.1',10673)
      connector_files_dirpath = '/var/tmp/aioconnectors'
      client_name = 'client1'

      
      connector_manager = aioconnectors.ConnectorManager(is_server=False, server_sockaddr=server_sockaddr,
                                                         use_ssl=False, ssl_allow_all=True, use_token=False,
                                                         connector_files_dirpath=connector_files_dirpath,
                                                         certificates_directory_path=connector_files_dirpath,
                                                         send_message_types=['type1','type2'], recv_message_types=['any'],
                                                         file_recv_config={'any': {'target_directory':connector_files_dirpath}},
                                                         client_name=client_name, disk_persistence_send=True)

      task_manager =  loop.create_task(connector_manager.start_connector())
      loop.run_until_complete(task_manager)

      
      connector_api = aioconnectors.ConnectorAPI(is_server=False, server_sockaddr=server_sockaddr,
                                                 connector_files_dirpath=connector_files_dirpath, client_name=client_name,
                                                 send_message_types=['type1','type2'], recv_message_types=['any'],
                                                 default_logger_log_level='INFO')

      
      
      
      

      
      async def send_messages():
          await asyncio.sleep(1)
          index = 0
          
          
          while True:
              index += 1
              print(f'CLIENT : message {index} published')
              
              await connector_api.publish_message(data={'application message': f'CLIENT MESSAGE {index}'}, message_type='type1')#,
                                                  
              
              await asyncio.sleep(1)

      loop.create_task(send_messages())

      try:
          print(f'Connector is running, check log at {connector_files_dirpath+"/aioconnectors.log"}'
                f', type Ctrl+C to stop')
          loop.run_forever()
      except:
          print('Connector stopped !')

      
      connector_api.stop_waiting_for_messages(message_type='any')

      
      task_stop = loop.create_task(connector_manager.stop_connector(delay=None, hard=False, shutdown=True))
      loop.run_until_complete(task_stop)

  2.Encryption without authentication
  In order to use encryption, you should set use\_ssl to True in both server and client ConnectorManager instantiations.
  A directory containing certificates must be created before running the example, which is done by a single command :

      python3 -m aioconnectors create_certificates

  If you decide to use server_ca=true on your connector server, then you need to add "--ca" (<a href="#classes">4-</a>).
  If you run server and client on different machines, this command should be run on both machines.

  3.Encryption with authentication
  In this example, the kwarg ssl\_allow\_all is true (both on server and client), meaning the communication between server and client if encrypted is not authenticated.
  In case you want to run this example with authentication too, you have 2 options :
  3.1. Set use\_ssl to True and ssl\_allow\_all to False in both server and client ConnectorManager instantiations.
  If you run server and client on the same machine, this only requires to run the command "python3 -m aioconnectors create\_certificates" beforehand like in 2.
  In case the server and client run on different machines, you should run the prerequisite command "python3 -m aioconnectors create_certificates" only once, and copy the generated directory /var/tmp/aioconnectors/certificates/server to your server (preserving symlinks) and /var/tmp/aioconnectors/certificates/client to your client.
  3.2. Set use\_ssl to True, ssl\_allow\_all to True, and use\_token to True, in both server and client ConnectorManager instantiations, to use token authentication. This also requires to run beforehand "python3 -m aioconnectors create_certificates".


  <a name="hld"></a>


  The client and server are connected by one single tcp socket.
  When a peer sends a message, it is first sent by unix socket to the connector, then transferred to a different queue for each remote peer. Messages are read from these priority queues and sent to the remote peer on the client/server socket. After a message reaches its peer, it is sent to a queue, one queue per message type. The api listens on a unix socket to receive messages of a specific type, that are read from the corresponding queue.
  The optional encryption uses TLS. The server certificate and the default client certificate are automatically generated and pre-shared, so that a server or client without prior knowledge of these certificates cannot communicate. Then, the server generates on the fly a new certificate per client, so that different clients cannot interfere with one another. Alternatively, the server can generate on the fly a new token per client.


  <a name="usecases"></a>


  -The standard use case is running server and client on separate stations. Each client station can then initiate a connection to the server station.
  The valid message topics are defined in the server and client configurations (send\_message\_types and recv\_message\_types), and the messages are sent point to point.
  In order to have all clients/server connections authenticated and encrypted, you just have to call

      python3 -m aioconnectors create_certificates <optional_directory_path>

  And then share the created directories between server and clients as explained in <a href="#enc">1-</a>.
  You can also use a proxy between your client and server, as explained in <a href="#classes">4-</a>.

  -You might prefer to use a publish/subscribe approach.
  This is also supported by configuring a single server as the broker (you just need to set pubsub\_central\_broker=True).
  The other connectors should be clients. A client can subscribe to specific topics (message\_types) by setting the attribute subscribe\_message\_types in its constructor, or by calling the set\_subscribe\_message\_types command on the fly.

  -You might want both sides to be able to initiate a connection, or even to have multiple nodes being able to initiate connections between one another.
  The following lines describe a possible approach to do that using aioconnectors.
  Each node should be running an aioconnector server, and be able to also spawn a aioconnector client each time it initiates a connection to a different remote server. A new application layer handling these connectors could be created, and run on each node.
  Your application might need to know if a peer is already connected before initiating a connection : to do so, you might use the connector_manager.show\_connected\_peers method (explained in <a href="#cli">7-</a>).
  Your application might need to be able to disconnect a specific client on the server : to do so, you might use the connector\_manager.disconnect\_client method.
  A comfortable approach would be to share the certificates directories created in the first step between all the nodes. All nodes would share the same server certificate, and use the same client default certificate to initiate the connection (before receiving their individual certificate). The only differences between clients configurations would be their client_name, and their remote server (the configurations are explained in <a href="#classes">4-</a>).

  -There are multiple tools to let the server filter clients. Your application might need to decide whether to accept a client connection or not.
  The following tools filter clients in this order :
  whitelisted_clients_ip/subnet : in configuration file, or on the fly with add_whitelist_client (it updates the configuration file).
  hook_whitelist_clients(extra_info, source_id) : coroutine that lets you take a decision after having filtered a non whitelisted client (maybe allow it from now on).
  blacklisted_clients_ip/subnet: in configuration file or on the fly with add_blacklist_client.
  whitelisted_clients_id : in configuration file or on the fly with add_whitelist_client (uses regex).
  hook_whitelist_clients(extra_info, source_id) : same.
  blacklisted_clients_id : in configuration file or on the fly with add_blacklist_client (uses regex).
  hook_allow_certificate_creation(source_id) : coroutine that lets you prevent certificate creation based on the source_id.
  hook_server_auth_client(source_id) : coroutine that gives a last opportunity to filter the source_id.
  The hooks must be fed to the ConnectorManager constructor (explained in <a href="#classes">4-</a>).


  <a name="usage"></a>


  aioconnectors provides the ConnectorManager class which runs the connectors, and the ConnectorAPI class which sends and receives messages. It provides as well the ConnectorRemoteTool class which can lightly manage the connector outside of the ConnectorManager.
  The ConnectorManager client and server can run on different machines. However, ConnectorAPI and ConnectorRemoteTool communicate internally with their ConnectorManager, and the three must run on the same machine.
  aioconnectors also provides a command line tool accessible by typing

      python3 -m aioconnectors --help


  <a name="enc"></a>


  Encryption mode is, as everything else, configurable through the ConnectorManager kwargs or config file, as explained later in <a href="#classes">4-</a>. The relevant parameters are use_ssl and ssl_allow_all.
  The default mode is the most secure : use_ssl is enabled and ssl\_allow\_all is disabled, both on server and client.
  -If you choose to use encryption, you should call

      python3 -m aioconnectors create_certificates [<optional_directory_path>] [--ca] [--help]

  A directory called "certificates" will be created under your optional\_directory\_path, or under /var/tmp/aioconnectors if not specified.
  Under it, 2 subdirectories will be created : certificates/server and certificates/client.
  You need to copy certificates/server to your server (preserving symlinks), and certificates/client to your client. That's all you have to do.
  This is the recommended approach, since it ensures traffic encryption, client and server authentication, and prevents client impersonation.
  Clients use the default certificate to first connect to server, then an individual certificate is generated by the server for each client. Client automatically uses this individual certificate for further connections. This individual certificate is mapped to the client_name.
  The first client named client_name reaching the server is granted a certificate for this client_name. Different clients further attempting to use the same client_name will be rejected.
  When server\_ca is false on server side (default), the client certificates are checked against the certificates pem kept on the server, otherwise against the server CA.
  When using ssl, the default approach is to have server\_ca false (default), meaning your server will generate and manage self signed client certificates, providing certificates visibility, and tools like delete\_client\_certificate to delete client certificates on the fly.
  Using server\_ca true lets your server become a CA with a self signed CA certificate that will sign your client certificates. If you choose to run your server with server\_ca true, then you need the --ca argument in create\_certificates, otherwise you don't need it (default).
  The server\_ca true mode comes with server\_ca\_certs\_not\_stored enabled by default, meaning the client certificates are deleted from server side. Not having to store the client certificates on the server might be an advantage but it doesn't enable you to delete them : if you want to be able to delete them in ca mode, then you might just use server\_ca false. The server\_ca\_certs\_not\_stored option set to false requires to delete the certificates yourself, since it is not currently supported when server_ca is true : this implementation would require something like "openssl ca -gencrl -config certificates/server/server\_ca\_details.conf -out revoked.pem", and also "SSLContext.verify\_flags |= ssl.VERIFY\_CRL\_CHECK\_LEAF" before loading the revoked.pem into SSLContext.load\_verify\_locations.
  -The client also checks the server certificate to prevent MITM.
  Instead of using the generated server certificate, you also have the option to use a hostname for your server and use a CA signed server certificate that the clients will verify. For that you should :
  -On server side, under "certificates" directory, replace /server/server-cert/server.pem and server.key with your signed certificates. You don't need to do that manually, there is a tool that does it :

      python3 -m aioconnectors replace_server_certificate <custom_server_pem_file_path> [<optional_directory_path>]

  Note that the custom server pem file should contain the whole chain of .crt including the intermediate certificates.
  and in case you want to roll back to use the original generated server certificate :

      python3 -m aioconnectors replace_server_certificate --revert

  -On client side, configure server\_sockaddr with the server hostname instead of IP address, and set client\_cafile\_verify\_server to be the ca cert path (like /etc/ssl/certs/ca-certificates.crt), to enable CA verification of your server certificate.
  -You can delete a client certificate on the server (and also on client) by calling delete\_client\_certificate in

      python3 -m aioconnectors cli

  For this purpose, you can also call programmatically the ConnectorManager.delete_client\_certificate method.
  -You shouldn't need to modify the certificates, however there is a way to tweak the certificates template : run create\_certificates once, then modify certificates/server/csr\_details\_template.conf according to your needs (without setting the Organization field), delete other directories under certificates and run create\_certificates again.
  -On server side, you can store manually additional default certificates with their symlink, under certificates/server/client-certs/symlinks. They must be called defaultN where N is an integer, or be another CA certificate in case server\_ca is true.
  -Other options :

  -ssl\_allow\_all and use\_token enabled : this is a similar approach but instead of generating a certificate per client, the server generates a token per client. This approach is simpler. Note that you can also delete the token on the fly by calling delete\_client\_token.
  You can combine ssl\_allow\_all with token\_verify\_peer\_cert (on client and server) and token\_client\_send\_cert (on client) : in order to authenticate the default certificate only. On client side the token\_verify\_peer\_cert can also be the path of ca certificates (like /etc/ssl/certs/ca-certificates.crt) or custom server public certificate.
  token\_client\_verify\_server\_hostname can be the server hostname that your client authenticates (through its certificate).

  By setting ssl\_allow\_all on both sever and client, you can use encryption without the hassle of sharing certificates. In such a case you can run independently create_certificates on server and client side, without the need to copy a directory. This disables authentication, so that any client and server can communicate.

  By unsetting use_ssl, you can disable encryption at all.


  <a name="run"></a>


  2.1.Command line tool
  -To configure the Connector Manager, create a <config\_json\_path> file based on the Manager template json, and configure it according to your needs (more details in <a href="#classes">4-</a>). Relevant for both server and client.
  A Manager template json can be obtained by calling :

      python3 -m aioconnectors print_config_templates

  -Then create and start you connector (both server and client, each with its own <config_json_path>)

      python3 -m aioconnectors create_connector <config_json_path>

  If you are testing your connector server and client on the same machine, you can use the configuration generated by print\_config\_templates almost out of the box.
  The only change you should do is set is\_server to False in the client configuration, and use\_ssl to False in both configurations (unless you already run "python3 -m aioconnectors create_certificates").
  If you want to test messages sending/receiving, you should also set a client\_name value in the client configuration.
  Then you can use the other command line testing facilites mentioned in <a href="#testing">8-</a> : on both server and client you can run "python3 -m aioconnectors test\_receive\_messages <config\_json\_path>" and "python3 -m aioconnectors test\_send\_messages <config\_json\_path>".

  2.2.Programmatically, examples are provided in applications.py and in aioconnectors\_test.py.
  To create and start a connector :

      connector_manager = aioconnectors.ConnectorManager(config_file_path=config_file_path)
      await connector_manager.start_connector()

  To stop a connector :

      await connector_manager.stop_connector()

  To shutdown a connector :

      await connector_manager.stop_connector(shutdown=True)

  You don't have to use a config file (config\_file\_path), you can also directly initialize your ConnectorManager kwargs, as shown in the previous basic examples, and in aioconnectors\_test.py.


  <a name="sendreceive"></a>


  3.1.To configure the Connector API, create a <config\_json\_path> file based on the API template json.
  Relevant for both server and client. This connector_api config file is a subset of the connector_manager config file. So if you already have a relevant connector_manager config file on your machine, you can reuse it for connector_api, and you don't need to create a different connector_api config file.

      python3 -m aioconnectors print_config_templates
      connector_api = aioconnectors.ConnectorAPI(config_file_path=config_file_path)

  3.2.Or you can directly initialize your ConnectorAPI kwargs

  Then you can send and receive messages by calling the following coroutines in your program, as shown in aioconnectors\_test.py, and in applications.py (test\_receive\_messages and test\_send\_messages).

  3.3.To send messages :

      await connector_api.send_message(data=None, binary=None, **kwargs)

  This returns a status (True or False).
  "data" is your message, "binary" is an optional additional binary message in case you want your "data" to be a json for example.
  If your "data" is already a binary, then the "binary" field isn't necessary.
  kwargs contain all the transport instructions for this message, as explained in <a href="#send">5-</a>.
  If you set the await\_response kwarg to True, this returns the response, which is a (transport\_json , data, binary) triplet.
  The received transport\_json field contains all the kwargs sent by the peer.
  You can also send messages synchronously, with :

      connector_api.send_message_sync(data=None, binary=None, **kwargs)

  Similarly, use the "publish\_message" and "publish\_message\_sync" methods in the publish/subscribe approach.
  More details in <a href="#send">5-</a>.

  3.4.To register to receive messages of a specific message\_type :

      await connector_api.start_waiting_for_messages(message_type='', message_received_cb=message_received_cb, reuse_uds_path=False)

  -**binary** is an optional binary message (or None).
  -**data** is the message data bytes. It is always bytes, so if it was originally sent as a json or a string, you'll have to convert it back by yourself.
  -**message\_received\_cb** is an async def coroutine that you must provide, receiving and processing the message quadruplet (logger, transport\_json, data, binary).
  -**reuse_uds_path** is false by default, preventing multiple listeners of same message type. In case it raises an exception even with a single listener, you might want to find and delete an old uds\_path\_receive\_from\_connector file specified in the exception.
  -**transport\_json** is a json with keys related to the "transport layer" of our message protocol : these are the kwargs sent in send_message. They are detailed in <a href="#send">5-</a>. The main arguments are source\_id, destination\_id, request\_id, response\_id, etc.
  Your application can read these transport arguments to obtain information about peer (source\_id, request\_id if provided, etc), and in order to create a proper response (with correct destination\_id, and response\_id for example if needed, etc).
  transport\_json will contain a with\_file key if a file has been received, more details in <a href="#send">5-</a>.
  -**Note** : if you send a message using send\_message(await\_response=True), the response value is the expected response message : so in that case the response message is not received by the start\_waiting\_for\_messages task.


  <a name="classes"></a>


      logger=None, use_default_logger=True, default_logger_log_level='INFO', default_logger_rotate=True, config_file_path=<path>,default_logger_bk_count=5

  config\_file\_path can be the path of a json file like the following, or instead you can load its items as kwargs, as shown in the basic example later on and in aioconnectors\_test.py
  You can use both kwargs and config\_file\_path : if there are shared items, the ones from config_file_path will override the kwargs, unless you specify config\_file\_overrides\_kwargs=False (True by default).
  The main use case for providing a config\_file\_path while having config\_file\_overrides\_kwargs=False is when you prefer to configure your connector only with kwargs but you also want to let the connector update its config file content on the fly (for example blacklisted\_clients\_id, whitelisted\_clients\_id, or ignore\_peer\_traffic).

  Here is an example of config\_file\_path, with ConnectorManager class arguments, used to create a connector

      {
          "alternate_client_default_cert": false,
          "blacklisted_clients_id": null,
          "blacklisted_clients_ip": null,
          "blacklisted_clients_subnet": null,
          "certificates_directory_path": "/var/tmp/aioconnectors",
          "client_bind_ip": null,
          "client_cafile_verify_server": null,
          "client_name": null,
          "connect_timeout": 10,
          "connector_files_dirpath": "/var/tmp/aioconnectors",
          "debug_msg_counts": true,
          "default_logger_bk_count":5,
          "default_logger_dirpath": "/var/tmp/aioconnectors",
          "default_logger_log_level": "INFO",
          "default_logger_rotate": true,
          "disk_persistence_recv": false,
          "disk_persistence_send": false,
          "enable_client_try_reconnect": true,
          "everybody_can_send_messages": true,
          "file_recv_config": {},
          "ignore_peer_traffic": false,
          "is_server": true,
          "keep_alive_period": null,
          "keep_alive_timeout": 5,
          "max_certs": 1024,
          "max_number_of_unanswered_keep_alive": 2,
          "max_size_file_upload_recv": 8589930194,
          "max_size_file_upload_send": 8589930194,
          "max_size_persistence_path": 1073741824,
          "proxy": {},
          "pubsub_central_broker": false,
          "recv_message_types": [
              "any"
          ],
          "reuse_server_sockaddr": false,
          "reuse_uds_path_commander_server": false,
          "reuse_uds_path_send_to_connector": false,
          "send_message_types": [
              "any"
          ],
          "send_message_types_priorities": {},
          "send_timeout": 50,
          "server_ca": false,
          "server_ca_certs_not_stored": true,
          "server_secure_tls": true,
          "server_sockaddr": [
              "127.0.0.1",
              10673
          ],
          "silent": true,
          "ssl_allow_all": false,
          "subscribe_message_types": [],
          "token_client_send_cert": true,
          "token_client_verify_server_hostname": null,
          "token_server_allow_authorized_non_default_cert": false,
          "token_verify_peer_cert": true,
          "tokens_directory_path": "/var/tmp/aioconnectors",
          "uds_path_receive_preserve_socket": true,
          "uds_path_send_preserve_socket": true,
          "use_ssl": true,
          "use_token": false,
          "whitelisted_clients_id": null,
          "whitelisted_clients_ip": null,
          "whitelisted_clients_subnet": null
      }


  Here is an example of config\_file\_path, with ConnectorAPI class arguments, used to send/receive messages.
  These are a subset of ConnectorManager arguments : which means you can use the ConnectorManager config file also for ConnectorAPI.


      {
          "client_name": null,
          "connector_files_dirpath": "/var/tmp/aioconnectors",
          "default_logger_bk_count":5,
          "default_logger_dirpath": "/var/tmp/aioconnectors",
          "default_logger_log_level": "INFO",
          "default_logger_rotate": true,
          "is_server": true,
          "max_size_chunk_upload": 209715200,
          "pubsub_central_broker": false,
          "receive_from_any_connector_owner": true,
          "recv_message_types": [
              "any"
          ],
          "send_message_types": [
              "any"
          ],
          "server_sockaddr": [
              "127.0.0.1",
              10673
          ],
          "uds_path_receive_preserve_socket": true,
          "uds_path_send_preserve_socket": true
      }


  -**alternate\_client\_default\_cert** is false by default : if true it lets the client try to connect alternatively with the default certificate, in case of failure with the private certificate. This can save the hassle of having to delete manually your client certificate when the certificate was already deleted on server side. This affects also the token authentication : the client will try to connect alternatively by requesting a new token if its token fails.
  -**blacklisted\_clients\_id|ip|subnet** : a list of blacklisted clients (regex for blacklisted\_clients\_id), can be updated on the fly with the api functions add|remove\_blacklist\_client or in the cli.
  -**certificates\_directory\_path** is where your certificates are located, if use\_ssl is True. This is the <optional\_directory\_path> where you generated your certificates by calling "python3 -m aioconnectors create\_certificates <optional\_directory\_path>".
  -**client\_cafile\_verify\_server** : On client side, if server\_sockaddr is configured with the server hostname, you can set client\_cafile\_verify\_server to be the ca cert path (like /etc/ssl/certs/ca-certificates.crt), to enable CA verification of you server certificate.
  -**client\_name** is used on client side. It is the name that will be associated with this client on server side. Auto generated if not supplied in ConnectorManager. Mandatory in ConnectorAPI. It should match the regex \^\[0\-9a\-zA\-Z\-\_\:\]\+$
  -**client_bind_ip** is optional, specifies the interface to bind your client. You can use an interface name or its ip address (string).
  -**connect\_timeout** : On client side, the socket timeout to connect to Tsoc. Default is 10s, you might need to increase it when using a server hostname in server\_sockaddr, since sometimes name resolution with getaddrinfo is slow.
  -**connector\_files\_dirpath** is important, it is the path where all internal files are stored. The default is /var/tmp/aioconnectors. unix sockets files, default log files, and persistent files are stored there.
  -**debug_msg_counts** is a boolean, enables to display every 2 minutes a count of messages in the log file, and in stdout if **silent** is disabled.
  -**default\_logger\_rotate** (boolean) can also be an integer telling the maximum size of the log file in bytes.
  -**default\_logger\_bk\_count**  an integer telling the maximum number of gzip compressed logs kept when log rotate is enabled. Default is 5.
  -**disk\_persistence\_recv** : In order to enable persistence between the connector and a message listener (supported on both client and server sides), use disk\_persistence\_recv=True (applies to all message types). disk\_persistence\_recv can also be a list of message types for which to apply persistence. There will be 1 persistence file per message type.
  -**file\_recv\_config** : In order to be able to receive files, you must define the destination path of files according to their associated dst\_type. This is done in file\_recv\_config, as shown in aioconnectors\_test.py. file\_recv\_config = {"target\_directory":"", "owner":"", "override\_existing":False}. **target\_directory** is later formatted using the transport\_json fields : which means you can use a target\_directory value like "/my_destination_files/{message\_type}/{source\_id}". **owner** is optional, it is the owner of the uploaded file. It must be of the form "user:group". **override\_existing** is optional and false by default : when receiving a file with an already existing destination path, it decides whether to override the existing file or not.
  -**enable\_client\_try\_reconnect** is a boolean set to True by default. If enabled, it lets the client try to reconnect automatically to the server every 5 seconds in case of failure.
  -**keep\_alive\_period** is null by default. If an integer then the client periodically sends a ping keep-alive to the server. If **max\_number\_of\_unanswered\_keep\_alive** (default is 2) keep-alive responses are not received by the client, each after **keep\_alive\_timeout** (default is 5s), then the client disconnects and tries to reconnect with the same mechanism used by enable\_client\_try\_reconnect.
  -**everybody\_can\_send\_messages** if True lets anyone send messages through the connector, otherwise the sender must have write permission to the connector. Setting to True requires the connector to run as root.
  -**hook\_allow\_certificate\_creation** : does not appear in the config file (usable as a kwargs only). Only for server. Can be an async def coroutine receiving a client_name and returning a boolean, to let the server accept or block the client_name certificate creation.
  -**hook\_server\_auth\_client** : does not appear in the config file (usable as a kwargs only). Only for server. Can be an async def coroutine receiving a client peername and returning a boolean, to let the server accept or block the client connection. An example exists in the chat implementation in applications.py.
  -**hook\_store\_token** and **hook\_load\_token** : lets you manipulate the token before it is stored on disk, for client only.
  -**hook\_target\_directory** : does not appear in the config file (usable as a kwargs only). A dictionary of the form {dst\_type: custom_function} where custom\_function receives transport\_json as an input and outputs a destination path to be appended to target\_directory. If custom\_function returns None, it has no effect on the target\_directory. If custom\_function returns False, the file is refused. This enables better customization of the target\_directory according to transport\_json. An example exists in the chat implementation in applications.py.
  -**hook\_whitelist\_clients** : does not appear in the config file (usable as a kwargs only). Has 2 arguments : extra_info, peername. Lets you inject some code when blocking non whitelisted client.
  -**hook\_proxy\_authorization** : does not appear in the config file (usable as a kwargs only). Only for client. A function that receives and returns 2 arguments : the proxy username and password. It returns them after an eventual transformation (like a decryption for example).
  -**ignore_peer_traffic** to ignore a peer traffic, can be updated on the fly with the api functions ignore\_peer\_traffic\_enable, ignore\_peer\_traffic\_enable\_unique, or ignore\_peer\_traffic\_disable or in the cli.
  -**is\_server** (boolean) is important to differentiate between server and client
  -**max\_certs** (integer) limits the maximum number of clients that can connect to a server using client ssl certificates.
  -**max_size_chunk_upload** (integer) used only by ConnectorAPI to send a file in chunks, default chunk length is 200MB. You can try a max chunk length of up to 1GB in a fast network, and might need to lower it in a slow network.
  -**max\_size\_file\_upload\_send** and **max\_size\_file\_upload\_recv**: Size limit of the files you send and receive, both on server and on client. Default is 8GB. However best performance is achieved until 1GB. Once you exceed 1GB, the file is divided in 1GB chunks and reassembled after reception, which is time consuming.
  -**disk\_persistence\_send** : In order to enable persistence between client and server (supported on both client and server sides), use disk\_persistence\_send=True (applies to all message types). disk\_persistence\_send can also be a list of message types for which to apply persistence. There will be 1 persistence file per message type. You can limit the persistence files size with **max\_size\_persistence\_path**.
  -**pubsub\_central\_broker** : set to True if you need your server to be the broker. Used in the publish/subscribe approach, not necessary in the point to point approach.
  -**proxy** an optional dictionary like {"enabled":true, "address":"<proxy_url>", "port":<proxy_port>, "authorization":"", "ssl\_server":false}. Relevant only on client side. Lets the client connect to the server through an http(s) proxy with the connect method, if the **enabled** field is true. The authorization field can have a value like {"username":"<username>", "password":"<password>"}. Regardless of the aioconnectors inner encryption, you can set the "ssl\_server" flag in case your proxy listens on ssl : this feature is under development and not tested because such proxy setup is rare.
  -**receive\_from\_any\_connector\_owner** if True lets the api receive messages from a connector being run by any user, otherwise the connector user must have write permission to the api. True by default (requires the api to run as root to be effective).
  -**recv\_message\_types** : the list of message types that can be received by connector. Default is ["any"]. It should include the send\_message\_types using await\_response.
  -**reuse\_server\_sockaddr**, **reuse\_uds\_path\_send\_to\_connector**, **reuse\_uds\_path\_commander\_server** : booleans false by default, that prevent duplicate processes you might create by mistake from using the same sockets. In case your OS is not freeing a closed socket, you still can set the relevant boolean to true.
  -**send\_message\_types** : the list of message types that can be sent from connector. Default is ["any"] if you don't care to differentiate between message types on your
  application level.
  -**send\_message\_types\_priorities** : None, or a dictionary specifying for each send\_message\_type its priority. The priority is an integer, a smaller integer meaning a higher priority. Usually this is not needed, but with very high throughputs you may want to use it in order to ensure that a specific message type will not get drown by other messages. This might starve the lowest priority messages. Usage example : "send\_message\_types\_priorities": {"type\_fast":0, "type\_slow":1}.
  -**send\_timeout** : maximum time for sending a message between peers on the socket. By default 50 seconds. After timeout, the message is lost, the sending peer disconnects, and peers reconnect if enable\_client\_try\_reconnect.
  -**server\_ca** : (server only) If set to false (default), the server authenticates client certificates according to the stored certificates, otherwise according to its CA. You can always add manually defaultN or CA certificates, under certificates/server/client-certs/symlinks.
  -**server\_ca\_certs\_not\_stored** : (server only) True by default. If server\_ca is true, the generated client certificates won't be stored on server side.
  -**server\_secure\_tls** : (server only) If set to true (default), the server allows only clients using TLS version >= v1.2.
  -**server\_sockaddr** can be configured as a tuple when used as a kwarg, or as a list when used in the json, and is mandatory on both server and client sides. You can use an interface name instead of its ip on server side, for example ("eth0", 10673).
  -**subscribe\_message\_types** : In the publish/subscribe approach, specify for your client the message types you want to subscribe to. It is a subset of recv\_message\_types.
  -**tokens\_directory\_path** : The path of your server token json file, or client token file.
  -**token\_verify\_peer\_cert** : True by default. If boolean, True means the server/client verifies its peer certificate according to its default location under certificates_directory_path. On client : can also be a string with full path of a custom server certificate, or even a string with full path of CA certificate to authenticate server hostname (for example "/etc/ssl/certs/ca-certificates.crt", in that case token\_client\_verify\_server\_hostname should be true).
  -**token\_client\_send\_cert** : True by default. Boolean, must be True if server has token\_verify\_peer\_cert enabled : sends the client certificate.
  -**token\_client\_verify\_server\_hostname** : if true, client authenticates the server hostname with token\_verify\_peer\_cert (CA path) during SSL handshake.
  -**token\_server\_allow\_authorized\_non\_default\_cert** : boolean false by default. If true, server using use\_token will allow client with non default authorized certificate, even if this client doesn't use a token.
  -**uds\_path\_receive\_preserve\_socket** should always be True for better performance, your message\_received\_cb coroutine in start\_waiting\_for\_messages is called for each message without socket disconnection between messages (in fact, only 1 disconnection per 100 messages).
  -**uds\_path\_send\_preserve\_socket** should always be True for better performance.
  -**use\_ssl**, **ssl\_allow\_all**, **use\_token** are boolean, must be identical on server and client. use\_ssl enables encryption as explained previously. When ssl\_allow\_all is disabled, certificates validation is enforced. use\_token requires use\_ssl and ssl\_allow\_all both enabled.
  -**whitelisted\_clients\_id|ip|subnet** : a list of whitelisted clients (regex for whitelisted\_clients\_id), can be updated on the fly with the api functions add|remove\_whitelist\_client or in the cli.


  <a name="send"></a>


      send_message(message_type=None, destination_id=None, request_id=None, response_id=None,
      data=None, data_is_json=True, binary=None, await_response=False, with_file=None,
      wait_for_ack=False, await_response_timeout=None)
      with_file can be like : {'src_path':'','dst_type':'', 'dst_name':'', 'delete':False, 'owner':''}

  send_message is an async coroutine.
  These arguments must be filled on the application layer by the user
  -**await\_response** is False by default, set it to True if your coroutine calling send\_message expects a response value.
  In such a case, the remote peer has to answer with response\_id equal to the request\_id of the request. (This is shown in aioconnectors\_test.py).
  -**await_response_timeout** is None by default. If set to a number, and if await\_response is true, the method waits up to this timeout for the peer response, and if timeout is exceeded it returns False.
  -**data** is the payload of your message. By default it expects a json, but it can be a string, and even bytes. However, using together the "data" argument for a json or a string, and the "binary" argument for binary payload, is a nice way to accompany a binary payload with some textual information. Contrary to "data", **binary** must be bytes, and cannot be a string. A message size should not exceed 1GB.
  -**data\_is\_json** is True by default since it assumes "data" is a json, and it dumps it automatically. Set it to False if "data" is not a json.
  -**destination\_id** is mandatory for server : it is the remote client id. Not needed by client.
  -**message\_type** is mandatory, it enables to have different listeners that receive different message types. You can use "any" as a default.
  -**request\_id** and **response\_id** are optional (integer or string) : they are helpful to keep track of asynchronous messages on the application layer. At the application level, the remote peer should answer with response\_id equal to the request\_id of the request. The request sender can then associate the received response with the request sent.
  -The **publish\_message** and **publish\_message\_sync** methods are the same as the send_message ones, but used by a client in the publish/subscribe approach.
  -The **send\_message\_await\_response** method is the same as send_message, but automatically sets await_response to True.
  -The **send\_message\_sync** method is almost the same as send_message, but called synchronously (not an async coroutine). It can also receive a "loop" as a kwarg. If a loop is running in the background, it schedules and returns a task. Otherwise it returns the peer response if called with await\_response.
  -**wait\_for\_ack** is not recommended for high throughputs, since it slows down dramatically. Basic testing showed a rate of ten messages per second, instead of a few thousands messages per second in the point to point approach.
  Not a benchmark, but some point-to-point and pubsub trials (VM with 8GB RAM and 4 cores) showed that up until 4000 messages (with data of 100 bytes) per second could be received by a server without delay, and from that point the receive queue started to be non empty. This test gave the same result with 100 clients sending each 40 events per second, and with 1 client sending 4000 events per second.
  -**with\_file** lets you embed a file, with {'src\_path':'','dst\_type':'', 'dst\_name':'', 'delete':False, 'owner':''}. **src\_path** is the source path of the file to be sent, **dst\_type** is the type of the file, which enables the remote peer to evaluate the destination path thanks to its ConnectorManager attribute "file\_recv\_config" dictionary. **dst\_name** is the name the file will be stored under. **delete** is a boolean telling if to delete the source file after it has been sent. **owner** is the optional user:group of your uploaded file : if used, it overrides the "owner" value optionally set on server side in file\_recv\_config. If an error occurs while opening the file to send, the file will not be sent but with\_file will still be present in transport\_json received by peer, and will contain an additional key **file\_error** telling the error to the peer application.
  -**tag** lets you add a tag string to your message in transport\_json : it has the advantage of being accessible at reception directly in transport\_json without the need to look into the data structure.


  <a name="management"></a>


  The class ConnectorManager has several methods to manage your connector. These methods are explained in <a href="#cli">7-</a>.
  -**delete\_client\_certificate**, **delete\_client\_token**, **disconnect\_client**, **reload\_tokens**
  -**add\_blacklist_client, remove\_blacklist_client**, **add\_whitelist_client, remove\_whitelist_client**
  -**delete\_previous\_persistence\_remains**
  -**ignore\_peer\_traffic\_show**, **ignore\_peer\_traffic\_enable**, **ignore\_peer\_traffic\_enable\_unique**, **ignore\_peer\_traffic\_disable**
  -**show\_connected\_peers**
  -**show\_log\_level**, **set\_log\_level**
  -**show\_subscribe\_message\_types**, **set\_subscribe\_message\_types**
  -**start\_connector**, **stop\_connector**, **restart\_connector**
  The same methods can be executed remotely, with the ConnectorRemoteTool class. This class is instantiated exactly like ConnectorAPI, with the same arguments (except for receive_from_any_connector_owner)

      connector_remote_tool = aioconnectors.ConnectorRemoteTool(config_file_path=config_file_path)

  An example of ConnectorRemoteTool is available in applications.py in the cli implementation.


  <a name="cli"></a>


      python3 -m aioconnectors cli

  to run several interesting commands like :
  -**start/stop/restart** your connectors.
  -**show\_connected\_peers** : show currently connected peers.
  -**delete\_client\_certificate** enables your server to delete a specific client certificate. delete\_client\_certificate enables your client to delete its own certificate and fallback using the default one. In order to delete a certificate of a currently connected client, first delete the certificate on server side, which will disconnect the client instantaneously, and then delete the certificate on client side : the client will then reconnect automatically and obtain a new certificate. The client side deletion is not needed in case alternate\_client\_default\_cert is true.
  -**delete\_client\_token** enables your server to delete a specific client token. Enables you client to delete its own token and fallback requesting a new token.
  -**reload\_tokens** reloads tokens after for example modifying them on disk.
  -**disconnect_client** enables your server to disconnect a specific client.
  -**add\_blacklist_client, remove\_blacklist_client** enables your server to blacklist a client by id (regex), ip, or subnet, at runtime. Disconnects the client if blacklisted by id, also deletes its certificate if exists. Kept in the connector config file if exists.
  -**add\_whitelist_client, remove\_whitelist_client** enables your server to whitelist a client by id (regex), ip, or subnet, at runtime. Kept in the connector config file if exists.
  -**peek\_queues** to show the internal queues sizes.
  -**ignore\_peer\_traffic** can be a boolean, or a peer name. When enabled, the connector drops all new messages received from peers, or from the specified peer. It also drops new messages to be sent to all peers, or to the specified peer. This mode can be useful to let the queues evacuate their accumulated messages.
  -**show\_log\_level** to show the current log level.
  -**set\_log\_level** to set the log level on the fly.
  -**show\_subscribe\_message\_types** to show the subscribed message types of a client.
  -**set\_subscribe\_message\_types** to set the list of all subscribed message types of a client.


  <a name="testing"></a>


  -To let your connector send pings to a remote connector, and print its replies.

      python3 -m aioconnectors ping <config_json_path>

  -To simulate a simple application waiting for messages, and print all received messages. Your application should not wait for incoming messages when using this testing tool.

      python3 -m aioconnectors test_receive_messages <config_json_path>

  -To simulate a simple application sending dummy messages.

      python3 -m aioconnectors test_send_messages <config_json_path>


  <a name="chat"></a>


  A simple chat using aioconnectors is embedded. It allows you to exchange messages, files and directories easily between 2 Linux or Mac stations. It can also be configured to execute the commands it receives.
  It is encrypted, and supports authentication by prompting to accept connections.
  It is not a multi user chat, but more of a tool to easily transfer stuff between your computers.

  -On the 1st station (server side), type :

      python3 -m aioconnectors chat

  -Then on the 2nd station (client side), type :

      python3 -m aioconnectors chat --target <server_ip>

  You can execute local shell commands by preceding them with a \"\!\".
  You can also upload files during a chat, by typing \"\!upload \<file or dir path\>\".
  Files are uploaded to your current working directory. A directory is transferred as a zip file.
  You can simply unzip a zip file by using \"\!dezip \<file name\>\".

  The cleanest way to exit a chat is by typing \"\!exit\" on both sides.

  -On client side, you can also directly upload a file or directory to the server without opening a chat :

       python3 -m aioconnectors chat --target <server_ip> --upload <file or dir path>

  -You can configure client or server (not simultaneously) to execute the commands it receives, by using the --exec <shell_path> option :

      python3 -m aioconnectors chat --exec /bin/sh
      python3 -m aioconnectors chat --target <server_ip>
      or
      python3 -m aioconnectors chat
      python3 -m aioconnectors chat --target <server_ip>  --exec /bin/sh

  -On server side, you can accept client connections without prompting by specifying --accept :

      python3 -m aioconnectors chat --accept

  -More info :

      python3 -m aioconnectors chat --help

  -If you need your server to listen on a specific interface :

      python3 -m aioconnectors chat --bind_server_ip <server_ip>

  <server\_ip> can be an ip address, or an interface name

  -If you don't want your server to use the default port (10673), use --port on both peers :

      python3 -m aioconnectors chat --port <port> [--target <server_ip>]

  -By default the chat has tab completion, you can disable it with --nowrap.


  <a name="containers"></a>


  Connector client and server, as well as connector api, can run in a Docker container, you just need to pip install aioconnectors in a Python image (or any image having Python >= 3.6 and openssl).
  A connector and its connector api must run on the same host, or in the same Kubernetes pod.
  A connector and its connector api can run in the same container, or in different containers. In case you choose to run them in different containers, you must configure their connector_files_dirpath path as a shared volume, in order to let them share their UDS sockets.


  <a name="windows"></a>


  To port aioconnectors to Windows, these steps should be taken, and probably more :
  -Replace usage of unix sockets by maybe : local sockets, or named pipes, or uds sockets if and when they are supported.
  Since the implementation relies on unix sockets paths, a possible approach would be to preserve these paths, and manage a mapping between the paths and their corresponding local listening ports.
  -Port the usage of openssl in ssl_helper.py
  -Convert paths
  -Ignore the file uploaded ownership feature
  -Convert the interface to ipaddress function using ip (used for sockaddr and client\_bind\_ip)


pkgId: 73a7c433e6c5d5c0709aff2d29ec66825e2be482589e4e88ad4164ee12a3cb93
name: python-aioconsole
arch: src
version: 0.8.0
epoch: 0
release: 1
summary: Asynchronous console and interfaces for asyncio
url: https://github.com/vxgmichel/aioconsole
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-aioconsole-0.8.0-1.src.rpm
checksum_type: sha256
description:
  |docs-badge| |cov-badge| |ci-badge| |version-badge| |pyversion-badge|
  Asynchronous console and interfaces for asyncio
  aioconsole_ provides:
  * asynchronous equivalents to `input`_, `print`_, `exec`_ and `code.interact`_
  * an interactive loop running the asynchronous python console
  * a way to customize and run command line interface using `argparse`_
  * `stream`_ support to serve interfaces instead of using standard streams
  * the ``apython`` script to access asyncio code at runtime without modifying the sources

rpm_license:
  GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007  Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.  Preamble  The GNU General Public License is a free, copyleft license for software and other kinds of works.  The licenses for most software and other practical works are designed to take away your freedom to share and change the works.  By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users.  We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors.  You can apply it to your programs, too.  When we speak of free software, we are referring to freedom, not price.  Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.  To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights.  Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.  For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received.  You must make sure that they, too, receive or can get the source code.  And you must show them these terms so they know their rights.  Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.  For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software.  For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.  Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so.  This is fundamentally incompatible with the aim of protecting users' freedom to change the software.  The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable.  Therefore, we have designed this version of the GPL to prohibit the practice for those products.  If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.  Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary.  To prevent this, the GPL assures that patents cannot be used to render the program non-free.  The precise terms and conditions for copying, distribution and modification follow.  TERMS AND CONDITIONS  0. Definitions.  "This License" refers to version 3 of the GNU General Public License.  "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.  "The Program" refers to any copyrightable work licensed under this License.  Each licensee is addressed as "you".  "Licensees" and "recipients" may be individuals or organizations.  To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy.  The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work.  A "covered work" means either the unmodified Program or a work based on the Program.  To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy.  Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.  To "convey" a work means any kind of propagation that enables other parties to make or receive copies.  Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.  An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License.  If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.  1. Source Code.  The "source code" for a work means the preferred form of the work for making modifications to it.  "Object code" means any non-source form of a work.  A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.  The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form.  A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.  The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities.  However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work.  For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.  The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.  The Corresponding Source for a work in source code form is that same work.  2. Basic Permissions.  All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met.  This License explicitly affirms your unlimited permission to run the unmodified Program.  The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work.  This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.  You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force.  You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright.  Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.  Conveying under any other circumstances is permitted solely under the conditions stated below.  Sublicensing is not allowed; section 10 makes it unnecessary.  3. Protecting Users' Legal Rights From Anti-Circumvention Law.  No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.  When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.  4. Conveying Verbatim Copies.  You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.  You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.  5. Conveying Modified Source Versions.  You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:  a) The work must carry prominent notices stating that you modified it, and giving a relevant date.  b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7.  This requirement modifies the requirement in section 4 to "keep intact all notices".  c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy.  This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged.  This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.  d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.  A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit.  Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.  6. Conveying Non-Source Forms.  You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:  a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.  b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.  c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source.  This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.  d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge.  You need not require recipients to copy the Corresponding Source along with the object code.  If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source.  Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.  e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.  A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.  A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling.  In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage.  For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product.  A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.  "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source.  The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.  If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information.  But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).  The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed.  Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.  Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.  7. Additional Terms.  "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law.  If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.  When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it.  (Additional permissions may be written to require their own removal in certain cases when you modify the work.)  You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.  Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:  a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or  b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or  c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or  d) Limiting the use for publicity purposes of names of licensors or authors of the material; or  e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or  f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.  All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10.  If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term.  If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.  If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.  Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.  8. Termination.  You may not propagate or modify a covered work except as expressly provided under this License.  Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).  However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.  Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.  Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License.  If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.  9. Acceptance Not Required for Having Copies.  You are not required to accept this License in order to receive or run a copy of the Program.  Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance.  However, nothing other than this License grants you permission to propagate or modify any covered work.  These actions infringe copyright if you do not accept this License.  Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.  10. Automatic Licensing of Downstream Recipients.  Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License.  You are not responsible for enforcing compliance by third parties with this License.  An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations.  If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.  You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License.  For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.  11. Patents.  A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based.  The work thus licensed is called the contributor's "contributor version".  A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version.  For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.  Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.  In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement).  To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.  If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients.  "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.  If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.  A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License.  You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.  Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.  12. No Surrender of Others' Freedom.  If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License.  If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all.  For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.  13. Use with the GNU Affero General Public License.  Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work.  The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.  14. Revised Versions of this License.  The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time.  Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.  Each version is given a distinguishing version number.  If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation.  If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.  If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.  Later license versions may give you additional or different permissions.  However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.  15. Disclaimer of Warranty.  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.  16. Limitation of Liability.  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.  17. Interpretation of Sections 15 and 16.  If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.  END OF TERMS AND CONDITIONS  How to Apply These Terms to Your New Programs  If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.  To do so, attach the following notices to the program.  It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.  {one line to give the program's name and a brief idea of what it does.} Copyright (C) {year}  {name of author}  This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.  This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.  You should have received a copy of the GNU General Public License along with this program.  If not, see <http://www.gnu.org/licenses/>.  Also add information on how to contact you by electronic and paper mail.  If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode:  {project}  Copyright (C) {year}  {fullname} This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details.  The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License.  Of course, your program's commands might be different; for a GUI interface, you would use an "about box".  You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see <http://www.gnu.org/licenses/>.  The GNU General Public License does not permit incorporating your program into proprietary programs.  If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library.  If this is what you want to do, use the GNU Lesser General Public License instead of this License.  But first, please read <http://www.gnu.org/philosophy/why-not-lgpl.html>.


