# packages

pkgId: 2fa39ea89a7565d610b5bd32813c8dec1695a149abada19e91211a7968363e16
name: python-crawlera-session
arch: src
version: 1.2.8
epoch: 0
release: 1
url: https://github.com/kalessin/crawlera-sessions
rpm_license: BSD
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crawlera-session-1.2.8-1.src.rpm
checksum_type: sha256
summary:
  Class that provides decorators and functions for easy handling of crawlera sessions in a scrapy spider.

description:
  Class that provides decorators and functions for easy handling of crawlera sessions in a scrapy spider.



  pip install crawlera-session



  Ensure `COOKIES_ENABLED` is set to True (otherwise there is no point in using this class)
  Subclass your spider from `CrawleraSessionMixinSpider`.

  Provided decorator must be applied for every callback that yields requests that
  must conserve session. For starting requests, use `init_start_request`. This decorator will
  instruct requests provided by start requests, to initiate each one a new session.

  The callback that yields requests that must follow the session initiated previously within same
  requests chain must be decorated with `follow_session`.

  Example:

  ```python
  from crawlera_session import CrawleraSessionMixinSpider, RequestSession

  crawlera_session = RequestSession()


  class MySpider(CrawleraSessionMixinSpider, Spider):

      @crawlera_session.init_start_requests
      def start_requests(self):
          ...
          yield Request(...)


      @crawlera_session.follow_session
      def parse(self, response):
          ...
          yield Request(...)
  ```

  Some times you need to initialize a session for a single request generated in a spider method. In that case,
  you can use `init_request()` method:

  ```python
      def parse(self, response):
          ...
          
          yield Request(...)
          ...
          
          yield crawlera_session.init_request(Request(...))
  ```

  Alternatively, and probably more elegant with better code separation, you could do:


  ```python
      def parse(self, response):
          ...
          
          yield Request(...)

          
          yield from self.generate_init_requests(response)

      @crawlera_session.init_requests
      def generate_init_requests(self, response):
          ...
          yield Request(...)
  ```

  The decorator `init_requests` (don't confuse with `init_request()` method just described) is similar to `init_start_request`
  but decorates a callback instead of `start_requests()`.

  If on the contrary, you want to send a normal (not session) request from a callback that was decorated with `follow_session`,
  you can use the `no_crawlera_session` meta tag:

  ```python
      @crawlera_session.follow_session
      def parse(self, response):
          ...
          
          yield Request(...)
          ...
          
          yield Request(..., meta={'no_crawlera_session': True})
  ```

  or, alternatively:

  ```python

      def parse(self, response):
          
          yield from generate_session_reqs(response)
          ...
          
          yield Request(...)

      @crawlera_session.follow_session
      def generate_session_reqs(self, response)
          ...
          yield Request(...)

  ```


  In short, the logic `init_request->follow_session` makes a chain of requests to use the same session. So requests issued by callbacks
  decorated by `follow_session` reuse the session created by the request which initiated it, in the same request chain as defined
  by the spider logic.

  However, there are use cases where you want to reuse a session initiated in another chain, instead of initiating a new one.
  For that purpose, you can defer the session assignation of the requests until a previously created session is available for reusage
  (when the chain that created it is completed). There are two other decorators that implements this logic: `defer_assign_session` and
  `unlock_session`. Their logic must be used in combination of spider attribute `MAX_PARALLEL_SESSIONS`.

  `defer_assign_session` makes requests yielded by the decorated callback:
  * either to initiate a new request if number of initiated sessions is below `MAX_PARALLEL_SESSIONS` or `MAX_PARALLEL_SESSIONS` is None.
  * or wait for an available session for reusage in other case.

  In order to indicate the end of a request chain for unlocking its session for reusage, the last callback of the chain must be
  decorated with `unlock_session`.

  Example:

  ```python
  from crawlera_session import CrawleraSessionMixinSpider, RequestSession

  crawlera_session = RequestSession()


  class MySpider(CrawleraSessionMixinSpider, Spider):

      MAX_PARALLEL_SESSIONS = 4

      def start_requests(self):
          ...
          yield Request(...)

      @crawlera_session.defer_assign_session
      def parse(self, response):
          ...
          yield Request(..., callback=callback2)

      @crawlera_session.follow_session
      def callback2(self, response):
          yield Request(..., callback=callback3)

      ...

      @crawlera_session.unlock_session
      def callbackN(self, response):
          yield Item(...)

  ```


  It is important to consider that isage of `unlock_session` is not mandatory, as it is not always possible to determine whether a session
  can be unlocked. For example, consider the case where you need to extract multiple items from a search, and you can't unlock the session
  until the last request is handled. In this case you don't know which will be the last request, so you don't have a callback where to apply
  `unlock_session` decorator. In this situation, locked sessions will be automatically unlocked only when no more requests are pending in the
  scheduler. But notice that this is a suboptimal approach, as many locked sessions should be really available, but not used because
  we cannot know when they are really available until scheduler is idle. (There is a circumvented way to know in advance if
  there is some request in process belonging to a given session, by scanning all scrapy scheduler and downloader queues, a TODO is to check
  viability of this approach, For now it has not been implemented for simplicity.)

  For better performance, normally it is better to set the number of concurrent requests to the same or more than as `MAX_PARALLEL_SESSIONS`. If
  you are combining crawlera session requests with no crawlera session requests, concurrent requests need to be bigger than `MAX_PARALLEL_SESSIONS`.
  Otherwise they can be equal. If smaller, session handling will be suboptimal in terms of speed. If too much bigger, many requests may be retained on memory
  and its use may increase significantly, so handling may be suboptimal in terms of memory usage.

  Notice that if you don't set `MAX_PARALLEL_SESSIONS`, the behavior of the callback decorated by `defer_assign_session` will
  be that all requests yielded by it will initiate a new session. So the lock/unlock logic doesn't have much sense.
  In this case, you can just use `init_requests` decorator:


  ```python
  from crawlera_session import CrawleraSessionMixinSpider, RequestSession

  crawlera_session = RequestSession()


  class MySpider(CrawleraSessionMixinSpider, Spider):

      MAX_PARALLEL_SESSIONS = 4

      def start_requests(self):
          ...
          yield Request(...)

      @crawlera_session.init_requests
      def parse(self, response):
          ...
          yield Request(..., callback=callback2)

      @crawlera_session.follow_session
      def callback2(self, response):
          yield Request(..., callback=callback3)

      ...

      @crawlera_session.discard_session
      def callbackN(self, response):
          yield Item(...)

  ```


  Notice that in the last callback we replaced the decorator `unlock_session` by `discard_session`. This decorator is optional, but in
  case your spider generates large amounts of requests, the memory usage can increase significantly if you don't drop unused sessions.
  Regardless you need to use it or not for saving memory, it is still a good practice when you can apply it (in situations where there
  are multiple final chain requests, it is not possible to drop a session when reaching any one of them).

  By default, retrying a request uses the same session. However, frequently you need to reinitialize a session instead. The `RequestSession()`
  object provides a decorator for indicating special retry treatment on specific requests. For example, if the requests yielded by `callback3()`
  in the example above need to reinitialize session starting from the first request in the chain, you would write something like this:

  ```python

  class MySpider(CrawleraSessionMixinSpider, Spider):

      (...)

      @crawlera_session.init_requests
      def parse(self, response):
          ...
          yield Request(..., callback=callback2)


      (...)

      @crawlera_session.new_session_on_retry
      @crawlera_session.follow_session
      def callback3(self, response):
          yield Request(..., callback=self.callback4)

      (...)

      def callback4_errback(self, failure) -> Request:
          return Request(..., callback=callback2)

  ```

  Notice the introduction of a new decorator, `new_session_on_retry`, and the definition (in this case) of `callback4_errback()` method:

  - Every response yielded by a callback decorated by  `new_session_on_retry`, will be assigned an errback with the same name as its
    callback, but with the `_errback` suffix appended.
  - If this method is not implemented in the spider, an assertion error will be raised.
  - Request returned by `callback_errback()` will be instructed internaly to initialize a new session, and the same errback will be
    assigned to it for further retries. So you don't need explicit action for it.

  By default, the number of session retries for a given request will be 3. This default value can be overriden in the `RequestSession()`
  object initialization, i.e.:

  ```python
  crawlera_session = RequestSession(new_session_retries=5)
  ```

  Finally, if you want to adjust priority on each successive request of a chain of requests, the `RequestSession()` instantiator admits
  the parameter `priority_adjust`. For example, if you want to ensure that requests more advanced in the chain are sent before new
  initial chain requests when you have multiple of them, you would rather use:

  ```python
  crawlera_session = RequestSession(priority_adjust=1)
  ```


pkgId: 42ae66184366ef7ec40b9fd880c920166974fe103ebb8571f62d40c4e08f59cf
name: python-crawlerdetect
arch: src
version: 0.1.7
epoch: 0
release: 1
summary: CrawlerDetect is a Python class for detecting bots/crawlers/spiders via the user agent.
url: https://github.com/moskrc/CrawlerDetect
rpm_license: BSD
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crawlerdetect-0.1.7-1.src.rpm
checksum_type: sha256
description:
  This is a Python wrapper for [CrawlerDetect](https://github.com/JayBizzle/Crawler-Detect) - the web crawler detection library
  It helps to detect  bots/crawlers/spiders via the user agent and other HTTP-headers. Currently able to detect > 1,000's of bots/spiders/crawlers.


  Run `pip install crawlerdetect`




  ```Python
  from crawlerdetect import CrawlerDetect
  crawler_detect = CrawlerDetect()
  crawler_detect.isCrawler('Mozilla/5.0 (compatible; Sosospider/2.0; +http://help.soso.com/webspider.htm)')

  ```


  ```Python
  from crawlerdetect import CrawlerDetect
  crawler_detect = CrawlerDetect(user_agent='Mozilla/5.0 (iPhone; CPU iPhone OS 7_1 like Mac OS X) AppleWebKit (KHTML, like Gecko) Mobile (compatible; Yahoo Ad monitoring; https://help.yahoo.com/kb/yahoo-ad-monitoring-SLN24857.html)')
  crawler_detect.isCrawler()

  ```


  ```Python
  from crawlerdetect import CrawlerDetect
  crawler_detect = CrawlerDetect(headers={'DOCUMENT_ROOT': '/home/test/public_html', 'GATEWAY_INTERFACE': 'CGI/1.1', 'HTTP_ACCEPT': '*/*', 'HTTP_ACCEPT_ENCODING': 'gzip, deflate', 'HTTP_CACHE_CONTROL': 'no-cache', 'HTTP_CONNECTION': 'Keep-Alive', 'HTTP_FROM': 'googlebot(at)googlebot.com', 'HTTP_HOST': 'www.test.com', 'HTTP_PRAGMA': 'no-cache', 'HTTP_USER_AGENT': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.71 Safari/537.36', 'PATH': '/bin:/usr/bin', 'QUERY_STRING': 'order=closingDate', 'REDIRECT_STATUS': '200', 'REMOTE_ADDR': '127.0.0.1', 'REMOTE_PORT': '3360', 'REQUEST_METHOD': 'GET', 'REQUEST_URI': '/?test=testing', 'SCRIPT_FILENAME': '/home/test/public_html/index.php', 'SCRIPT_NAME': '/index.php', 'SERVER_ADDR': '127.0.0.1', 'SERVER_ADMIN': 'webmaster@test.com', 'SERVER_NAME': 'www.test.com', 'SERVER_PORT': '80', 'SERVER_PROTOCOL': 'HTTP/1.1', 'SERVER_SIGNATURE': '', 'SERVER_SOFTWARE': 'Apache', 'UNIQUE_ID': 'Vx6MENRxerBUSDEQgFLAAAAAS', 'PHP_SELF': '/index.php', 'REQUEST_TIME_FLOAT': 1461619728.0705, 'REQUEST_TIME': 1461619728})
  crawler_detect.isCrawler()

  ```

  ```Python
  from crawlerdetect import CrawlerDetect
  crawler_detect = CrawlerDetect()
  crawler_detect.isCrawler('Mozilla/5.0 (compatible; Sosospider/2.0; +http://help.soso.com/webspider.htm)')

  crawler_detect.getMatches()

  ```


  If you find a bot/spider/crawler user agent that CrawlerDetect fails to detect, please submit a pull request with the regex pattern added to the array in `providers/crawlers.py` and add the failing user agent to `tests/crawlers.txt`.

  Failing that, just create an issue with the user agent you have found, and we'll take it from there :)


  To use this library with NodeJS or any ES6 application based, check out [es6-crawler-detect](https://github.com/JefferyHus/es6-crawler-detect).


  To use this library in a .net standard (including .net core) based project, check out [NetCrawlerDetect](https://github.com/gplumb/NetCrawlerDetect).


  To use this library with the Nette framework, checkout [NetteCrawlerDetect](https://github.com/JanGalek/Crawler-Detect).



  To use this library with Ruby on Rails or any Ruby-based application, check out [crawler_detect](https://github.com/loadkpi/crawler_detect) gem.

  _Parts of this class are based on the brilliant [MobileDetect](https://github.com/serbanghita/Mobile-Detect)_

  [![Analytics](https://ga-beacon.appspot.com/UA-72430465-1/Crawler-Detect/readme?pixel)](https://github.com/JayBizzle/Crawler-Detect)


pkgId: c9b75a91e1a387de4c7e5e577ce0077fcacdbd6154c83aed50ec8175652233ff
name: python-crawlerdetect
arch: src
version: 0.2.4
epoch: 0
release: 1
url: https://github.com/moskrc/crawlerdetect
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crawlerdetect-0.2.4-1.src.rpm
checksum_type: sha256
summary:
  CrawlerDetect is a Python library designed to identify bots, crawlers, and spiders by analyzing their user agents.

description:
  This is a Python wrapper for [CrawlerDetect](https://github.com/JayBizzle/Crawler-Detect) - the web crawler detection library
  It helps to detect bots/crawlers/spiders via the user agent and other HTTP-headers. Currently able to detect > 1,000's of bots/spiders/crawlers.


  Run `pip install crawlerdetect`




  ```Python
  from crawlerdetect import CrawlerDetect
  crawler_detect = CrawlerDetect()
  crawler_detect.isCrawler('Mozilla/5.0 (compatible; Sosospider/2.0; +http://help.soso.com/webspider.htm)')

  ```


  ```Python
  from crawlerdetect import CrawlerDetect
  crawler_detect = CrawlerDetect(user_agent='Mozilla/5.0 (iPhone; CPU iPhone OS 7_1 like Mac OS X) AppleWebKit (KHTML, like Gecko) Mobile (compatible; Yahoo Ad monitoring; https://help.yahoo.com/kb/yahoo-ad-monitoring-SLN24857.html)')
  crawler_detect.isCrawler()

  ```


  ```Python
  from crawlerdetect import CrawlerDetect
  crawler_detect = CrawlerDetect(headers={'DOCUMENT_ROOT': '/home/test/public_html', 'GATEWAY_INTERFACE': 'CGI/1.1', 'HTTP_ACCEPT': '*/*', 'HTTP_ACCEPT_ENCODING': 'gzip, deflate', 'HTTP_CACHE_CONTROL': 'no-cache', 'HTTP_CONNECTION': 'Keep-Alive', 'HTTP_FROM': 'googlebot(at)googlebot.com', 'HTTP_HOST': 'www.test.com', 'HTTP_PRAGMA': 'no-cache', 'HTTP_USER_AGENT': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.71 Safari/537.36', 'PATH': '/bin:/usr/bin', 'QUERY_STRING': 'order=closingDate', 'REDIRECT_STATUS': '200', 'REMOTE_ADDR': '127.0.0.1', 'REMOTE_PORT': '3360', 'REQUEST_METHOD': 'GET', 'REQUEST_URI': '/?test=testing', 'SCRIPT_FILENAME': '/home/test/public_html/index.php', 'SCRIPT_NAME': '/index.php', 'SERVER_ADDR': '127.0.0.1', 'SERVER_ADMIN': 'webmaster@test.com', 'SERVER_NAME': 'www.test.com', 'SERVER_PORT': '80', 'SERVER_PROTOCOL': 'HTTP/1.1', 'SERVER_SIGNATURE': '', 'SERVER_SOFTWARE': 'Apache', 'UNIQUE_ID': 'Vx6MENRxerBUSDEQgFLAAAAAS', 'PHP_SELF': '/index.php', 'REQUEST_TIME_FLOAT': 1461619728.0705, 'REQUEST_TIME': 1461619728})
  crawler_detect.isCrawler()

  ```

  ```Python
  from crawlerdetect import CrawlerDetect
  crawler_detect = CrawlerDetect()
  crawler_detect.isCrawler('Mozilla/5.0 (compatible; Sosospider/2.0; +http://help.soso.com/webspider.htm)')

  crawler_detect.getMatches()

  ```


  ```Python
  import crawlerdetect
  crawlerdetect.__version__
  ```



  The patterns and testcases are synced from the PHP repo. If you find a bot/spider/crawler user agent that crawlerdetect fails to detect, please submit a pull request with the regex pattern and a testcase to the [upstream PHP repo](https://github.com/JayBizzle/Crawler-Detect).


  To use this library with NodeJS or any ES6 application based, check out [es6-crawler-detect](https://github.com/JefferyHus/es6-crawler-detect).


  To use this library in a .net standard (including .net core) based project, check out [NetCrawlerDetect](https://github.com/gplumb/NetCrawlerDetect).


  To use this library with the Nette framework, checkout [NetteCrawlerDetect](https://github.com/JanGalek/Crawler-Detect).



  To use this library with Ruby on Rails or any Ruby-based application, check out [crawler_detect](https://github.com/loadkpi/crawler_detect) gem.

  _Parts of this class are based on the brilliant [MobileDetect](https://github.com/serbanghita/Mobile-Detect)_




  ```bash
  poetry install
  ```


  ```bash
  poetry run pytest
  ```


  ```bash
  ./update_data.sh
  ```


  ```bash
  poetry run bump-my-version bump [patch|minor|major]
  ```


pkgId: 10a07560ceba778c34b56f13c5220baf9da38214d0f62d966c7add7dbd94d4d5
name: python-crawlipt
arch: src
version: 0.1.4
epoch: 0
release: 1
summary: The script for selenium in python
url: https://github.com/WwwwwyDev/crawlipt
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crawlipt-0.1.4-1.src.rpm
checksum_type: sha256
description:
  <!-- markdownlint-disable MD033 MD041 -->
  <p align="center">
    <a href="https://github.com/WwwwwyDev/crawlipt"><img src="https://s2.loli.net/2024/05/10/PCcpwynVMmURjBv.png" alt="crawlist" style="width:50%; height:50%" ></a>
  </p>

  <div align="center">



  <!-- prettier-ignore-start -->
  <!-- markdownlint-disable-next-line MD036 -->
  The script for selenium in python
  <!-- prettier-ignore-end -->

  <p align="center">
    <a href="https://pypi.python.org/pypi/crawlipt">
      <img src="https://img.shields.io/pypi/v/crawlipt" alt="pypi">
    </a>
    <img src="https://img.shields.io/badge/python-3.10.0+-blue" alt="python">
    <a href="https://github.com/WwwwwyDev/crawlipt/stargazers"><img src="https://img.shields.io/github/stars/WwwwwyDev/crawlipt" alt="GitHub stars"style="max-width: 100%;">
    </a>
    <br/>
  </p>
  </div>




  You can use crawlipt to driver the selenium by script in python.The script adopts JSON format for better cross language operations and physical storage.


  You can use pip or pip3 to install the crawlipt

  `pip install crawlipt` or `pip3 install crawlipt`

  If you have already installed crawlipt, you may need to update to the latest version

  `pip install --upgrade crawlipt`


  ```python
  from webdriver_manager.chrome import ChromeDriverManager
  from selenium import webdriver as wd
  from selenium.webdriver.chrome.service import Service
  import crawlipt as cpt
  option = wd.ChromeOptions()
  option.add_argument("start-maximized")
  option.add_argument("window-size=1920x3000")
  agent = 'user-agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"'
  option.add_argument(agent)
  webdriver = wd.Chrome(service=Service(ChromeDriverManager().install()), options=option)



  script = {
      "method": "redirect",
      "url": "https://www.baidu.com/",
      "next": {
          "method": "input",
          "xpath": "//*[@id=\"kw\"]",
          "keyword": "和泉雾纱",
          "next": {
              "method": "click",
              "xpath": "//*[@id=\"su\"]"
          }
      }
  }

  cpt.Script(script, interval=2)(webdriver)

  ```



  If you are interested and would like to see more detailed documentation, please click on the link below.

  [中文](https://wwydev.gitbook.io/crawlipt-zh "中文文档")|[English](https://wwydev.gitbook.io/crawlipt "English Document")


  Please submit pull requests to the develop branch


pkgId: c77ded9b90370fc38d6242ba5ca0ddd653d5c2bcc6e155751c489c37f2c7722d
name: python-crayons
arch: src
version: 0.4.0
epoch: 0
release: 1
summary: TextUI colors for Python.
url: https://github.com/MasterOdin/crayons
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crayons-0.4.0-1.src.rpm
checksum_type: sha256
description:
  This module is really simple, it gives you colored strings for terminal
  usage. Included colors are ``red``, ``green``, ``yellow``, ``blue``, ``black``, ``magenta``, ``cyan``, ``white``, and
  ``normal`` (as well as ``clean`` and ``disable``).
  **Crayons** is nice because it automatically wraps a given string in both the foreground color, as well as returning to the
  original state after the string is complete. Most terminal color libraries make you manage this yourself.
  Arguments include ``always=True`` and ``bold=True``.


pkgId: 277d585c9965157d2924a009a6e264510c93f00f75d3be7d2a7aa9962541d485
name: python-crazy-thursday
arch: src
version: 2024.11.11.1
epoch: 0
release: 1
summary: a cli tool to print crazy thursday article
url: https://github.com/zqmillet/sphinx-console
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crazy-thursday-2024.11.11.1-1.src.rpm
checksum_type: sha256
description:
  [![](https://img.shields.io/badge/sponsored%20by-Crazy--Thursday-brightgreen?logo=KFC)](https://www.kfchk.com/index.html)
  [![](https://img.shields.io/badge/powered%20by-Github%20Actions-brightgreen?logo=Github)](https://docs.github.com/actions)
  [![](https://img.shields.io/pypi/v/crazy-thursday?logo=PyPI)](https://pypi.org/project/crazy-thursday/)
  [![](https://github.com/zqmillet/crazy-thursday/actions/workflows/update_curpus.yaml/badge.svg)](https://github.com/zqmillet/crazy-thursday/actions)

  大家好, 我是秦始皇, 其实我并没有死, 我在西安有 100000 吨黄金, 今天肯德基疯狂星期四, 谁可以 V 我 50 元, 我明天直接带部队复活, 让你统领三军!



  ``` bash
  pip3 install crazy-thursday
  ```

  或者
  ```
  python3 -m pip install crazy-thursday
  ```

  ![](./static/install.svg)



  如果成功安装, 系统中便会存在一个名为 `crazy-thursday` 和一个名为 `kfc` 的命令. 直接调用 `crazy-thursday` 或 `kfc` 便会在控制台中随机地输出一段疯狂星期四文案.

  ![](./static/kfc.svg)



  你不需要贡献代码, 只需要[创建 issue](https://github.com/zqmillet/crazy-thursday/issues/new?assignees=&labels=add+article&template=add-article.yaml&title=thanks+for+taking+the+time+to+contribute+article+about+crazy-thursday.), 并且留下文案即可.

  后台有一个定时任务, 定时收集本项目的所有 issue, 并汇总打包成 `.whl` 文件, 发布到 [PyPI](https://pypi.org/project/crazy-thursday/) 上.



  本项目采用 4 位版本号, 其格式为 `<year>.<month>.<day>.<build>`, 其中:

  - `<year>` 为发布时间中的年份.
  - `<month>` 为发布时间中的月份.
  - `<day>` 为发布时间中的日期.
  - `<build>` 为发布当天构建序号, 从 `0` 开始.

  比如版本 `1926.8.16.3` 含义为该版本是 1926 年 8 月 16 日构建的第 4 个版本.



  本项利用 Github Actions 每天自动发布版本, 其工作原理如下图所示.

  ```mermaid
  %{init: {"theme": "base", "themeVariables": {"primaryColor": "#FFFFFF", "primaryBorderColor": "#000000"}}}%

  graph TD
      A("☁️ https://github.com/zqmillet/crazy-thursday") -->|collect issues| B("📄 crazy_thursday/corpus.jsonl")
      B -->|update version| C("📄 crazy_thursday/__init__.py")
      C --> |commit & push| D("☁️ https://github.com/zqmillet/crazy-thursday")
      D --> |build| E("📦 dist/crazy_thursday-*.whl")
      E --> |publish| F("🌐 https://pypi.org/project/crazy-thursday")
  ```

  定时任务的工作流程为:

  - 首先 clone 项目, 配置 Python, 安装依赖.
  - 执行 `scripts/update_curpus.py` 脚本, 自动抓去本项目的所有 issue 并保存到 `crazy_thursday/corpus.jsonl` 文件中.
  - 更新 `crazy_thursday/__init__.py` 文件中的版本号.
  - 提交 commit 并且 push 回代码仓.
  - 将最新的代码打包成 `.whl` 文件, 并发布到 PyPI 上.

  该定时任务每天会执行两次, 你提交的 issue 会出现在第二天的版本中.


pkgId: 01a5a57f5f1fbf926b7e7a3c208f22a895a1f2352a7e782bf92f2635ffab9796
name: python-crc-bonfire
arch: src
version: 5.11.0
epoch: 0
release: 1
summary: A CLI tool used to deploy ephemeral environments for testing cloud.redhat.com applications
url: https://www.github.com/RedHatInsights/bonfire
rpm_license: MIT License
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crc-bonfire-5.11.0-1.src.rpm
checksum_type: sha256
description:
  A CLI tool used by Red Hat engineers to deploy console.redhat.com applications into kubernetes/OpenShift. This tool is mainly used for the purpose of creating ephemeral test environments.

  As an example, typing `bonfire deploy host-inventory` leads to the host-inventory application and all its dependencies being deployed and ready to run in under 4 minutes:

  ![Demo gif](demo.gif)




  - [About](#about)
  - [Installation](#installation)
  - [Quick Start](#quick-start)
    - [Deploying](#deploying)
    - [Namespace Management](#namespace-management)
    - [Namespace Context](#namespace-context)
  - [Examples for Common Use Cases](#examples-for-common-use-cases)
  - [Commonly Used CLI Options](#commonly-used-cli-options)
    - [Deploying/Processing](#deployingprocessing)
    - [Trusted/Untrusted Resource Configurations](#trusteduntrusted-resource-configurations)
  - [Interactions with Ephemeral Namespace Operator](#interactions-with-ephemeral-namespace-operator)
  - [Interactions with Clowder Operator](#interactions-with-clowder-operator)
    - [ClowdEnvironments](#clowdenvironments)
    - [Dependency Processing](#dependency-processing)
  - [Configuration Details](#configuration-details)
    - [Using a local config](#using-a-local-config)
    - [Local config examples](#local-config-examples)
      - [Deploying local repo changes](#deploying-local-repo-changes)
      - [Deploying changes changes in a remote git branch](#deploying-changes-changes-in-a-remote-git-branch)
    - [Advanced](#advanced)
      - [Running a local qontract-server](#running-a-local-qontract-server)



  `bonfire` interacts with a running instance of [qontract-server](https://github.com/app-sre/qontract-server) (the component that powers the [AppSRE team](https://github.com/app-sre/)'s internal `app-interface` graphql API) to obtain applications' OpenShift templates, process them, and deploy them. A local configuration file can be defined that allows you to override an application config if you wish.

  It also interacts with the [ephemeral namespace operator](https://github.com/RedHatInsights/ephemeral-namespace-operator) to manage the reservation of ephemeral namespaces for testing.

  It has special functionality related to the [Clowder operator](https://github.com/RedHatInsights/clowder) and [Frontend operator](https://github.com/RedHatInsights/frontend-operator/) such as auto-deploying ClowdApp dependencies.

  A wide range of CLI options allow you to customize exactly what combination of components get deployed into a namespace.

  > NOTE: for information related to app-interface configurations, see the internal [ConsoleDot Docs](https://consoledot.pages.redhat.com/)





  We'd recommend setting up a virtual environment for bonfire:

  ```bash
  VENV_DIR=~/bonfire_venv
  mkdir -p $VENV_DIR
  python3 -m venv $VENV_DIR
  . $VENV_DIR/bin/activate
  pip install crc-bonfire
  ```

  To prevent GitHub rate limiting issues when bonfire reaches out to GitHub APIs,
  [create a personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token)
  on your GitHub account which grants bonfire read access to your repos.

  Configure bonfire to use the token with:
  ```
  echo 'GITHUB_TOKEN=<your api token>' >> ~/.config/bonfire/env
  ```

  **Please note**: When using the Github token (classic), it **must have** the `read:project` scope.
  In addition, since some projects may be private, you will need to add the `repo` (full control of private repositories) scope too.
  for the template fetching to work!



  We provide a container image at quay.io/cloudservices/bonfire. The image wraps a Python virtual environment with **crc-bonfire** installed on it.

  In order to use Bonfire you have to provide either a valid KUBECONFIG or a URL and a TOKEN to connect to the target OpenShift cluster.

  The container's entrypoint already invokes the **bonfire** CLI with the arguments passed to the container, so you should be able to run any bonfire command you'd typically run, for example:

  ```
  podman run -it --rm quay.io/cloudservices/bonfire version
  ```



  The Bonfire image can use the `OC_LOGIN_SERVER` and `OC_LOGIN_TOKEN` variables to connect to an Openshift cluster.

  ```
  podman run -it --rm -e OC_LOGIN_SERVER=https://api.openshift.example.com:6443 \
      -e OC_LOGIN_TOKEN=some-api-token \
      quay.io/cloudservices/bonfire namespace list
  ```

  You can also make use of the kubeconfig file on your host by mounting it into the container's `$HOME` directory:

  ```
  podman run -it --rm --userns=keep-id:uid=1000,gid=1000 -v ${KUBECONFIG:="$HOME/.kube/config"}:/opt/bonfire/.kube/config:Z \
      quay.io/cloudservices/bonfire namespace list
  ```

  If you desire for the kubeconfig to live in a non-standard location in the container, you can mount the kubeconfig into another path in the container, and set the KUBECONFIG environment variable:

  ```
  podman run -it --rm --userns=keep-id:uid=1000,gid=1000 -v $HOME/.kube/config:/opt/kubeconfig:Z \
      -e KUBECONFIG=/opt/kubeconfig \
      quay.io/cloudservices/bonfire namespace list
  ```



  Start with `bonfire --help` to familiarize yourself with the basic command groups. Don't forget to use the `--help` flag on sub-commmands as well if you are curious to learn more about different CLI commands, options, and arguments.



  The command you are most likely to use is `bonfire deploy`.

  If you are on the Red Hat VPN, `bonfire` will communicate with an internal instance of the App-SRE team's `qontract-server` API. You need to use `oc login` to log in to the ephemeral cluster.

  Once logged in, you should be able to type `bonfire deploy advisor`

  This will cause `bonfire` to do the following:
  1. reserve a namespace
  2. fetch the templates for all components in the 'advisor' app and process them. By default, bonfire will look up the template and commit hash using the 'main'/'master' branch of each component defined in the app. It will look up the git commit hash for this branch and automatically set the `IMAGE_TAG` parameter passed to the templates.
  3. if ClowdApp resources are found, figure out which additional ClowdApps to fetch and process
  4. apply all the processed template resources into your reserved namespace
  5. wait for all the resources to reach a 'ready' state

  Run `bonfire namespace list --mine` and you will see your namespace.

  Switch into that namespace with `oc project <NAMESPACE>`

  Run `oc get clowdapp` in your namespace and you should see several ClowdApps have been deployed.

  If you want to to extend the time you have to work with your namespace, use `bonfire namespace extend <NAMESPACE>`

  When you are done working with your namespace, type `bonfire namespace release <NAMESPACE>` to instruct the ephemeral namespace operator to delete your reservation.

  The deploy command is an 'all-in-one' command that ties together 4 steps:
  1. `bonfire namespace reserve` to reserve a namespace
  2. `bonfire process` to fetch and process app templates
  3. `oc apply` to apply the processed app templates into the namespace
  4. `bonfire namespace wait-on-resources <NAMESPACE>` to wait on all resources in the namespace to reach 'ready' state



  * Reserve a namespace with: `bonfire namespace reserve`
      * By default, the duration is 1 hour. Increase it with `-d/--duration <time>` -- example time format: `48h`
      * Different namespace pools are set up to provide different test environment configurations. Use `--pool <pool>` if you need to select a non-default pool. To get a list of valid pools, use `bonfire pool list`
  * Look up namespaces with: `bonfire namespace list`
      * use `--mine` to see only ones reserved in your name
  * Extend your reservation with: `bonfire namespace extend <NAMESPACE> -d <time>` -- example time format: `48h`
  * Release your namespace reservation with: `bonfire namespace release <NAMESPACE>`



  As of v4.12.0, `bonfire` now analyzes the namespace set in your oc/kubectl context. This means you can run commands such as `namespace extend`, `namespace release`, or `deploy` after you have switched into a namespace using `oc project` and you no longer need to specify the namespace on the CLI. `bonfire` will attempt to use your current namespace (it will run checks to ensure that you own it first and warn if you do not). In addition, when a new namespace is reserved using `bonfire deploy` or `bonfire namespace reserve`, bonfire will also go ahead and run `oc project <NAMESPACE>` for you to switch your context into that new namespace.

  The `deploy` command can be run using the `--reserve` flag if you wish to ignore the current namespace and force a namespace reservation to occur.

  The automatic 'oc' context switching into a newly reserved namespace is disabled when bonfire is operating in "bot" mode (i.e. when the env var `BONFIRE_BOT` is set to `true`). When using bonfire in an automated CI/CD environment such as Jenkins, you should run in bot mode to disable automatic context switching.



  In these examples, we will use the 'advisor' app which has a ClowdApp component named 'advisor-backend'

  * Deploy advisor-backend using a custom git branch:
  ```
  bonfire deploy advisor --set-template-ref advisor-backend=custom_branch
  ```

  * Deploy advisor-backend using a custom git commit:
  ```
  bonfire deploy advisor --set-template-ref advisor-backend=df0d7a620b1ac02e59c5718eb22fe82b8a4cfd3d
  ```

  * Use a certain branch to process the advisor-backend template, but set a different image tag on the container:
  ```
  bonfire deploy advisor --set-template-ref advisor-backend=some_branch --set-parameter advisor-backend/IMAGE_TAG=some_tag
  ```

  * Deploy the production version of advisor and its dependencies:
  ```
  bonfire deploy advisor --ref-env insights-production
  ```

  * Deploy the production version of everything but use a dev branch for advisor-backend:
  ```
  bonfire deploy advisor --ref-env insights-production --set-template-ref advisor-backend=dev_branch
  ```

  * Adjust the 'REPLICAS' parameter value at deploy time:
  ```
  bonfire deploy advisor --set-parameter advisor-backend/REPLICAS=3
  ```

  * Override the tag for all occurences of a specific container image:
  ```
  bonfire deploy advisor --set-image-tag quay.io/cloudservices/advisor-backend=my_tag
  ```




  * `--frontends=true` -- by default, bonfire will not deploy Frontend resources. Use this flag to enable the deployment of app frontends.
  * `--set-image-tag <image uri>=<tag>` -- use this to change the image tag of a container image that appears in your templates. This does a search/replace for all occurences of `<image uri>` and sets the tag to be `<tag>`
  * `--target-env` -- this changes which deploy target `bonfire` looks up to determine the parameters to apply when processing app templates. By default, the target env is set to `insights-ephemeral`
  * `--ref-env` -- this changes which deploy target `bonfire` looks up to determine the git ref to fetch for your app configuration. For example, using `--ref-env insights-stage` would cause bonfire to deploy the stage git ref of your app and `--ref-env insights-production` would cause bonfire to deploy the production git ref of your app. If a target matching the environment is not found, `bonfire` defaults back to deploying the 'main'/'master' branch.
  * `--set-template-ref <component>=<ref>` -- use this to change the git ref deployed for just a single component.
  * `--set-parameter <component>/<name>=<value>` -- use this to set a parameter value on a specific component's template.
  * `--optional-deps-method <hybrid|all|none>` -- change the way that bonfire processes ClowdApp optional dependencies (see "Dependency Processing" section)
  * `--prefer PARAM_NAME=PARAM_VALUE` -- in cases where bonfire finds more than one deployment target, use this to set the parameter names and values that should be used to select a "preferred" deployment target. This option can be passed in multiple times. `bonfire` will select the target with the highest amount of "preferred parameters" on it. Default is currently set to `ENV_NAME=frontends` to select "stable" frontends in the consoledot environments.



  When templates are processed, bonfire removes all untrusted CPU/Memory requests and limits from ClowdApp/ClowdJob/ClowdJobInvocation objects within OpenShift templates (this is because the default value for `--remove-resources` is `all`). If the resource config is unset in a ClowdApp, Clowder will set the deployments to use default values defined in the “ClowdEnvironment” to take effect.

   The reason for this behavior is because many app templates tend to request far more CPU/memory in their template compared to what they actually need in a test environment.

  You can use the `--no-remove-resources` option to turn this behavior off for certain apps or components but the preferred approach is to audit your CPU/memory configurations and set up a resource configuration that bonfire trusts.

  Once you have audited your container CPU/mem usage in test environments and have determined efficient values that you want to use, you can indicate that bonfire should trust the CPU/Memory requests and limits by adhering to the following requirements:

  1. Any ClowdApp/ClowdJob/ClowdJobInvocation in your template asking for CPU/mem using requests or limits should use a parameter with a name formatted like this:
  * `CPU_REQUEST_<NAME>`
  * `CPU_LIMIT_<NAME>`
  * `MEM_REQUEST_<NAME>` or `MEMORY_REQUEST_<NAME>`
  * `MEM_LIMIT_<NAME>` or `MEMORY_LIMIT_<NAME>`

    Where `<NAME>` can be whatever arbitrary name you'd like to use containing `A-Z`, `0-9,` and `_`. For example, either of these would be valid:
    * `CPU_REQUEST_MQ_CONSUMER`
    * `MEM_LIMIT_API`

    **NOTE:** If you only have a single component in your template, you can omit `_<NAME>` from the parameter names if you desire.

  2. Your deployment configuration for the component must explicitly define values for these parameters. For ephemeral environments normally this will mean that your parameters are defined under the ephemeral deploy target in app-interface.

  If these steps are followed then your resource config is considered "trusted" and bonfire will not remove the requests/limits configurations.


  **NOTE:** a couple things that will change in the future:
  * The "host-inventory" app is trusted by default, but once their configurations are tweaked to be trusted we will remove this
  * Object types such as Deployment/StatefulSet/DaemonSet/etc. are not currently analyzed. In future once teams have audited all container resource configurations, we will begin to have bonfire check for trusted configurations on all object types.




  `bonfire` creates/modifies `NamespaceReservation` resources on the cluster to reserve and release namespaces. The template for the object that bonfire applies into the cluster can be found [here](bonfire/resources/reservation-template.yaml)

  For more information about how the ephemeral namespace operator works, see its documentation [here](https://github.com/RedHatInsights/ephemeral-namespace-operator)





  * `bonfire` expects a Clowder `ClowdEnvironment` resource to be created for a namespace before it can deploy into it. This `ClowdEnvironment` is already created by the ephemeral namespace operator.

  * When `bonfire deploy` is executed for a namespace, it will attempt to find the ClowdEnvironment associated with that namespace and set the `ENV_NAME` parameter accordingly for all templates it processes. All templates that define a `ClowdApp` resource should set the `environment` mapping in their spec using a parameter named `${ENV_NAME}`.



  In a ClowdApp definition, an app listed under `dependencies` is considered an app that MUST be present for your app to function, while an app listed under `optionalDependencies` is considered an app that might be absent, but your app could still come up and function without it.

  When bonfire processes templates, if it finds a ClowdApp, it will do the following:
  * if the ClowdApp has `dependencies`, it will try to look up the config for that ClowdApp in app-interface and also fetch its templates
  * if the ClowdApp has `optionalDependencies`, it will behave differently based on which optional dependencies method is selected:

    * `hybrid` (default): if an app group was explicitly specified on the CLI (example: when running `bonfire deploy app-a` the app group 'app-a' is being explicitly specified) then the `optionalDependencies` will be deployed for it. For any ClowdApp `bonfire` comes across that is not a member of an explicitly specified app group, the `optionalDependencies` will NOT be deployed. As an example:
      * `app-a` has `app-b-clowdapp` listed under `optionalDependencies`
      * `app-b-clowdapp` has `app-c-clowdapp` listed under its `optionalDependencies`
      * You will end up with all components of `app-a` and `app-b-clowdapp` in your namespace. `app-c-clowdapp` would NOT be deployed into the namespace.
    * `all`: `bonfire` will deploy all `optionalDependencies` for all ClowdApps it encounters. It will recursively process dependencies. As an example:
      * `app-a` has `app-b-clowdapp` listed under `optionalDependencies`
      * `app-b-clowdapp` has `app-c-clowdapp` listed under its `optionalDependencies`
      * You will end up with all components of `app-a`, `app-b-clowdapp`, AND `app-c-clowdapp` deployed into the namespace.
    * `none`: `bonfire` will ignore the `optionalDependencies` on all ClowdApps that it encounters



  > NOTE: for information related to app-interface configurations, see the internal [ConsoleDot Docs](https://consoledot.pages.redhat.com/)

  When running `bonfire process`/`bonfire deploy`, by default the app-sre team's internal GraphQL API server is used. `bonfire` will query the GraphQL API and read the application's deploy configuration.

  *NOTE*: You need to be on the internal VPN in order to access the default GraphQL API URL.

  `bonfire` relies on a few key pieces of info to process app configs:

  1. The application name. This is typically the name of the listed in `app.yaml` in `app-interface`
  2. A 'target env' -- the name of the `app-interface` environment that bonfire looks at to determine the parameters to apply when processing app templates. An app's config will only be processed if it has a deploy target set up that is pointing to a namespace in this environment (default: "ephemeral")
  3. A 'ref env' -- the name of the `app-interface` environment that we want to use in order to figure out which git ref of the components to deploy and which `IMAGE_TAG` value to set. By default, none is set which causes bonfire to use the 'main'/'master' git branch for all components.
  4. Any template refs you wish to override (optional)
  5. Any image tags you wish to override (optional)
  6. Any parameters you wish to override (optional)

  By default, if app components use `ClowdApp` resources in their templates, then `bonfire` will dynamically load dependencies (see "Dependency Processing" section)



  `bonfire` ships with a [default config](bonfire/resources/default_config.yaml) that should be enough to get started for most internal Red Hat employees.

  By default, the configuration file will be stored in `~/.config/bonfire/config.yaml`.

  If you wish to override any app configurations, you can edit your local configuration file by typing `bonfire config edit`. You can then define an app under the `apps` key of the config. You can reset the config to default at any time using `bonfire config write-default`.

  As of `bonfire` v5, there are two options for how the local configuration is loaded (controlled by the `--local-config-method` CLI option). Let's say we have an app configured in app-interface like this:

  ```
  resourceTemplates:
  - name: mycomponent1
    path: /deployment.yaml
    url: https://github.com/myorg/myrepo1
    targets:
    - namespace:
        $ref: /services/insights/ephemeral/namespaces/ephemeral-base.yml
      parameters:
        MIN_REPLICAS: 1
  - name: mycomponent2
    path: /deployment.yaml
    url: https://github.com/myorg/myrepo2
    targets:
    - namespace:
        $ref: /services/insights/ephemeral/namespaces/ephemeral-base.yml
      parameters:
        MIN_REPLICAS: 2
        SOME_OTHER_PARAM: some_other_value
  ```

  and the local config file has this entry:

  ```
  apps:
  - name: myapp
    components:
    - name: mycomponent2
      parameters:
        MIN_REPLICAS: 10
  ```

  `bonfire` can override the remote configuration using one of two methods:

  1. `--local-config-method merge` (default). In this mode, the apps config in your local config is merged with the configuration that bonfire fetched remotely. With the above config, only the 'MIN_REPLICAS' parameter of 'mycomponent2' within app 'myapp' will be overridden. The 'SOME_OTHER_PARAM' parameter will still be present, and 'mycomponent1' would be unchanged.

  2. `--local-config-method override`. In this mode, the local app configuration will take precedence over the app's configuration that bonfire fetched remotely. In other words, defining a local app configuration will replace the configuration defined in app-interface for ALL components within that app. So 'mycomponent1' would be completely removed, and 'mycomponent2' would only have the parameters you defined in the local config.





  If you wanted to test out some changes you're making to an app but you have not yet pushed these changes to a git repo, the local config could look similar to:

  ```
  apps:
  - name: my_app
    components:
      - name: service
        host: local
        repo: ~/dev/projects/my-app
        path: /clowdapp.yaml
        parameters:
          SOME_PARAMETER: some_value
  ```

  - Where **host** set `local` indicates to look for the repo in a local directory
  - Where **repo** indicates the path to your git repo folder
  - Where **path** specifies the relative path to your ClowdApp template file in your git repo

  By default, `bonfire` will run `git rev-parse` to determine the current working commit hash in your repo folder, and this determines what IMAGE_TAG to set when the template is deployed. This means you would need to have a valid container image pushed for this commit hash. However, you can use `--set-image-tag`/`--set-parameter` or define the `IMAGE_TAG` parameter in your config in order to override the image you wish to use during the deployment.



  If you wanted to deploy changes to your app that you were working on which have been pushed to a PR/branch, the local config could look similar to:

  ```
  apps:
  - name: my_app
    components:
      - name: service
        host: github
        repo: MyOrg/MyRepo
        ref: my_branch
        path: /clowdapp.yaml
  ```

  - Where **host** set to `github` or `gitlab` indicates where the repo is hosted
  - Where **repo** indicates the `OrganizationName/RepoName`
  - Where **path** specifies the relative path to your ClowdApp template file in your git repo
  - Where **ref** specifies the branch or commit of the repo you want to deploy

  By default, bonfire will use the latest commit hash found at the specified git ref to determine what IMAGE_TAG pass on to the deployment templates.




  bonfire is configured to point to the app-sre team's internal GraphQL API by default, but by using env variables you can point to your your own instance of `qontract-server`:

  ```bash
  export QONTRACT_BASE_URL="https://localhost:4000/graphql"
  export QONTRACT_USERNAME=myUsername
  export QONTRACT_PASSWORD=myPassword
  ```

  For testing/debug purposes, instead of committing changes directly to app-interface, you can run your own local copy of the app-interface API server.

  1. Clone https://github.com/app-sre/qontract-server
  2. Clone the internal `app-interface` repo

  In `qontract-server`, run:
  ```
  npm install yarn
  yarn install
  yarn build
  make bundle APP_INTERFACE_PATH=/path/to/app-interface
  LOAD_METHOD=fs DATAFILES_FILE=bundle/bundle.json yarn run server
  ```


pkgId: 6b3e28aa896845e9e2f8abb297c3fd0dc674e057f21873e57812410c2e71542b
name: python-crc-bonfire
arch: src
version: 5.11.1
epoch: 0
release: 1
summary: A CLI tool used to deploy ephemeral environments for testing cloud.redhat.com applications
url: https://www.github.com/RedHatInsights/bonfire
rpm_license: MIT License
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crc-bonfire-5.11.1-1.src.rpm
checksum_type: sha256
description:
  A CLI tool used by Red Hat engineers to deploy console.redhat.com applications into kubernetes/OpenShift. This tool is mainly used for the purpose of creating ephemeral test environments.

  As an example, typing `bonfire deploy host-inventory` leads to the host-inventory application and all its dependencies being deployed and ready to run in under 4 minutes:

  ![Demo gif](demo.gif)




  - [About](#about)
  - [Installation](#installation)
  - [Quick Start](#quick-start)
    - [Deploying](#deploying)
    - [Namespace Management](#namespace-management)
    - [Namespace Context](#namespace-context)
  - [Examples for Common Use Cases](#examples-for-common-use-cases)
  - [Commonly Used CLI Options](#commonly-used-cli-options)
    - [Deploying/Processing](#deployingprocessing)
    - [Trusted/Untrusted Resource Configurations](#trusteduntrusted-resource-configurations)
  - [Interactions with Ephemeral Namespace Operator](#interactions-with-ephemeral-namespace-operator)
  - [Interactions with Clowder Operator](#interactions-with-clowder-operator)
    - [ClowdEnvironments](#clowdenvironments)
    - [Dependency Processing](#dependency-processing)
  - [Configuration Details](#configuration-details)
    - [Using a local config](#using-a-local-config)
    - [Local config examples](#local-config-examples)
      - [Deploying local repo changes](#deploying-local-repo-changes)
      - [Deploying changes changes in a remote git branch](#deploying-changes-changes-in-a-remote-git-branch)
    - [Advanced](#advanced)
      - [Running a local qontract-server](#running-a-local-qontract-server)



  `bonfire` interacts with a running instance of [qontract-server](https://github.com/app-sre/qontract-server) (the component that powers the [AppSRE team](https://github.com/app-sre/)'s internal `app-interface` graphql API) to obtain applications' OpenShift templates, process them, and deploy them. A local configuration file can be defined that allows you to override an application config if you wish.

  It also interacts with the [ephemeral namespace operator](https://github.com/RedHatInsights/ephemeral-namespace-operator) to manage the reservation of ephemeral namespaces for testing.

  It has special functionality related to the [Clowder operator](https://github.com/RedHatInsights/clowder) and [Frontend operator](https://github.com/RedHatInsights/frontend-operator/) such as auto-deploying ClowdApp dependencies.

  A wide range of CLI options allow you to customize exactly what combination of components get deployed into a namespace.

  > NOTE: for information related to app-interface configurations, see the internal [ConsoleDot Docs](https://consoledot.pages.redhat.com/)





  We'd recommend setting up a virtual environment for bonfire:

  ```bash
  VENV_DIR=~/bonfire_venv
  mkdir -p $VENV_DIR
  python3 -m venv $VENV_DIR
  . $VENV_DIR/bin/activate
  pip install crc-bonfire
  ```

  To prevent GitHub rate limiting issues when bonfire reaches out to GitHub APIs,
  [create a personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token)
  on your GitHub account which grants bonfire read access to your repos.

  Configure bonfire to use the token with:
  ```
  echo 'GITHUB_TOKEN=<your api token>' >> ~/.config/bonfire/env
  ```

  **Please note**: When using the Github token (classic), it **must have** the `read:project` scope.
  In addition, since some projects may be private, you will need to add the `repo` (full control of private repositories) scope too.
  for the template fetching to work!



  ```bash
  brew tap redhatinsights/bonfire
  brew install bonfire
  ```



  We provide a container image at quay.io/cloudservices/bonfire. The image wraps a Python virtual environment with **crc-bonfire** installed on it.

  In order to use Bonfire you have to provide either a valid KUBECONFIG or a URL and a TOKEN to connect to the target OpenShift cluster.

  The container's entrypoint already invokes the **bonfire** CLI with the arguments passed to the container, so you should be able to run any bonfire command you'd typically run, for example:

  ```
  podman run -it --rm quay.io/cloudservices/bonfire version
  ```



  The Bonfire image can use the `OC_LOGIN_SERVER` and `OC_LOGIN_TOKEN` variables to connect to an Openshift cluster.

  ```
  podman run -it --rm -e OC_LOGIN_SERVER=https://api.openshift.example.com:6443 \
      -e OC_LOGIN_TOKEN=some-api-token \
      quay.io/cloudservices/bonfire namespace list
  ```

  You can also make use of the kubeconfig file on your host by mounting it into the container's `$HOME` directory:

  ```
  podman run -it --rm --userns=keep-id:uid=1000,gid=1000 -v ${KUBECONFIG:="$HOME/.kube/config"}:/opt/bonfire/.kube/config:Z \
      quay.io/cloudservices/bonfire namespace list
  ```

  If you desire for the kubeconfig to live in a non-standard location in the container, you can mount the kubeconfig into another path in the container, and set the KUBECONFIG environment variable:

  ```
  podman run -it --rm --userns=keep-id:uid=1000,gid=1000 -v $HOME/.kube/config:/opt/kubeconfig:Z \
      -e KUBECONFIG=/opt/kubeconfig \
      quay.io/cloudservices/bonfire namespace list
  ```



  Start with `bonfire --help` to familiarize yourself with the basic command groups. Don't forget to use the `--help` flag on sub-commmands as well if you are curious to learn more about different CLI commands, options, and arguments.



  The command you are most likely to use is `bonfire deploy`.

  If you are on the Red Hat VPN, `bonfire` will communicate with an internal instance of the App-SRE team's `qontract-server` API. You need to use `oc login` to log in to the ephemeral cluster.

  Once logged in, you should be able to type `bonfire deploy advisor`

  This will cause `bonfire` to do the following:
  1. reserve a namespace
  2. fetch the templates for all components in the 'advisor' app and process them. By default, bonfire will look up the template and commit hash using the 'main'/'master' branch of each component defined in the app. It will look up the git commit hash for this branch and automatically set the `IMAGE_TAG` parameter passed to the templates.
  3. if ClowdApp resources are found, figure out which additional ClowdApps to fetch and process
  4. apply all the processed template resources into your reserved namespace
  5. wait for all the resources to reach a 'ready' state

  Run `bonfire namespace list --mine` and you will see your namespace.

  Switch into that namespace with `oc project <NAMESPACE>`

  Run `oc get clowdapp` in your namespace and you should see several ClowdApps have been deployed.

  If you want to to extend the time you have to work with your namespace, use `bonfire namespace extend <NAMESPACE>`

  When you are done working with your namespace, type `bonfire namespace release <NAMESPACE>` to instruct the ephemeral namespace operator to delete your reservation.

  The deploy command is an 'all-in-one' command that ties together 4 steps:
  1. `bonfire namespace reserve` to reserve a namespace
  2. `bonfire process` to fetch and process app templates
  3. `oc apply` to apply the processed app templates into the namespace
  4. `bonfire namespace wait-on-resources <NAMESPACE>` to wait on all resources in the namespace to reach 'ready' state



  * Reserve a namespace with: `bonfire namespace reserve`
      * By default, the duration is 1 hour. Increase it with `-d/--duration <time>` -- example time format: `48h`
      * Different namespace pools are set up to provide different test environment configurations. Use `--pool <pool>` if you need to select a non-default pool. To get a list of valid pools, use `bonfire pool list`
  * Look up namespaces with: `bonfire namespace list`
      * use `--mine` to see only ones reserved in your name
  * Extend your reservation with: `bonfire namespace extend <NAMESPACE> -d <time>` -- example time format: `48h`
  * Release your namespace reservation with: `bonfire namespace release <NAMESPACE>`



  As of v4.12.0, `bonfire` now analyzes the namespace set in your oc/kubectl context. This means you can run commands such as `namespace extend`, `namespace release`, or `deploy` after you have switched into a namespace using `oc project` and you no longer need to specify the namespace on the CLI. `bonfire` will attempt to use your current namespace (it will run checks to ensure that you own it first and warn if you do not). In addition, when a new namespace is reserved using `bonfire deploy` or `bonfire namespace reserve`, bonfire will also go ahead and run `oc project <NAMESPACE>` for you to switch your context into that new namespace.

  The `deploy` command can be run using the `--reserve` flag if you wish to ignore the current namespace and force a namespace reservation to occur.

  The automatic 'oc' context switching into a newly reserved namespace is disabled when bonfire is operating in "bot" mode (i.e. when the env var `BONFIRE_BOT` is set to `true`). When using bonfire in an automated CI/CD environment such as Jenkins, you should run in bot mode to disable automatic context switching.



  In these examples, we will use the 'advisor' app which has a ClowdApp component named 'advisor-backend'

  * Deploy advisor-backend using a custom git branch:
  ```
  bonfire deploy advisor --set-template-ref advisor-backend=custom_branch
  ```

  * Deploy advisor-backend using a custom git commit:
  ```
  bonfire deploy advisor --set-template-ref advisor-backend=df0d7a620b1ac02e59c5718eb22fe82b8a4cfd3d
  ```

  * Use a certain branch to process the advisor-backend template, but set a different image tag on the container:
  ```
  bonfire deploy advisor --set-template-ref advisor-backend=some_branch --set-parameter advisor-backend/IMAGE_TAG=some_tag
  ```

  * Deploy the production version of advisor and its dependencies:
  ```
  bonfire deploy advisor --ref-env insights-production
  ```

  * Deploy the production version of everything but use a dev branch for advisor-backend:
  ```
  bonfire deploy advisor --ref-env insights-production --set-template-ref advisor-backend=dev_branch
  ```

  * Adjust the 'REPLICAS' parameter value at deploy time:
  ```
  bonfire deploy advisor --set-parameter advisor-backend/REPLICAS=3
  ```

  * Override the tag for all occurences of a specific container image:
  ```
  bonfire deploy advisor --set-image-tag quay.io/cloudservices/advisor-backend=my_tag
  ```




  * `--frontends=true` -- by default, bonfire will not deploy Frontend resources. Use this flag to enable the deployment of app frontends.
  * `--set-image-tag <image uri>=<tag>` -- use this to change the image tag of a container image that appears in your templates. This does a search/replace for all occurences of `<image uri>` and sets the tag to be `<tag>`
  * `--target-env` -- this changes which deploy target `bonfire` looks up to determine the parameters to apply when processing app templates. By default, the target env is set to `insights-ephemeral`
  * `--ref-env` -- this changes which deploy target `bonfire` looks up to determine the git ref to fetch for your app configuration. For example, using `--ref-env insights-stage` would cause bonfire to deploy the stage git ref of your app and `--ref-env insights-production` would cause bonfire to deploy the production git ref of your app. If a target matching the environment is not found, `bonfire` defaults back to deploying the 'main'/'master' branch.
  * `--set-template-ref <component>=<ref>` -- use this to change the git ref deployed for just a single component.
  * `--set-parameter <component>/<name>=<value>` -- use this to set a parameter value on a specific component's template.
  * `--optional-deps-method <hybrid|all|none>` -- change the way that bonfire processes ClowdApp optional dependencies (see "Dependency Processing" section)
  * `--prefer PARAM_NAME=PARAM_VALUE` -- in cases where bonfire finds more than one deployment target, use this to set the parameter names and values that should be used to select a "preferred" deployment target. This option can be passed in multiple times. `bonfire` will select the target with the highest amount of "preferred parameters" on it. Default is currently set to `ENV_NAME=frontends` to select "stable" frontends in the consoledot environments.



  When templates are processed, bonfire removes all untrusted CPU/Memory requests and limits from ClowdApp/ClowdJob/ClowdJobInvocation objects within OpenShift templates (this is because the default value for `--remove-resources` is `all`). If the resource config is unset in a ClowdApp, Clowder will set the deployments to use default values defined in the “ClowdEnvironment” to take effect.

   The reason for this behavior is because many app templates tend to request far more CPU/memory in their template compared to what they actually need in a test environment.

  You can use the `--no-remove-resources` option to turn this behavior off for certain apps or components but the preferred approach is to audit your CPU/memory configurations and set up a resource configuration that bonfire trusts.

  Once you have audited your container CPU/mem usage in test environments and have determined efficient values that you want to use, you can indicate that bonfire should trust the CPU/Memory requests and limits by adhering to the following requirements:

  1. Any ClowdApp/ClowdJob/ClowdJobInvocation in your template asking for CPU/mem using requests or limits should use a parameter with a name formatted like this:
  * `CPU_REQUEST_<NAME>`
  * `CPU_LIMIT_<NAME>`
  * `MEM_REQUEST_<NAME>` or `MEMORY_REQUEST_<NAME>`
  * `MEM_LIMIT_<NAME>` or `MEMORY_LIMIT_<NAME>`

    Where `<NAME>` can be whatever arbitrary name you'd like to use containing `A-Z`, `0-9,` and `_`. For example, either of these would be valid:
    * `CPU_REQUEST_MQ_CONSUMER`
    * `MEM_LIMIT_API`

    **NOTE:** If you only have a single component in your template, you can omit `_<NAME>` from the parameter names if you desire.

  2. Your deployment configuration for the component must explicitly define values for these parameters. For ephemeral environments normally this will mean that your parameters are defined under the ephemeral deploy target in app-interface.

  If these steps are followed then your resource config is considered "trusted" and bonfire will not remove the requests/limits configurations.


  **NOTE:** a couple things that will change in the future:
  * The "host-inventory" app is trusted by default, but once their configurations are tweaked to be trusted we will remove this
  * Object types such as Deployment/StatefulSet/DaemonSet/etc. are not currently analyzed. In future once teams have audited all container resource configurations, we will begin to have bonfire check for trusted configurations on all object types.




  `bonfire` creates/modifies `NamespaceReservation` resources on the cluster to reserve and release namespaces. The template for the object that bonfire applies into the cluster can be found [here](bonfire/resources/reservation-template.yaml)

  For more information about how the ephemeral namespace operator works, see its documentation [here](https://github.com/RedHatInsights/ephemeral-namespace-operator)





  * `bonfire` expects a Clowder `ClowdEnvironment` resource to be created for a namespace before it can deploy into it. This `ClowdEnvironment` is already created by the ephemeral namespace operator.

  * When `bonfire deploy` is executed for a namespace, it will attempt to find the ClowdEnvironment associated with that namespace and set the `ENV_NAME` parameter accordingly for all templates it processes. All templates that define a `ClowdApp` resource should set the `environment` mapping in their spec using a parameter named `${ENV_NAME}`.



  In a ClowdApp definition, an app listed under `dependencies` is considered an app that MUST be present for your app to function, while an app listed under `optionalDependencies` is considered an app that might be absent, but your app could still come up and function without it.

  When bonfire processes templates, if it finds a ClowdApp, it will do the following:
  * if the ClowdApp has `dependencies`, it will try to look up the config for that ClowdApp in app-interface and also fetch its templates
  * if the ClowdApp has `optionalDependencies`, it will behave differently based on which optional dependencies method is selected:

    * `hybrid` (default): if an app group was explicitly specified on the CLI (example: when running `bonfire deploy app-a` the app group 'app-a' is being explicitly specified) then the `optionalDependencies` will be deployed for it. For any ClowdApp `bonfire` comes across that is not a member of an explicitly specified app group, the `optionalDependencies` will NOT be deployed. As an example:
      * `app-a` has `app-b-clowdapp` listed under `optionalDependencies`
      * `app-b-clowdapp` has `app-c-clowdapp` listed under its `optionalDependencies`
      * You will end up with all components of `app-a` and `app-b-clowdapp` in your namespace. `app-c-clowdapp` would NOT be deployed into the namespace.
    * `all`: `bonfire` will deploy all `optionalDependencies` for all ClowdApps it encounters. It will recursively process dependencies. As an example:
      * `app-a` has `app-b-clowdapp` listed under `optionalDependencies`
      * `app-b-clowdapp` has `app-c-clowdapp` listed under its `optionalDependencies`
      * You will end up with all components of `app-a`, `app-b-clowdapp`, AND `app-c-clowdapp` deployed into the namespace.
    * `none`: `bonfire` will ignore the `optionalDependencies` on all ClowdApps that it encounters



  > NOTE: for information related to app-interface configurations, see the internal [ConsoleDot Docs](https://consoledot.pages.redhat.com/)

  When running `bonfire process`/`bonfire deploy`, by default the app-sre team's internal GraphQL API server is used. `bonfire` will query the GraphQL API and read the application's deploy configuration.

  *NOTE*: You need to be on the internal VPN in order to access the default GraphQL API URL.

  `bonfire` relies on a few key pieces of info to process app configs:

  1. The application name. This is typically the name of the listed in `app.yaml` in `app-interface`
  2. A 'target env' -- the name of the `app-interface` environment that bonfire looks at to determine the parameters to apply when processing app templates. An app's config will only be processed if it has a deploy target set up that is pointing to a namespace in this environment (default: "ephemeral")
  3. A 'ref env' -- the name of the `app-interface` environment that we want to use in order to figure out which git ref of the components to deploy and which `IMAGE_TAG` value to set. By default, none is set which causes bonfire to use the 'main'/'master' git branch for all components.
  4. Any template refs you wish to override (optional)
  5. Any image tags you wish to override (optional)
  6. Any parameters you wish to override (optional)

  By default, if app components use `ClowdApp` resources in their templates, then `bonfire` will dynamically load dependencies (see "Dependency Processing" section)



  `bonfire` ships with a [default config](bonfire/resources/default_config.yaml) that should be enough to get started for most internal Red Hat employees.

  By default, the configuration file will be stored in `~/.config/bonfire/config.yaml`.

  If you wish to override any app configurations, you can edit your local configuration file by typing `bonfire config edit`. You can then define an app under the `apps` key of the config. You can reset the config to default at any time using `bonfire config write-default`.

  As of `bonfire` v5, there are two options for how the local configuration is loaded (controlled by the `--local-config-method` CLI option). Let's say we have an app configured in app-interface like this:

  ```
  resourceTemplates:
  - name: mycomponent1
    path: /deployment.yaml
    url: https://github.com/myorg/myrepo1
    targets:
    - namespace:
        $ref: /services/insights/ephemeral/namespaces/ephemeral-base.yml
      parameters:
        MIN_REPLICAS: 1
  - name: mycomponent2
    path: /deployment.yaml
    url: https://github.com/myorg/myrepo2
    targets:
    - namespace:
        $ref: /services/insights/ephemeral/namespaces/ephemeral-base.yml
      parameters:
        MIN_REPLICAS: 2
        SOME_OTHER_PARAM: some_other_value
  ```

  and the local config file has this entry:

  ```
  apps:
  - name: myapp
    components:
    - name: mycomponent2
      parameters:
        MIN_REPLICAS: 10
  ```

  `bonfire` can override the remote configuration using one of two methods:

  1. `--local-config-method merge` (default). In this mode, the apps config in your local config is merged with the configuration that bonfire fetched remotely. With the above config, only the 'MIN_REPLICAS' parameter of 'mycomponent2' within app 'myapp' will be overridden. The 'SOME_OTHER_PARAM' parameter will still be present, and 'mycomponent1' would be unchanged.

  2. `--local-config-method override`. In this mode, the local app configuration will take precedence over the app's configuration that bonfire fetched remotely. In other words, defining a local app configuration will replace the configuration defined in app-interface for ALL components within that app. So 'mycomponent1' would be completely removed, and 'mycomponent2' would only have the parameters you defined in the local config.





  If you wanted to test out some changes you're making to an app but you have not yet pushed these changes to a git repo, the local config could look similar to:

  ```
  apps:
  - name: my_app
    components:
      - name: service
        host: local
        repo: ~/dev/projects/my-app
        path: /clowdapp.yaml
        parameters:
          SOME_PARAMETER: some_value
  ```

  - Where **host** set `local` indicates to look for the repo in a local directory
  - Where **repo** indicates the path to your git repo folder
  - Where **path** specifies the relative path to your ClowdApp template file in your git repo

  By default, `bonfire` will run `git rev-parse` to determine the current working commit hash in your repo folder, and this determines what IMAGE_TAG to set when the template is deployed. This means you would need to have a valid container image pushed for this commit hash. However, you can use `--set-image-tag`/`--set-parameter` or define the `IMAGE_TAG` parameter in your config in order to override the image you wish to use during the deployment.



  If you wanted to deploy changes to your app that you were working on which have been pushed to a PR/branch, the local config could look similar to:

  ```
  apps:
  - name: my_app
    components:
      - name: service
        host: github
        repo: MyOrg/MyRepo
        ref: my_branch
        path: /clowdapp.yaml
  ```

  - Where **host** set to `github` or `gitlab` indicates where the repo is hosted
  - Where **repo** indicates the `OrganizationName/RepoName`
  - Where **path** specifies the relative path to your ClowdApp template file in your git repo
  - Where **ref** specifies the branch or commit of the repo you want to deploy

  By default, bonfire will use the latest commit hash found at the specified git ref to determine what IMAGE_TAG pass on to the deployment templates.




  bonfire is configured to point to the app-sre team's internal GraphQL API by default, but by using env variables you can point to your your own instance of `qontract-server`:

  ```bash
  export QONTRACT_BASE_URL="https://localhost:4000/graphql"
  export QONTRACT_USERNAME=myUsername
  export QONTRACT_PASSWORD=myPassword
  ```

  For testing/debug purposes, instead of committing changes directly to app-interface, you can run your own local copy of the app-interface API server.

  1. Clone https://github.com/app-sre/qontract-server
  2. Clone the internal `app-interface` repo

  In `qontract-server`, run:
  ```
  npm install yarn
  yarn install
  yarn build
  make bundle APP_INTERFACE_PATH=/path/to/app-interface
  LOAD_METHOD=fs DATAFILES_FILE=bundle/bundle.json yarn run server
  ```


pkgId: 7f63ed104936d52b493ec4170e01c9f065d9c57218bc3df84d84f0e31277d69a
name: python-crc32c
arch: src
version: 2.7.1
epoch: 0
release: 1
summary: A python package implementing the crc32c algorithm in hardware and software
url: https://github.com/ICRAR/crc32c
rpm_license: LGPL-2.1-or-later
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crc32c-2.7.1-1.src.rpm
checksum_type: sha256
description:
  This package implements the crc32c checksum algorithm.
  It automatically chooses between a hardware-based implementation
  (using the CRC32C SSE 4.2 instruction of Intel CPUs,
  and the crc32* instructions on ARMv8 CPUs),
  or a software-based one when no hardware support can be found.
  Because ``crc32c`` is in PyPI, you can install it with::
   pip install crc32c
  Supported platforms are Linux and OSX using the gcc and clang compilers,
  and Windows using the Visual Studio compiler. Other compilers in
  Windows (MinGW for instance) might work.
  Binary wheels are also provided in PyPI for major platforms/architectures.
  The project is using certain gcc/clang compiler extensions to support
  building hardware-specific functions that might not be supported
  by older compiler versions.


pkgId: 0a63c9f10b3334e601789cf26a61f55815745658ca2a0a591b3b1a46954aa69b
name: python-crc64iso
arch: src
version: 0.0.2
epoch: 0
release: 1
summary: CRC-64 checksum generator
url: https://pypi.org/project/crc64iso/
rpm_license: MIT License
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crc64iso-0.0.2-1.src.rpm
checksum_type: sha256
description:
  Package for calculating checksums using __64-bit cyclic redundancy checks (CRC)__ according to the __ISO 3309__ standard.

  Generator polynomial: x<sup>64</sup> + x<sup>4</sup> + x<sup>3</sup> + x + 1

  Reference:
  _W. H. Press, S. A. Teukolsky, W. T. Vetterling, and B. P. Flannery, "Numerical recipes in C", 2nd ed.,
  Cambridge University Press. Pages 896ff._




  - python 3.x




  - Calculate 64-bit checksum from a string:

  ```
  from crc64iso.crc64iso import crc64

  checksum = crc64iso.crc64("ILOVEMATH")
  ```

  - Calculate 64-bit checksum from incremental (bytes) data:

  ```
  from crc64iso.crc64iso import crc64_pair, format_crc64_pair

  crc_pair_1 = crc64_pair("ILOVE".encode())
  crc_pair_2 = crc64_pair("MATH".encode(), crc_pair_1)
  checksum = format_crc64_pair(crc_pair_2)
  ```


pkgId: 2375ba8bbc7f3536beb6f840795367c3039a4f9a8f0b82b7651a88ac64928f92
name: python-crcFinder
arch: src
version: 0.0.3
epoch: 0
release: 1
summary: A tool to find well known crc params that matches the input data and crc result (right or wrong)
url: https://github.com/leommxj/crcFinder
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crcFinder-0.0.3-1.src.rpm
checksum_type: sha256
description:
  A tool to find well known crc params that matches the input data and crc result (right or wrong)



  ```bash
  pip install crcFinder
  ```







  ```python
  from crcFinder import CrcFinder
  import zlib

  data = []
  data.append((b"123456789", zlib.crc32(b'123456789')))
  data.append((b"123456789xxxx", zlib.crc32(b'123456789xxxx')))
  f = CrcFinder()
  r = f.findCrc(data)
  print([str(i) for i in r])
  ```



  ```python
  from crcFinder import CrcFinder
  data = []
  data.append((b"123456789\x09", b'\x11\x60\x7a\x37'))
  data.append((b"1234567890\x0a", b'\xb3\x95\xcb\x46'))
  f = CrcFinder()
  r = f.findCrc(data)
  print(r[0])
  ```



  ```python
  from crcFinder import CrcCalculator, ShiftType
  crc_pkzip = CrcCalculator(32, 0x04c11db7, 0xffffffff, True, True, 0xffffffff, ShiftType.LEFT, ShiftType.LEFT)
  assert(crc_pkzip.check() == 0xcbf43926)
  ```



  ```bash
  python3 -m crcFinder -d 616263646566,4b8e39ef
  python3 -m crcFinder -d 616263646566,0x4b8e39ef 313233343536373839,0xcbf43926
  ```



  - <https://reveng.sourceforge.io/crc-catalogue/all.htm>
  - <https://github.com/Michaelangel007/crc32>


pkgId: af08539353deb58415a562872d1ad9e6501dbcb1bb7e88f0bd3454c2493bd75d
name: python-crccheck
arch: src
version: 1.3.0
epoch: 0
release: 1
summary: Calculation library for CRCs and checksums
url: https://github.com/MartinScharrer/crccheck
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crccheck-1.3.0-1.src.rpm
checksum_type: sha256
description:
  The ``crccheck.crc`` module implements all CRCs listed in the
  `Catalogue of parametrised CRC algorithms <http://reveng.sourceforge.net/crc-catalogue/>`_:
      CRC-3/GSM, CRC-3/ROHC, CRC-4/G-704, CRC-4/INTERLAKEN, CRC-5/EPC-C1G2, CRC-5/G-704, CRC-5/USB, CRC-6/CDMA2000-A,
      CRC-6/CDMA2000-B, CRC-6/DARC, CRC-6/G-704, CRC-6/GSM, CRC-7/MMC, CRC-7/ROHC, CRC-7/UMTS, CRC-8/AUTOSAR,
      CRC-8/BLUETOOTH, CRC-8/CDMA2000, CRC-8/DARC, CRC-8/DVB-S2, CRC-8/GSM-A, CRC-8/GSM-B, CRC-8/HITAG, CRC-8/I-432-1,
      CRC-8/I-CODE, CRC-8/LTE, CRC-8/MAXIM-DOW, CRC-8/MIFARE-MAD, CRC-8/NRSC-5, CRC-8/OPENSAFETY, CRC-8/ROHC,
      CRC-8/SAE-J1850, CRC-8/SMBUS, CRC-8/TECH-3250, CRC-8/WCDMA, CRC-10/ATM, CRC-10/CDMA2000, CRC-10/GSM, CRC-11/FLEXRAY,
      CRC-11/UMTS, CRC-12/CDMA2000, CRC-12/DECT, CRC-12/GSM, CRC-12/UMTS, CRC-13/BBC, CRC-14/DARC, CRC-14/GSM, CRC-15/CAN,
      CRC-15/MPT1327, CRC-16/ARC, CRC-16/CDMA2000, CRC-16/CMS, CRC-16/DDS-110, CRC-16/DECT-R, CRC-16/DECT-X, CRC-16/DNP,
      CRC-16/EN-13757, CRC-16/GENIBUS, CRC-16/GSM, CRC-16/IBM-3740, CRC-16/IBM-SDLC, CRC-16/ISO-IEC-14443-3-A,
      CRC-16/KERMIT, CRC-16/LJ1200, CRC-16/M17, CRC-16/MAXIM-DOW, CRC-16/MCRF4XX, CRC-16/MODBUS, CRC-16/NRSC-5,
      CRC-16/OPENSAFETY-A, CRC-16/OPENSAFETY-B, CRC-16/PROFIBUS, CRC-16/RIELLO, CRC-16/SPI-FUJITSU, CRC-16/T10-DIF,
      CRC-16/TELEDISK, CRC-16/TMS37157, CRC-16/UMTS, CRC-16/USB, CRC-16/XMODEM, CRC-17/CAN-FD, CRC-21/CAN-FD, CRC-24/BLE,
      CRC-24/FLEXRAY-A, CRC-24/FLEXRAY-B, CRC-24/INTERLAKEN, CRC-24/LTE-A, CRC-24/LTE-B, CRC-24/OPENPGP, CRC-24/OS-9,
      CRC-30/CDMA, CRC-31/PHILIPS, CRC-32/AIXM, CRC-32/AUTOSAR, CRC-32/BASE91-D, CRC-32/BZIP2, CRC-32/CD-ROM-EDC,
      CRC-32/CKSUM, CRC-32/ISCSI, CRC-32/ISO-HDLC, CRC-32/JAMCRC, CRC-32/MEF, CRC-32/MPEG-2, CRC-32/XFER, CRC-40/GSM,
      CRC-64/ECMA-182, CRC-64/GO-ISO, CRC-64/MS, CRC-64/REDIS, CRC-64/WE, CRC-64/XZ, CRC-82/DARC
  For the class names simply remove all dashes and slashes from the above names and apply CamelCase, e.g.
  "CRC-32/MPEG-2" is implemented by ``Crc32Mpeg2``. Other CRC can be calculated by using the general class
  ``crccheck.crc.Crc`` by providing all required CRC parameters.
  The ``crccheck.checksum`` module implements additive and XOR checksums with 8, 16 and 32 bit:
  ``Checksum8``, ``Checksum16``, ``Checksum32`` and ``ChecksumXor8``, ``ChecksumXor16``, ``ChecksumXor32``
  Usage example::
      from crccheck.crc import Crc32, CrcXmodem
      from crccheck.checksum import Checksum32
      
      data = bytearray.fromhex("DEADBEEF")
      crc = Crc32.calc(data)
      checksum = Checksum32.calc(data)
      
      data1 = b"Binary string"  # or use .encode(..) on normal sring - Python 3 only
      data2 = bytes.fromhex("1234567890")  # Python 3 only, use bytearray for older versions
      data3 = (0x0, 255, 12, 99)  # Iterable which returns ints in byte range (0..255)
      crcinst = CrcXmodem()
      crcinst.process(data1)
      crcinst.process(data2)
      crcinst.process(data3[1:-1])
      crcbytes = crcinst.finalbytes()
      crchex = crcinst.finalhex()
      crcint = crcinst.final()
  License:
      MIT License
      Copyright (c) 2015-2022 by Martin Scharrer <martin.scharrer@web.de>
      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: 783c07397589703cc4337ea79fce5c669c70425518d7b2517b481a8b7355755b
name: python-crcmod-plus
arch: src
version: 2.1.0
epoch: 0
release: 1
summary: CRC generator - modernized
url: https://pypi.org/project/crcmod-plus/
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crcmod-plus-2.1.0-1.src.rpm
checksum_type: sha256
description:
  The software in this package is a Python module for generating objects that
  compute the Cyclic Redundancy Check (CRC).  There is no attempt in this package
  to explain how the CRC works.  There are a number of resources on the web that
  give a good explanation of the algorithms.  Just do a Google search for "crc
  calculation" and browse till you find what you need.  Another resource can be
  found in chapter 20 of the book "Numerical Recipes in C" by Press et. al.
  This package allows the use of any 8, 16, 24, 32, or 64 bit CRC.  You can
  generate a Python function for the selected polynomial or an instance of the
  Crc class which provides the same interface as the `md5` and `sha` modules
  from the Python standard library.  A `Crc` class instance can also generate
  C/C++ source code that can be used in another application.

  Documentation is available from the doc strings.  It is up to you to decide
  what polynomials to use in your application.  If someone has not specified the
  polynomials to use, you will need to do some research to find one suitable for
  your application.  Examples are available in the unit tests in the `tests`
  folder.  You may also use the `predefined` module to select one of the standard
  polynomials.
  If you need to generate code for another language, I suggest you subclass the
  `Crc` class and replace the method `generateCode`.  Use `generateCode` as
  a model for the new version.


  This package supports Python 3.7 and newer.

  To build the C extension, the appropriate compiler tools for your platform must
  be installed. Refer to the Python documentation for building C extensions for
  details. If you have a C compiler and all the usual Python development tools,
  including the `build` frontend, then running `python -m build` should build the
  package.

  The `crcmod-plus` package is installed from PyPI using `pip`. Run the following
  command:
  ```sh
  $ pip install crcmod-plus
  ```

  `crcmod-plus` uses `pytest` as the testing environment. You can run the unit
  tests with:
  ```sh
  $ pytest tests
  ```

  The `crcmod` package is capable of generating C functions that can be compiled
  with a C or C++ compiler.  In the `tests` directory, there is an `examples.py`
  script that demonstrates how to use the code generator.  The result of this is
  written out to the file `examples.c`.  The generated code was checked to make
  sure it compiles with the GCC compiler.

  The `crcmod-plus` package is released under the MIT license. See the `LICENSE`
  file for details.

  * Ray Buvel (the original `crcmod` package)

  * Craig McQueen (contributor of the original `crcmod` package)
  * Tamas Nepusz (modernisation into `crcmod-plus`)

rpm_license:
  ---------------------------------------------------------------------------- Copyright (c) 2010  Raymond L. Buvel Copyright (c) 2010  Craig McQueen  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: a010852ae46d15f6ce6ca19d710acfa7940f6de3ddb16c1e9133cc26cee05e94
name: python-crdclib
arch: src
version: 0.0.1
epoch: 0
release: 1
summary: A collection of functions useful for interactive with parts of CRDC
url: https://github.com/pihltd/CRDCLib
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crdclib-0.0.1-1.src.rpm
checksum_type: sha256
description:
  Personal library of CRDC routines I use a lot.  Theres nothing special, just saving writing time.
  *Use at your own risk*


pkgId: b30f13059dec66382fd0a564e10c6dd9be4d0f6a547f583c55b981b871b9ca39
name: python-crds
arch: src
version: 12.0.3
epoch: 0
release: 1
summary: Calibration Reference Data System, HST/JWST/Roman reference file management
url: https://pypi.org/project/crds/
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crds-12.0.3-1.src.rpm
checksum_type: sha256
rpm_license:
  # Copyright (C) 2010 Association of Universities for Research in Astronomy(AURA) # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # #     1. Redistributions of source code must retain the above copyright #       notice, this list of conditions and the following disclaimer. # #     2. Redistributions in binary form must reproduce the above #       copyright notice, this list of conditions and the following #       disclaimer in the documentation and/or other materials provided #       with the distribution. # #     3. The name of AURA and its representatives may not be used to #       endorse or promote products derived from this software without #       specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY AURA ``AS IS'' AND ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL AURA BE LIABLE FOR ANY DIRECT, INDIRECT, # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR # TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE # USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH # DAMAGE.


pkgId: ed2dd80ab5910aca0e548da8e20a6f646076d081b29fb9fb2c244ea27ed4c9ff
name: python-crdt-tool-api-client
arch: src
version: 1.0.0
epoch: 0
release: 1
summary: A client library for accessing crdt-tool API
url: https://pypi.org/project/crdt-tool-api-client/
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crdt-tool-api-client-1.0.0-1.src.rpm
checksum_type: sha256
description:
  A client library for accessing crdt-tool API


  First, create a client:

  ```python
  from crdt_tool_api_client import Client

  client = Client(base_url="https://api.example.com")
  ```

  If the endpoints you're going to hit require authentication, use `AuthenticatedClient` instead:

  ```python
  from crdt_tool_api_client import AuthenticatedClient

  client = AuthenticatedClient(base_url="https://api.example.com", token="SuperSecretToken")
  ```

  Now call your endpoint and use your models:

  ```python
  from crdt_tool_api_client.models import MyDataModel
  from crdt_tool_api_client.api.my_tag import get_my_data_model
  from crdt_tool_api_client.types import Response

  with client as client:
      my_data: MyDataModel = get_my_data_model.sync(client=client)
      
      response: Response[MyDataModel] = get_my_data_model.sync_detailed(client=client)
  ```

  Or do the same thing with an async version:

  ```python
  from crdt_tool_api_client.models import MyDataModel
  from crdt_tool_api_client.api.my_tag import get_my_data_model
  from crdt_tool_api_client.types import Response

  async with client as client:
      my_data: MyDataModel = await get_my_data_model.asyncio(client=client)
      response: Response[MyDataModel] = await get_my_data_model.asyncio_detailed(client=client)
  ```

  By default, when you're calling an HTTPS API it will attempt to verify that SSL is working correctly. Using certificate verification is highly recommended most of the time, but sometimes you may need to authenticate to a server (especially an internal server) using a custom certificate bundle.

  ```python
  client = AuthenticatedClient(
      base_url="https://internal_api.example.com",
      token="SuperSecretToken",
      verify_ssl="/path/to/certificate_bundle.pem",
  )
  ```

  You can also disable certificate validation altogether, but beware that **this is a security risk**.

  ```python
  client = AuthenticatedClient(
      base_url="https://internal_api.example.com",
      token="SuperSecretToken",
      verify_ssl=False
  )
  ```

  Things to know:
  1. Every path/method combo becomes a Python module with four functions:
      1. `sync`: Blocking request that returns parsed data (if successful) or `None`
      1. `sync_detailed`: Blocking request that always returns a `Request`, optionally with `parsed` set if the request was successful.
      1. `asyncio`: Like `sync` but async instead of blocking
      1. `asyncio_detailed`: Like `sync_detailed` but async instead of blocking

  1. All path/query params, and bodies become method arguments.
  1. If your endpoint had any tags on it, the first tag will be used as a module name for the function (my_tag above)
  1. Any endpoint which did not have a tag will be in `crdt_tool_api_client.api.default`



  There are more settings on the generated `Client` class which let you control more runtime behavior, check out the docstring on that class for more info. You can also customize the underlying `httpx.Client` or `httpx.AsyncClient` (depending on your use-case):

  ```python
  from crdt_tool_api_client import Client

  def log_request(request):
      print(f"Request event hook: {request.method} {request.url} - Waiting for response")

  def log_response(response):
      request = response.request
      print(f"Response event hook: {request.method} {request.url} - Status {response.status_code}")

  client = Client(
      base_url="https://api.example.com",
      httpx_args={"event_hooks": {"request": [log_request], "response": [log_response]}},
  )


  ```

  You can even set the httpx client directly, but beware that this will override any existing settings (e.g., base_url):

  ```python
  import httpx
  from crdt_tool_api_client import Client

  client = Client(
      base_url="https://api.example.com",
  )

  client.set_httpx_client(httpx.Client(base_url="https://api.example.com", proxies="http://localhost:8030"))
  ```


  This project uses [Poetry](https://python-poetry.org/) to manage dependencies  and packaging.  Here are the basics:
  1. Update the metadata in pyproject.toml (e.g. authors, version)
  1. If you're using a private repository, configure it with Poetry
      1. `poetry config repositories.<your-repository-name> <url-to-your-repository>`
      1. `poetry config http-basic.<your-repository-name> <username> <password>`
  1. Publish the client with `poetry publish --build -r <your-repository-name>` or, if for public PyPI, just `poetry publish --build`

  If you want to install this client into another project without publishing it (e.g. for development) then:
  1. If that project **is using Poetry**, you can simply do `poetry add <path-to-this-client>` from that project
  1. If that project is not using Poetry:
      1. Build a wheel with `poetry build -f wheel`
      1. Install that wheel from the other project `pip install <path-to-wheel>`


pkgId: a8e2fbb14335a26228a3869ff7f4e0af0f165f747755fd8de4479f289af2441f
name: python-crealand
arch: src
version: 1.0.57
epoch: 0
release: 1
summary: Python SDK for the Crealand
url: https://pypi.org/project/crealand/
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crealand-1.0.57-1.src.rpm
checksum_type: sha256
description:
  Crealand SDK



  - 修改`version.txt`中的版本号



  - build
   - setuptools
   - wheel
   - twine



  需要先 pip 安装 build（setuptools 和 wheel会自动安装）， 再编译打包：

  ```
  python3 -m pip install build
  python3 -m build
  ```



  ```bash
  pip install crealand
  ```



  ```bash
  pip uninstall crealand
  ```





  - 把根目录的`.pypirc`文件拷贝到系统用户根目录；
  - 安装`twine`



  > https://test.pypi.org/

  ```bash
  python3 -m twine upload --repository testpypi dist/*
  ```



  > https://pypi.org/

  ```bash
  python3 -m twine upload --repository pypi dist/*
  ```

rpm_license:
  MIT License  Copyright (c) 2012-2023  UBTECH Robotics Corp. All Rights Reserved  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: ff6d0ad6af7908fff8214b43561b692f055e17109a3c4fc35b1b420b45d88d58
name: python-creao
arch: src
version: 0.3.51
epoch: 0
release: 1
summary: A description of your project
url: https://creao@dev.azure.com/creao/creao/_git/creao
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-creao-0.3.51-1.src.rpm
checksum_type: sha256
description:
  * to create any new pr
  * please make sure you have added a test, and provide the bazel command to run the test
  * for formatting, please run 'bazel run //:format '


pkgId: 93be026f13b3d578c662703653079a3798dff387ed7ff1d5a3fbe5d05d219e7d
name: python-create-app
arch: src
version: 0.6.2
epoch: 0
release: 1
url: https://github.com/application-creators/create_app
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-create-app-0.6.2-1.src.rpm
checksum_type: sha256
summary:
  A tool that allows to quickly get your basic project structure ready, while adopting the best technologies, tools, and practices.

description:
  <p align="center">
    <img alt="Create App logo" src="https://raw.githubusercontent.com/application-creators/create_app/main/docs/static/logo-cropped.png">
  </p>

  <p align="center">
      <a href="https://github.com/application-creators/create_app/actions"><img alt="Test Workflow Status" src="https://github.com/application-creators/create_app/workflows/Test/badge.svg"></a>
      <a href="https://github.com/application-creators/create_app/actions"><img alt="Linting Workflow Status" src="https://github.com/application-creators/create_app/workflows/Lint/badge.svg"></a>
      <a href="https://github.com/application-creators/create_app/actions"><img alt="PyPI Publication Workflow Status" src="https://github.com/application-creators/create_app/workflows/Publish%20to%20PyPI/badge.svg"></a>
      <a href="https://coveralls.io/github/application-creators/create_app?branch=main"><img alt="Coverage Status" src="https://coveralls.io/repos/github/application-creators/create_app/badge.svg?branch=main"></a>
      <!-- <a href="https://github.com/application-creators/create_app/blob/main/LICENSE"><img alt="License: MIT" src="https://create_app.readthedocs.io/en/stable/_static/license.svg"></a> -->
      <!-- <a href="https://create_app.readthedocs.io/en/stable/?badge=stable"><img alt="Documentation Status" src="https://readthedocs.org/projects/create_app/badge/?version=stable"></a>  -->
      <a href="https://pypi.org/project/create_app/"><img alt="PyPI" src="https://img.shields.io/pypi/v/create_app"></a>
      <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>

  _create_app_ is a tool for creating applications from templates.

  When developers start a new project, they perform some repetitive tasks to build the basic project structure before
  actually start coding features. This basic structure involves things like: Well, the project structure, unit testing,
  code coverage, containerization, code linting and formatting, GIT hooks, building code documentation, among many others.

  _create_app_ is a tool that allows to quickly get your basic project structure ready. It provides a set of templates
  from which you can get your project started, plus it's super easy to use and encourages the adoption of the best
  technologies, tools, and practices.

  At the moment, there are only Python templates available. But _create_app_ can generate projects of **any language**,
  as it uses [cookiecutter](https://cookiecutter.readthedocs.io/en/stable/).




  Just install it with PIP:
  ```shell
  python -m pip install create_app
  ```



  Learn how to use the _create_app_ command:
  ```shell
  python -m create_app --help
  ```

  You can use the _--help_ option for all subcommands too.




  Use the _list_ subcommand to know which templates you can use:

  ```shell
  python -m create_app list
  ```




  Use the _create_ subcommand and specify the _TEMPLATE_NAME_ you wish to use:
  ```shell
  create_app create TEMPLATE_NAME
  ```




  If you don't want to configure your project and just want to create it from the template using all the default values,
  use the _--use-defaults_ flag:
  ```shell
  create_app create TEMPLATE_NAME --use-defaults
  ```




  When creating a project, you are asked to type your project configuration in. If you already know which the template
  settings are and the values you want to use, you can use the _--config-file_ option to specify these values from a JSON
  file. This option is specially useful for scripting:
  ```shell
  create_app create TEMPLATE_NAME --config-file=config.json
  ```




  You or your organization may need to keep a separate index with your own templates.

  If that's the case, you can list the templates in the custom index by running:
  ```shell
  create_app list --index="https://www.somewhere.com/templates-index"
  ```

  And create your project from a template in that index:
  ```shell
  create_app create TEMPLATE_NAME --index="https://www.somewhere.com/templates-index"
  ```




  You can import create_app from Python too, which is great for scripting or creating multiple projects at once:

  ```python
  from create_app.main import create_app


  create_app("python_simple")
  ```




  It uses a great tool named [cookiecutter](https://cookiecutter.readthedocs.io/en/stable/) to build your project from
  a template. The templates are cookiecutters, so you could simply use cookiecutter to build your project from the
  template repo URL:
  ```shell
  python -m cookiecutter https://github.com/application-creators/python_simple
  ```

  _create_app_ is just an entry point to a set of templates, and I was inspired by
  [create-react-app](https://create-react-app.dev/docs/getting-started#selecting-a-template), which lets you create your
  project from a template by just specifying a template name.

  The main goal though, and what I would like to focus on, is to come up with great project templates. Then people can
  choose to directly use cookiecutter to build their projects, or could use this tool to discover which templates are
  available and to create their project.




  There's an [index of templates](/templates.json), from which you can get your project started:

  | **Template**                                                                                         | **Description**                                                                                                                                                                                                                                                                                                                                                                                                                                    |
  |------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
  | [python_simple](https://github.com/application-creators/python_simple)                               | Python project with unit tests, GIT hooks ([pre-commit](https://pre-commit.com/), [black](https://github.com/psf/black), [isort](https://pycqa.github.io/isort/), and [flake8](https://flake8.pycqa.org/en/latest/)), and Docker                                                                                                                                                                                                                   |
  | [python_compose](https://github.com/application-creators/python_compose)                             | Python project with unit tests, GIT hooks ([pre-commit](https://pre-commit.com/), [black](https://github.com/psf/black), [isort](https://pycqa.github.io/isort/), and [flake8](https://flake8.pycqa.org/en/latest/)), and Docker Compose                                                                                                                                                                                                           |
  | [python_fastapi](https://github.com/application-creators/python_fastapi)                             | FastAPI project with unit tests, GIT hooks ([pre-commit](https://pre-commit.com/), [black](https://github.com/psf/black), [isort](https://pycqa.github.io/isort/), and [flake8](https://flake8.pycqa.org/en/latest/)), and Docker                                                                                                                                                                                                                  |
  | [python_fastapi_with_database](https://github.com/application-creators/python_fastapi_with_database) | FastAPI project with unit tests, GIT hooks ([pre-commit](https://pre-commit.com/), [black](https://github.com/psf/black), [isort](https://pycqa.github.io/isort/), and [flake8](https://flake8.pycqa.org/en/latest/)), Docker Compose, a [PostgreSQL](https://www.postgresql.org/) database (which can be very easily changed for any other), [SQLAlchemy](https://www.sqlalchemy.org/), and [Alembic](https://alembic.sqlalchemy.org/) migrations |




  [Application Creators](https://github.com/application-creators) is a new GitHub organization I've created to host,
  debate, and maintain this tool and the project templates. Its goal is to generate state-of-the-art templates useful
  to everyone. Feel free to express you opinion and contribute!


pkgId: cf20eb809eb607313f48943bcc254791eae5a7e1d98b1ff81e0c8b8113b9bd8e
name: python-create-fastapi-project
arch: src
version: 0.2.5
epoch: 0
release: 1
summary: please add a summary manually as the author left a blank one
url: https://pypi.org/project/create-fastapi-project/
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-create-fastapi-project-0.2.5-1.src.rpm
checksum_type: sha256
description:
  We love ❤️ [FastAPI](https://fastapi.tiangolo.com/) and its ecosystem so we decided to make easier to get started with [FastAPI](https://fastapi.tiangolo.com/) projects. By using the `create-fastapi-project` CLI tool, you can quickly start building a new FastAPI application with a basic folder structure, with everything set up for you.

  To get started, use the following command:

  ```bash
  pip install create-fastapi-project
  create-fastapi-project
  ```

  After you that you are going to see an interactive screen like this:

  ![create-app-terminal](https://res.cloudinary.com/dnv0qwkrk/image/upload/v1692746180/Allient/create-fastapi-project/demo-create-fastapi-final_fyirob.gif)





  <details>
    <summary>See More</summary>

    We're excited to introduce you to our FastAPI Basic Project Template, carefully designed to jumpstart your FastAPI development journey. This template offers you a pre-configured project with a fundamental FastAPI setup and an organized folder structure, allowing you to hit the ground running.



  ```bash
  └───app
    ├───app
    │   ├───api
    │   │   └───v1
    │   │       └───endpoints
    │   ├───core
    │   ├───schemas
    │   └───utils
    │       └───exceptions
    └───test
  ```

  </details>



  <details>
    <summary>See More</summary>

    We're thrilled to introduce you to the LangChain project template, designed to accelerate your development process. This template serves as a solid foundation for your project, complete with essential features and an organized folder structure, all thoughtfully configured and ready for use.



  ```bash
  app
      ├───app
      │   ├───api
      │   │   └───v1
      │   │       └───endpoints
      │   ├───core
      │   ├───schemas
      │   ├───templates
      │   │   └───general_pages
      │   └───utils
      │       ├───adaptive_cards
      │       └───exceptions
      └───test
  ```



  ![langchain-architecture](https://res.cloudinary.com/dnv0qwkrk/image/upload/v1693340056/Allient/create-fastapi-project/image_2_mraj02.png)
  As this project uses [Caddy](https://caddyserver.com/) as a reverse proxy, which uses namespaces routing, you can access the documentation with the following path [http://fastapi.localhost/docs](http://fastapi.localhost/docs)



  ```bash
  PROJECT_NAME=
  OPENAI_API_KEY=
  UNSPLASH_API_KEY= # Optional
  SERP_API_KEY= # Optional




  EXT_ENDPOINT1=127.0.0.1
  LOCAL_1=localhost
  LOCAL_2=127.0.0.1
  ```



  - Search weather tool ![weather-tool](https://res.cloudinary.com/dnv0qwkrk/image/upload/v1692746086/Allient/create-fastapi-project/weather-tool-demo_lgqtwu.gif)
  - Search images tool ![images-tool](https://res.cloudinary.com/dnv0qwkrk/image/upload/v1692746086/Allient/create-fastapi-project/search-images-demo_mkorzv.gif)
  - Search videos tool ![videos-tool](https://res.cloudinary.com/dnv0qwkrk/image/upload/v1692746087/Allient/create-fastapi-project/search-videos-demo_wikzn1.gif)
  - Search pokemon tool ![pokemon-tool](https://res.cloudinary.com/dnv0qwkrk/image/upload/v1692746086/Allient/create-fastapi-project/pokemon-tool-demo_ggsc63.gif)
  </details>



  <details>
    <summary>See More</summary>

  This is a project template which uses [FastAPI](https://fastapi.tiangolo.com/), [Alembic](https://alembic.sqlalchemy.org/en/latest/) and async [SQLModel](https://sqlmodel.tiangolo.com/) as ORM. It shows a complete async CRUD template using authentication. Our implementation utilizes the newest version of FastAPI and incorporates typing hints that are fully compatible with **Python 3.10** and later versions. If you're looking to build modern and efficient web applications with Python, this template will provide you with the necessary tools to get started quickly. You can read a short article with the motivations for starting this sample project [here](https://medium.com/allient/our-journey-using-async-fastapi-to-harnessing-the-power-of-modern-web-apis-90301827f14c?source=friends_link&sk=9006b3f2a4137a28a8576a69546c8c18).



  Developing web applications can be a challenging process, especially when dealing with databases, authentication, asynchronous tasks, and other complex components. Our template is designed to simplify this process and offer you a solid starting point. Some of the highlights of this template include:

  - FastAPI Integration: FastAPI is a modern and efficient web framework that allows you to quickly and easily create APIs. This template uses the latest features of FastAPI and offers type hints that are compatible with **Python 3.10** and later versions.
  - Asynchronous Database Management: We use SQLModel, an asynchronous ORM library, to interact with the database efficiently and securely.
  - Asynchronous Tasks with Celery: This template includes examples of how to execute asynchronous and scheduled tasks using Celery, which is ideal for operations that require significant time or resources.
  - Authentication and Authorization: We implement JWT-based authentication and role-based access control to ensure that your APIs are secure and protected.
  - Documentation and Automated Testing: The template is configured to automatically generate interactive documentation for your APIs. It also includes automated tests using pytest to ensure code quality.
  - Development Best Practices: We apply code formatting, type checking, and static analysis tools to ensure that the code is readable, robust, and reliable.



  ```bash
  .
  ├───.github
  │   └───workflows
  ├───.vscode
  ├───backend
  │   └───app
  │       ├───alembic
  │       │   └───versions
  │       ├───app
  │       │   ├───api
  │       │   │   └───v1
  │       │   │       └───endpoints
  │       │   ├───core
  │       │   ├───crud
  │       │   ├───db
  │       │   ├───deps
  │       │   ├───models
  │       │   ├───schemas
  │       │   └───utils
  │       │       └───exceptions
  │       └───test
  │           └───api
  ├───caddy
  ├───db_docker
  ├───docs
  ├───minio
  ├───pgadmin
  ├───sonarqube
  ├───static
  └───terraform
  ```



  - [FastAPI](https://fastapi.tiangolo.com/) - A modern, fast (high-performance), web framework for building APIs with Python 3.6+ based on standard Python type hints.
  - [Pydantic](https://docs.pydantic.dev/latest/) - A library for data validation and settings management based on Python type hints.
  - [SQLModel](https://sqlmodel.tiangolo.com/) - A library for interacting with SQL databases from Python code, with Python objects.
  - [Alembic](https://alembic.sqlalchemy.org/en/latest/) - A lightweight database migration tool for usage with the SQLAlchemy Database Toolkit for Python.
  - [Caddy](https://caddyserver.com/) - A powerful, enterprise-ready, open source web server with automatic HTTPS written in Go.
  - [Docker](https://www.docker.com/) - A set of platform as a service (PaaS) products that use OS-level virtualization to deliver software in packages called containers.
  - [PostgreSQL](https://www.postgresql.org/) - A powerful, open source object-relational database system.
  - [PGAdmin](https://www.pgadmin.org/) - The most popular and feature rich Open Source administration and development platform for PostgreSQL.
  - [Celery](https://docs.celeryq.dev/en/stable/) - A simple, flexible, and reliable distributed system to process vast amounts of messages, while providing operations with the tools required to maintain such a system.
  - [Redis](https://redis.io/) - An open source (BSD licensed), in-memory data structure store, used as a database, cache, and message broker.
  - [Minio](https://min.io/) - A high performance distributed object storage server, designed for large-scale private cloud infrastructure.
  - [SonarQube](https://www.sonarqube.org/) - An open source platform for continuous inspection of code quality.
  - [Pytest](https://docs.pytest.org/en/stable/) - A framework that makes it easy to write small tests, yet scales to support complex functional testing for applications and libraries.

  </details>



  The commands in this documentation can be customized on the **Makefile**. It can be started with and without docker.

  After your project is created. First, make sure you have all packages installed:

  ```bash
  make install
  ```

  Run the server:

  ```bash

  make run-app


  make run-dev-build


  make run-dev-build


  make run-prod
  ```



  To learn more about Fastapi, take a look at the following resources:

  - [Fastapi Documentation](https://fastapi.tiangolo.com/).
  - [fastapi-alembic-sqlmodel-async](https://github.com/jonra1993/fastapi-alembic-sqlmodel-async).
  - [full-stack-fastapi-postgresql](https://github.com/tiangolo/full-stack-fastapi-postgresql).
  - [sqlmodel-tutorial](https://sqlmodel.tiangolo.com/tutorial/fastapi/).
  - [asyncer-tutorial](https://asyncer.tiangolo.com/tutorial/).
  - [fastapi-pagination](https://github.com/uriyyo/fastapi-pagination).
  - [fastapi-best-practices](https://github.com/zhanymkanov/fastapi-best-practices).
  - [awesome-fastapi](https://github.com/mjhea0/awesome-fastapi).



  `create-fastapi-project` provides a streamlined way to kickstart your FastAPI projects. Here are some compelling reasons to choose it for your project setup:



  Running `create-fastapi-project` (with no arguments) launches an interactive experience that guides you through the process of setting up your project. This interactive approach simplifies the initial configuration and gets you started quickly.



  `create-fastapi-project` has been designed to be lightweight and efficient. It requires zero external dependencies, ensuring that your project remains unburdened by unnecessary packages.



  `create-fastapi-project` is maintained by the [Allient development team](https://www.allient.io/). Our team is composed by a experienced professionals specializing in FastAPI projects and NLP. If you need assistance or support for your project, please don't hesitate to get in touch with us at [info@allient.io](mailto:info@allient.io) or schedule a meeting with us [here](https://calendly.com/jonathanvargas).

  You can check out the [create-fastapi-project GitHub repository](https://github.com/allient/create-fastapi-project) - your feedback and contributions are welcome ❤️!



  [![License](http://img.shields.io/:license-mit-blue.svg?style=flat-square)](http://badges.mit-license.org)

  - This project is licensed under the terms of the **[MIT license](LICENSE)**


pkgId: bcfef96cdbf6ca4cf0fd8fe96817355e20fe3c145eee6102c92d6bdb1896ee19
name: python-create-icon
arch: src
version: 0.5.0
epoch: 0
release: 1
summary: A Simple icon to replace the tkinter feather for your programs
url: https://github.com/Caveman-Software/create_icon
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-create-icon-0.5.0-1.src.rpm
checksum_type: sha256
description:
      import os
      from tkinter import Tk
      root=Tk()
      root.minsize(300,100)
      
      if os.name == 'nt':
          homepath = os.path.expanduser('~')
          tempFile = os.path.join(homepath, 'Caveman Software', 'Icon', 'icon.ico')
          if (os.path.exists(tempFile) == True):
              root.wm_iconbitmap(default=tempFile)
          else:
              import create_icon
              print('File Created')
              root.wm_iconbitmap(default=tempFile)


pkgId: 615e3f147d850f71b64946bee8db8c74deeddbbf1634a9684c31c6a0ea7c09e4
name: python-create-mcp-server
arch: src
version: 1.0.1
epoch: 0
release: 1
summary: Create an MCP server project from a template.
url: https://pypi.org/project/create-mcp-server/
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-create-mcp-server-1.0.1-1.src.rpm
checksum_type: sha256
description:
  [![PyPI](https://img.shields.io/pypi/v/create-mcp-server)](https://pypi.org/project/create-mcp-server/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

  Create [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server projects with no build configuration.



  ```sh

  uvx create-mcp-server


  pip install create-mcp-server
  create-mcp-server
  ```

  You don't need to install or configure any dependencies manually. The tool will set up everything you need to create an MCP server.



  **You'll need to have [UV](https://docs.astral.sh/uv/) >= 0.4.10 installed on your machine.**

  To create a new server, run either of these commands:


  ```sh
  uvx create-mcp-server
  ```


  ```sh
  pip install create-mcp-server
  create-mcp-server
  ```

  It will walk you through creating a new MCP server project. When complete, you'll have a new directory with this structure:

  ```
  my-server/
  ├── README.md
  ├── pyproject.toml
  └── src/
      └── my_server/
          ├── __init__.py
          ├── __main__.py
          └── server.py
  ```

  No configuration or complicated folder structures, only the files you need to run your server.

  Once installation is done, you can start the server:

  ```sh
  cd my-server
  uv sync --dev --all-extras
  uv run my-server
  ```



  - Simple command-line interface for creating new projects
  - Auto-configures Claude Desktop app integration when available
  - Uses [uvx](https://docs.astral.sh/uv/guides/tools/) for fast, reliable package management and project creation
  - Sets up basic MCP server structure
  - Uses the [Model Context Protocol Python SDK](https://github.com/modelcontextprotocol/python-sdk) for the server project



  - **Zero Configuration:** No need to manually set up project structure or dependencies.
  - **Best Practices:** Follows Python packaging standards and MCP server patterns.
  - **Batteries Included:** Comes with everything needed to start building an MCP server.



  Create MCP Server is open source software [licensed as MIT](https://opensource.org/licenses/MIT).


pkgId: f34bf8ad5e2095a889a3800c773f1cd8704c44f82b0d5acd12d060c4c44e757c
name: python-create-pypi-skeleton
arch: src
version: 0.0.5
epoch: 0
release: 1
url: https://github.com/zlliu246/create_pypi_skeleton
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-create-pypi-skeleton-0.0.5-1.src.rpm
checksum_type: sha256
summary:
  This module automatically creates a PyPI project skeleton for you so you don't have to do this manually.

description:
  This module automatically creates a PyPI project skeleton for you so you don't have to do this manually.


  ```
  pip install create-pypi-skeleton
  ```


  ```
  python -m create_pypi_skeleton your_module_name
  ```


  ```python
  from create_pypi_skeleton import create_pypi_skeleton

  create_pypi_skeleton("your_module_name")
  ```



  ```
  Typical PyPI project skeleton given module_name="testing123"

  testing123/
      src/                    # all code goes here
          testing123/
              __init__.py     # main folder where users import functions from
          tests/
              main.py         # unit tests go here
          __init__.py
      .gitignore              # files/folders written here are ignored by git
      LICENSE                 # license stuff
      pyproject.toml          # contains important config stuff for PyPI
      README.md               # tells users what your project is about
      upload.py               # helper script to upload project to PyPI
  ```


pkgId: fa9536e264f068e3c12a1ef15e51ce7d25bd7e4a0cd0c66070f9da3a73c41e21
name: python-create-python-cmd
arch: src
version: 2.0.0
epoch: 0
release: 1
summary: Cross platform(ish) productivity commands written in python.
url: https://github.com/zackees/create-python-cmd
rpm_license: BSD 3-Clause License
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-create-python-cmd-2.0.0-1.src.rpm
checksum_type: sha256
description:
  [![Linting](https://github.com/zackees/createpythonapp/actions/workflows/lint.yml/badge.svg)](https://github.com/zackees/createpythonapp/actions/workflows/lint.yml)

  [![MacOS_Tests](https://github.com/zackees/createpythonapp/actions/workflows/push_macos.yml/badge.svg)](https://github.com/zackees/createpythonapp/actions/workflows/push_macos.yml)
  [![Ubuntu_Tests](https://github.com/zackees/createpythonapp/actions/workflows/push_ubuntu.yml/badge.svg)](https://github.com/zackees/createpythonapp/actions/workflows/push_ubuntu.yml)
  [![Win_Tests](https://github.com/zackees/createpythonapp/actions/workflows/push_win.yml/badge.svg)](https://github.com/zackees/createpythonapp/actions/workflows/push_win.yml)


  This is a command for creating a skeleton project for python commands. It uses
  uv to boot strap the project and install an environment. Helpful utilities for
  installing the project are given, wee below.

  Template that this uses is here:
    * https://github.com/zackees/template-python-cmd

  ```python
  > pip install create-python-cmd
  > git clone https://github.com/.../myproject
  > cd myproject
  > createpythoncmd # Creates a new Python command line application.
  ```

  Creates a new Python command line application with linters and tests.



  The following tools will be installed
    * `install` - script to boot strap and install the python package
    * `clean` - removes build artifacts
    * `lint` - runs the linters on the source code
    * `test` - runs the unit test



  The following linters are used
    * `ruff`
    * `black`
    * `isort`
    * `mypy`




  To upload your project to pypi simply run `. ./upload_package.sh`


    * `2.0.0` - Moved to the uv build system as this is much better and fixes the boot strapping of python issue. Fixes git bash not being cd'd to the current directory in VSCode.
    * `1.2.5` - Varius fixes and test fixes.
    * `1.2.2` - Adds retries to get correct parameters and auto corrects parameters instead of exiting.
    * `1.2.0` - Refresh with new modern practices like an installation script.
    * `1.1.1` - Adds chmod +x to shell scripts and adds post install instructions.
    * `1.1.0` - createpythonapp -> createpythoncmd.
    * `1.0.9` - Adds keywords prompt during setup.


pkgId: 21e2da324f4279182c24d27e6aea0105d31c0bc26b08d377377978cfefcf38ba
name: python-createcoverage
arch: src
version: 1.5
epoch: 0
release: 1
summary: Single command to create coverage reports (assumes a bin/test)
url: https://github.com/reinout/createcoverage
rpm_license: GPL
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-createcoverage-1.5-1.src.rpm
checksum_type: sha256
description:
  This package installs one command: ``createcoverage`` that runs your tests
  with coverage.py and opens the coverage reports in your browser.  All with
  just one single handy command.
  Assumption: you're using buildout.  Or rather, the assumption is that you have
  a ``bin/test`` command that runs all your tests.
  No options are passed to coverage.py, so any extra options you want to give to
  coverage must be put in a ``.coveragerc`` in your buildout's root.  This is a
  good idea in any case :-)  An example .coveragerc that omits code you normally
  don't want to include in a coverage report::
      [report]
      omit =
          /home/*/.buildout/eggs/*
          /usr/*
          parts/*
          eggs/*
          */test*
  Installing ``createcoverage`` in a zc.recipe.egg section is enough.
  Createcoverage itself depends on `coverage.py
  <http://nedbatchelder.com/code/coverage/>`_ and makes sure ``bin/coverage`` is
  created::
      [console_scripts]
      recipe = zc.recipe.egg
      eggs = createcoverage


pkgId: 4f941b81b8d9751d12897d32875248e7bf91d9f8b6bcfb6fb9b0f75c586f7ebc
name: python-creatio-api-py
arch: src
version: 1.1.1
epoch: 0
release: 1
summary: Python client for Creatio OData API
url: https://github.com/yisuschrist/creatio-api-py
rpm_license: GPL-3.0-only
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-creatio-api-py-1.1.1-1.src.rpm
checksum_type: sha256
description:
  ![Creatio](https://upload.wikimedia.org/wikipedia/commons/thumb/7/76/Creatio_logo.svg/2560px-Creatio_logo.svg.png)

  <p align="center">
      <a href="https://github.com/YisusChrist/creatio-api-py/issues">
          <img src="https://img.shields.io/github/issues/YisusChrist/creatio-api-py?color=171b20&label=Issues%20%20&logo=gnubash&labelColor=e05f65&logoColor=ffffff">&nbsp;&nbsp;&nbsp;
      </a>
      <a href="https://github.com/YisusChrist/creatio-api-py/forks">
          <img src="https://img.shields.io/github/forks/YisusChrist/creatio-api-py?color=171b20&label=Forks%20%20&logo=git&labelColor=f1cf8a&logoColor=ffffff">&nbsp;&nbsp;&nbsp;
      </a>
      <a href="https://github.com/YisusChrist/creatio-api-py/">
          <img src="https://img.shields.io/github/stars/YisusChrist/creatio-api-py?color=171b20&label=Stargazers&logo=octicon-star&labelColor=70a5eb">&nbsp;&nbsp;&nbsp;
      </a>
      <a href="https://github.com/YisusChrist/creatio-api-py/actions">
          <img alt="Tests Passing" src="https://github.com/YisusChrist/creatio-api-py/actions/workflows/github-code-scanning/codeql/badge.svg">&nbsp;&nbsp;&nbsp;
      </a>
      <a href="https://github.com/YisusChrist/creatio-api-py/pulls">
          <img alt="GitHub pull requests" src="https://img.shields.io/github/issues-pr/YisusChrist/creatio-api-py?color=0088ff">&nbsp;&nbsp;&nbsp;
      </a>
      <a href="https://opensource.org/license/gpl-2-0/">
          <img alt="License" src="https://img.shields.io/github/license/YisusChrist/creatio-api-py?color=0088ff">
      </a>
  </p>

  <br>

  <p align="center">
      <a href="https://github.com/YisusChrist/creatio-api-py/issues/new/choose">Report Bug</a>
      ·
      <a href="https://github.com/YisusChrist/creatio-api-py/issues/new/choose">Request Feature</a>
      ·
      <a href="https://github.com/YisusChrist/creatio-api-py/discussions">Ask Question</a>
      ·
      <a href="https://github.com/YisusChrist/creatio-api-py/security/policy#reporting-a-vulnerability">Report security bug</a>
  </p>

  <br>

  ![Alt](https://repobeats.axiom.co/api/embed/7fb383884a6d110fbd2119f26faed85c7cdc8202.svg "Repobeats analytics image")

  <br>

  This Python library is designed for testing the OData API of Creatio. It includes functionality for authentication, making generic HTTP requests to the OData service, and performing various operations on object collections.

  <details>
  <summary>Table of Contents</summary>

  - [Features](#features)
  - [Requirements](#requirements)
  - [Installation](#installation)
    - [From PyPI](#from-pypi)
    - [Manual installation](#manual-installation)
    - [Uninstall](#uninstall)
  - [Usage](#usage)
    - [Authentication](#authentication)
    - [Add a Record to a Collection](#add-a-record-to-a-collection)
    - [Modify a Record in a Collection](#modify-a-record-in-a-collection)
    - [Get Data from a Collection](#get-data-from-a-collection)
    - [Delete a Record from a Collection](#delete-a-record-from-a-collection)
    - [Handle information from the API session](#handle-information-from-the-api-session)
  - [Contributors](#contributors)
    - [How do I contribute to creatio-api-py?](#how-do-i-contribute-to-creatio-api-py)
  - [License](#license)

  </details>



  - **Authentication**: Authenticate and obtain a session cookie for subsequent requests.
  - **HTTP Requests**: Make generic HTTP requests (GET, POST, PATCH, DELETE) to the OData service.
  - **Collection Operations**: Interact with object collections, including adding, modifying, and deleting records.
  - **Logging**: Enable debugging to log detailed information about HTTP requests and responses.



  Here's a breakdown of the packages needed and their versions:

  - [poetry](https://pypi.org/project/poetry) >= 1.7.1 (_only for manual installation_)
  - [python-dotenv](https://pypi.org/project/aiohttp) >= 1.0.1
  - [requests-cache](https://pypi.org/project/requests-cache) >= 1.1.1
  - [requests-pprint](https://pypi.org/project/requests-pprint) >= 1.0.0
  - [requests](https://pypi.org/project/requests) >= 2.31.0
  - [rich](https://pypi.org/project/rich) >= 13.7.0

  > [!NOTE]\
  > The software has been developed and tested using Python `3.12.1`. The minimum required version to run the software is Python 3.6. Although the software may work with previous versions, it is not guaranteed.





  `creatio-api-py` can be installed easily as a PyPI package. Just run the following command:

  ```bash
  pip3 install creatio-api-py
  ```

  > [!IMPORTANT]
  > For best practices and to avoid potential conflicts with your global Python environment, it is strongly recommended to install this program within a virtual environment. Avoid using the --user option for global installations. We highly recommend using [pipx](https://pypi.org/project/pipx) for a safe and isolated installation experience. Therefore, the appropriate command to install `creatio-api-py` would be:
  >
  > ```bash
  > pipx install creatio-api-py
  > ```



  If you prefer to install the program manually, follow these steps:

  > [!NOTE]\
  > This will install the version from the latest commit, not the latest release.

  1. Download the latest version of [creatio-api-py](https://github.com/YisusChrist/creatio-api-py) from this repository:

     ```sh
     git clone https://github.com/YisusChrist/creatio-api-py
     cd creatio-api-py
     ```

  2. Install the package:

     ```sh
     poetry install --only-main
     ```



  If you installed it from PyPI, you can use the following command:

  ```bash
  pipx uninstall creatio-api-py
  ```



  The package allows you to stablish connection to any Creatio environment using the credentials of a user with the necessary permissions. The following steps will guide you through the process of setting up the environment and running the script.

  1. Set up your environment variables by creating a .env file with the following content:

     ```env
     CREATIO_USERNAME=your_username
     CREATIO_PASSWORD=your_password
     ```

  2. Authenticate to the Creatio environment:

     ```python
     from creatio_api_py.api import CreatioODataAPI
     from creatio_api_py.utils import print_exception

     creatio_url: str = "https://your-environment.creatio.com"
     api = CreatioODataAPI(base_url=creatio_url)
     try:
        
        api.authenticate()
     except Exception as e:
        print_exception(e, f"Unable to authenticate on {creatio_url}")
     ```

     If you don't want to use the .env file, you can pass the credentials directly to the `authenticate` method:

     ```python
     api.authenticate(username="your_username", password="your_password")
     ```

     The `authenticate` method will return an HTTP response object. If the status code is 200, the authentication was successful, and the session cookie is stored in the `api` object. Therefore, your don't need to pass the cookie to the other methods, it will be used automatically for the next requests.

     However, if you want to check the cookie value, you can access it using the `cookie` attribute:

     ```python
     cookie = api.session_cookies
     print(cookie)
     ```

     Response Cookie:

     ```python
     {
        'BPMLOADER': 'lima0ugkfcecqs23bdeio1k4',
        '.ASPXAUTH': '7AE0D4CDCD7DCB01A65ACAF85D8DAC0D842B41745CB17A4AEF4C6F18701757AEA7EAFA90565091E61A54E5559A2B1113C6A6EDA78EFEDECD10176937BBD7F9FEBCAC9210963D42AC059C9858A29F7C903E9CB5FAC3B36CF273B8FF94850CDC01D21F69874990586EEDE392900D87C9D09DF3053D7E5AEDB0D79E0F9172634C9F2566424A5B5F38BD58C2EF1BC06E98ED9168488F7ADE262147E73A3A082CB8CAC74C6A4F6B50555D1ED2A93FC05070E0607B79B32F4ED8B8306918E1F2CCAC1C88CB651DFDF795A36E0A03EFFE0A8AA960BDCD358065C8FDABBF9C59A3FC0B2FEFD77C7E1FC484B6CDAB162F2A5EFB0084FDAA6404AF2773C3DBB8147F83E7040400172E332523BB415AC9432269BF5ED53E2BD70C336CDA513228617AC7A2C9BAD79CBEFE1DE193B1C8E5D6EC836D9F67F4F4033F759CA7E7EDBC433C72441110ECCBD386E05E960822BE049D7BACE51EDFA6B47E57BC654C4B7B3D047AEF9F14F92ACAB37D4286FC9494656B489DE1512DB33869291366E70DA77C9BEDB67706F5896F65B3F835D3C6B4D3367FC7FD086556E1B6F7777FD123848A7038F0AF923758AE398705069FF295D4C0CC180710DC2DE26DD91C09025F0093784241B60757937FEE936A2B80995617DFBB7FE54262F85F7AD4D5465413554A1C67BB0FD21793826C050E8AB83D39747A049C138792E079',
        'BPMCSRF': 'ezBoM358i3BgxRyW1kKF0u',
        'UserType': 'General',
        'UserName': '83|117|112|101|114|118|105|115|111|114'
     }
     ```

  Here are some examples of how to interact with the Creatio API using this package:



  ```python
  from creatio_api_py.api import CreatioODataAPI
  from creatio_api_py.utils import print_exception

  creatio_url: str = "https://your-environment.creatio.com"
  api = CreatioODataAPI(base_url=creatio_url)
  try:
     
     api.authenticate()
  except Exception as e:  # pylint: disable=broad-except
     print_exception(e, f"Unable to authenticate on {creatio_url}")
  ```



  ```python
  payload: dict[str, str] = {
     "UsrEmail": "test@test.com",
     "UsrTelefono": "123456789",
     "UsrDescripcionBienContratado": "Test",
     
  }

  response = api.add_collection_data("Case", data=payload)
  ```

  - Response code: 201 Created
  - Response body:

  ```python
  {
     '@odata.context': 'https://your-environment.creatio.com/0/odata/$metadata#Case/$entity',
     'Id': 'cf8c6558-9e3e-48ca-a237-765b0f54b798',
     'CreatedOn': '2024-06-17T15:28:32.7013964Z',
     'CreatedById': '410006e1-ca4e-4502-a9ec-e54d922d2c00',
     'ModifiedOn': '2024-06-17T15:28:32.7013964Z',
     'ModifiedById': '410006e1-ca4e-4502-a9ec-e54d922d2c00',
     'ProcessListeners': 0,
     'Number': 'SR00005250',
     'UsrDescripcionBienContratado': 'Test',
     'UsrEmail': 'test@test.com',
     'UsrTelefono': '123456789',
     
  }
  ```

  Creatio returns the created record with the `Id` field. You can use this ID to modify or delete the record later.



  ```python
  payload: dict[str, str] = {
     "UsrDescripcionBienContratado": "New test description",
  }

  record_id = "cf8c6558-9e3e-48ca-a237-765b0f54b798"
  response = api.modify_collection_data("Case", record_id=record_id, data=payload)
  ```

  - Response code: 204 No Content
  - Response body: None

  The response code 204 indicates that the record has been successfully updated. Creatio does not return a body in this case.



  ```python
  record_id = "cf8c6558-9e3e-48ca-a237-765b0f54b798"
  response = api.get_collection_data("Case", record_id=record_id)
  ```

  - Response code: 200 OK
  - Response body:

  ```python
  {
     '@odata.context': 'https://your-environment.creatio.com/0/odata/$metadata#Case/$entity',
     'Id': 'cf8c6558-9e3e-48ca-a237-765b0f54b798',
     'CreatedOn': '2024-06-17T15:28:32.7013964Z',
     'CreatedById': '410006e1-ca4e-4502-a9ec-e54d922d2c00',
     'ModifiedOn': '2024-06-17T15:28:32.7013964Z',
     'ModifiedById': '410006e1-ca4e-4502-a9ec-e54d922d2c00',
     'ProcessListeners': 0,
     'Number': 'SR00005250',
     'UsrDescripcionBienContratado': 'New test description',
     'UsrEmail': 'test@test.com',
     'UsrTelefono': '123456789',
     
  }
  ```

  As you can see, the field `UsrDescripcionBienContratado` has been updated.



  - Response code: 204 No Content
  - Response body: None

  ```python
  record_id = "cf8c6558-9e3e-48ca-a237-765b0f54b798"
  response = api.delete_collection_data("Case", record_id=record_id)
  ```

  The response code 204 indicates that the record has been successfully deleted. Creatio does not return a body in this case.

  If we try to get the record again, we will get a 404 Not Found response:

  ```python
  record_id = "cf8c6558-9e3e-48ca-a237-765b0f54b798"
  response = api.get_collection_data("Case", record_id=record_id)
  ```

  - Response code: 404 Not Found
  - Response body: None



  It is possible to retrieve information like the total number of requests made, the base url used for the class instance, and the session cookies.

  ```python
  total_requests = api.total_requests

  base_url = api.base_url

  session_cookies = api.session_cookies

  ```

  Additionally, you can modify the object's base url if needed:

  ```python
  api.base_url = "https://another-environment.creatio.com"
  ```



  <a href="https://github.com/YisusChrist/creatio-api-py/graphs/contributors"><img src="https://contrib.rocks/image?repo=YisusChrist/creatio-api-py" /></a>



  Before you participate in our delightful community, please read the [code of conduct](https://github.com/YisusChrist/.github/blob/main/CODE_OF_CONDUCT.md).

  I'm far from being an expert and suspect there are many ways to improve – if you have ideas on how to make the configuration easier to maintain (and faster), don't hesitate to fork and send pull requests!

  We also need people to test out pull requests. So take a look through [the open issues](https://github.com/YisusChrist/creatio-api-py/issues) and help where you can.

  See [Contributing](https://github.com/YisusChrist/.github/blob/main/CONTRIBUTING.md) for more details.



  `creatio-api-py` is licensed under the [GNU General Public License v3.0](https://opensource.org/licenses/GPL-3.0).


pkgId: ea6f2c4679c2267158b9869fd0c52eb338ddc67f6949dac476cf156ba8c8c8be
name: python-creatio-api-py
arch: src
version: 1.2.0
epoch: 0
release: 1
summary: Python client for Creatio OData API
url: https://github.com/yisuschrist/creatio-api-py
rpm_license: GPL-3.0-only
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-creatio-api-py-1.2.0-1.src.rpm
checksum_type: sha256
description:
  ![Creatio](https://upload.wikimedia.org/wikipedia/commons/thumb/7/76/Creatio_logo.svg/2560px-Creatio_logo.svg.png)

  <p align="center">
      <a href="https://github.com/YisusChrist/creatio-api-py/issues">
          <img src="https://img.shields.io/github/issues/YisusChrist/creatio-api-py?color=171b20&label=Issues%20%20&logo=gnubash&labelColor=e05f65&logoColor=ffffff">&nbsp;&nbsp;&nbsp;
      </a>
      <a href="https://github.com/YisusChrist/creatio-api-py/forks">
          <img src="https://img.shields.io/github/forks/YisusChrist/creatio-api-py?color=171b20&label=Forks%20%20&logo=git&labelColor=f1cf8a&logoColor=ffffff">&nbsp;&nbsp;&nbsp;
      </a>
      <a href="https://github.com/YisusChrist/creatio-api-py/stargazers">
          <img src="https://img.shields.io/github/stars/YisusChrist/creatio-api-py?color=171b20&label=Stargazers&logo=octicon-star&labelColor=70a5eb">&nbsp;&nbsp;&nbsp;
      </a>
      <a href="https://github.com/YisusChrist/creatio-api-py/actions">
          <img alt="Tests Passing" src="https://github.com/YisusChrist/creatio-api-py/actions/workflows/github-code-scanning/codeql/badge.svg">&nbsp;&nbsp;&nbsp;
      </a>
      <a href="https://github.com/YisusChrist/creatio-api-py/pulls">
          <img alt="GitHub pull requests" src="https://img.shields.io/github/issues-pr/YisusChrist/creatio-api-py?color=0088ff">&nbsp;&nbsp;&nbsp;
      </a>
      <a href="https://opensource.org/license/GPL-3.0/">
          <img alt="License" src="https://img.shields.io/github/license/YisusChrist/creatio-api-py?color=0088ff">
      </a>
  </p>

  <br>

  <p align="center">
      <a href="https://github.com/YisusChrist/creatio-api-py/issues/new/choose">Report Bug</a>
      ·
      <a href="https://github.com/YisusChrist/creatio-api-py/issues/new/choose">Request Feature</a>
      ·
      <a href="https://github.com/YisusChrist/creatio-api-py/discussions">Ask Question</a>
      ·
      <a href="https://github.com/YisusChrist/creatio-api-py/security/policy#reporting-a-vulnerability">Report security bug</a>
  </p>

  <br>

  ![Alt](https://repobeats.axiom.co/api/embed/7fb383884a6d110fbd2119f26faed85c7cdc8202.svg "Repobeats analytics image")

  <br>

  This Python library is designed for testing the OData API of Creatio. It includes functionality for authentication, making generic HTTP requests to the OData service, and performing various operations on object collections.

  <details>
  <summary>Table of Contents</summary>

  - [Features](#features)
  - [Requirements](#requirements)
  - [Installation](#installation)
    - [From PyPI](#from-pypi)
    - [Manual installation](#manual-installation)
    - [Uninstall](#uninstall)
  - [Usage](#usage)
    - [Authentication](#authentication)
    - [Add a Record to a Collection](#add-a-record-to-a-collection)
    - [Modify a Record in a Collection](#modify-a-record-in-a-collection)
    - [Get Data from a Collection](#get-data-from-a-collection)
    - [Delete a Record from a Collection](#delete-a-record-from-a-collection)
    - [Handle information from the API session](#handle-information-from-the-api-session)
  - [Contributors](#contributors)
    - [How do I contribute to creatio-api-py?](#how-do-i-contribute-to-creatio-api-py)
  - [License](#license)

  </details>



  - **Authentication**: Authenticate and obtain a session cookie for subsequent requests.
  - **HTTP Requests**: Make generic HTTP requests (GET, POST, PATCH, DELETE) to the OData service.
  - **Collection Operations**: Interact with object collections, including adding, modifying, and deleting records.
  - **Logging**: Enable debugging to log detailed information about HTTP requests and responses.



  Here's a breakdown of the packages needed and their versions:

  - [poetry](https://pypi.org/project/poetry) >= 1.7.1 (_only for manual installation_)
  - [python-dotenv](https://pypi.org/project/aiohttp) >= 1.0.1
  - [requests-cache](https://pypi.org/project/requests-cache) >= 1.1.1
  - [requests-pprint](https://pypi.org/project/requests-pprint) >= 1.0.0
  - [requests](https://pypi.org/project/requests) >= 2.31.0
  - [rich](https://pypi.org/project/rich) >= 13.7.0

  > [!NOTE]\
  > The software has been developed and tested using Python `3.12.1`. The minimum required version to run the software is Python 3.6. Although the software may work with previous versions, it is not guaranteed.





  `creatio-api-py` can be installed easily as a PyPI package. Just run the following command:

  ```bash
  pip3 install creatio-api-py
  ```

  > [!IMPORTANT]
  > For best practices and to avoid potential conflicts with your global Python environment, it is strongly recommended to install this program within a virtual environment. Avoid using the --user option for global installations. We highly recommend using [pipx](https://pypi.org/project/pipx) for a safe and isolated installation experience. Therefore, the appropriate command to install `creatio-api-py` would be:
  >
  > ```bash
  > pipx install creatio-api-py
  > ```



  If you prefer to install the program manually, follow these steps:

  > [!NOTE]\
  > This will install the version from the latest commit, not the latest release.

  1. Download the latest version of [creatio-api-py](https://github.com/YisusChrist/creatio-api-py) from this repository:

     ```sh
     git clone https://github.com/YisusChrist/creatio-api-py
     cd creatio-api-py
     ```

  2. Install the package:

     ```sh
     poetry install --only-main
     ```



  If you installed it from PyPI, you can use the following command:

  ```bash
  pipx uninstall creatio-api-py
  ```



  The package allows you to stablish connection to any Creatio environment using the credentials of a user with the necessary permissions. The following steps will guide you through the process of setting up the environment and running the script.

  1. Set up your environment variables by creating a .env file with the following content:

     ```env
     CREATIO_USERNAME=your_username
     CREATIO_PASSWORD=your_password
     ```

  2. Authenticate to the Creatio environment:

     ```python
     from creatio_api_py.api import CreatioODataAPI
     from creatio_api_py.utils import print_exception

     creatio_url: str = "https://your-environment.creatio.com"
     api = CreatioODataAPI(base_url=creatio_url)
     try:
        
        api.authenticate()
     except Exception as e:
        print_exception(e, f"Unable to authenticate on {creatio_url}")
     ```

     If you don't want to use the .env file, you can pass the credentials directly to the `authenticate` method:

     ```python
     api.authenticate(username="your_username", password="your_password")
     ```

     The `authenticate` method will return an HTTP response object. If the status code is 200, the authentication was successful, and the session cookie is stored in the `api` object. Therefore, your don't need to pass the cookie to the other methods, it will be used automatically for the next requests.

     However, if you want to check the cookie value, you can access it using the `cookie` attribute:

     ```python
     cookie = api.session_cookies
     print(cookie)
     ```

     Response Cookie:

     ```json
     {
        "BPMLOADER": "lima0ugkfcecqs23bdeio1k4",
        ".ASPXAUTH": "7AE0D4CDCD7DCB01A65ACAF85D8DAC0D842B41745CB17A4AEF4C6F18701757AEA7EAFA90565091E61A54E5559A2B1113C6A6EDA78EFEDECD10176937BBD7F9FEBCAC9210963D42AC059C9858A29F7C903E9CB5FAC3B36CF273B8FF94850CDC01D21F69874990586EEDE392900D87C9D09DF3053D7E5AEDB0D79E0F9172634C9F2566424A5B5F38BD58C2EF1BC06E98ED9168488F7ADE262147E73A3A082CB8CAC74C6A4F6B50555D1ED2A93FC05070E0607B79B32F4ED8B8306918E1F2CCAC1C88CB651DFDF795A36E0A03EFFE0A8AA960BDCD358065C8FDABBF9C59A3FC0B2FEFD77C7E1FC484B6CDAB162F2A5EFB0084FDAA6404AF2773C3DBB8147F83E7040400172E332523BB415AC9432269BF5ED53E2BD70C336CDA513228617AC7A2C9BAD79CBEFE1DE193B1C8E5D6EC836D9F67F4F4033F759CA7E7EDBC433C72441110ECCBD386E05E960822BE049D7BACE51EDFA6B47E57BC654C4B7B3D047AEF9F14F92ACAB37D4286FC9494656B489DE1512DB33869291366E70DA77C9BEDB67706F5896F65B3F835D3C6B4D3367FC7FD086556E1B6F7777FD123848A7038F0AF923758AE398705069FF295D4C0CC180710DC2DE26DD91C09025F0093784241B60757937FEE936A2B80995617DFBB7FE54262F85F7AD4D5465413554A1C67BB0FD21793826C050E8AB83D39747A049C138792E079",
        "BPMCSRF": "ezBoM358i3BgxRyW1kKF0u",
        "UserType": "General",
        "UserName": "83|117|112|101|114|118|105|115|111|114"
     }
     ```

  Here are some examples of how to interact with the Creatio API using this package:



  ```python
  from creatio_api_py.api import CreatioODataAPI
  from creatio_api_py.utils import print_exception

  creatio_url: str = "https://your-environment.creatio.com"
  api = CreatioODataAPI(base_url=creatio_url)
  try:
     
     api.authenticate()
  except Exception as e:  # pylint: disable=broad-except
     print_exception(e, f"Unable to authenticate on {creatio_url}")
  ```

  - Response code: `200 OK`
  - Response body:

  ```json
  {
    "Code": 0,
    "Message": "",
    "Exception": null,
    "PasswordChangeUrl": null,
    "RedirectUrl": "/0/Shell",
    "UserType": "General"
  }
  ```



  ```python
  payload: dict[str, str] = {
     "UsrEmail": "test@test.com",
     "UsrTelefono": "123456789",
     "UsrDescripcionBienContratado": "Test",
     
  }

  response = api.add_collection_data("Case", data=payload)
  ```

  - Response code: `201 Created`
  - Response body:

  ```json
  {
     "@odata.context": "https://your-environment.creatio.com/0/odata/$metadata#Case/$entity",
     "Id": "cf8c6558-9e3e-48ca-a237-765b0f54b798",
     "CreatedOn": "2024-06-17T15:28:32.7013964Z",
     "CreatedById": "410006e1-ca4e-4502-a9ec-e54d922d2c00",
     "ModifiedOn": "2024-06-17T15:28:32.7013964Z",
     "ModifiedById": "410006e1-ca4e-4502-a9ec-e54d922d2c00",
     "ProcessListeners": 0,
     "Number": "SR00005250",
     "UsrDescripcionBienContratado": "Test",
     "UsrEmail": "test@test.com",
     "UsrTelefono": "123456789"
     // ... other fields ...
  }

  ```

  Creatio returns the created record with the `Id` field. You can use this ID to modify or delete the record later.



  ```python
  payload: dict[str, str] = {
     "UsrDescripcionBienContratado": "New test description",
  }

  record_id = "cf8c6558-9e3e-48ca-a237-765b0f54b798"
  response = api.modify_collection_data("Case", record_id=record_id, data=payload)
  ```

  - Response code: `204 No Content`
  - Response body: None

  The response code 204 indicates that the record has been successfully updated. Creatio does not return a body in this case.



  ```python
  record_id = "cf8c6558-9e3e-48ca-a237-765b0f54b798"
  response = api.get_collection_data("Case", record_id=record_id)
  ```

  - Response code: `200 OK`
  - Response body:

  ```json
  {
     "@odata.context": "https://your-environment.creatio.com/0/odata/$metadata#Case/$entity",
     "Id": "cf8c6558-9e3e-48ca-a237-765b0f54b798",
     "CreatedOn": "2024-06-17T15:28:32.7013964Z",
     "CreatedById": "410006e1-ca4e-4502-a9ec-e54d922d2c00",
     "ModifiedOn": "2024-06-17T15:28:32.7013964Z",
     "ModifiedById": "410006e1-ca4e-4502-a9ec-e54d922d2c00",
     "ProcessListeners": 0,
     "Number": "SR00005250",
     "UsrDescripcionBienContratado": "New test description",
     "UsrEmail": "test@test.com",
     "UsrTelefono": "123456789",
     // ... other fields ...
  }
  ```

  As you can see, the field `UsrDescripcionBienContratado` has been updated and we have retrieved the last value.



  - Response code: `204 No Content`
  - Response body: None

  ```python
  record_id = "cf8c6558-9e3e-48ca-a237-765b0f54b798"
  response = api.delete_collection_data("Case", record_id=record_id)
  ```

  The response code `204` indicates that the record has been successfully deleted. Creatio does not return a body in this case.

  If we try to get the record again, we will get a 404 Not Found response:

  ```python
  record_id = "cf8c6558-9e3e-48ca-a237-765b0f54b798"
  response = api.get_collection_data("Case", record_id=record_id)
  ```

  - Response code: `404 Not Found`
  - Response body: None



  It is possible to retrieve information like the total number of requests made, the base url used for the class instance, and the session cookies.

  ```python
  total_requests = api.total_requests

  base_url = api.base_url

  session_cookies = api.session_cookies

  ```

  Additionally, you can modify the object's base url if needed:

  ```python
  api.base_url = "https://another-environment.creatio.com"
  ```



  <a href="https://github.com/YisusChrist/creatio-api-py/graphs/contributors"><img src="https://contrib.rocks/image?repo=YisusChrist/creatio-api-py" /></a>



  Before you participate in our delightful community, please read the [code of conduct](https://github.com/YisusChrist/.github/blob/main/CODE_OF_CONDUCT.md).

  I'm far from being an expert and suspect there are many ways to improve – if you have ideas on how to make the configuration easier to maintain (and faster), don't hesitate to fork and send pull requests!

  We also need people to test out pull requests. So take a look through [the open issues](https://github.com/YisusChrist/creatio-api-py/issues) and help where you can.

  See [Contributing Guidelines](https://github.com/YisusChrist/.github/blob/main/CONTRIBUTING.md) for more details.



  `creatio-api-py` is licensed under the [GNU General Public License v3.0](https://opensource.org/license/GPL-3.0).


pkgId: a15552bc30ecc0ec16e509208ab5d067ee3186c0d6fe784151714a22c62a8dcd
name: python-creativiousUtilities
arch: src
version: 2.2.4
epoch: 0
release: 1
summary: Experimental and likely to break by update
url: https://pypi.org/project/creativiousUtilities/
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-creativiousUtilities-2.2.4-1.src.rpm
checksum_type: sha256
description:
  If you are to use this have it require the specific version you know works
  General purpose prebuilt functions for any project that I work on
  Author-email: Creativious <timothy@creativious.net>
  License-File: LICENSE
  Classifier: Operating System :: OS Independent
  Classifier: Programming Language :: Python :: 3
  Requires-Python: >=3.11
  Description-Content-Type: text/markdown


  ```diff
  - HIGHLY LIKELY TO BREAK FOR EACH VERSION, BACKUP BEFORE UPDATING, AND REQUIRE SPECIFIC VERSION IF YOU ARE TO USE THIS
  ```


pkgId: 9f8c04bf4bb97ce63fac01bf6c1a873ea5d5cf9e881960417031a238f6cac72c
name: python-credal
arch: src
version: 0.0.16
epoch: 0
release: 1
summary: please add a summary manually as the author left a blank one
url: https://pypi.org/project/credal/
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-credal-0.0.16-1.src.rpm
checksum_type: sha256
description:
  <div align="center">
    <img src="./credal-dark-logo.svg" width="400" />
    <h1>Credal Python SDK</h1>

    <p>
      <strong>The Credal Python Library provides convenient access to the Credal API from applications written in Python.</strong>
    </p>

    <br>
    <div>
      <a href="https://buildwithfern.com/"><img src="https://img.shields.io/badge/%F0%9F%8C%BF-SDK%20generated%20by%20Fern-brightgreen">
    </div>
    <br>
  </div>



  Docs for the API endpoints available through the SDK can be found [here](https://docs.credal.ai/getting-started/overview).



  A full reference of the SDK is available [here](./reference.md).



  ```sh
  pip install --upgrade credal
  ```



  ```python
  from credal.client import CredalApi

  client = CredalApi(
      api_key="YOUR_API_KEY",
  )

  client.copilots.send_message(
      message="Is Credal SOC 2 compliant?",
      user_email="ravin@credal.ai",
  )
  ```



  ```python
  client = CredalApi(
      api_key="YOUR_API_KEY",
      base_url="https://<custom-domain>/api",
  )
  ```



  ```python
  from credal.client import AsyncCredalApi

  client = AsyncCredalApi(
      api_key="YOUR_API_KEY",
  )
  ```



  All errors thrown by the SDK will be subclasses of [`ApiError`](./src/credal/core/api_error.py).

  ```python
  import credal

  ...

  try:
      client.copilots.send_message(...)
  except credal.core.ApiError as e: # Handle all errors
      print(e.status_code)
      print(e.body)
  ```





  By default, requests time out after 60 seconds. You can configure this with a
  timeout option at the client or request level.

  ```python
  from credal.client import CredalApi

  client = CredalApi(
      ...,
      
      timeout=20.0,
  )


  client.copilots.send_message(..., {
      timeout_in_seconds=20.0
  })
  ```



  The SDK is instrumented with automatic retries with exponential backoff. A request will be
  retried as long as the request is deemed retriable and the number of retry attempts has not grown larger
  than the configured retry limit (default: 2).

  A request is deemed retriable when any of the following HTTP status codes is returned:

  - [408](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/408) (Timeout)
  - [429](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429) (Too Many Requests)
  - [5XX](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500) (Internal Server Errors)

  Use the `max_retries` request option to configure this behavior.

  ```python
  client.copilots.send_message(..., {
      max_retries=1
  })
  ```



  You can override the httpx client to customize it for your use-case. Some common use-cases
  include support for proxies and transports.

  ```python
  import httpx

  from credal.client import CredalApi

  client = CredalApi(...,
      http_client=httpx.Client(
          proxies="http://my.test.proxy.example.com",
          transport=httpx.HTTPTransport(local_address="0.0.0.0"),
      ),
  )
  ```



  This SDK is in beta, and there may be breaking changes between versions without a major
  version update. Therefore, we recommend pinning the package version to a specific version.
  This way, you can install the same version each time without breaking changes.


pkgId: 0cd7c59e3865e74cf21eb21e847a5252c72f7d3c74d41c7c432690cb96d8c4cc
name: python-credentials
arch: src
version: 1.1
epoch: 0
release: 1
summary: Credential Manager
url: https://github.com/OniOni/credentials
rpm_license: LGPLv3
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-credentials-1.1-1.src.rpm
checksum_type: sha256
description:
  [![Build Status](https://travis-ci.org/OniOni/credentials.svg?branch=master)](https://travis-ci.org/OniOni/credentials)


  ```shell
  $ pip install credentials
  ```




  Using default setup, this will try and load credentials first from the processes environement variables and then from `~/.credentials.json`
  ```python
  from credentials import credentials

  creds = credentials.require(['cred1', 'cred2'])
  function_that_needs_creds(creds.cred1)
  ...

  my_cred = credentials.load('cred_3')
  function_that_needs_creds(my_cred)
  ...
  ```


  ```python

  from credentials import Credentials, EnvBackend
  creds = Credentials([EnvBackend()])
  ...
  ```


  A backend is just an object with a `load` method. Method should take a `key` as an argument and return the associated credentials or `None` if it could not be loaded.

  Example:
  ```python
  class UniversalCredLoader(object):

     def load(self, key):
        return 42
  ...
  from credentials import Credentials
  creds = Credentials([UniversalCredLoader()])
  cred.load('cred1')
  >>> 42
  ```


pkgId: 4fb56d8201b4b820a57c9de273f9fcaa795afb957f0afc5bc8403d0c34ba0a5d
name: python-credisdict
arch: src
version: 1.0.0
epoch: 0
release: 1
summary: BRSynth Utilities
url: https://github.com/brsynth/CRedisDict
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-credisdict-1.0.0-1.src.rpm
checksum_type: sha256
description:
  [![Anaconda-Server Badge](https://anaconda.org/brsynth/credisdict/badges/version.svg)](https://anaconda.org/brsynth/credisdict) [![Anaconda-Server Badge](https://anaconda.org/brsynth/credisdict/badges/latest_release_date.svg)](https://anaconda.org/brsynth/credisdict)

  Data structure to implement a dictionary whose keys and values can complex data (dict, list...) and are stored in a Redis database. The dictionary is initiated by copying each single (key,value) rather than using `hmset`. It takes more time at initialisation but it is faster each time a key is accessed.



  * Python 3 with the following modules:
      * redis




  * **Joan Hérisson**



  CRedisDict is released under the MIT licence. See the LICENCE file for details.


pkgId: b28cb21f08a959a4bde8df1b4b37751b98632fe4ac3669f34c6572c19a24acd9
name: python-creds
arch: src
version: 1.0.16
epoch: 0
release: 1
summary: Creds is a library for managing Linux, FreeBSD and OpenBSD user accounts and credentials.
url: http://github.com/jonhadfield/creds
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-creds-1.0.16-1.src.rpm
checksum_type: sha256
description:
  Creds is a library that simplifies the management of user accounts and
  their credentials on Linux, FreeBSD and OpenBSD.
  Instead of issuing commands to create, update and delete users and their
  ssh keys, supply Creds with details of the users you want and it will
  take care of the implementation.
  The supported inputs are currently YAML, JSON or python dictionaries.


pkgId: 6e1dfd198a185402e1e79c76c90e53ef8d23b3e26fc31bed134fdbe819974df1
name: python-credsweeper
arch: src
version: 1.9.1
epoch: 0
release: 1
summary: Credential Sweeper
url: https://github.com/Samsung/CredSweeper
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-credsweeper-1.9.1-1.src.rpm
checksum_type: sha256
description:
  [![GitHub release (latestSemVer)](https://img.shields.io/github/v/release/Samsung/CredSweeper)](https://github.com/Samsung/CredSweeper/releases)
  [![Documentation Status](https://readthedocs.org/projects/credsweeper/badge/?version=latest)](https://credsweeper.readthedocs.io/en/latest/?badge=latest)
  [![License](https://img.shields.io/badge/licence-MIT-green.svg?style=flat)](LICENSE)
  [![PyPI](https://img.shields.io/pypi/v/credsweeper)](https://pypi.org/project/credsweeper/)
  [![Python](https://img.shields.io/pypi/pyversions/credsweeper.svg)](https://badge.fury.io/py/credsweeper)
  [![Test](https://github.com/Samsung/CredSweeper/actions/workflows/test.yml/badge.svg)](https://github.com/Samsung/CredSweeper/actions/workflows/test.yml)
  [![codecov](https://codecov.io/gh/Samsung/CredSweeper/branch/main/graph/badge.svg)](https://codecov.io/gh/Samsung/CredSweeper)
  [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/6055/badge)](https://bestpractices.coreinfrastructure.org/projects/6055)
  [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/Samsung/CredSweeper/badge)](https://api.securityscorecards.dev/projects/github.com/Samsung/CredSweeper)

  <img src="https://raw.githubusercontent.com/Samsung/CredSweeper/main/docs/images/Logo.png" width="500"/>

  - [CredSweeper](#credsweeper)
    - [Introduction](#introduction)
    - [How To Use](#how-to-use)
      - [Main Requirements](#main-requirements)
      - [Installation](#installation)
      - [Run](#run)
      - [Config](#config)
    - [Develop](#develop)
      - [Tests](#tests)
      - [Benchmark](#benchmark)
    - [Overall Architecture](#overall-architecture)
    - [Retrain Model](#retrain-model)
    - [License](#license)
    - [How to Get Involved](#how-to-get-involved)
      - [Project Roles](#project-roles)
        - [Contributor](#contributor)
        - [Maintainer](#maintainer)
    - [How to Contact](#how-to-contact)



  CredSweeper is a tool to detect credentials in any directories or files.
  CredSweeper could help users to detect unwanted exposure of credentials
  (such as tokens, passwords, api keys etc.) in advance.
  By scanning lines, filtering, and using AI model as option,
  CredSweeper reports lines with possible credentials, where the line is,
  and expected type of the credential as a result.

  Full documentation can be found here: <https://credsweeper.readthedocs.io/>





  - Python 3.8, 3.9, 3.10, 3.11



  Details [here](https://credsweeper.readthedocs.io/en/latest/install.html).

  ```bash
  pip install credsweeper
  ```



  [How to use](https://credsweeper.readthedocs.io/en/latest/guide.html).

  Get all argument list:

  ``` bash
  python -m credsweeper --help
  ```

  Run CredSweeper:

  ``` bash
  python -m credsweeper --path tests/samples/password.gradle --save-json output.json
  ```

  To check JSON file run:

  ```bash
  cat output.json
  ```

  ``` json
  [
      {
          "api_validation": "NOT_AVAILABLE",
          "ml_validation": "VALIDATED_KEY",
          "ml_probability": 0.99755,
          "rule": "Password",
          "severity": "medium",
          "confidence": "moderate",
          "line_data_list": [
              {
                  "line": "password = \"cackle!\"",
                  "line_num": 1,
                  "path": "tests/samples/password.gradle",
                  "info": "",
                  "value": "cackle!",
                  "value_start": 12,
                  "value_end": 19,
                  "variable": "password",
                  "entropy_validation": {
                      "iterator": "BASE64_CHARS",
                      "entropy": 2.120589933192232,
                      "valid": false
                  }
              }
          ]
      }
  ]
  ```



  [credsweeper/secret/config.json](credsweeper/secret/config.json) - Configuration file for pre-processing of CredSweeper. For more details please check [here](https://credsweeper.readthedocs.io/en/latest/overall_architecture.html#pre-processing).

  You can set the `pattern`, `extension` and `path` you want to exclude from scanning as below.

  ``` json
  {
      "exclude": {
          "pattern": [
              "AKIA[0-9A-Z]{9}EXAMPLE",
              ...
          ],
          "extension": [
              "gif",
              "jpg",
              ...
          ],
          "path": [
              "/.git/",
              "/openssl/",
              ...
          ]
      },
      ...
  }
  ```

  And you can also set `source_ext`, `source_quote_ext`, `find_by_ext_list`, `check_for_literals`, `line_data_output`, and `candidate_output` as below.

  - `source_ext`: List of extensions for scanning categorized as source files.
  - `source_quote_ext`: List of extensions for scanning categorized as source files that using quote.
  - `find_by_ext_list`: List of extensions to detect only extensions.
  - `check_for_literals`: Bool value for whether to check line has string literal declaration or not.
  - `line_data_output`: List of attributes of [line_data](credsweeper/credentials/line_data.py) for output.
  - `candidate_output`: List of attributes of [candidate](credsweeper/credentials/candidate.py) for output.

  ``` json
  {
      ...
      "source_ext": [
          ".py",
          ".cpp",
          ...
      ],
      "source_quote_ext": [
          ".py",
          ".cpp",
          ...
      ],
      "find_by_ext_list": [
          ".pem",
          ".cer",
          ...
      ],
      "check_for_literals": true,
      "line_data_output": [
          "line",
          "line_num",
          ...
      ],
      "candidate_output": [
          "rule",
          "severity",
          ...
      ]
  }
  ```

  [credsweeper/rules/config.yaml](credsweeper/secret/config.yaml) - Configuration file for setting Rule. For more details please check [here](https://credsweeper.readthedocs.io/en/latest/overall_architecture.html#rule).

  ``` yaml
  ...
  - name: API
  severity: medium
  confidence: moderate
  type: keyword
  values:
  - api
  filter_type: GeneralKeyword
  use_ml: true
  validations: []
  - name: AWS Client ID
  ...
  ```





  To run all tests:

  ``` bash
  python -m pytest --cov=credsweeper --cov-report=term-missing -s tests/
  ```

  To run only tests independent of external api:

  ``` bash
  python -m pytest -m "not api_validation_test" tests/
  ```

  To obtain manageable (without subprocesses) coverage:

  ``` bash
  python -m pytest --cov=credsweeper --cov-report=html tests/ --ignore=tests/test_app.py
  ```



  We have a dataset for testing credential scanners that called [CredData](https://github.com/Samsung/CredData). If you want to test CredSweeper with this dataset please check [here](https://github.com/Samsung/CredData/blob/main/README.md#benchmark).



  To check overall architecture of CredSweeper please check [here](https://credsweeper.readthedocs.io/en/latest/overall_architecture.html).



  If you want to check how model was trained or retrain it on your own data, please refer to the [experiment](experiment/README.md) folder



  The CredSweeper is an Open Source project released under the terms of [MIT License V2](https://opensource.org/licenses/mit-license.php).



  In addition to developing under an Open Source license, A use an Open Source Development approach, welcoming everyone to participate, contribute, and engage with each other through the project.



  A recognizes the following formal roles: Contributor and Maintainer. Informally, the community may organize itself and give rights and responsibilities to the necessary people to achieve its goals.



  A Contributor is anyone who wishes to contribute to the project, at any level. Contributors are granted the following rights, to:

  - Contribute code, documentation, translations, artwork, and etc.
  - Report defects (bugs) and suggestions for enhancement.
  - Participate in the process of reviewing contributions by others.

  If you want to participate in the project development, check out the [how to contribute guideline](./docs/howto/how-to-contribute.md) in advance.

  Contributors who show dedication and skill are rewarded with additional rights and responsibilities. Their opinions weigh more when decisions are made, in a fully meritocratic fashion.



  A Maintainer is a Contributor who is also responsible for knowing, directing and anticipating the needs of a given a Module. As such, Maintainers have the right to set the overall organization of the source code in the Module, and the right to participate in the decision-making. Maintainers are required to review the contributor’s requests and decide whether to accept or not.

  Name | E-Mail
  -- | --
  [Jaeku Yun](https://github.com/silentearth) | jk0113.yun@samsung.com
  [Shinhyung Choi](https://github.com/csh519) | sh519.choi@samsung.com
  [Roman Babenko](https://github.com/babenek) | r.babenko@samsung.com
  [Yuliia Tatarinova](https://github.com/Yullia) | yuliia.t@samsung.com



  Please post questions, [issues, or suggestions in issues](https://github.com/Samsung/CredSweeper/issues). This is the best way to communicate with the developers.


pkgId: f1a9f1f9187dd2d645f3f71d20ecccc08b6536bade3180785a39f9ab029da6eb
name: python-credsweeper
arch: src
version: 1.9.5
epoch: 0
release: 1
summary: Credential Sweeper
url: https://github.com/Samsung/CredSweeper
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-credsweeper-1.9.5-1.src.rpm
checksum_type: sha256
description:
  [![GitHub release (latestSemVer)](https://img.shields.io/github/v/release/Samsung/CredSweeper)](https://github.com/Samsung/CredSweeper/releases)
  [![Documentation Status](https://readthedocs.org/projects/credsweeper/badge/?version=latest)](https://credsweeper.readthedocs.io/en/latest/?badge=latest)
  [![License](https://img.shields.io/badge/licence-MIT-green.svg?style=flat)](LICENSE)
  [![PyPI](https://img.shields.io/pypi/v/credsweeper)](https://pypi.org/project/credsweeper/)
  [![Python](https://img.shields.io/pypi/pyversions/credsweeper.svg)](https://badge.fury.io/py/credsweeper)
  [![Test](https://github.com/Samsung/CredSweeper/actions/workflows/test.yml/badge.svg)](https://github.com/Samsung/CredSweeper/actions/workflows/test.yml)
  [![codecov](https://codecov.io/gh/Samsung/CredSweeper/branch/main/graph/badge.svg)](https://codecov.io/gh/Samsung/CredSweeper)
  [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/6055/badge)](https://bestpractices.coreinfrastructure.org/projects/6055)
  [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/Samsung/CredSweeper/badge)](https://api.securityscorecards.dev/projects/github.com/Samsung/CredSweeper)

  <img src="https://raw.githubusercontent.com/Samsung/CredSweeper/main/docs/images/Logo.png" width="500"/>

  - [CredSweeper](#credsweeper)
    - [Introduction](#introduction)
    - [How To Use](#how-to-use)
      - [Main Requirements](#main-requirements)
      - [Installation](#installation)
      - [Run](#run)
      - [Config](#config)
    - [Develop](#develop)
      - [Tests](#tests)
      - [Benchmark](#benchmark)
    - [Overall Architecture](#overall-architecture)
    - [Retrain Model](#retrain-model)
    - [License](#license)
    - [How to Get Involved](#how-to-get-involved)
      - [Project Roles](#project-roles)
        - [Contributor](#contributor)
        - [Maintainer](#maintainer)
    - [How to Contact](#how-to-contact)



  CredSweeper is a tool to detect credentials in any directories or files.
  CredSweeper could help users to detect unwanted exposure of credentials
  (such as tokens, passwords, api keys etc.) in advance.
  By scanning lines, filtering, and using AI model as option,
  CredSweeper reports lines with possible credentials, where the line is,
  and expected type of the credential as a result.

  Full documentation can be found here: <https://credsweeper.readthedocs.io/>





  - Python 3.8, 3.9, 3.10, 3.11, 3.12



  Details [here](https://credsweeper.readthedocs.io/en/latest/install.html).

  ```bash
  pip install credsweeper
  ```



  [How to use](https://credsweeper.readthedocs.io/en/latest/guide.html).

  Get all argument list:

  ``` bash
  python -m credsweeper --help
  ```

  Run CredSweeper:

  ``` bash
  python -m credsweeper --path tests/samples/password.gradle --save-json output.json
  ```

  To check JSON file run:

  ```bash
  cat output.json
  ```

  ``` json
  [
      {
          "api_validation": "NOT_AVAILABLE",
          "ml_validation": "VALIDATED_KEY",
          "ml_probability": 0.99755,
          "rule": "Password",
          "severity": "medium",
          "confidence": "moderate",
          "line_data_list": [
              {
                  "line": "password = \"cackle!\"",
                  "line_num": 1,
                  "path": "tests/samples/password.gradle",
                  "info": "",
                  "value": "cackle!",
                  "value_start": 12,
                  "value_end": 19,
                  "variable": "password",
                  "entropy_validation": {
                      "iterator": "BASE64_CHARS",
                      "entropy": 2.120589933192232,
                      "valid": false
                  }
              }
          ]
      }
  ]
  ```



  [credsweeper/secret/config.json](credsweeper/secret/config.json) - Configuration file for pre-processing of CredSweeper. For more details please check [here](https://credsweeper.readthedocs.io/en/latest/overall_architecture.html#pre-processing).

  You can set the `pattern`, `extension` and `path` you want to exclude from scanning as below.

  ``` json
  {
      "exclude": {
          "pattern": [
              "AKIA[0-9A-Z]{9}EXAMPLE",
              ...
          ],
          "extension": [
              "gif",
              "jpg",
              ...
          ],
          "path": [
              "/.git/",
              "/openssl/",
              ...
          ]
      },
      ...
  }
  ```

  And you can also set `source_ext`, `source_quote_ext`, `find_by_ext_list`, `check_for_literals`, `line_data_output`, and `candidate_output` as below.

  - `source_ext`: List of extensions for scanning categorized as source files.
  - `source_quote_ext`: List of extensions for scanning categorized as source files that using quote.
  - `find_by_ext_list`: List of extensions to detect only extensions.
  - `check_for_literals`: Bool value for whether to check line has string literal declaration or not.
  - `line_data_output`: List of attributes of [line_data](credsweeper/credentials/line_data.py) for output.
  - `candidate_output`: List of attributes of [candidate](credsweeper/credentials/candidate.py) for output.

  ``` json
  {
      ...
      "source_ext": [
          ".py",
          ".cpp",
          ...
      ],
      "source_quote_ext": [
          ".py",
          ".cpp",
          ...
      ],
      "find_by_ext_list": [
          ".pem",
          ".cer",
          ...
      ],
      "check_for_literals": true,
      "line_data_output": [
          "line",
          "line_num",
          ...
      ],
      "candidate_output": [
          "rule",
          "severity",
          ...
      ]
  }
  ```

  [credsweeper/rules/config.yaml](credsweeper/secret/config.yaml) - Configuration file for setting Rule. For more details please check [here](https://credsweeper.readthedocs.io/en/latest/overall_architecture.html#rule).

  ``` yaml
  ...
  - name: API
  severity: medium
  confidence: moderate
  type: keyword
  values:
  - api
  filter_type: GeneralKeyword
  use_ml: true
  validations: []
  - name: AWS Client ID
  ...
  ```





  To run all tests:

  ``` bash
  python -m pytest --cov=credsweeper --cov-report=term-missing -s tests/
  ```

  To run only tests independent of external api:

  ``` bash
  python -m pytest -m "not api_validation_test" tests/
  ```

  To obtain manageable (without subprocesses) coverage:

  ``` bash
  python -m pytest --cov=credsweeper --cov-report=html tests/ --ignore=tests/test_app.py
  ```



  We have a dataset for testing credential scanners that called [CredData](https://github.com/Samsung/CredData). If you want to test CredSweeper with this dataset please check [here](https://github.com/Samsung/CredData/blob/main/README.md#benchmark).



  To check overall architecture of CredSweeper please check [here](https://credsweeper.readthedocs.io/en/latest/overall_architecture.html).



  If you want to check how model was trained or retrain it on your own data, please refer to the [experiment](experiment/README.md) folder



  The CredSweeper is an Open Source project released under the terms of [MIT License V2](https://opensource.org/licenses/mit-license.php).



  In addition to developing under an Open Source license, A use an Open Source Development approach, welcoming everyone to participate, contribute, and engage with each other through the project.



  A recognizes the following formal roles: Contributor and Maintainer. Informally, the community may organize itself and give rights and responsibilities to the necessary people to achieve its goals.



  A Contributor is anyone who wishes to contribute to the project, at any level. Contributors are granted the following rights, to:

  - Contribute code, documentation, translations, artwork, and etc.
  - Report defects (bugs) and suggestions for enhancement.
  - Participate in the process of reviewing contributions by others.

  If you want to participate in the project development, check out the [how to contribute guideline](./docs/howto/how-to-contribute.md) in advance.

  Contributors who show dedication and skill are rewarded with additional rights and responsibilities. Their opinions weigh more when decisions are made, in a fully meritocratic fashion.



  A Maintainer is a Contributor who is also responsible for knowing, directing and anticipating the needs of a given a Module. As such, Maintainers have the right to set the overall organization of the source code in the Module, and the right to participate in the decision-making. Maintainers are required to review the contributor’s requests and decide whether to accept or not.

  Name | E-Mail
  -- | --
  [Jaeku Yun](https://github.com/silentearth) | jk0113.yun@samsung.com
  [Shinhyung Choi](https://github.com/csh519) | sh519.choi@samsung.com
  [Roman Babenko](https://github.com/babenek) | r.babenko@samsung.com
  [Yuliia Tatarinova](https://github.com/Yullia) | yuliia.t@samsung.com



  Please post questions, [issues, or suggestions in issues](https://github.com/Samsung/CredSweeper/issues). This is the best way to communicate with the developers.


pkgId: fbce4180dc7a2dcaf76528940ef119db4952f8b8ffc9e3bfe9da87b343fcc74e
name: python-creevey
arch: src
version: 2.3.0
epoch: 0
release: 1
summary: Bulk image processing
url: https://github.com/ShopRunner/creevey
rpm_license: UNKNOWN
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-creevey-2.3.0-1.src.rpm
checksum_type: sha256
description:
  > **Note 6/15/20:** Our team previously had a tradition of naming projects with terms or characters from the Harry Potter series, but we are disappointed by J.K. Rowling’s persistent transphobic comments. In response, we will be renaming this repository, and are working to develop an inclusive solution that minimizes disruption to our users.

  Creevey is a file processing framework. It is designed for IO-bound workflows that involve reading files into memory, doing some processing on their contents, and writing out the results. It makes running those workflows faster and more reliable by parallelizing them across files, optional skipping files that have already been processed, handling errors, and keeping organized records of what happened.

  Creevey was developed for deep learning computer vision projects, so in addition to the general framework it also provides predefined components for image processing. However, it can be used for any project that involves processing data from many sources.

  See [the docs](https://creevey.readthedocs.io/) for more details.


pkgId: 853afb6b872eb278a81a1a2d8283a8351f7d501b82a471d410a582a9ee3fc215
name: python-crelm
arch: src
version: 0.0.36
epoch: 0
release: 1
summary: Utility that automates turning simple C classes into Python objects
url: https://github.com/wideopensource/crelm
rpm_license: MIT License
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crelm-0.0.36-1.src.rpm
checksum_type: sha256
description:
  The Crelm package provides a relatively simple API around the CFFI system. Give it C code or source files, it gives you a package with bindings to functions and `struct`s. Easiest way to get started is hack up the examples in [the repo](https://github.com/wideopensource/crelm/tree/main/examples).



  pip3 install crelm



  ```
  from crelm import Factory

  paste = Factory(debug=False, verbose=True).create_Tube('add2') \
      .add_source_text('int add2(int a, int b) { return a + b; }') \
      .squeeze()

  print(f'2 + 3 = {paste.add2(2, 3)}')
  ```


pkgId: ef6c9d97769a4a834cdf5dee6fcacb10b57553732abdbfa5c3db13fe51c916fc
name: python-crem
arch: src
version: 0.2.12
epoch: 0
release: 1
summary: CReM: chemically reasonable mutations framework
url: https://github.com/DrrDom/crem
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crem-0.2.12-1.src.rpm
checksum_type: sha256
description:
  **CReM** is an open-source Python framework to generate chemical structures using a fragment-based approach.

  The main idea behind is similar to matched molecular pairs considering context that fragments in the identical context are interchangeable. Therefore, one can create a database of interchangeable fragments and use it for generation of chemically valid structures.

  **Features:**
  1) Generation of a custom fragment database
  2) Three modes of structure generation: MUTATE, GROW, LINK
  3) Context radius to consider for replacement
  4) Fragment size to replace and the size of a replacing fragment
  5) Protection of atoms from modification (e.g. scaffold protection)
  6) Replacements with fragments occurred in a fragment database with certain minimal frequency
  7) Make randomly chosen replacements up to the specified number

  **Limitations and known issues**
  1) New ring systems cannot be constructed from fragments, thus representativeness of ring systems in generated structures depends on a used fragment database. We are working on that issue.
  2) Very large molecules will not be processed by CReM. If a molecule has more than 30 non-ring single bonds it will not be MUTATED. If a molecule has more than 100 hydrogen atoms it will not be processed by GROW and LINK.
  3) Canonicalisation of contexts depends on RDKit SMILES representation. Thus, changing in RDKit SMILES representation may affect fragment databases and make impossible to use a database prepared with previous RDKit version from code running under later RDKit versions.



  https://crem.readthedocs.io/en/latest/



  To play with a tool online.
  https://crem.imtm.cz/



  Several command line utilities will be installed to create fragment databases and `crem` module will become available in Python imports to generate structures.

  From pypi package
  ```text
  pip install crem
  ```

  Manually from repository
  ```text
  git clone https://github.com/DrrDom/crem
  cd crem
  python3 setup.py sdist bdist_wheel
  pip install dist/crem-0.1-py3-none-any.whl
  ```

  Uninstall
  ```text
  pip uninstall crem
  ```



  `crem` requires `rdkit>=2017.09`. To run the guacamol test `guacamol` should be installed.



  This step is required if you want to generate a custom fragment database. You can download precompiled databases obtained by fragmentation of the whole ChEMBL by links provided on this page - http://www.qsar4u.com/pages/crem.php.

  For convenience there is the bash script crem_create_frag_db.sh which includes all steps below. It takes three positional arguments: input file with SMILES, output directory where intermediate files and a final database will be stored and number of CPUs to use (this is optional, default value is 1).
  ```text
  crem_create_frag_db.sh input.smi fragdb_dir 32
  ```

  Fragmentation of input structures:
  ```text
  fragmentation -i input.smi -o frags.txt -c 32 -v
  ```

  Convert fragments to standardized representation of a core and a context of a given radius:
  ```text
  frag_to_env -i frags.txt -o r3.txt -r 3 -c 32 -v
  ```

  Remove duplicated lines in the output file and count frequency of occurrence of fragemnt-context pairs. These (`sort` and `uniq`) are `bash` utilities but since Win10 is Linux-friendly that should not be a big issue for Win users to execute them
  ```text
  sort r3.txt | uniq -c > r3_c.txt
  ```

  Create DB and import the file to a database table
  ```text
  env_to_db -i r3_c.txt -o fragments.db -r 3 -c -v
  ```

  Last three steps should be executed for each radius. All tables can be stored in the same database.



  Import necessary functions from the main module
  ```python
  from crem.crem import mutate_mol, grow_mol, link_mols
  from rdkit import Chem
  ```

  Create a molecute and **mutate** it. Only one heavy atom will be substituted. Default radius is 3.
  ```python
  m = Chem.MolFromSmiles('c1cc(OC)ccc1C')  # methoxytoluene
  mols = list(mutate_mol(m, db_name='replacements.db', max_size=1))
  ```
  output example
  ```text
  ['CCc1ccc(C)cc1',
   'CC#Cc1ccc(C)cc1',
   'C=C(C)c1ccc(C)cc1',
   'CCCc1ccc(C)cc1',
   'CC=Cc1ccc(C)cc1',
   'CCCCc1ccc(C)cc1',
   'CCCOc1ccc(C)cc1',
   'CNCCc1ccc(C)cc1',
   'COCCc1ccc(C)cc1',
   ...
   'Cc1ccc(C(C)(C)C)cc1']
  ```


  Add hydrogens to the molecule to **mutate hydrogens** as well
  ```python
  mols = list(mutate_mol(Chem.AddHs(m), db_name='replacements.db', max_size=1))
  ```
  output
  ```text
  ['CCc1ccc(C)cc1',
   'CC#Cc1ccc(C)cc1',
   'C=C(C)c1ccc(C)cc1',
   'CCCc1ccc(C)cc1',
   'Cc1ccc(C(C)C)cc1',
   'CC=Cc1ccc(C)cc1',
   ...
   'COc1ccc(C)cc1C',
   'C=Cc1cc(C)ccc1OC',
   'COc1ccc(C)cc1Cl',
   'COc1ccc(C)cc1CCl']
  ```

  **Grow** molecule. Only hydrogens will be replaced. Hydrogens should not be added explicitly.
  ```python
  mols = list(grow_mol(m, db_name='replacements.db'))
  ```
  output
  ```text
  ['COc1ccc(C)c(Br)c1',
   'COc1ccc(C)c(C)c1',
   'COc1ccc(C)c(Cl)c1',
   'COc1ccc(C)c(OC)c1',
   'COc1ccc(C)c(N)c1',
   ...
   'COc1ccc(CCN)cc1']
  ```

  Create the second molecule and **link** it to toluene
  ```python
  m2 = Chem.MolFromSmiles('NCC(=O)O')  # glycine
  mols = list(link_mols(m, m2, db_name='replacements.db'))
  ```
  output
  ```text
  ['Cc1ccc(OCC(=O)NCC(=O)O)cc1',
   'Cc1ccc(OCCOC(=O)CN)cc1',
   'COc1ccc(CC(=N)NCC(=O)O)cc1',
   'COc1ccc(CC(=O)NCC(=O)O)cc1',
   'COc1ccc(CC(=S)NCC(=O)O)cc1',
   'COc1ccc(CCOC(=O)CN)cc1']
  ```

  You can vary the size of a linker and specify the distance between two attachment points in a linking fragment. There are many other arguments available in these functions, look at their **docstrings** for details.



  An example of a filtering function which will keep only fragments containing a specific atom to be chosen for replacing.

  ```python
  from collections import defaultdict
  from functools import partial
  from rdkit import Chem

  def filter_function(row_ids, cur, radius, atom_number):

      """
      The first three arguments should be always the same as shown in the example. These parameters will be passed to a function from a main function, e.g. from mutate_mol. All other arguments are user-defined. The function should return the list of row ids of fragments which will be used for replacing.

      :param row_id: a list of row ids from CReM database of those fragments which satisfy other selection criteria
      :param cur: cursor of CReM database
      :param radius: radius of a context
      :param atom_number: an atomic number, fragments with this number will be discarded
      :return list of remaining row ids
      """

      
      
      if not row_ids:
          return []
      batch_size = 32000  # SQLite has a limit on a number of passed values to a query
      row_ids = list(row_ids)
      smis = defaultdict(list)  # {smi_1: [rowid_1, rowid_5, ...], ...}
      for start in range(0, len(row_ids), batch_size):
          batch = row_ids[start:start + batch_size]
          sql = f"SELECT rowid, core_smi FROM radius{radius} WHERE rowid IN ({','.join('?' * len(batch))})"
          for i, smi in cur.execute(sql, batch).fetchall():
              smis[smi].append(i)

      output_row_ids = []
      for smi, ids in smis.items():
          for a in Chem.MolFromSmiles(smi).GetAtoms():
              if a.GetAtomicNum() == atom_number:
                  output_row_ids.extend(ids)
      return output_row_ids


  mol = Chem.MolFromSmiles('c1ccccc1C')
  mols = mutate_mol(mol, db_name='replacements.db', filter_func=partial(filter_function, atom_number=9), max_size=1, max_inc=3)
  ```
  output
  ```text
  ['Fc1ccccc1',
   'FC(F)(F)c1ccccc1',
   'FC(F)Oc1ccccc1',
   'FC(F)Sc1ccccc1']
  ```



  For convenience there is a function `enumerate_compounds` in `utils` module (added in version 0.2.6). It performs iterative growing (scaffold decoration) or mutation (analog enumeration) of a supplied molecule. More details are in docstring of the function.

  Example. Enumerate derivatives of 1-chloro-3-methylbenzene at positions 2 and 4 of the ring and at the methyl group at the same time. In this case one should choose `scaffold` mode, 3 iterations, specify atom ids (0-based indices) where fragments can be attached and set `protect_added_frag=True` to restrict enumeration only to selected positions.

  ```python
  from crem.utils import enumerate_compounds

  mol = Chem.MolFromMolBlock("""
    Mrv1922 05242309182D

    8  8  0  0  0  0            999 V2000
     -3.2813    1.3161    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
     -3.9957    0.9036    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
     -3.9957    0.0786    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
     -3.2813   -0.3339    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
     -2.5668    0.0786    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
     -2.5668    0.9036    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
     -3.2813   -1.1589    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
     -1.8523    1.3161    0.0000 Cl  0  0  0  0  0  0  0  0  0  0  0  0
    1  2  1  0  0  0  0
    2  3  2  0  0  0  0
    3  4  1  0  0  0  0
    4  5  2  0  0  0  0
    5  6  1  0  0  0  0
    1  6  2  0  0  0  0
    4  7  1  0  0  0  0
    6  8  1  0  0  0  0
  M  END
  """)

  mols = enumerate_compounds(mol, 'replacements_sa2.db', mode='scaffold', n_iterations=3,
                             radius=3, max_replacements=2, replace_ids=[2,4,6], protect_added_frag=True,
                             return_smi=True)
  ```
  output
  ```
  ['COc1c(C)cccc1Cl',
  'Cc1cc(Cl)ccc1Cl',
  'COc1ccc(Cl)c(OC)c1C',
  'COc1c(Cl)cccc1CF',
  'Cc1c(Cl)ccc(Cl)c1C',
  'CSCc1cc(Cl)ccc1Cl',
  'COc1ccc(Cl)c(OC)c1CC#N',
  'COCc1c(OC)ccc(Cl)c1OC',
  'COc1c(Cl)cccc1C(F)F',
  'COc1c(Cl)ccc(CO)c1CF',
  'Cc1c(Cl)ccc(Cl)c1CC#N',
  'Cc1c(Cl)ccc(Cl)c1CCN',
  'CSCc1c(Cl)ccc(Cl)c1C',
  'CSCc1c(Cl)ccc(Cl)c1Cl']
  ```


  All functions have an argument `ncores` and can make mupltile replacement in one molecule in parallel. If you want to process several molecules in parallel you have to write your own code. However, the described functions are generators and cannot be used with `multiprocessing` module. Therefore, three complementary functions `mutate_mol2`, `grow_mol2` and `link_mols2` were created. They return the list with results and can be pickled and used with `multiprocessing.Pool` or other tools.

  Example:
  ```python
  from multiprocessing import Pool
  from functools import partial
  from crem.crem import mutate_mol2
  from rdkit import Chem

  p = Pool(2)
  input_smi = ['c1ccccc1N', 'NCC(=O)OC', 'NCCCO']
  input_mols = [Chem.MolFromSmiles(s) for s in input_smi]

  res = list(p.imap(partial(mutate_mol2, db_name='replacements.db', max_size=1), input_mols))
  ```

  `res` would be a list of lists with SMILES of generated molecules





  |task|SMILES LSTM*|SMILES GA*|Graph GA*|Graph MCTS*|CReM
  |---|:---:|:---:|:---:|:---:|:---:|
  |Celecoxib rediscovery|**1.000**|0.732|**1.000**|0.355|**1.000**
  |Troglitazone rediscovery|**1.000**|0.515|**1.000**|0.311|**1.000**
  |Thiothixene rediscovery|**1.000**|0.598|**1.000**|0.311|**1.000**
  |Aripiprazole similarity|**1.000**|0.834|**1.000**|0.380|**1.000**
  |Albuterol similarity|**1.000**|0.907|**1.000**|0.749|**1.000**
  |Mestranol similarity|**1.000**|0.79|**1.000**|0.402|**1.000**
  |C11H24|**0.993**|0.829|0.971|0.410|0.966
  |C9H10N2O2PF2Cl|0.879|0.889|**0.982**|0.631|0.940
  |Median molecules 1|**0.438**|0.334|0.406|0.225|0.371
  |Median molecules 2|0.422|0.38|0.432|0.170|**0.434**
  |Osimertinib MPO|0.907|0.886|0.953|0.784|**0.995**
  |Fexofenadine MPO|0.959|0.931|0.998|0.695|**1.000**
  |Ranolazine MPO|0.855|0.881|0.92|0.616|**0.969**
  |Perindopril MPO|0.808|0.661|0.792|0.385|**0.815**
  |Amlodipine MPO|0.894|0.722|0.894|0.533|**0.902**
  |Sitagliptin MPO|0.545|0.689|**0.891**|0.458|0.763
  |Zaleplon MPO|0.669|0.413|0.754|0.488|**0.770**
  |Valsartan SMARTS|0.978|0.552|0.990|0.04|**0.994**
  |Deco Hop|0.996|0.970|**1.000**|0.590|**1.000**
  |Scaffold Hop|0.998|0.885|**1.000**|0.478|**1.000**
  |total score|17.341|14.398|17.983|9.011|17.919


  BSD-3


  CReM: chemically reasonable mutations framework for structure generation
  Pavel Polishchuk
  *Journal of Cheminformatics* **2020**, 12, (1), 28
  https://doi.org/10.1186/s13321-020-00431-w

  Control of Synthetic Feasibility of Compounds Generated with CReM
  Pavel Polishchuk
  *Journal of Chemical Information and Modeling* **2020**, 60, 6074-6080
  https://dx.doi.org/10.1021/acs.jcim.0c00792


pkgId: d09a3dcc408ebf2eb2c3f713cc42c39ac0d93434fcd540499974f39372f757f7
name: python-crem
arch: src
version: 0.2.13
epoch: 0
release: 1
summary: CReM: chemically reasonable mutations framework
url: https://github.com/DrrDom/crem
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crem-0.2.13-1.src.rpm
checksum_type: sha256
description:
  **CReM** is an open-source Python framework to generate chemical structures using a fragment-based approach.

  The main idea behind is similar to matched molecular pairs considering context that fragments in the identical context are interchangeable. Therefore, one can create a database of interchangeable fragments and use it for generation of chemically valid structures.

  **Features:**
  1) Generation of a custom fragment database
  2) Three modes of structure generation: MUTATE, GROW, LINK
  3) Context radius to consider for replacement
  4) Fragment size to replace and the size of a replacing fragment
  5) Protection of atoms from modification (e.g. scaffold protection)
  6) Replacements with fragments occurred in a fragment database with certain minimal frequency
  7) Make randomly chosen replacements up to the specified number

  **Limitations and known issues**
  1) New ring systems cannot be constructed from fragments, thus representativeness of ring systems in generated structures depends on a used fragment database. We are working on that issue.
  2) Very large molecules will not be processed by CReM. If a molecule has more than 30 non-ring single bonds it will not be MUTATED. If a molecule has more than 100 hydrogen atoms it will not be processed by GROW and LINK.
  3) Canonicalisation of contexts depends on RDKit SMILES representation. Thus, changing in RDKit SMILES representation may affect fragment databases and make impossible to use a database prepared with previous RDKit version from code running under later RDKit versions.



  https://crem.readthedocs.io/en/latest/



  To play with a tool online.
  https://crem.imtm.cz/



  Several command line utilities will be installed to create fragment databases and `crem` module will become available in Python imports to generate structures.

  From pypi package
  ```text
  pip install crem
  ```

  Manually from repository
  ```text
  git clone https://github.com/DrrDom/crem
  cd crem
  python3 setup.py sdist bdist_wheel
  pip install dist/crem-0.1-py3-none-any.whl
  ```

  Uninstall
  ```text
  pip uninstall crem
  ```



  `crem` requires `rdkit>=2017.09`. To run the guacamol test `guacamol` should be installed.



  This step is required if you want to generate a custom fragment database. You can download precompiled databases obtained by fragmentation of the whole ChEMBL by links provided on this page - http://www.qsar4u.com/pages/crem.php.

  For convenience there is the bash script crem_create_frag_db.sh which includes all steps below. It takes three positional arguments: input file with SMILES, output directory where intermediate files and a final database will be stored and number of CPUs to use (this is optional, default value is 1).
  ```text
  crem_create_frag_db.sh input.smi fragdb_dir 32
  ```

  Fragmentation of input structures:
  ```text
  fragmentation -i input.smi -o frags.txt -c 32 -v
  ```

  Convert fragments to standardized representation of a core and a context of a given radius:
  ```text
  frag_to_env -i frags.txt -o r3.txt -r 3 -c 32 -v
  ```

  Remove duplicated lines in the output file and count frequency of occurrence of fragemnt-context pairs. These (`sort` and `uniq`) are `bash` utilities but since Win10 is Linux-friendly that should not be a big issue for Win users to execute them
  ```text
  sort r3.txt | uniq -c > r3_c.txt
  ```

  Create DB and import the file to a database table
  ```text
  env_to_db -i r3_c.txt -o fragments.db -r 3 -c -v
  ```

  Last three steps should be executed for each radius. All tables can be stored in the same database.



  Import necessary functions from the main module
  ```python
  from crem.crem import mutate_mol, grow_mol, link_mols
  from rdkit import Chem
  ```

  Create a molecute and **mutate** it. Only one heavy atom will be substituted. Default radius is 3.
  ```python
  m = Chem.MolFromSmiles('c1cc(OC)ccc1C')  # methoxytoluene
  mols = list(mutate_mol(m, db_name='replacements.db', max_size=1))
  ```
  output example
  ```text
  ['CCc1ccc(C)cc1',
   'CC#Cc1ccc(C)cc1',
   'C=C(C)c1ccc(C)cc1',
   'CCCc1ccc(C)cc1',
   'CC=Cc1ccc(C)cc1',
   'CCCCc1ccc(C)cc1',
   'CCCOc1ccc(C)cc1',
   'CNCCc1ccc(C)cc1',
   'COCCc1ccc(C)cc1',
   ...
   'Cc1ccc(C(C)(C)C)cc1']
  ```


  Add hydrogens to the molecule to **mutate hydrogens** as well
  ```python
  mols = list(mutate_mol(Chem.AddHs(m), db_name='replacements.db', max_size=1))
  ```
  output
  ```text
  ['CCc1ccc(C)cc1',
   'CC#Cc1ccc(C)cc1',
   'C=C(C)c1ccc(C)cc1',
   'CCCc1ccc(C)cc1',
   'Cc1ccc(C(C)C)cc1',
   'CC=Cc1ccc(C)cc1',
   ...
   'COc1ccc(C)cc1C',
   'C=Cc1cc(C)ccc1OC',
   'COc1ccc(C)cc1Cl',
   'COc1ccc(C)cc1CCl']
  ```

  **Grow** molecule. Only hydrogens will be replaced. Hydrogens should not be added explicitly.
  ```python
  mols = list(grow_mol(m, db_name='replacements.db'))
  ```
  output
  ```text
  ['COc1ccc(C)c(Br)c1',
   'COc1ccc(C)c(C)c1',
   'COc1ccc(C)c(Cl)c1',
   'COc1ccc(C)c(OC)c1',
   'COc1ccc(C)c(N)c1',
   ...
   'COc1ccc(CCN)cc1']
  ```

  Create the second molecule and **link** it to toluene
  ```python
  m2 = Chem.MolFromSmiles('NCC(=O)O')  # glycine
  mols = list(link_mols(m, m2, db_name='replacements.db'))
  ```
  output
  ```text
  ['Cc1ccc(OCC(=O)NCC(=O)O)cc1',
   'Cc1ccc(OCCOC(=O)CN)cc1',
   'COc1ccc(CC(=N)NCC(=O)O)cc1',
   'COc1ccc(CC(=O)NCC(=O)O)cc1',
   'COc1ccc(CC(=S)NCC(=O)O)cc1',
   'COc1ccc(CCOC(=O)CN)cc1']
  ```

  You can vary the size of a linker and specify the distance between two attachment points in a linking fragment. There are many other arguments available in these functions, look at their **docstrings** for details.



  An example of a filtering function which will keep only fragments containing a specific atom to be chosen for replacing.

  ```python
  from collections import defaultdict
  from functools import partial
  from rdkit import Chem

  def filter_function(row_ids, cur, radius, atom_number):

      """
      The first three arguments should be always the same as shown in the example. These parameters will be passed to a function from a main function, e.g. from mutate_mol. All other arguments are user-defined. The function should return the list of row ids of fragments which will be used for replacing.

      :param row_id: a list of row ids from CReM database of those fragments which satisfy other selection criteria
      :param cur: cursor of CReM database
      :param radius: radius of a context
      :param atom_number: an atomic number, fragments with this number will be discarded
      :return list of remaining row ids
      """

      
      
      if not row_ids:
          return []
      batch_size = 32000  # SQLite has a limit on a number of passed values to a query
      row_ids = list(row_ids)
      smis = defaultdict(list)  # {smi_1: [rowid_1, rowid_5, ...], ...}
      for start in range(0, len(row_ids), batch_size):
          batch = row_ids[start:start + batch_size]
          sql = f"SELECT rowid, core_smi FROM radius{radius} WHERE rowid IN ({','.join('?' * len(batch))})"
          for i, smi in cur.execute(sql, batch).fetchall():
              smis[smi].append(i)

      output_row_ids = []
      for smi, ids in smis.items():
          for a in Chem.MolFromSmiles(smi).GetAtoms():
              if a.GetAtomicNum() == atom_number:
                  output_row_ids.extend(ids)
      return output_row_ids


  mol = Chem.MolFromSmiles('c1ccccc1C')
  mols = mutate_mol(mol, db_name='replacements.db', filter_func=partial(filter_function, atom_number=9), max_size=1, max_inc=3)
  ```
  output
  ```text
  ['Fc1ccccc1',
   'FC(F)(F)c1ccccc1',
   'FC(F)Oc1ccccc1',
   'FC(F)Sc1ccccc1']
  ```



  If not all possible derivatives are necessary to generate a user may limit the number of returned compounds by `max_replacements` argument which enable uniform sampling of a desired number of molecules. To enable custom sampling and bias selection to more desired chemotypes there is an argument `sample_func` which takes a function implementing the selection. This function should take four necessary arguments: row_ids (list or set of row_ids from the fragment database), cursor of that fragment database, radius (int) and the number of returned items (int). An example of such a function is implemented in `utils` module and showed below. Other biases can be introduced via this option. Please not, using of complex sampling functions may slow down structure generation.
  ```python
  def sample_csp3(row_ids, cur, radius, n):
      """
      Performs random selection of fragments proportionally to a squared fraction of sp3 carbon atoms.
      :param row_ids: the list of row ids of fragments to consider
      :param cur: cursor to the fragment database
      :param radius: context radius
      :param n: the number of fragments to select
      :return: the list of row ids of selected fragments
      """
      d = defaultdict(list)
      for rowid, core_smi, _, _ in _get_replacements(cur, radius, row_ids):
          d[core_smi].append(rowid)
      smis = list(d.keys())
      values = [rdMolDescriptors.CalcFractionCSP3(Chem.MolFromSmiles(smi)) ** 2 for smi in smis]
      values = [v + 1e-8 for v in values]
      values = np.array(values) / sum(values)
      selected_smiles = np.random.choice(smis, n, replace=False, p=values).tolist()
      ids = []
      for smi in selected_smiles:
          ids.extend(d[smi])
      ids = random.sample(ids, n)
      return ids
  ```
  Example of `sample_func` application. F atom is replaced and 10 derivatives is returned biased by the fraction of sp3 carbons and not.
  ```python
  m = Chem.MolFromSmiles('c1ccccc1F')

  res = list(mutate_mol(m, 'replacements_sa2_f5.db',
                        radius=3, min_inc=0, max_inc=10, max_replacements=10,
                        replace_ids=[6]))
  values = sorted(round(rdMolDescriptors.CalcFractionCSP3(Chem.MolFromSmiles(smi)), 4) for smi in res)
  print(res)
  print(values)

  res = list(mutate_mol(m, 'replacements_sa2_f5.db',
                        radius=3, min_inc=0, max_inc=10, max_replacements=10,
                        replace_ids=[6], sample_func=sample_csp3))
  values = sorted(round(rdMolDescriptors.CalcFractionCSP3(Chem.MolFromSmiles(smi)), 4) for smi in res)
  print(res)
  print(values)
  ```
  output
  ```text

  ['c1ccc(-c2ccc(-c3csnn3)cc2)cc1', 'c1ccc(COc2cccnc2)cc1', 'CCCc1ccc(OCc2ccccc2)cc1', 'CC(C)(O)C(=O)NCCc1ccccc1', 'CN(C)C(=O)CNC(=O)OCc1ccccc1', 'COc1ccc(-c2ccccc2)cc1C(N)=O', 'Fc1ccccc1-c1ccccc1', 'Nc1cccnc1Sc1ccccc1', 'O=C(Nc1ccc(F)c(F)c1)c1ccccc1', 'O=C(COC(=O)c1ccco1)c1ccccc1']
  [0.0, 0.0, 0.0, 0.0, 0.0714, 0.0769, 0.0833, 0.25, 0.3333, 0.4167]


  ['c1ccc(CNCc2ccncc2)cc1', 'Cc1cccc(CSc2ccccc2)n1', 'CC(=Cc1ccccc1)CN1CCN(C)CC1', 'CC(C)N(CCOc1ccccc1)C(C)C', 'CCN(CCC#N)C(=O)Nc1ccccc1', 'CSCc1ccccc1', 'O=C(Cc1ccccc1)NCCc1ccoc1', 'O=C(CCc1ccccc1)NC1CCCCC1', 'O=C(CN1CCCC1)NCCc1ccccc1', 'O=C(CSc1ccccc1)NC1CC1']
  [0.1538, 0.1538, 0.2143, 0.25, 0.3333, 0.3636, 0.4667, 0.5, 0.5333, 0.5714]
  ```
  In the latter case there are molecules having the greater fraction of sp3-carbon atoms.




  For convenience there is a function `enumerate_compounds` in `utils` module (added in version 0.2.6). It performs iterative growing (scaffold decoration) or mutation (analog enumeration) of a supplied molecule. More details are in docstring of the function.

  Example. Enumerate derivatives of 1-chloro-3-methylbenzene at positions 2 and 4 of the ring and at the methyl group at the same time. In this case one should choose `scaffold` mode, 3 iterations, specify atom ids (0-based indices) where fragments can be attached and set `protect_added_frag=True` to restrict enumeration only to selected positions.

  ```python
  from crem.utils import enumerate_compounds

  mol = Chem.MolFromMolBlock("""
    Mrv1922 05242309182D

    8  8  0  0  0  0            999 V2000
     -3.2813    1.3161    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
     -3.9957    0.9036    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
     -3.9957    0.0786    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
     -3.2813   -0.3339    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
     -2.5668    0.0786    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
     -2.5668    0.9036    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
     -3.2813   -1.1589    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
     -1.8523    1.3161    0.0000 Cl  0  0  0  0  0  0  0  0  0  0  0  0
    1  2  1  0  0  0  0
    2  3  2  0  0  0  0
    3  4  1  0  0  0  0
    4  5  2  0  0  0  0
    5  6  1  0  0  0  0
    1  6  2  0  0  0  0
    4  7  1  0  0  0  0
    6  8  1  0  0  0  0
  M  END
  """)

  mols = enumerate_compounds(mol, 'replacements_sa2.db', mode='scaffold', n_iterations=3,
                             radius=3, max_replacements=2, replace_ids=[2,4,6], protect_added_frag=True,
                             return_smi=True)
  ```
  output
  ```
  ['COc1c(C)cccc1Cl',
  'Cc1cc(Cl)ccc1Cl',
  'COc1ccc(Cl)c(OC)c1C',
  'COc1c(Cl)cccc1CF',
  'Cc1c(Cl)ccc(Cl)c1C',
  'CSCc1cc(Cl)ccc1Cl',
  'COc1ccc(Cl)c(OC)c1CC#N',
  'COCc1c(OC)ccc(Cl)c1OC',
  'COc1c(Cl)cccc1C(F)F',
  'COc1c(Cl)ccc(CO)c1CF',
  'Cc1c(Cl)ccc(Cl)c1CC#N',
  'Cc1c(Cl)ccc(Cl)c1CCN',
  'CSCc1c(Cl)ccc(Cl)c1C',
  'CSCc1c(Cl)ccc(Cl)c1Cl']
  ```


  All functions have an argument `ncores` and can make mupltile replacement in one molecule in parallel. If you want to process several molecules in parallel you have to write your own code. However, the described functions are generators and cannot be used with `multiprocessing` module. Therefore, three complementary functions `mutate_mol2`, `grow_mol2` and `link_mols2` were created. They return the list with results and can be pickled and used with `multiprocessing.Pool` or other tools.

  Example:
  ```python
  from multiprocessing import Pool
  from functools import partial
  from crem.crem import mutate_mol2
  from rdkit import Chem

  p = Pool(2)
  input_smi = ['c1ccccc1N', 'NCC(=O)OC', 'NCCCO']
  input_mols = [Chem.MolFromSmiles(s) for s in input_smi]

  res = list(p.imap(partial(mutate_mol2, db_name='replacements.db', max_size=1), input_mols))
  ```

  `res` would be a list of lists with SMILES of generated molecules





  |task|SMILES LSTM*|SMILES GA*|Graph GA*|Graph MCTS*|CReM
  |---|:---:|:---:|:---:|:---:|:---:|
  |Celecoxib rediscovery|**1.000**|0.732|**1.000**|0.355|**1.000**
  |Troglitazone rediscovery|**1.000**|0.515|**1.000**|0.311|**1.000**
  |Thiothixene rediscovery|**1.000**|0.598|**1.000**|0.311|**1.000**
  |Aripiprazole similarity|**1.000**|0.834|**1.000**|0.380|**1.000**
  |Albuterol similarity|**1.000**|0.907|**1.000**|0.749|**1.000**
  |Mestranol similarity|**1.000**|0.79|**1.000**|0.402|**1.000**
  |C11H24|**0.993**|0.829|0.971|0.410|0.966
  |C9H10N2O2PF2Cl|0.879|0.889|**0.982**|0.631|0.940
  |Median molecules 1|**0.438**|0.334|0.406|0.225|0.371
  |Median molecules 2|0.422|0.38|0.432|0.170|**0.434**
  |Osimertinib MPO|0.907|0.886|0.953|0.784|**0.995**
  |Fexofenadine MPO|0.959|0.931|0.998|0.695|**1.000**
  |Ranolazine MPO|0.855|0.881|0.92|0.616|**0.969**
  |Perindopril MPO|0.808|0.661|0.792|0.385|**0.815**
  |Amlodipine MPO|0.894|0.722|0.894|0.533|**0.902**
  |Sitagliptin MPO|0.545|0.689|**0.891**|0.458|0.763
  |Zaleplon MPO|0.669|0.413|0.754|0.488|**0.770**
  |Valsartan SMARTS|0.978|0.552|0.990|0.04|**0.994**
  |Deco Hop|0.996|0.970|**1.000**|0.590|**1.000**
  |Scaffold Hop|0.998|0.885|**1.000**|0.478|**1.000**
  |total score|17.341|14.398|17.983|9.011|17.919


  BSD-3


  CReM: chemically reasonable mutations framework for structure generation
  Pavel Polishchuk
  *Journal of Cheminformatics* **2020**, 12, (1), 28
  https://doi.org/10.1186/s13321-020-00431-w

  Control of Synthetic Feasibility of Compounds Generated with CReM
  Pavel Polishchuk
  *Journal of Chemical Information and Modeling* **2020**, 60, 6074-6080
  https://dx.doi.org/10.1021/acs.jcim.0c00792


pkgId: 8eac3338f946d24983ba8f93b30217c3f087e4015c2bc567119fba1679f81ab0
name: python-creme-crm
arch: src
version: 2.6.3
epoch: 0
release: 1
summary: A CRM software using the django web framework
url: https://www.cremecrm.com
rpm_license: AGPL-3.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-creme-crm-2.6.3-1.src.rpm
checksum_type: sha256
description:
  Creme is a free/open-source Customer Relationship Management software developed by Hybird (www.hybird.org).

  It is designed with an entities/relationships architecture, and is highly configurable, which allows
  adapting Creme to many workflows.

  ![Detailed view of a contact](https://github.com/HybirdCorp/creme_crm/raw/main/screenshot.png)

  It provides apps (i.e. modules) to manage:
   - Contacts & organisations.
   - Documents & folders.
   - Activities (meetings, phone calls, tasks...) with a calendar.
   - Products & services.
   - Invoices, quotes, sales orders & credit notes.
   - Opportunities.
   - Commercial actions.
   - Email campaigns.
   - Reports.
   - Tickets.
   - Alerts, todos & memos.
   - Geolocation.
   - ...

  Lots of aspects can be configured through a graphical interface :
   - Detailed views for entities are built from blocks; you can configure which blocks are
     displayed, you can create your own the blocks (chose the fields which are used)...
   - You can configure the columns of the list views (columns can be related to fields, custom-fields,
     relationships...), and filter the lines with powerful rules.
   - You can create your custom-fields, or hide existing fields.
   - You can choose which fields of forms are used, and group them like you want.
   - You can create your own types of relationship, adapted to your business.
   - ...

  Creme has powerful tools to filter, search or import data. it provides a credential system with
  some cool features (teams, allow/forbid entities from a filter on fields/relationships, ...).

  If you have very specific needs, Creme can also be used as a CRM framework to code your own CRM.

  Creme is coded in Python, and uses the Django web framework (http://www.djangoproject.com/) and
  the JQuery javascript library (http://jquery.com/).

  You can find more information on Creme on its official website: http://cremecrm.com/
  You can ask your questions in our forum: https://www.cremecrm.com/forum/index.php
  (there is an english section)



   - English (could probably be improved)
   - French




  It's recommended to use a database engine which supports transactions :
   - PostGreSQL is probably the best choice for databases with 100,000+ entities.
   - SQLite support is principally done for developers, but it remains a solution
     for small databases (e.g. a use as mono-user app with the server running of your computer).

  You probably should use 'virtualenv' (for an upgrade from Creme 2.4, you should create a new
  virtual env, in order to keep the old one working).




   - Python 3.8+
   - MySQL 8+ (or MariaDB 10.4+ but we do not advise you to use MariaDB because it regularly causes strange issues)
     or PostGreSQL 12+
     or SQLite (which is included with Python)
   - A web server compatible with Python, like Apache 2.4
   - Redis 3+
   - These Python packages :
     (exact versions of Python packages are indicated in the 'setup.cfg' file)
     - Mandatory :
       - Django
       - redis
       - python-dateutil
       - cryptography
       - bleach
       - Pillow
       - django-formtools
       - xlrd (to import contacts, organisations, activities, tickets... from xls files)
       - xlwt (to export all types of entities -- like contacts or organisations -- as xls files)
       - openpyxl (to import & export as above but with xlsx files)
       - csscompressor
       - rJSmin
     - Optional :
       - creme.billing :
         If you want PDF export, you can use :
         - xhtml2pdf (default)
         - weasyprint (easy to install on Linux ; harder on Windows)
         - you can also use the binary "pdflatex" (Ubuntu package 'texlive-latex-base').

  Installation with 'pip':
   - You should probably use "virtualenv".
   - To install Creme itself :
     - You can just install from pyPI: 'pip install creme-crm==2.6'
     - If you retrieved the source, you can use the following command at the source's root: 'pip install -e .'
   - About DB server :
     - If you use MySQL/MariaDB, you must add the 'mysql' flag :
       'pip install creme-crm[mysql]==2.6' (or 'pip install -e .[mysql]' with the source).
     - For PostGreSQL,  you must add the 'pgsql' flag :
       'pip install creme-crm[pgsql]==2.6' (or 'pip install -e .[pgsql]' with the source).
     - SQLite doesn't require a specific flag (see RECOMMENDATIONS).
   - Notice some of these Python packages need system libraries to be installed.
     For example, here a list of Debian/Ubuntu packages you'll have to install before:
     - python-dev
     - mysql_config & libmysqlclient-dev (or libpq-dev if you want to use PostGreSQL)
     - redis-server
     - libjpeg-dev
     - libcairo-dev




  Global remarks:
   - You should know how to install/deploy a Django application.
   - Upgrade note: if you already have a Creme installation, upgrade the version one by one
     (e.g. do not try to upgrade from 2.0 to 2.2, upgrade to 2.1 and then 2.2).

  Database configuration:
  For a new installation, you have to create a new database & a new DB user
  (who is allowed to create/drop tables, indices...).
  For an upgrade from the previous major version, back up your existing DB
  (of course you should back up regularly, even when you do not upgrade Creme...).

  Project creation:
  For new installations AND for upgrades from a previous version, create a new project;
  with the virtualenv activated, use the following command which creates a new folder:
  ```sh
  >> creme creme_start_project my_project
  ```

  Settings:
  The newly created file "my_project/my_project/settings.py" gives all the information
  for a basic installation with the minimal information you must fill.

  For an upgrade from the previous version of Creme :
   - See the section "UPGRADE NOTE" corresponding to the new version in the file CHANGELOG.txt.
   - Do not remove apps in INSTALLED_APPS during the upgrade (because they are installed in your DB) ;
     complete your installation & then uninstall apps you do not want anymore (see below).


  Filling the DB tables & creating the static asset:
  You must be in the parent folder "my_project/" (i.e. not "my_project/my_project/").
  Run the following commands (new installations AND upgrades from a previous version):
  ```sh
  >> creme migrate --settings=my_project.settings
  >> creme creme_populate --settings=my_project.settings
  >> creme generatemedia --settings=my_project.settings
  ```

  Note for MySQL users: you should load the time zone tables.
   - On Unix servers, it can be done with:
     ```sh
     >> mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql
     ```
   - For Windows environment, see https://stackoverflow.com/questions/14454304/convert-tz-returns-null




  To run the development server, you just have to run this command:
  ```sh
  >> creme runserver --settings=my_project.settings
  ```
  You can then go to http://localhost:8000 & log in with root/root.

  For a production deployment (Apache, Nginx...), you should read https://docs.djangoproject.com/en/3.2/howto/deployment/

  In order to get a completely functional instance, the job manager must be launched
  (some features need it: sending emails campaign, CSV import...).
  To run it, use this command (in a production environment a watch dog is advised):
  ```sh
  >> creme creme_job_manager --settings=my_project.settings
  ```




  When you have a working installation, & want to remove an (optional) app, use the command 'creme_uninstall' which will
  clean the DB. When it's done, you can comment the app in local_settings.py




  The repository is using CircleCI and launch some linting tests. To check them locally before any commit or push you can
  use the hooks in '.githooks'. There are two ways to configure them:

  Simply change git configuration
  ```sh
  >> git config core.hooksPath .githooks
  ```

  Or create symlink in '.git/hooks/'. Make sure the old one are moved or removed.
  ```sh
  >> ln -s ../../.githooks/pre-commit .git/hooks/pre-commit
  >> ln -s ../../.githooks/pre-push .git/hooks/pre-push
  ```

  In order to run the JavaScript linter locally, you can install a NodeJS environment within your virtualenv thanks to the
  Python package nodeenv. In your virtualenv (named "mycremeenv"):
  ```sh
  >> pip install nodeenv
  >> nodeenv -n 14.20.0 -p    # to install nodejs 14.20.0 with "mycremeenv"
  >> deactivate
  >> workon mycremeenv
  >> nodejs --version  # to check the installation is OK
  >> make node-update  # Install nodejs requirements
  ```

  Now you can run "make eslint" manually, and the pre-commit hook will check the new/modified files.



  Creme CRM source code is available on the [Creme CRM GitHub Repository](https://github.com/HybirdCorp/creme_crm).

  Want to know more about Creme CRM ?
  Check out the [Creme CRM Website](https://www.cremecrm.com).

  Want to try Creme CRM ?
  Visit the [Creme CRM Public Demo Website](https://demos.cremecrm.com/).

  Want your own demo instance ?
  Pull the latest Creme CRM Demo Docker image on the [Creme CRM DockerHub Repository](https://hub.docker.com/r/cremecrm/cremecrm-demo).

  Want to know more about our company ?
  Check out the [Hybird Website](https://hybird.org/).

  Any other questions ?
  Need help ?
  Reach us on the [Creme CRM Forums](https://www.cremecrm.com/forum/).
  Our (french) [Video tutorials](https://www.youtube.com/channel/UCqt-dsKnW7sNwlCWOODTDWQ).


pkgId: 89a75286364fd55d7874671e4dbe1444491a5a8fbc45f9d3882a76313de340aa
name: python-crep
arch: src
version: 2024.2.6
epoch: 0
release: 1
summary: please add a summary manually as the author left a blank one
url: https://pypi.org/project/crep/
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crep-2024.2.6-1.src.rpm
checksum_type: sha256
description:
  [![pytest](https://github.com/eurobios-scb/crep/actions/workflows/pytest.yml/badge.svg?event=push)](https://docs.pytest.org)
  ![code coverage](https://raw.githubusercontent.com/eurobios-mews-labs/crep/coverage-badge/coverage.svg?raw=true)
  ```python
  pip install crep
  ```

  This simple module aims at providing some function to tackle tabular
  data that have a continuous axis. In situations, this index can represent
  time, but this tool was originally developed to tackle rail way description.

  This simple tools helps providing tools to represent a linear structure (cable, rail, beam, pipe)
  whose characteristics are piece-wize constant (of strongly heterogeneous length)



  * **Merge function** merge together two dataframe
  ```python
  import pandas as pd

  from crep import merge


  df_left = pd.DataFrame(
      dict(id=[2, 2, 2],
           t1=[0, 100, 120],
           t2=[100, 120, 130],
           data1=[0.2, 0.1, 0.5])
  )
  df_right = pd.DataFrame(
      dict(id=[2, 2, 2],
           t1=[0, 80, 100],
           t2=[70, 100, 140],
           data2=[0.1, 0.3, 0.2])
  )

  ret = merge(data_left=df_left,
              data_right=df_right,
              id_continuous=["t1", "t2"],
              id_discrete=["id"],
              how="outer")
  ```
  Yield the following result


  <img src="examples/merge.png" alt="drawing" width="350"/>



  Test if your data is admissible to the merge function, you can use the tools module

  ```python
  import pandas as pd

  from crep import tools


  df_admissible = pd.DataFrame(
      dict(id=[2, 2, 2],
           t1=[0, 100, 120],
           t2=[100, 120, 130],
           data1=[0.2, 0.1, 0.5])
  )
  df_not_admissible = pd.DataFrame(
      dict(id=[2, 2, 2],
           t1=[0, 90, 120],
           t2=[100, 120, 130],
           data1=[0.2, 0.1, 0.5])
  )


  assert tools.admissible_dataframe(
      df_admissible, id_continuous=["t1", "t2"],
      id_discrete=["id"])
  assert not tools.admissible_dataframe(
      df_not_admissible, id_continuous=["t1", "t2"],
      id_discrete=["id"])
  print(tools.sample_non_admissible_data(
      df_not_admissible, id_continuous=["t1", "t2"],
      id_discrete=["id"]
  ))


  ```



  This implementation come from an SNCF DTIPG project and is
  developed and maintained by Mews Labs and SNCF DTIPG.

  <img src="https://www.sncf.com/themes/contrib/sncf_theme/images/logo-sncf.svg?v=3102549095" alt="drawing" width="100"/>
  <img src="./.static/mews_labs.png" alt="drawing" width="120"/>


pkgId: f377a6220344e0a2215721735191eff2551cc1c16792ce96f01e51b21dc4475f
name: python-crepes
arch: src
version: 0.7.1
epoch: 0
release: 1
summary: Conformal classifiers, regressors, and predictive systems (crepes)
url: https://github.com/henrikbostrom/crepes
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crepes-0.7.1-1.src.rpm
checksum_type: sha256
description:
  <p align="center"><a href="https://crepes.readthedocs.io"><img alt="crepes" src="https://github.com/henrikbostrom/crepes/blob/main/docs/crepes_logo.png"></a></p>

  <p align="center">
  <a href="https://pypi.org/project/crepes/"><img src="https://img.shields.io/badge/pypi package-0.7.1-brightgreen" alt="PyPI version" height=20 align="center"></a>
  <a href="https://anaconda.org/conda-forge/crepes"><img src="https://img.shields.io/badge/conda--forge-0.7.1-orange" alt="conda-forge version" height=20 align="center"></a>
  <a href="https://pepy.tech/project/crepes"><img src="https://static.pepy.tech/badge/crepes?dummy=unused" alt="Downloads" height=20 align="center"></a>
  <a href="https://crepes.readthedocs.io/en/latest"><img src="https://readthedocs.org/projects/crepes/badge/?version=latest" alt="docs status" height=20 align="center"></a>
  <a href="https://github.com/henrikbostrom/crepes/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-BSD--3--clause-blue" alt="License" height=20 align="center"></a>
  <a href="https://github.com/henrikbostrom/crepes/blob/main/CHANGELOG.md"><img src="https://img.shields.io/github/release-date/henrikbostrom/crepes" alt="Release date" height=20 align="center"></a>
  </p>

  <br>

  `crepes` is a Python package for conformal prediction that implements conformal classifiers,
  regressors, and predictive systems on top of any standard classifier
  and regressor, turning the original predictions into
  well-calibrated p-values and cumulative distribution functions, or
  prediction sets and intervals with coverage guarantees.

  The `crepes` package implements standard and Mondrian conformal
  classifiers as well as standard, normalized and Mondrian conformal
  regressors and predictive systems. While the package allows you to use
  your own functions to compute difficulty estimates, non-conformity
  scores and Mondrian categories, there is also a separate module,
  called `crepes.extras`, which provides some standard options for
  these.



  From [PyPI](https://pypi.org/project/crepes/)

  ```bash
  pip install crepes
  ```

  From [conda-forge](https://anaconda.org/conda-forge/crepes)

  ```bash
  conda install conda-forge::crepes
  ```



  For the complete documentation, see [crepes.readthedocs.io](https://crepes.readthedocs.io/en/latest/).



  Let us illustrate how we may use `crepes` to generate and apply
  conformal classifiers with a dataset from
  [www.openml.org](https://www.openml.org), which we first split into a
  training and a test set using `train_test_split` from
  [sklearn](https://scikit-learn.org), and then further split the
  training set into a proper training set and a calibration set:

  ```python
  from sklearn.datasets import fetch_openml
  from sklearn.model_selection import train_test_split

  dataset = fetch_openml(name="qsar-biodeg", parser="auto")

  X = dataset.data.values.astype(float)
  y = dataset.target.values

  X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5)

  X_prop_train, X_cal, y_prop_train, y_cal = train_test_split(X_train, y_train,
                                                              test_size=0.25)
  ```

  We now "wrap" a random forest classifier, fit it to the proper
  training set, and fit a standard conformal classifier through the
  `calibrate` method:

  ```python
  from crepes import WrapClassifier
  from sklearn.ensemble import RandomForestClassifier

  rf = WrapClassifier(RandomForestClassifier(n_jobs=-1))

  rf.fit(X_prop_train, y_prop_train)

  rf.calibrate(X_cal, y_cal)
  ```

  We may now produce p-values for the test set (an array with as many
  columns as there are classes):

  ```python
  rf.predict_p(X_test)
  ```

  ```numpy
  array([[0.00427104, 0.74842304],
         [0.07874355, 0.2950549 ],
         [0.50529983, 0.01557963],
         ...,
         [0.8413356 , 0.00201167],
         [0.84402215, 0.00654927],
         [0.29601955, 0.07766093]])
  ```

  We can also get prediction sets, represented by binary vectors
  indicating presence (1) or absence (0) of the class labels that
  correspond to the columns, here at the 90% confidence level:

  ```python
  rf.predict_set(X_test, confidence=0.9)
  ```

  ```numpy
  array([[0, 1],
         [0, 1],
         [1, 0],
         ...,
         [1, 0],
         [1, 0],
         [1, 0]])
  ```

  Since we have access to the true class labels, we can evaluate the
  conformal classifier (here using all available metrics which is the
  default), at the 99% confidence level:

  ```python
  rf.evaluate(X_test, y_test, confidence=0.99)
  ```

  ```python
  {'error': 0.005681818181818232,
   'avg_c': 1.691287878787879,
   'one_c': 0.3087121212121212,
   'empty': 0.0,
   'time_fit': 2.3365020751953125e-05,
   'time_evaluate': 0.017678260803222656}
  ```

  To control the error level across different groups of objects of
  interest, we may use so-called Mondrian conformal classifiers. A
  Mondrian conformal classifier if formed by providing a function or a
  `MondrianCategorizer` (defined in `crepes.extras`) as an additional
  argument, named `mc`, for the `calibrate` method.

  For illustration, we will use the predicted labels of the underlying
  model to form the categories. Note that the prediction sets are generated
  for the test objects using the same categorization (under the hood).

  ```python
  rf_mond = WrapClassifier(rf.learner)

  rf_mond.calibrate(X_cal, y_cal, mc=rf_mond.predict)

  rf_mond.predict_set(X_test)
  ```

  ```numpy
  array([[0, 1],
         [1, 1],
         [1, 0],
         ...,
         [1, 0],
         [1, 0],
         [1, 1]])
  ```

  We may also form the categories using a `MondrianCategorizer`, which
  may be fitted in several different ways. Below we show how to form
  categories by (equal-sized) binning of the first feature value, using
  five bins (instead of the default which is 10); note that we need
  objects to get the threshold values for the categories (bins).

  ```python
  from crepes.extras import MondrianCategorizer

  def get_values(X):
      return X[:,0]

  mc = MondrianCategorizer()
  mc.fit(X_cal, f=get_values, no_bins=5)

  rf_mond = WrapClassifier(rf.learner)
  rf_mond.calibrate(X_cal, y_cal, mc=mc)

  rf_mond.predict_set(X_test)
  ```

  ```numpy
  array([[0, 1],
         [1, 1],
         [1, 0],
         ...,
         [1, 0],
         [1, 0],
         [1, 1]])
  ```

  For conformal classifiers that employ learners that use bagging, like
  random forests, we may consider an alternative strategy to dividing
  the original training set into a proper training and calibration set;
  we may use the out-of-bag (OOB) predictions, which allow us to use the
  full training set for both model building and calibration. It should
  be noted that this strategy does not come with the theoretical
  validity guarantee of the above (inductive) conformal classifiers, due
  to that calibration and test instances are not handled in exactly the
  same way. In practice, however, conformal classifiers based on
  out-of-bag predictions rarely fail to meet the coverage requirements.

  Below we show how to enable this in conjunction with a specific type
  of Mondrian conformal classifier, a so-called class-conditional
  conformal classifier, which uses the class labels as Mondrian
  categories:

  ```python
  rf = WrapClassifier(RandomForestClassifier(n_jobs=-1, n_estimators=500, oob_score=True))

  rf.fit(X_train, y_train)

  rf.calibrate(X_train, y_train, class_cond=True, oob=True)

  rf.evaluate(X_test, y_test, confidence=0.9)
  ```

  ```python
  {'error': 0.10795454545454541,
   'avg_c': 1.0984848484848484,
   'one_c': 0.9015151515151515,
   'empty': 0.0,
   'time_fit': 0.0001518726348876953,
   'time_evaluate': 0.06513118743896484}
  ```

  Let us also illustrate how `crepes` can be used to generate conformal
  regressors and predictive systems. Again, we import a dataset from
  [www.openml.org](https://www.openml.org), which we split into a
  training and a test set and then further split the training set into a
  proper training set and a calibration set:

  ```python
  from sklearn.datasets import fetch_openml
  from sklearn.model_selection import train_test_split

  dataset = fetch_openml(name="house_sales", version=3, parser="auto")

  X = dataset.data.values.astype(float)
  y = dataset.target.values.astype(float)

  X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5)
  X_prop_train, X_cal, y_prop_train, y_cal = train_test_split(X_train, y_train,
                                                              test_size=0.25)
  ```

  Let us now "wrap" a `RandomForestRegressor` from
  [sklearn](https://scikit-learn.org) using the class `WrapRegressor`
  from `crepes` and fit it (in the usual way) to the proper training
  set:

  ```python
  from sklearn.ensemble import RandomForestRegressor
  from crepes import WrapRegressor

  rf = WrapRegressor(RandomForestRegressor())
  rf.fit(X_prop_train, y_prop_train)
  ```

  We may now fit a conformal regressor using the calibration set through
  the `calibrate` method:

  ```python
  rf.calibrate(X_cal, y_cal)
  ```

  The conformal regressor can now produce prediction intervals for the
  test set, here using a confidence level of 99%:

  ```python
  rf.predict_int(X_test, confidence=0.99)
  ```

  ```numpy
  array([[   8260.53, 1065083.53],
         [ -54858.5 , 1001964.5 ],
         [  -7779.25, 1049043.75],
         ...,
         [ 297229.8 , 1354052.8 ],
         [-270260.  ,  786563.  ],
         [-185146.94,  871676.06]])
  ```

  The output is a [NumPy](https://numpy.org) array with a row for each
  test instance, and where the two columns specify the lower and upper
  bound of each prediction interval.

  We may request that the intervals are cut to exclude impossible
  values, in this case below 0, and if we also rely on the default
  confidence level (0.95), the output intervals will be a bit tighter:

  ```python
  rf.predict_int(X_test, y_min=0)
  ```

  ```numpy
  array([[ 288602.83,  784741.23],
         [ 225483.8 ,  721622.2 ],
         [ 272563.05,  768701.45],
         ...,
         [ 577572.1 , 1073710.5 ],
         [  10082.3 ,  506220.7 ],
         [  95195.36,  591333.76]])
  ```

  The above intervals are not normalized, i.e., they are all of the same
  size (at least before they are cut). We could make them more
  informative through normalization using difficulty estimates; objects
  considered more difficult will be assigned wider intervals.

  We will use a `DifficultyEstimator` from the `crepes.extras` module
  for this purpose. Here we estimate the difficulty by the standard
  deviation of the target of the k (default `k=25`) nearest neighbors in
  the proper training set to each object in the calibration set. A small
  value (beta) is added to the estimates, which may be given through an
  argument to the function; below we just use the default, i.e.,
  `beta=0.01`.

  We first fit the difficulty estimator and then calibrate the conformal
  regressor, using the calibration objects and labels together the
  difficulty estimator:

  ```python
  from crepes.extras import DifficultyEstimator

  de = DifficultyEstimator()
  de.fit(X_prop_train, y=y_prop_train)

  rf.calibrate(X_cal, y_cal, de=de)
  ```

  To obtain prediction intervals, we just have to provide test objects
  to the `predict_int` method, as the difficulty estimates will be
  computed by the incorporated difficulty estimator:

  ```python
  rf.predict_int(X_test, y_min=0)
  ```

  ```numpy
  array([[ 222036.82862012,  851307.23137988],
         [ 316413.83821721,  630692.16178279],
         [ 384784.44135415,  656480.05864585],
         ...,
         [ 110527.74801848, 1540754.85198152],
         [ 174799.94131735,  341503.05868265],
         [ 274305.55734858,  412223.56265142]])
  ```

  Depending on the employed difficulty estimator, the normalized
  intervals may sometimes be unreasonably large, in the sense that they
  may be several times larger than any previously observed
  error. Moreover, if the difficulty estimator is uninformative, e.g.,
  completely random, the varying interval sizes may give a false
  impression of that we can expect lower prediction errors for instances
  with tighter intervals. Ideally, a difficulty estimator providing
  little or no information on the expected error should instead lead to
  more uniformly distributed interval sizes.

  A Mondrian conformal regressor can be used to address these problems,
  by dividing the object space into non-overlapping so-called Mondrian
  categories, and forming a (standard) conformal regressor for each
  category. We may form a Mondrian conformal regressor by providing a
  function or a `MondrianCategorizer` (defined in `crepes.extras`) as an
  additional argument, named `mc`, for the `calibrate` method.

  Here we employ a `MondrianCategorizer`; it may be fitted in several
  different ways, and below we show how to form categories by binning of
  the difficulty estimates into 20 bins, using the difficulty estimator
  fitted above.

  ```python
  from crepes.extras import MondrianCategorizer

  mc_diff = MondrianCategorizer()
  mc_diff.fit(X_cal, de=de, no_bins=20)

  rf.calibrate(X_cal, y_cal, mc=mc_diff)
  ```

  When making predictions, the test objects will be assigned to Mondrian categories
  according to the incorporated `MondrianCategorizer` (or labeling function):

  ```python
  rf.predict_int(X_test, y_min=0)
  ```

  ```numpy
  array([[ 242624.89,  830719.17],
         [ 329358.5 ,  617747.5 ],
         [ 371028.  ,  670236.5 ],
         ...,
         [      0.  , 1730501.3 ],
         [ 157022.53,  359280.47],
         [ 266456.61,  420072.51]])
  ```

  We could very easily switch from conformal regressors to conformal
  predictive systems. The latter produce cumulative distribution
  functions (conformal predictive distributions). From these we can
  generate prediction intervals, but we can also obtain percentiles,
  calibrated point predictions, as well as p-values for given target
  values. Let us see how we can go ahead to do that.

  Well, there is only one thing above that changes: just provide
  `cps=True` to the `calibrate` method.

  We can, for example, form normalized Mondrian conformal predictive
  systems, by providing both a Mondrian categorizer and difficulty estimator
  to the `calibrate` method. Here we will consider Mondrian categories formed
  from binning the point predictions:

  ```python
  mc_pred = MondrianCategorizer()
  mc_pred.fit(X_cal, f=rf.predict, no_bins=5)

  rf.calibrate(X_cal, y_cal, de=de, mc=mc_pred, cps=True)
  ```

  We can now make predictions with the conformal predictive system,
  through the method `predict_cps`.  The output of this method can be
  controlled quite flexibly; here we request prediction intervals with
  95% confidence to be output:

  ```python
  rf.predict_cps(X_test, lower_percentiles=2.5, higher_percentiles=97.5, y_min=0)
  ```

  ```numpy
  array([[ 240114.65604157,  869014.03528742],
         [ 339706.24924814,  609239.58260891],
         [ 404920.87940518,  637934.16698199],
         ...,
         [      0.        , 1947549.10314688],
         [ 173038.55234664,  335836.19025193],
         [ 280187.36965593,  399290.04471503]])
  ```

  If we would like to take a look at the p-values for the true targets (these should be uniformly distributed), we can do the following:

  ```python
  rf.predict_cps(X_test, y=y_test)
  ```

  ```numpy
  array([0.38424814, 0.54023864, 0.28727364, ..., 0.35291685, 0.6110545 ,
         0.60037036])
  ```

  We may request that the `predict_cps` method returns the full
  conformal predictive distribution (CPD) for each test instance, as
  defined by the threshold values, by setting `return_cpds=True`. The
  format of the distributions vary with the type of conformal predictive
  system; for a standard and normalized CPS, the output is an array with
  a row for each test instance and a column for each calibration
  instance (residual), while for a Mondrian CPS, the default output is a
  vector containing one CPD per test instance, since the number of
  values may vary between categories.

  ```python
  cpds = rf.predict_cps(X_test, return_cpds=True)
  ```

  The resulting vector of arrays is not displayed here, but we instead provide a plot for the CPD of a random test instance:

  ![cpd](https://user-images.githubusercontent.com/7838741/235081969-328d7a23-26c9-4799-a246-8c35fd7ac88e.png)



  For additional examples of how to use the package and module, see [the documentation](https://crepes.readthedocs.io/en/latest/), [this Jupyter notebook using WrapClassifier and WrapRegressor](https://github.com/henrikbostrom/crepes/blob/main/docs/crepes_nb_wrap.ipynb), and [this Jupyter notebook using ConformalClassifier, ConformalRegressor, and ConformalPredictiveSystem](https://github.com/henrikbostrom/crepes/blob/main/docs/crepes_nb.ipynb).



  If you use `crepes` for a scientific publication, you are kindly requested to cite the following paper:

  Boström, H., 2022. crepes: a Python Package for Generating Conformal Regressors and Predictive Systems. In Conformal and Probabilistic Prediction and Applications. PMLR, 179. [Link](https://proceedings.mlr.press/v179/bostrom22a.html)

  Bibtex entry:

  ```bibtex
  @InProceedings{crepes,
    title = 	 {crepes: a Python Package for Generating Conformal Regressors and Predictive Systems},
    author =       {Bostr\"om, Henrik},
    booktitle = 	 {Proceedings of the Eleventh Symposium on Conformal and Probabilistic Prediction and Applications},
    year = 	 {2022},
    editor = 	 {Johansson, Ulf and Boström, Henrik and An Nguyen, Khuong and Luo, Zhiyuan and Carlsson, Lars},
    volume = 	 {179},
    series = 	 {Proceedings of Machine Learning Research},
    publisher =    {PMLR}
  }
  ```



  <a id="1">[1]</a> Vovk, V., Gammerman, A. and Shafer, G., 2005. Algorithmic learning in a random world. Springer [Link](https://link.springer.com/book/10.1007/b106715)

  <a id="2">[2]</a> Papadopoulos, H., Proedrou, K., Vovk, V. and Gammerman, A., 2002. Inductive confidence machines for regression. European Conference on Machine Learning, pp. 345-356. [Link](https://link.springer.com/chapter/10.1007/3-540-36755-1_29)

  <a id="3">[3]</a> Johansson, U., Boström, H., Löfström, T. and Linusson, H., 2014. Regression conformal prediction with random forests. Machine learning, 97(1-2), pp. 155-176. [Link](https://link.springer.com/article/10.1007/s10994-014-5453-0)

  <a id="4">[4]</a> Boström, H., Linusson, H., Löfström, T. and Johansson, U., 2017. Accelerating difficulty estimation for conformal regression forests. Annals of Mathematics and Artificial Intelligence, 81(1-2), pp.125-144. [Link](https://link.springer.com/article/10.1007/s10472-017-9539-9)

  <a id="5">[5]</a> Boström, H. and Johansson, U., 2020. Mondrian conformal regressors. In Conformal and Probabilistic Prediction and Applications. PMLR, 128, pp. 114-133. [Link](https://proceedings.mlr.press/v128/bostrom20a.html)

  <a id="6">[6]</a> Vovk, V., Petej, I., Nouretdinov, I., Manokhin, V. and Gammerman, A., 2020. Computationally efficient versions of conformal predictive distributions. Neurocomputing, 397, pp.292-308. [Link](https://www.aminer.org/pub/5e09aac9df1a9c0c416c9b70/computationally-efficient-versions-of-conformal-predictive-distributions)

  <a id="7">[7]</a> Boström, H., Johansson, U. and Löfström, T., 2021. Mondrian conformal predictive distributions. In Conformal and Probabilistic Prediction and Applications. PMLR, 152, pp. 24-38. [Link](https://proceedings.mlr.press/v152/bostrom21a.html)

  <a id="8">[8]</a> Vovk, V., 2022. Universal predictive systems. Pattern Recognition. 126: pp. 108536 [Link](https://dl.acm.org/doi/abs/10.1016/j.patcog.2022.108536)


  - - -

  Author: Henrik Boström (bostromh@kth.se)
  Copyright 2024 Henrik Boström
  License: BSD 3 clause


pkgId: c758b8c0073638d28225947db4797ae9620f63e77100f0faa3f6b1028bf053b3
name: python-crepex-pyutil
arch: src
version: 0.17.0
epoch: 0
release: 1
summary: CrepeX python utilities
url: https://pypi.org/project/crepex-pyutil/
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crepex-pyutil-0.17.0-1.src.rpm
checksum_type: sha256
description:
  - `poetry` 를 사용해서 개발
  - 가상환경은 `poetry shell`
  - 패키지 설치는 `poetry install`
  - 최조 pre-commit 셋팅 `pre-commit install`




  - TestPypi 계정준비, API 토큰 준비

  ```shell

  poetry config repositories.testpypi https://test.pypi.org/legacy/

  poetry config http-basic.testpypi __token__ pypi-your-api-token-here


  poetry build
  poetry publish -r testpypi


  pip install -i https://test.pypi.org/.../your-package-name
  ```


  - Pypi 계정준비, API 토큰 준비
  ```shell

  poetry config pypi-token.pypi pypi-your-token-here


  poetry publish --build
  ```


pkgId: 3a073da981820db28ad6cad70806880526fd9d9aa4afd60ebe44ed305e60e2f3
name: python-cressp
arch: src
version: 0.2.10
epoch: 0
release: 1
url: https://github.com/ahs2202/cressp
rpm_license: GPLv3
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-cressp-0.2.10-1.src.rpm
checksum_type: sha256
summary:
  a program to find cross-reactive epitopes with structural information from known protein structures.

description:
  ![CRESSP Logo](https://raw.githubusercontent.com/ahs2202/cressp/master/documentation/cressp_logo.PNG)



   A program to find cross-reactive epitopes with structural information from known protein structures.





  Our new pipeline, called Cross-ReactiveEpitope-Search-using-Structural-Properties-of-proteins (CRESSP), use structural information from RCSB-PDB database to search potential cross-reactive B-cell epitopes of human and pathogen proteins.

  First, protein sequences of interest (provided by user) are searched with either BLASTP alone or in combination with HMMER3 with an HMM profile database built from ~5000 Pan-Proteomes from the UniProt database.

  Second, using pre-computed experimental and predicted relative-surface-availability (RSA) values of human protein residues, the alignment between human and pathogen proteins are further analyzed to identify potential cross-reactive B-cell epitopes. The RSA-weighted BLOSUM62 scores are calculated with an array of sliding windows (provided by user) to estimate possible cross-reactivity between two proteins.

  Lastly, the output file from our pipeline can be visualized interactively with web-browser-based application (similar to the interactive interface in our web-application for SARS-CoV-2, http://ahs2202.github.io/3M/)

  Currently, we are additionally implementing neural-network-based (bi-directional stacked RNN) surface-availability prediction module in our tool to efficiently predict RSA values of any protein sequences of interests so that CRESSP can predict B-cell cross-reactivity between any proteome of interest, including proteins from metagenome-assembled genomes.





  CRESSP requires BLASTP from **BLAST+ (v2.10.1+)** and HMMER3, which can be installed through conda with the following commands:

  ```sh
      conda install -c bioconda blast
      conda install -c bioconda hmmer
  ```

  BLAST+ binaries can be also downloaded from [here](https://ftp.ncbi.nlm.nih.gov/blast/executables/blast+/LATEST/).

  CRESSP can be installed from PyPI (https://pypi.org/project/cressp/)

  ```sh
      pip install cressp
  ```

  CRESSP uses **TensorFlow (>2.3.0)** for prediction of relative surface area (RSA) and secondary structure classification. If CUDA-enabled GPU is available, CRESSP will automatically use GPU for prediction of structural properties of input proteins.



  For T-cell cross-reactive epitope prediction, CRESSP uses **MHCflurry 2** to predict MHC binding affinity values of aligned peptides. Before using CRESSP, MHCflurry 2 models and datasets should be downloaded by executing the following command:

  ```shell
  mhcflurry-downloads fetch
  ```







  ```
  usage: cressp [-h] [-t DIR_FILE_PROTEIN_TARGET] [-q DIR_FILE_PROTEIN_QUERY] [-o DIR_FOLDER_OUTPUT] [-c CPU] [-w WINDOW_SIZE] [-e FLOAT_THRES_E_VALUE] [-H] [-d DIR_FILE_QUERY_HMMDB] [-R] [-Q]
                [-s FLOAT_THRES_AVG_SCORE_BLOSUM_WEIGHTED] [-S FLOAT_THRES_AVG_SCORE_BLOSUM] [-C FLOAT_THRES_RSA_CORRELATION]

  Cross-Reactive-Epitope-Search-using-Structural-Properties-of-proteins (cressp): a program to find cross-reactive epitopes with structural information from known protein structures.

  optional arguments:
    -h, --help            show this help message and exit
    -t DIR_FILE_PROTEIN_TARGET, --dir_file_protein_target DIR_FILE_PROTEIN_TARGET
                          (Required) an input FASTA file containing target protein sequences.
    -q DIR_FILE_PROTEIN_QUERY, --dir_file_protein_query DIR_FILE_PROTEIN_QUERY
                          (Default: UniProt human proteins) an input FASTA file containing query protein sequences.
    -o DIR_FOLDER_OUTPUT, --dir_folder_output DIR_FOLDER_OUTPUT
                          (Default: a subdirectory 'cressp_out/' of the current directory) an output directory
    -c CPU, --cpu CPU     (Default: 1) Number of logical CPUs (threads) to use in the current compute node.
    -w WINDOW_SIZE, --window_size WINDOW_SIZE
                          (Default: 30) list of window sizes separated by comma. Example: 15,30,45
    -e FLOAT_THRES_E_VALUE, --float_thres_e_value FLOAT_THRES_E_VALUE
                          (Default: 1e-20) threshold for the global alignment e-value in a scientific notation Example: 1e-3
    -H, --flag_use_HMM_search
                          (Default: False) Set this flag to perform HMM search in addition to BLASTP search. HMM profile search is performed with HMMER3. The search usually takes several hours for
                          metagenome-assembled genomes
    -d DIR_FILE_QUERY_HMMDB, --dir_file_query_hmmdb DIR_FILE_QUERY_HMMDB
                          (Default: a HMM profile database of 1012 human proteins searched against UniProt Pan Proteomes. These proteins consist of experimentally validated human autoantigens) a file
                          containing HMM DB of query proteins aligned against pan-proteomes
    -R, --flag_use_rcsb_pdb_only
                          (Default: False) When calculating consensus structural properties of input proteins, do not use homology-based modeled structures from SWISS-MODEL repositories and only use
                          experimental protein structures from RCSB PDB
    -Q, --flag_only_use_structural_properties_of_query_proteins
                          (Default: False) Only use estimated structural properties of the query proteins when predicting cross-reactivity between target and query proteins (skip the estimation of
                          structural properties of target proteins). When 'dir_file_protein_query' == 'human' (default value), it will significantly reduce computation time by skipping estimation and
                          prediction steps of structural properties of target and query proteins.
    -s FLOAT_THRES_AVG_SCORE_BLOSUM_WEIGHTED, --float_thres_avg_score_blosum_weighted FLOAT_THRES_AVG_SCORE_BLOSUM_WEIGHTED
                          (Default: 0.15) threshold for average weighted BLOSOM62 alignment score for filtering predicted cross-reactive epitopes
    -S FLOAT_THRES_AVG_SCORE_BLOSUM, --float_thres_avg_score_blosum FLOAT_THRES_AVG_SCORE_BLOSUM
                          (Default: 0) threshold for average BLOSOM62 alignment score for filtering predicted cross-reactive epitopes
    -C FLOAT_THRES_RSA_CORRELATION, --float_thres_rsa_correlation FLOAT_THRES_RSA_CORRELATION
                          (Default: 0) threshold for correlation coefficient of Relative Surface Area (RSA) values for filtering predicted cross-reactive epitopes
  ```





  To run CRESSP from an interactive Python environment, the following code can be used.

  ```python
  import cressp


  cressp.cressp( dir_file_protein_target = "UP000464024_2697049.fasta", n_threads = 2, flag_use_HMM_search = True, l_window_size = [ 15, 30 ], float_thres_e_value = 1e-2 )
  ```



  Alternatively, to run only a part of CRESSP to estimate structural properties of protein sequences of interest, the following code can be used.

  ```python
  import cressp
  import cressp.structural_property_estimation


  cressp.structural_property_estimation.Estimate_structural_property( "UP000464024_2697049.fasta", n_threads = 2, dir_folder_pipeline = "output/" )


  dict_sp = cressp.Parse_Structural_Properties( "output/UP000464024_2697049.tsv.gz" )
  ```





  Open <u>CRESSP Web Viewer</u> `CRESSP_Web_Viewer.html` in the output directory with a web browser.

  <u>CRESSP Web Viewer</u> can be also found [**here**](https://ahs2202.github.io/cressp/).

  ![CRESSP Logo](https://raw.githubusercontent.com/ahs2202/cressp/master/documentation/CRESSP_Web_Viewer_before_loading.png)



  Then, load (drag & drop) CRESSP output files in the `web_application/` subdirectory of the output directory. Once all necessary files has been loaded, the text on the grey button will change into 'Start Analysis'. Click the button to explore CRESSP analysis results. (Below is an example screen of <u>CRESSP Web Viewer</u>). Example CRESSP output files can be found at **[here](https://github.com/ahs2202/cressp/tree/main/documentation/tutorial/web_application)**.

  ![CRESSP Logo](https://raw.githubusercontent.com/ahs2202/cressp/master/documentation/CRESSP_Web_Viewer_after_loading.png)





  1) Download the proteome of SARS-CoV-2 from UniProt ([UP000464024](https://ftp.uniprot.org/pub/databases/uniprot/current_release/knowledgebase/reference_proteomes/Viruses/UP000464024/UP000464024_2697049.fasta.gz)) as a FASTA sequence.

  2) Run CRESSP with the following command. (CRESSP can be also used as a python package)

  ```bash
      cressp -t UP000464024_2697049.fasta.gz --flag_use_HMM_search --float_thres_e_value 5e-2 --cpu 2
  ```



  Running CRESSP with the above command will do the following tasks:

  1. Search SARS-CoV-2 protein sequences with human protein sequences with BLASTP and HMMER3, and
  2. Align SARS-CoV-2 protein sequences against known or predicted protein structures from the [RCSB-PDB](https://www.rcsb.org/) database and the [SWISS-MODEL Repository](https://swissmodel.expasy.org/repository).
  3. Predict structural properties (surface accessibility and secondary structure) of protein residues not covered by the protein structure databases using Deep Neural Network (DNN) models trained on the protein structure databases.
  4. Calculate similarity scores based on estimated structural properties of SARS-CoV-2 proteins and (pre-computed) structural properties of human proteins



  3) Open [CRESSP Web Viewer](https://ahs2202.github.io/cressp/)

  4) Load [CRESSP output files](https://github.com/ahs2202/cressp/tree/main/documentation/tutorial/web_application)  in the `web_application/` subdirectory of the output directory.

  5) Interactively explore the results!


pkgId: 671dabb8bda99af67055d4e97217ea6e220e42cd07bf76b7786e78a3de6f591a
name: python-crevettes
arch: src
version: 0.0.5
epoch: 0
release: 1
summary: A Python utility to capture a thread and commends for a given Reddit thread.
url: https://pypi.org/project/crevettes/
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crevettes-0.0.5-1.src.rpm
checksum_type: sha256
description:
  A Python utility to capture a thread and commends for a given Reddit thread. This utility came out of a research need for the [Digital Feminist Network](https://digfemnet.org/).



  * [praw](https://github.com/praw-dev/praw)
  * [python-dotenv](https://github.com/theskumar/python-dotenv)



  Local CSV
  ```
  crevettes thread_id
  ```

  Google Sheets and Local CSV.
  ```
  crevettes thread_id google_sheets_folder_id path/to/json/keyfile
  ```



  ```
  crevettes 1bq51lp
  ```

  ```
  crevettes 1gnex8a 1Nr1xMEN1WTxrwNfyFz4fg1fTyB3oCAcg
  ```

  You will need a `.env` file populated with the following:

  ```
  REDDIT_CLIENT_ID=YOUR_CLIENT_ID
  REDDIT_CLIENT_SECRET=YOUR_CLIENT_SECRET
  REDDIT_USER_AGENT=YOUR_USER_AGENT
  ```



  The Unlicense


pkgId: 4ac47442318bf5312f67fb3443a4dded5404b434d400e1b5bba993c61d5bdb52
name: python-crewai-tools
arch: src
version: 0.13.4
epoch: 0
release: 1
summary: Set of tools for the crewAI framework
url: https://crewai.com
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crewai-tools-0.13.4-1.src.rpm
checksum_type: sha256
description:
  <div align="center">

  ![Logo of crewAI, two people rowing on a boat](./assets/crewai_logo.png)

  <div align="left">


  Welcome to crewAI Tools! This repository provides a comprehensive guide for setting up sophisticated tools for [crewAI](https://github.com/crewAIInc/crewAI) agents, empowering your AI solutions with bespoke tooling.

  In the realm of CrewAI agents, tools are pivotal for enhancing functionality. This guide outlines the steps to equip your agents with an arsenal of ready-to-use tools and the methodology to craft your own.

  </div>

  <h3>

  [Homepage](https://www.crewai.io/) | [Documentation](https://docs.crewai.com/) | [Chat with Docs](https://chatg.pt/DWjSBZn) | [Examples](https://github.com/crewAIInc/crewAI-examples) | [Discord](https://discord.com/invite/X4JWnZnxPb)

  </h3>

  </div>



  - [Creating Your Tools](#creating-your-tools)
  	- [Subclassing `BaseTool`](#subclassing-basetool)
  	- [Utilizing the `tool` Decorator](#utilizing-the-tool-decorator)
  - [Contribution Guidelines](#contribution-guidelines)
  - [Development Setup](#development-setup)



  crewAI Tools provides a wide range of pre-built tools, including:

  - File operations (FileWriterTool, FileReadTool)
  - Web scraping (ScrapeWebsiteTool, SeleniumScrapingTool)
  - Database interactions (PGSearchTool, MySQLSearchTool)
  - API integrations (SerperApiTool, EXASearchTool)
  - AI-powered tools (DallETool, VisionTool)
  - And many more!

  For a complete list and detailed documentation of each tool, please refer to the individual tool README files in the repository.



  Tools are always expect to return strings, as they are meant to be used by the agents to generate responses.

  There are three ways to create tools for crewAI agents:
  - [Subclassing `BaseTool`](#subclassing-basetool)
  - [Using the `tool` decorator](#utilizing-the-tool-decorator)



  ```python
  from crewai_tools import BaseTool

  class MyCustomTool(BaseTool):
      name: str = "Name of my tool"
      description: str = "Clear description for what this tool is useful for, you agent will need this information to use it."

      def _run(self, argument: str) -> str:
          
          pass
  ```

  Define a new class inheriting from `BaseTool`, specifying `name`, `description`, and the `_run` method for operational logic.




  For a simpler approach, create a `Tool` object directly with the required attributes and a functional logic.

  ```python
  from crewai_tools import tool
  @tool("Name of my tool")
  def my_tool(question: str) -> str:
      """Clear description for what this tool is useful for, you agent will need this information to use it."""
      
  ```

  The `tool` decorator simplifies the process, transforming functions into tools with minimal overhead.



  We welcome contributions! Here's how you can help:

  1. Fork the repository
  2. Create a feature branch (`git checkout -b feature/AmazingFeature`)
  3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
  4. Push to the branch (`git push origin feature/AmazingFeature`)
  5. Open a Pull Request

  Please ensure your code adheres to our coding standards and includes appropriate tests.



  **Installing Dependencies:**

  ```bash
  uv sync
  ```

  **Activating Virtual Environment:**

  ```bash
  uv venv
  source .venv/bin/activate
  ```

  **Setting Up Pre-commit Hooks:**

  ```bash
  pre-commit install
  ```

  **Running Tests:**

  ```bash
  uv run pytest
  ```

  **Static Type Checking:**

  ```bash
  uv run pyright
  ```

  **Packaging:**

  ```bash
  uv build
  ```

  **Local Installation:**

  ```bash
  pip install dist/*.tar.gz
  ```

  Thank you for your interest in enhancing the capabilities of AI agents through advanced tooling. Your contributions make a significant impact.



  For questions or support, please join our [Discord community](https://discord.com/invite/X4JWnZnxPb) or open an issue in this repository.


pkgId: d1ae0b8b18c216f0bc23f01bdac532e9fdf2f3ff73b4b75776f63d0070a7acc8
name: python-crewai-tools
arch: src
version: 0.17.0
epoch: 0
release: 1
summary: Set of tools for the crewAI framework
url: https://crewai.com
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crewai-tools-0.17.0-1.src.rpm
checksum_type: sha256
description:
  <div align="center">

  ![Logo of crewAI, two people rowing on a boat](./assets/crewai_logo.png)

  <div align="left">


  Welcome to crewAI Tools! This repository provides a comprehensive guide for setting up sophisticated tools for [crewAI](https://github.com/crewAIInc/crewAI) agents, empowering your AI solutions with bespoke tooling.

  In the realm of CrewAI agents, tools are pivotal for enhancing functionality. This guide outlines the steps to equip your agents with an arsenal of ready-to-use tools and the methodology to craft your own.

  </div>

  <h3>

  [Homepage](https://www.crewai.io/) | [Documentation](https://docs.crewai.com/) | [Chat with Docs](https://chatg.pt/DWjSBZn) | [Examples](https://github.com/crewAIInc/crewAI-examples) | [Discord](https://discord.com/invite/X4JWnZnxPb) | [Discourse](https://community.crewai.com/)

  </h3>

  </div>



  - [Creating Your Tools](#creating-your-tools)
  	- [Subclassing `BaseTool`](#subclassing-basetool)
  	- [Utilizing the `tool` Decorator](#utilizing-the-tool-decorator)
  - [Contribution Guidelines](#contribution-guidelines)
  - [Development Setup](#development-setup)



  crewAI Tools provides a wide range of pre-built tools, including:

  - File operations (FileWriterTool, FileReadTool)
  - Web scraping (ScrapeWebsiteTool, SeleniumScrapingTool)
  - Database interactions (PGSearchTool, MySQLSearchTool)
  - API integrations (SerperApiTool, EXASearchTool)
  - AI-powered tools (DallETool, VisionTool)
  - And many more!

  For a complete list and detailed documentation of each tool, please refer to the individual tool README files in the repository.



  Tools are always expect to return strings, as they are meant to be used by the agents to generate responses.

  There are three ways to create tools for crewAI agents:
  - [Subclassing `BaseTool`](#subclassing-basetool)
  - [Using the `tool` decorator](#utilizing-the-tool-decorator)



  ```python
  from crewai_tools import BaseTool

  class MyCustomTool(BaseTool):
      name: str = "Name of my tool"
      description: str = "Clear description for what this tool is useful for, you agent will need this information to use it."

      def _run(self, argument: str) -> str:
          
          pass
  ```

  Define a new class inheriting from `BaseTool`, specifying `name`, `description`, and the `_run` method for operational logic.




  For a simpler approach, create a `Tool` object directly with the required attributes and a functional logic.

  ```python
  from crewai_tools import tool
  @tool("Name of my tool")
  def my_tool(question: str) -> str:
      """Clear description for what this tool is useful for, you agent will need this information to use it."""
      
  ```

  The `tool` decorator simplifies the process, transforming functions into tools with minimal overhead.



  We welcome contributions! Here's how you can help:

  1. Fork the repository
  2. Create a feature branch (`git checkout -b feature/AmazingFeature`)
  3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
  4. Push to the branch (`git push origin feature/AmazingFeature`)
  5. Open a Pull Request

  Please ensure your code adheres to our coding standards and includes appropriate tests.



  **Installing Dependencies:**

  ```bash
  uv sync
  ```

  **Activating Virtual Environment:**

  ```bash
  uv venv
  source .venv/bin/activate
  ```

  **Setting Up Pre-commit Hooks:**

  ```bash
  pre-commit install
  ```

  **Running Tests:**

  ```bash
  uv run pytest
  ```

  **Static Type Checking:**

  ```bash
  uv run pyright
  ```

  **Packaging:**

  ```bash
  uv build
  ```

  **Local Installation:**

  ```bash
  pip install dist/*.tar.gz
  ```

  Thank you for your interest in enhancing the capabilities of AI agents through advanced tooling. Your contributions make a significant impact.



  For questions or support, please join our [Discord community](https://discord.com/invite/X4JWnZnxPb), [Discourse](https://community.crewai.com/) or open an issue in this repository.


pkgId: 24aa082930abdb044dfdc78fc78e0f2cd30b551dbf57c1a46c9f731977578117
name: python-crflux
arch: src
version: 1.0.6
epoch: 0
release: 1
summary: Parameterizations of the cosmic ray flux at Earth
url: https://github.com/afedynitch/crflux
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crflux-1.0.6-1.src.rpm
checksum_type: sha256
description:
  Historically, this module was part of the research code for a paper
  [A. Fedynitch, J. Becker Tjus, and P. Desiati, Phys. Rev. D 86, 114024
  (2012)](http://journals.aps.org/prd/abstract/10.1103/PhysRevD.86.114024),
  where we compared the effects of different Cosmic Ray Flux models on the atmospheric lepton flux.

  This code is now an integral dependency of the atmospheric neutrino and
  air-shower cascade research code [MCEq: Matrix Cascade Equations (MCEq)](https://github.com/afedynitch/MCEq) providing:

  - numerical models/parameterizations of high energy cosmic ray fluxes,
  - conversions from all-particle into all-nucleon flux,
  - and other convenience functions for semi-analytical atmospheric lepton flux calculations.

  Performance was never a bottle-neck, thus it's not the most numerically brilliant code to date but it does the job.

  If you find it too slow for your applications feel free to open an issue or send a pull request or just branch/fork and let me know.



  [The documentation is located here](http://crfluxmodels.readthedocs.org/en/latest/index.html). Please acknowledge the code by citing the paper above.




  Python 2 or 3, numpy, scipy, matplotlib.



      pip install crflux



  The interaction with the classes and plotting is demonstrated in the `test()` method::

      from crflux.models import *
      test()



  Hans Dembinski [@HDembinski](https://github.com/HDembinski)




  Code and documentation copyright 2015 Anatoli Fedynitch


pkgId: df3dba229f919f7294053a33a19da36330635c1e85b07438dee2a5973da48c3a
name: python-crfsuite
arch: src
version: 0.3.1
epoch: 0
release: 1
summary: Python binding for crfsuite
url: https://github.com/bosondata/crfsuite-rs
rpm_license: UNKNOWN
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crfsuite-0.3.1-1.src.rpm
checksum_type: sha256
description:
  [![Rust](https://github.com/bosondata/crfsuite-rs/workflows/Rust/badge.svg)](https://github.com/bosondata/crfsuite-rs/actions?query=workflow%3ARust)
  [![Python](https://github.com/bosondata/crfsuite-rs/workflows/Python/badge.svg)](https://github.com/bosondata/crfsuite-rs/actions?query=workflow%3APython)
  [![codecov](https://codecov.io/gh/bosondata/crfsuite-rs/branch/master/graph/badge.svg)](https://codecov.io/gh/bosondata/crfsuite-rs)
  [![Crates.io](https://img.shields.io/crates/v/crfsuite.svg)](https://crates.io/crates/crfsuite)
  [![docs.rs](https://docs.rs/crfsuite/badge.svg)](https://docs.rs/crfsuite/)
  [![PyPI](https://img.shields.io/pypi/v/crfsuite)](https://pypi.org/project/crfsuite)

  Rust binding to [crfsuite](https://github.com/chokkan/crfsuite)



  Add it to your ``Cargo.toml``:

  ```toml
  [dependencies]
  crfsuite = "0.3"
  ```

  Add ``extern crate crfsuite`` to your crate root and your're good to go!



  There is also a Python package named `crfsuite`, you can install it via `pip`:

  ```bash
  pip install -U crfsuite
  ```

  Usage example:

  ```python
  from crfsuite import Model

  if __name__ == '__main__':
      model = Model('path/to/crfsuite/model.crf')
      tagged = model.tag(["abc", "def"])
      print(tagged)
  ```



  This work is released under the MIT license. A copy of the license is provided in the [LICENSE](./LICENSE) file.


pkgId: ab19d4d68aa37a312861d5c2a1be343f66d4fabc53f8a333d0c6c7aa3ebbcb6b
name: python-crhelper
arch: src
version: 2.0.11
epoch: 0
release: 1
summary: crhelper simplifies authoring CloudFormation Custom Resources
url: https://github.com/aws-cloudformation/custom-resource-helper
rpm_license: Apache2
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crhelper-2.0.11-1.src.rpm
checksum_type: sha256
description:
  Simplify best practice Custom Resource creation, sending responses to CloudFormation and providing exception, timeout
  trapping, and detailed configurable logging.

  [![PyPI Version](https://img.shields.io/pypi/v/crhelper.svg)](https://pypi.org/project/crhelper/)
  ![Python Versions](https://img.shields.io/pypi/pyversions/crhelper.svg)
  [![Build Status](https://travis-ci.com/aws-cloudformation/custom-resource-helper.svg?branch=main)](https://travis-ci.com/aws-cloudformation/custom-resource-helper)
  [![Test Coverage](https://codecov.io/gh/aws-cloudformation/custom-resource-helper/branch/main/graph/badge.svg)](https://codecov.io/gh/aws-cloudformation/custom-resource-helper)



  * Dead simple to use, reduces the complexity of writing a CloudFormation custom resource
  * Guarantees that CloudFormation will get a response even if an exception is raised
  * Returns meaningful errors to CloudFormation Stack events in the case of a failure
  * Polling enables run times longer than the lambda 15 minute limit
  * JSON logging that includes request id's, stack id's and request type to assist in tracing logs relevant to a
  particular CloudFormation event
  * Catches function timeouts and sends CloudFormation a failure response
  * Static typing (mypy) compatible



  Install into the root folder of your lambda function

  ```shell
  cd my-lambda-function/
  pip install crhelper -t .
  ```



  [This blog](https://aws.amazon.com/blogs/infrastructure-and-automation/aws-cloudformation-custom-resource-creation-with-python-aws-lambda-and-crhelper/) covers usage in more detail.

  ```python
  from __future__ import print_function
  from crhelper import CfnResource
  import logging

  logger = logging.getLogger(__name__)

  helper = CfnResource(json_logging=False, log_level='DEBUG', boto_level='CRITICAL', sleep_on_delete=120, ssl_verify=None)

  try:
      
      pass
  except Exception as e:
      helper.init_failure(e)


  @helper.create
  def create(event, context):
      logger.info("Got Create")
      
      
      
      
      
      
      helper.Data.update({"test": "testdata"})

      
      if not helper.Data.get("test"):
          raise ValueError("this error will show in the cloudformation events log and console.")

      return "MyResourceId"


  @helper.update
  def update(event, context):
      logger.info("Got Update")
      
      


  @helper.delete
  def delete(event, context):
      logger.info("Got Delete")
      
      


  @helper.poll_create
  def poll_create(event, context):
      logger.info("Got create poll")
      
      
      return True


  def handler(event, context):
      helper(event, context)
  ```



  If you need longer than the max runtime of 15 minutes, you can enable polling by adding additional decorators for
  `poll_create`, `poll_update` or `poll_delete`. When a poll function is defined for `create`/`update`/`delete` the
  function will not send a response to CloudFormation and instead a CloudWatch Events schedule will be created to
  re-invoke the lambda function every 2 minutes. When the function is invoked the matching `@helper.poll_` function will
  be called, logic to check for completion should go here, if the function returns `None` then the schedule will run again
  in 2 minutes. Once complete either return a PhysicalResourceID or `True` to have one generated. The schedule will be
  deleted and a response sent back to CloudFormation. If you use polling the following additional IAM policy must be
  attached to the function's IAM role:

  ```json
  {
    "Version": "2012-10-17",
    "Statement": [
      {
        "Effect": "Allow",
        "Action": [
          "lambda:AddPermission",
          "lambda:RemovePermission",
          "events:PutRule",
          "events:DeleteRule",
          "events:PutTargets",
          "events:RemoveTargets"
        ],
        "Resource": "*"
      }
    ]
  }
  ```

  To turn off certification verification, or to use a custom CA bundle path for the underlying boto3 clients used by this library, override the `ssl_verify` argument with the appropriate values.  These can be either:
  * `False` - do not validate SSL certificates. SSL will still be used, but SSL certificates will not be verified.
  * `path/to/cert/bundle.pem` - A filename of the CA cert bundle to uses. You can specify this argument if you want to use a different CA cert bundle than the one used by botocore.



  Decorator implementation inspired by https://github.com/ryansb/cfn-wrapper-python

  Log implementation inspired by https://gitlab.com/hadrien/aws_lambda_logging



  This library is licensed under the Apache 2.0 License.


pkgId: 94cd4624d127e15e13cb959ff74343866e8b75e82baaeb78a35f8eb422ca508e
name: python-cribbage-scorer
arch: src
version: 0.2.4
epoch: 0
release: 1
summary: A Cribbage scoring tool
url: https://github.com/phoughton/cribbage_scorer
rpm_license: MIT License
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-cribbage-scorer-0.2.4-1.src.rpm
checksum_type: sha256
description:
  Cribbage scorer is a simple scoring engine for the classic card game.

  For details, history and a good summary of the rules of the game see [Wikipedia](https://en.wikipedia.org/wiki/Cribbage)

  For instruction on how to play and the rules see the [American Cribbage Congress](http://www.cribbage.org/NewSite/rules) (see link to PDF)

  The code for the web server front end that uses this python API can be [found on GitHub](https://github.com/phoughton/cribbage_server). Raise a bug here if you find any. This server is also now available as a [Docker container](https://hub.docker.com/r/phoughton/python-cribbage).


  This package is tested against against Python versions: "3.6", "3.7", "3.8", "3.9", "3.10" on Ubuntu-latest. (But should work on Windows and Mac etc.)


  ```bash
  pip install cribbage-scorer
  ```


  ```bash
  python -m pytest
  ```




  Examples of how to use the library are below.

  In the library and examples, I have used the following conventions:

  - 1 : Ace
  - 2-10 : Non face cards.
  - 11 : Jack
  - 12 : Queen
  - 13 : King

  D = Diamonds,
  H = Hearts,
  C = Clubs,
  S = Spades.

  Players are listed in the order in which they play. So...
  1. _Abi_ played a 5 of Diamonds,
  1. _Bob_ played a 5 of Spades,
  1. _Abi_ played a 5 of Clubs
  1. _Bob_ played a Jack of Diamonds.

  ...is represented as:
  ```python
  players = ["Abi", "Bob"]
  played_cards = [(5, "D"), (5, "S"), (5, "C"), (11, "D")]
  ```



  The `cut_calc_score` function is used during 'the cut' stage of the game.

  Its a simple function, to assign the 2 points given to the dealer if the pone cuts a Jack as the starter card.

  ```python

  from cribbage_scorer import cribbage_scorer

  cut_card = (11, "D")
  players = ["Abi", "Bob"]
  dealer = "Bob"

  scores, msg  = cribbage_scorer.cut_calc_score(cut_card, players, dealer)
  print(scores, msg )
  ```

  Results:
  ```bash
  {'Abi': 0, 'Bob': 2} Cut card is a Jack, Dealer scores 2pts.
  ```



  The `play_calc_score_set` function is used during 'the play' stage of the game.

  `play_calc_score_set` handles 3 and 4 players as well as the standard 2 player game. It also understands "Go" calls.

  Note: we use the term 'set' here to refer to a subset of the play, where the players are counting from a first played card upto either last card, Go or 31.
  Once the players have ended a set the cards are put aside and another set begins until all cards are played.
  The 'play' section of the game usually constitutes multiple sets.

  To use, clone from GitHub and run this Python code:
  ```python

  from cribbage_scorer import cribbage_scorer

  players = ["Abi", "Bob"]
  played_cards = [(5, "D"), (5, "S"), (5, "C"), (11, "D")]

  scores, current_count, play_log = cribbage_scorer.play_calc_score_set(played_cards, players)
  print(scores, current_count, play_log)
  ```

  Results:
  ```bash
  {'Abi': 8, 'Bob': 3} 25 ['Count: 5, No Points scored, None said Go. ', 'Count: 10, Bob: 2 of a kind (2pts), score so far: 2 ', 'Count: 15, Abi: 15 for 2pts, 3 of a kind (6pts), score so far: 8 ', 'Count: 25, Bob: Last card (1pt), score so far: 3 ']
  ```

  Behind the scenes this method calls `play_score_ongoing` for each card placed down. This provides the scoring and message for each card placed.
  You may choose to use this more internal method, to provide details of each card played, though the full play to that point in time requires `play_calc_score_set` to be used.


  The `show_calc_score` function is used during 'the show' stage of the game.

  `show_calc_score` handles Dealer and non dealer hands, for the standard 6 card (4 in your hand, 2 given to the crib) + starter/cut card version of the game.

  To use, clone from GitHub and run this Python code:
  ```python

  from cribbage_scorer import cribbage_scorer

  starter = (5, "H")
  hand = [(5, "D"), (5, "S"), (5, "C"), (11, "D")]
  crib = False

  score, msg = cribbage_scorer.show_calc_score(starter, hand, crib)
  print(score, msg)
  ```
  Results:
  ```
  (29, "Four of a kind: 5s (12pts), Made 15 from [(5, 'D'), (11, 'D')] (2pts), Made 15 from [(5, 'S'), (11, 'D')] (2pts), Made 15 from [(5, 'C'), (11, 'D')] (2pts), Made 15 from [(11, 'D'), (5, 'D')] (2pts), Made 15 from [(5, 'D'), (5, 'S'), (5, 'C')] (2pts), Made 15 from [(5, 'D'), (5, 'S'), (5, 'D')] (2pts), Made 15 from [(5, 'D'), (5, 'C'), (5, 'D')] (2pts), Made 15 from [(5, 'S'), (5, 'C'), (5, 'D')] (2pts), One for his nobs (1pt)")
  ```


  Copyright © 2023 Peter Houghton

  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: 3e9a63044d4c015659d94ca5cd67974048515757d48244550e3a05d14be224f7
name: python-cricguru
arch: src
version: 2.1.1
epoch: 0
release: 1
summary: please add a summary manually as the author left a blank one
url: https://github.com/puppetmaster12/cricguru
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-cricguru-2.1.1-1.src.rpm
checksum_type: sha256
description:
  <h2 align="center">Cricguru</h2>


  Cricguru is a data extraction module for extracting data from the Statsguru data query on Cricinfo. I was inspired to build a simple tool to extract dataframes from statsguru for analyzing cricket data and was finding it difficult to obtain overall figures from the website as they did not have an API for it. Cricinfo has a large variety of cricket data for all classes of cricket matches and also in-depth player data. However without an API it is impossible to extract any useful information from it. Hence this module has functions to easily get the cricket data we want without having to manually scrape the website. The data output is currently returned in the form of Pandas dataframes. You can find the full documentation <a href="https://cricguru.readthedocs.io/en/stable/overview.html" target="_blank">here</a>.


  Data by team can be obtained for the three main classes of cricket formats which are <b>Test</b>, <b>One-day</b> and <b>T20</b>. Excluding the class argument would return the overall data. In order to filter by teams and opposition you must provide one of the following ids to the team and opposition arguments respectively for some popular teams.

  {"all teams": "", "Afghanistan": "40", "Australia": "2", "Bangladesh": "25", "England": "1", "ICC World XI": "140", "India": "6", "Ireland": "29", "New Zealand": "5", "Pakistan": "7", "South Africa": "3", "Sri Lanka": "8", "West Indies": "4", "Zimbabwe": "9"}


  Data by player can be obtained for the same classes mentioned above. The player class however requires a player id which can be obtained from Cricinfo by selecting a team followed by a player from that team. For example <a href="https://www.espncricinfo.com/player/angelo-mathews-49764">Angelo Mathew's</a> id is 49764 which can be found appended to the url of the player's stats page on Cricinfo.


  This project primarily uses Python 3.8 in combination with Pandas. Pandas is used to get the tables directly from the Statsguru query pages and convert them to dataframes. Urllib is used to format the url and append the query parameters. Poetry is used for packaging and publishing.


  You can install the package using the following command.
  ```sh
  pip install cricguru
  ```


  You can get overall figures for all teams with the following. You must pass in the query parameters in a dictionary as shown. The "template" key with a "results" value is required along with the "class" variable which specifies which format of cricket you require data from. The classes for each format are as follows.
  <br>
  1 - Test
  <br>2 - ODI
  <br>3 - T20
  <br>11 - All
  <br>10 - Women's T20i
  <br>8 - Women's Test
  <br>9 - Women's ODI
  <br>20 - Youth Test
  <br>21 - Youth ODI
  <br>22 - Youth T20
  ```sh
  from cricguru import team

  team = team.Team()
  query_params = {"template": "results", "class": "2"}
  cric_data = team.overall(query_params)


  cric_data.head()
  ```
  For player data you have to provide the player id to initialize the player object and then call the function for the type of data you require. You have to specify what type of player data you need such as allround, batting or bowling.

  ```sh
  from cricguru import player

  player = player.Player(49764)
  query_params = {
      'class' : '1',
      'type' : 'allround'
  }

  cric_data = player.career_summary(query_params)
  print(cric_data.head())
  ```


  This is an amateur project at best and I am still a complete beginner to Python and would greatly welcome any suggestions, advice, constructive criticism, best practices or contributions to the project.  Simply open a pull request or issue and I will check it out.


  You can also contact me at pavithranthilakanathan@gmail.com or on twitter - <a href="https://twitter.com/pavin_v1">@pavin_v1</a>


  Distributed under the MIT license. See `LICENSE.md' for more information.


  <ul>
    <li><a href="https://www.espncricinfo.com/">ESPN Cricinfo</a></li>
  </ul>


  <ul>
    <li>100% code coverage</li>
    <li>Additional data formats</li>
  </ul>


pkgId: 6f73cd0b60ea35f8da5084ecc923cdfbff6d8a56575600ff105ae8848cef7f1e
name: python-cricinfo-stats
arch: src
version: 1.0
epoch: 0
release: 1
summary: Python/Pandas Client for https://www.espncricinfo.com stats
url: https://github.com/aaraza/cricinfo
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-cricinfo-stats-1.0-1.src.rpm
checksum_type: sha256
description:
  Library for loading cricket [stats](https://stats.espncricinfo.com/ci/engine/stats/index.html) from https://www.espncricinfo.com into pandas dataframes.



  1. Career batting/bowling/fielding/all-round statistics for international cricketers.
  2. Statistics for all partnerships in international cricket for a given team.
  3. Aggregated statitics for teams in international cricket.


  ```
  England
  Australia
  SouthAfrica
  WestIndies
  NewZealand
  India
  Pakistan
  SriLanka
  Zimbawe
  ```


  ```
  TEST
  ODI
  T20I
  International
  ```


  ```
  from cricinfo import Cricinfo
  from cricinfo import MatchFormat
  from cricinfo import Team

  Cricinfo.retrieve_batting_stats(team=Team.Pakistan, match_format=MatchFormat.Test)
  ```


  Run test and lint commands from the root of this repo.


  ```
  coverage run -m pytest -v -s
  coverage report -m
  ```


  `ruff check .`

  [![Coverage Status](coverage.svg)](https://github.com/aaraza/cricinfo)


pkgId: 078f6fd6cca901faa7cea1a2f4f8be85e4464d0ac7f562b1ab5be9e290773d53
name: python-cricket-scoring
arch: src
version: 1.0.1
epoch: 0
release: 1
summary: A library for cricket scoring logic.
url: https://github.com/Rad-99/cricket_scoring
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-cricket-scoring-1.0.1-1.src.rpm
checksum_type: sha256
description:
  A Python library for managing cricket scoring logic. This library provides utility functions for updating batting stats, bowling stats, and switching batting teams.



  - Update batting statistics (runs, balls, boundaries, dismissals).
  - Update bowling statistics (runs conceded, wickets, overs bowled).
  - Switch batting teams during a match.



  Install the library via pip:

  ```bash
  pip install cricket-scoring
  ```





  ```python
  from cricket_scoring.batting import update_batting_stats

  player_stats = {
      'runs': 10,
      'balls': 5,
      'fours': 1,
      'sixes': 0,
      'is_out': False
  }

  updated_stats = update_batting_stats(player_stats, runs=4, balls=1, is_out=False, is_four=True, is_six=False)
  print(updated_stats)
  ```



  ```python
  from cricket_scoring.bowling import update_bowling_stats

  bowler_stats = {
      'runs_conceded': 20,
      'balls_bowled': 12,
      'wickets': 1,
      'overs': 2.0
  }

  updated_stats = update_bowling_stats(bowler_stats, runs=4, balls=1, is_wicket=False)
  print(updated_stats)
  ```



  ```python
  from cricket_scoring.match import switch_batting_team

  current_team = "Team A"
  team1 = "Team A"
  team2 = "Team B"

  new_batting_team = switch_batting_team(current_team, team1, team2)
  print(new_batting_team)
  ```





  Install `pytest`:

  ```bash
  pip install pytest
  ```

  Run tests:

  ```bash
  pytest tests/
  ```



  This project is licensed under the MIT License.


pkgId: c3988211d00b683c37770b64d4dcd07db2f072b3044666a0e501d43d8b572f08
name: python-cricketstats
arch: src
version: 0.1.6
epoch: 0
release: 1
summary: A cricket analytics package for cricsheet data
url: https://github.com/nsaranga/cricketstats/
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-cricketstats-0.1.6-1.src.rpm
checksum_type: sha256
description:
  A python module which gets team and player statistics from the [cricsheet.org](https://cricsheet.org/) database for data analysis and analytics projects in cricket.

  **If you want to try this module out [CLICK HERE](https://cricanalyst.anivaasi.net/) to use a web implementation of it by Sudarshan Narayana**

  If you have any questions about the module you can contact me on [Twitter](https://www.twitter.com/humesfinger/), email me at [nsaranga@hotmail.com](mailto:nsaranga@hotmail.com). If you have any bugs to report or features to suggest you can use raise ticket on the issues tab in github. If you want to know more about why I decided to write it you can find a blog post [here](https://nsaranga.github.io/cricket/2021/12/19/TheAimOfCricketstats/), and if you want to know more about what the module can actually you do you can read another blog post [here](https://nsaranga.github.io/cricket/2021/12/24/WhatCanCricketstatsDo/)

  Some tips/warnings:
  1. Python packages this module requires: datetime, json, time, pandas, os, zipfile, numpy, math, importlib, matplotlib
  2. There will be bugs as this is my first python project. I'm still learning the language and programming in general.
  3. At its core the script is as good as the data, so output will depend on how quickly the data is updated on cricsheet and its accuracy.
  4. I recommend downloading and using the "all_json.zip" from cricsheet as the database.
  5. The first time you run this script it will take about 30-40 seconds because it is indexing file names, after that each search should take 6-7 seconds to complete. This of course will vary based on your CPU.



  - Analyse players/teams across finegrained parameters.
  - Analyse matchups of player/team against particular players/teams or a group eg. by bowling style, batter handedness.
  - Analyse the progression players/team performance across innings.
  - Analyse distributions of stats according to innings, to create predictive models of player and team performance.
  - Analyse the game itself according to all players or teams in given time period, match type (ie. a reverse lookup)

  This is essentially a module you can import into any python script to collect statistics from cricsheet json files.

  This script can find team and player statistics along any of the following parameters: date interval, match type, overs interval, innings, opposition players, opposition teams, venue, event, match result, batting position and more.

  The script can then find the following stats for players and teams: games played, wins played in, draws played in, win %, Innings played in, Scores/Figures in each innings, Runs, Fours, Sixes, Outs(with breakdown of all kinds of dismissal), Wickets taken (with breakdown of all kinds of dismissal), catches taken as fielder, Strike Turnover %, Batting and Bowling strike rate, average, economy rate, Batting and Bowling Boundary %, Batting and Bowling Dot ball %, Score and Strike rate mean absolute deviation, net run rate, net boundary %, Successfully Defended and Chased scores, and more.

  Also using the in built-in playerindex you can find matchup data for a player against certain types of batters (eg. Right or Left Hand) and bowlers (eg. Right arm pace, Left arm pace, Right arm Off break, Right arm Leg break, Left arm orthodox and Left arm wrist spin).

  As shown in the example.py file using "print(search1.result.columns)" will print all the available stats for a particular search.


   All you need to do is import cricketstats in any python script create a search object, call the "stats()" function with the necessary arguments for that search object and run the script through python3. The output of the function is a Pandas DataFrame that can be printed, analysed using pandas methods or served as the input to plotting methods like matplotlib.

  To understand how to use the module you can use the "example.py" which provides a simple example.


  - Clean up stats independent of checks with stats dependent on checks.
  - Command-line wrapper
  - Expected runs model? Basically sum of weighted average of runs per ball * average innings length. Something along the lines of pythagorean thing.
  - Index more things?, so they can serve as lists for seeing what teams there are in a comp. Venues by country also put in checks when values are null.
  - Let us know all the possibilities we can expect within result method for plotting (ie. loc?)
  - Arguments via a dict? dicts should be defined in a separate file
  - eachball will read better as this(?)ball (same for eachwicket and others)
  - Use "matchcase" in multiple if-conditions for the same variable
  - Release as PyPi module that can be installed via pip

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


pkgId: 726cb3cb808cf4daae7830b4b7b0a2caa12b2c5a8a9b7701020f124fa77a6262
name: python-crijndael
arch: src
version: 1.0.1
epoch: 0
release: 1
summary: AES-256 Decryption
url: https://github.com/Rin-Wood/crijndael
rpm_license: BSD
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crijndael-1.0.1-1.src.rpm
checksum_type: sha256
description:
  `crijndael` is a Python package for decrypting data, using a custom AES-256 decryption algorithm implemented in C.



  - Provides efficient AES-256 decryption functionality, based on C implementation.
  - Supports Python 3.6+



  Install the latest version of `crijndael` from PyPI:

  ```bash
  pip install crijndael
  ```


  ```python
  import crijndael

  data = b'...'
  key = b'...'
  iv = b'...'
  blocksize = 256
  keysize = 256
  mode = 0


  dec = crijndael.decrypt(data, key, iv, blocksize, keysize, mode)


pkgId: a16b5f9e2a051541ab88c10bace003a95744dfd9e26e6cad7975f0f45acd9370
name: python-crim_intervals
arch: src
version: 2.0.46
epoch: 0
release: 1
summary: CRIM intervals package
url: https://pypi.org/project/crim_intervals/
rpm_license: creative commons
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crim_intervals-2.0.46-1.src.rpm
checksum_type: sha256
description:
  [CRIM Intervals on github](https://github.com/HCDigitalScholarship/intervals/tree/main)



  Install with pypi package manager:  `pip install crim_intervals`



  Based on [**Python**](https://www.python.org/) and [**Pandas**](https://pandas.pydata.org/), and Mike Cuthbert's excellent **music21** (https://web.mit.edu/music21/), **CRIM Intervals** is a pattern finding engine for musical scores, with an emphasis on the kinds of melodic, harmonic, and contrapuntal patterns found in Renaissance polyphony. It has been developed as a primary data analysis tool for **Citations:  The Renaissance Imitation Mass** (http://crimproject.org and https://sites.google.com/haverford.edu/crim-project/home), directed by Professor Richard Freedman (Haverford College, USA), in partnership with dozens of researchers and students around the world. Contact rfreedma at haverford.edu to learn more about the project, and how you can take part.

  **File Formats**: CRIM Intervals will analyze scores encoded in several widely-used formats:  MEI, MusicXML, and MIDI.  Results will vary according to the editorial practices used in the underlying transcriptions and editions.

  **The CRIM Intervals Web Application**:  Get started quickly with the [CRIM Intervals Streamlit Application](https://crimintervals.streamlit.app/), which requires no coding sklls.  You can work with the CRIM Corpus, or import your own pieces, producing analytic tables, visualizations, and other results that you can download for use in publications and teaching.  The web app is free and requires no special account or software installation.  Tutorials are available on the site itself, with pointers back to the code and tutorials here on CRIM Intervals itself.

  **Learn How Others are Using CRIM Intervals** via [CRIM Essays and Experiments](https://crimproject.org/about/essays_experiments/), which assembles recent work by over two-dozen scholars and students from around the world. Find out what is possible, what others are thinking about, and how you might use their work to advance your teaching and research.



  This respository contains the CRIM Intervals library itself, along with tutorials that explain the various methods, and Jupyter Notebooks make them easy to use for your research and teaching.  There are various ways to get started:

  - The [CRIM Intervals Streamlit Application](https://crimintervals.streamlit.app/), which requires no coding sklls.  You can work with the CRIM Corpus, or import your own pieces, producing analytic tables, visualizations, and other results that you can download for use in publications and teaching.

  - Install and run CRIM Intervals (along with the Notebooks) locally with **Anaconda Navigator, VS-Code, and Jupyter**.  See Richard Freedman's [Encoding Music course page](https://github.com/RichardFreedman/Encoding_Music/blob/main/01_Tutorials/02_Anaconda_VS_Code_Jupyter.md) to learn how.

  - Install the latest version of CRIM Intervals library via [pypi.org](https://pypi.org/project/crim-intervals/).

  - Run CRIM Intervals via a free **Jupyter-hub maintained by Haverford College** (contact rfreedma at haverford.edu) to obtain an account.


  CRIM Intervals begins by importing one (or more) MEI, MusicXML, and MIDI files, for example: `piece = importScore('https://crimproject.org/mei/CRIM_Model_0008.mei')` Once imported this piece object can be explored in various ways. piece.notes(), for instance, produces a dataframe in which each staff (voice part) is represented as a column of events--notes, rests, durations, lyrics, etc. Other methods (see the list below) in turn present these basic events in many different ways: as melodic intervals, harmonic intervals, n-grams, contrapuntal "modules", and so on.

  There are many ways to configure these basic methods. For instance intervals can be diatonic, or chromatic, or with (and without) 'quality' (such as M3 vs m3). They can also be simple or compound (a tenth in the latter would be a third in the former).Unisons can be combined (something helpful for comparing similar melodies), or events can be taken at actual durations or 'sampled' at some regular durational span.

  Complete documentation of each method capacities is available via doc.strings via this command `print(model.YourMethod.__doc__)`, where you will replace 'YourMethod' with the name of the individual method, for example `print(piece.melodic.__doc__)`.

  Results are reported in **Pandas** dataframes (and thus exportable in a variey of standard formats for further analysis), and also via several visualizations methods.

  Some methods in **CRIM Intervals** also work with [**CRIM Project**](http://crimproject.org) data created by human observers.






  - **piece.notes()**, which finds all the notes and rests in a score, with a tabular score-like representation of the pitches, pitch classes, and durations (expressed in music21 "offsets", in which each quarter note corresponds to the value of 1.0). It can also derminte the location of any note as a measure+beat reference with detailIndex
  - **piece.melodic()**, which finds melodic intervals in any voice part, with various options for diatonic, chromatic and zero-based distances. Intervals can be compound (distinguishing between tenths and thirds, for instance), or simple, and can include quality (distinguishing major and minor thirds, for instance), or not.
  - **piece.harmonic()**, which finds harmonic intervals between every combination of two voices in a piece, with various options for diatonic and chromatic. These intervals can also be directed (as when a tenor voice sounds above the altus), or not.
  - **piece.lyrics()** (for every note)
  - **piece.durations()**, with quarter-note = 1.0, as per music21.
  - **piece.ngrams()**, which finds n-grams of any length in each voice part. n-grams are frequently used in linguistic analysis (), and can help us find repeating patterns within and among works. The ngram tool can be used for any of the methods above: melodic, harmonic, durations, lyrics. By default it finds contrapuntal modules, which represent in numerical values a combination of the vertical intervals made between any two voices with the melodic intervals heard in the motion of the lower voice. A module of `7_Held 6_-2, 8` for instance, represents vertical intervals of `7, 6, 8` between two voices and in the lower voice a tied note followed by a descending second. Together these five events represent a typical cadence formula. Repeating modules are a key part of Renaissance contrapuntal style.

  It is also possible to apply various **edit distance tools** to many of these patterns, thus allowing users to find **exact** and **close matches**.


  CRIM Intervals also include advanced methods that use combinations of the methods detailed above to predict "contrapuntal types" commonly found in Renaissance polyphony.

  - **Cadences** are one such type: `piece.cadences()` can find them with a high degree of accuracy.
  - We have also developed a method that predict various **imitative textures, including Fugas, Imitative Duos, Non-Imitative Duoes, and Periodic Entries** (as Peter Schubert has named them): `piece.presentationTypes()`.
  - It is also possible to accurately identify **homorhythmic passages** (where sets of voices move in the same durations and declaim the same lyrics): `piece.homorhythm()`.

  In each case we there are various options users can select to refine the searches, including various tools that allow for **similar no less than exact matches**. Melodic and rhythmic 'flexing' are key parts of Renaissance counterpoint. These methods are too complex to summarize in a short space. But they are powerful tools for machine prospecting of musical works.


  CRIM Intervals also features tools that help us visualize musical events in different ways, including:

  - **bar charts and histograms** of events (such as notes, or intervals), which are useful for understand ranges, distributions, and other large-scale distribution of categorical data
  - **heatmaps**, showing where in a piece patterns (such as repeating n-grams) occur
  - **radar plots**, used to show cadences in a radial plot that reveals the tonal profile of a composition (or a corpus of works)
  - **progress charts**, showing a cadences in a series (from start to finish)
  - **network diagrams**, showing related patterns or pieces



  CRIM Intervals methods can also be applied to a corpus of pieces. We first define a corpus: `corpus = CorpusBase(['https://crimproject.org/mei/CRIM_Mass_0006_1.mei', 'https://crimproject.org/mei/CRIM_Mass_0006_2.mei', 'https://crimproject.org/mei/CRIM_Mass_0006_3.mei'])`, then specify a method to run against each piece in the corpus: `corpus.batch(func=ImportedPiece.cadences)`. The results are reported as a combined dataframe.



  - CRIM Intervals also has the capacity to render results as modern score with Laurent Pugin's [Verovio](https://www.verovio.org/index.xhtml) (for example `piece.verovioCadences()`), as well as reporting them as data frames and visualizations.





  - Andrew Janco (Haverford College/Universit of Pennsylvania)
  - Freddie Gould (Haverford College/Audible)
  - Trang Dang (Bryn Mawr College)
  - Alexander Morgan (EcoRate)
  - Daniel Russo-Batterham (Melbourne University)
  - Richard Freedman (Haverford College)
  - Oleh Shostak (Haverford College)
  - Edgar Leon (Haverford College)
  - Harrison West (Haverford College)
  - Patty Guardiola (Haverford College)
  - Anna Lacy (Haverford College)



  - Haverford College
  - The American Council of Learned Societies

  All CRIM intervals tools are available via a **Creative Commons** license (Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)):  https://creativecommons.org/licenses/by-sa/4.0/.



    * [01_Introduction_and_Corpus](https://github.com/HCDigitalScholarship/intervals/blob/main/tutorial/01_Introduction_and_Corpus.md)
    * [02_Notes_Rests](https://github.com/HCDigitalScholarship/intervals/blob/main/tutorial/02_Notes_Rests.md)
    * [03_Durations](https://github.com/HCDigitalScholarship/intervals/blob/main/tutorial/03_Durations.md)
    * [04_TimeSignatures_Beat_Strength](https://github.com/HCDigitalScholarship/intervals/blob/main/tutorial/04_TimeSignatures_Beat_Strength.md)
    * [05_Detail_Index](https://github.com/HCDigitalScholarship/intervals/blob/main/tutorial/05_Detail_Index.md)
    * [06_Melodic_Intervals](https://github.com/HCDigitalScholarship/intervals/blob/main/tutorial/06_Melodic_Intervals.md)
    * [07_Harmonic_Intervals](https://github.com/HCDigitalScholarship/intervals/blob/main/tutorial/07_Harmonic_Intervals.md)
    * [08_Contrapuntal_Modules](https://github.com/HCDigitalScholarship/intervals/blob/main/tutorial/08_Contrapuntal_Modules.md)
    * [09_Ngrams_Heat_Maps](https://github.com/HCDigitalScholarship/intervals/blob/main/tutorial/09_Ngrams_Heat_Maps.md)
    * [10_Lyrics_Homorhythm](https://github.com/HCDigitalScholarship/intervals/blob/main/tutorial/10_Lyrics_Homorhythm.md)
    * [11_Cadences](https://github.com/HCDigitalScholarship/intervals/blob/main/tutorial/11_Cadences.md)
    * [12_Presentation_Types](https://github.com/HCDigitalScholarship/intervals/blob/main/tutorial/12_Presentation_Types.md)
    * [13_Musical_Examples_Verovio](https://github.com/HCDigitalScholarship/intervals/blob/main/tutorial/13_Musical_Examples_Verovio.md)
    * [14_Model_Finder](https://github.com/HCDigitalScholarship/intervals/blob/main/tutorial/14_Model_Finder.md)
    * [15_Network_Graphs](https://github.com/HCDigitalScholarship/intervals/blob/main/tutorial/15_Network_Graphs.md)
    * [16_Python_Basics](https://github.com/HCDigitalScholarship/intervals/blob/main/tutorial/16_Python_Basics.md)
    * [17_Pandas_Basics](https://github.com/HCDigitalScholarship/intervals/blob/main/tutorial/17_Pandas_Basics.md)
    * [18_Visualizations_Summary](https://github.com/HCDigitalScholarship/intervals/blob/main/tutorial/18_Visualizations_Summary.md)
    * [19_Music21_Basics](https://github.com/HCDigitalScholarship/intervals/blob/main/tutorial/19_Music21_Basics.md)
    * [99_Local_Installation](https://github.com/HCDigitalScholarship/intervals/blob/main/tutorial/99_Local_Installation.md)


pkgId: 06c116683e97226662ac3cec298af32247b914bc373e7179e91146a3df5dff04
name: python-cringelord
arch: src
version: 1.2.0
epoch: 0
release: 1
description: Coming soon.
url: https://pypi.org/project/cringelord/
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-cringelord-1.2.0-1.src.rpm
checksum_type: sha256
summary:
  Environment-sensitive configuration management tool that allows you use     the same code with different configurations.      You'll no longer need if-else statements or multiple files (one for each     environment) to get your code working in multiple environments.

rpm_license:
  Cringelord End-User License Agreement (EULA)  IMPORTANT: PLEASE READ THIS LICENSE CAREFULLY BEFORE USING THIS SOFTWARE.  1. License HeerlijkeHeer ("Licensor") hereby grants you ("User") a non-exclusive, non-transferable, limited license to use Cringelord ("Software") free of charge. Use of the Software under this license is restricted to non-commercial purposes. The Software is licensed, not sold, to you for use under the terms of this license.  2. Restrictions You may NOT:  Modify, translate, adapt, or otherwise create derivative works or improvements, whether patentable or not, of the Software. Reverse engineer, disassemble, decompile, decode, or otherwise attempt to derive or gain access to the source code of the Software. Rent, lease, lend, sell, sublicense, assign, distribute, publish, transfer, or otherwise make available the Software, or any features or functionality of the Software, to any third party for any reason. Remove, delete, efface, alter, obscure, translate, combine, supplement, or otherwise change any trademarks, terms of the licensing or copyright notices, proprietary rights, or other symbols, notices, or marks on or relating to any copy of the Software.  3. Intellectual Property The Software is the intellectual property of HeerlijkeHeer, and the structure, organization, and code are the valuable trade secrets and confidential information of HeerlijkeHeer. The Software is licensed, not sold.  4. Disclaimer of Warranty THE SOFTWARE IS PROVIDED "AS IS," WITH ALL FAULTS, AND WITHOUT WARRANTY OF ANY KIND. HeerlijkeHeer EXPRESSLY DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  5. Limitation of Liability IN NO EVENT WILL HeerlijkeHeer BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  6. Termination This license is effective until terminated. You may terminate it at any time by destroying the Software, together with all copies thereof. This license will also terminate if you fail to comply with any term or condition of this Agreement. Upon such termination, you agree to destroy the Software, together with all copies thereof.   Copyright (C) 2024 HeerlijkeHeer. All rights reserved.


pkgId: 1f15abf6349b1e6ad9c301426b03dd682f0640615a153e77d868839736f43608
name: python-crisp-api
arch: src
version: 1.1.19
epoch: 0
release: 1
summary: Crisp API Python.
url: https://github.com/crisp-im/python-crisp-api
rpm_license: MIT - http://opensource.org/licenses/mit-license.php
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crisp-api-1.1.19-1.src.rpm
checksum_type: sha256
description:
  [![Build and Release](https://github.com/crisp-im/python-crisp-api/workflows/Build%20and%20Release/badge.svg)](https://github.com/crisp-im/python-crisp-api/actions?query=workflow%3A%22Build+and+Release%22) [![PyPI](https://img.shields.io/pypi/v/crisp-api.svg)](https://pypi.org/project/crisp-api/) [![Downloads](https://img.shields.io/pypi/dm/crisp-api.svg)](https://pypi.org/project/crisp-api/)

  The Crisp API Python wrapper. Authenticate, send messages, fetch conversations, access your agent accounts from your Python code.

  Copyright 2023 Crisp IM SAS. See LICENSE for copying information.

  * **📝 Implements**: [REST API Reference (V1)](https://docs.crisp.chat/references/rest-api/v1/) at revision: 16/01/2023
  * **😘 Maintainers**: [@valeriansaliou](https://github.com/valeriansaliou), [@eliottvincent](https://github.com/eliottvincent)



  You may follow the [REST API Quickstart](https://docs.crisp.chat/guides/rest-api/quickstart/) guide, which will get you running with the REST API in minutes.

  Install the library:

  ```bash
  pip install crisp-api
  ```

  Then, import it:

  ```python
  from crisp_api import Crisp
  ```

  Construct a new authenticated Crisp client with your `identifier` and `key` tokens.

  ```python
  client = Crisp()

  client.set_tier("plugin")
  client.authenticate(identifier, key)
  ```

  Then, your client is ready to be consumed!



  To authenticate against the API, obtain your authentication token keypair by following the [REST API Authentication](https://docs.crisp.chat/guides/rest-api/authentication/) guide. You'll get a token keypair made of 2 values.

  **Keep your token keypair values private, and store them safely for long-term use.**

  Then, add authentication parameters to your `client` instance right after you create it:

  ```python
  client = Crisp()



  client.set_tier("plugin")
  client.authenticate(identifier, key)


  ```



  Most useful available Crisp API resources are implemented. **Programmatic methods names are named after their label name in the [REST API Reference](https://docs.crisp.chat/references/rest-api/v1/)**.

  All methods that you will most likely need when building a Crisp integration are prefixed with a star symbol (⭐).

  In the following method prototypes, `crisp` is to be replaced with your Crisp API instance. For example, instanciate `client = Crisp()` and then call eg: `client.website.list_conversations(website_id, 1)`.

  When calling a method that writes data to the API (eg. send a message with: `client.website.send_message_in_conversation()`), you need to submit it this way:

  ```python
  website_id = "88972681-a00c-4b3b-a383-cab281636484"
  session_id = "session_9df2a21e-f113-41d4-8ed2-bad8b49cafd1"

  client.website.send_message_in_conversation(
    website_id, session_id,

    {
      "type": "text",
      "content": "This message was sent from python-crisp-api! :)",
      "from": "operator",
      "origin": "chat"
    }
  )
  ```

  **⚠️ Note that, depending on your authentication token tier, which is either `user` or `plugin`, you may not be allowed to use all methods from the library. When in doubt, refer to the library method descriptions below. Most likely, you are using a `plugin` token.**



  * **Website Conversations**
    * ⭐ **List Conversations** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#list-conversations)
      * `client.website.list_conversations(website_id, page_number)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        page_number = 1

        client.website.list_conversations(website_id, page_number);
        ```
        </details>

    * **Search Conversations** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#list-conversations)
      * `client.website.search_conversations(website_id, page_number, search_query, search_type, search_operator, include_empty, filter_unread, filter_resolved, filter_not_resolved, filter_mention, filter_assigned, filter_unassigned, filter_date_start, filter_date_end, order_date_created", order_date_updated)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        page_number = 1

        client.website.list_conversations(website_id, page_number);
        ```
        </details>


  * **Website Conversation**
    * ⭐ **Create A New Conversation** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#create-a-new-conversation)
      * `client.website.create_new_conversation(website_id)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"

        client.website.create_new_conversation(website_id);
        ```
        </details>

    * **Check If Conversation Exists** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#check-if-conversation-exists)
      * `client.website.check_conversation_exists(website_id, session_id)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        session_id = "session_700c65e1-85e2-465a-b9ac-ecb5ec2c9881"

        client.website.check_conversation_exists(website_id, session_id);
        ```
        </details>

    * ⭐ **Get A Conversation** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#get-a-conversation)
      * `client.website.get_conversation(website_id, session_id)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        session_id = "session_700c65e1-85e2-465a-b9ac-ecb5ec2c9881"

        client.website.get_conversation(website_id, session_id);
        ```
        </details>

    * **Remove A Conversation** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#remove-a-conversation)
      * `client.website.remove_conversation(website_id, session_id)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        session_id = "session_700c65e1-85e2-465a-b9ac-ecb5ec2c9881"

        client.website.remove_conversation(website_id, session_id);
        ```
        </details>

    * **Initiate A Conversation With Existing Session** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#initiate-a-conversation-with-existing-session)
      * `client.website.initiate_conversation_with_existing_session(website_id, session_id)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        session_id = "session_700c65e1-85e2-465a-b9ac-ecb5ec2c9881"

        client.website.initiate_conversation_with_existing_session(website_id, session_id);
        ```
        </details>

    * ⭐ **Get Messages In Conversation** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#get-messages-in-conversation)
      * `client.website.get_messages_in_conversation(website_id, session_id, query)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        session_id = "session_700c65e1-85e2-465a-b9ac-ecb5ec2c9881"

        client.website.get_messages_in_conversation(website_id, session_id, query);
        ```
        </details>

    * **Send A Message In Conversation** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#send-a-message-in-conversation)
      * `client.website.send_message_in_conversation(website_id, session_id, query)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        session_id = "session_700c65e1-85e2-465a-b9ac-ecb5ec2c9881"

        query = {
          "type": "text",
          "from": "operator",
          "origin": "chat",
          "content": "Hey there! Need help?"
        }

        client.website.send_message_in_conversation(website_id, session_id, query);
        ```
        </details>

    * **Get A Message In Conversation** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#get-a-message-in-conversation)
      * `client.website.get_message_in_conversation(website_id, session_id, fingerprint)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        session_id = "session_700c65e1-85e2-465a-b9ac-ecb5ec2c9881"
        fingerprint = 524653764345

        client.website.get_message_in_conversation(website_id, session_id, fingerprint);
        ```
        </details>

    * **Update A Message In Conversation** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#update-a-message-in-conversation)
      * `client.website.update_message_in_conversation(website_id, session_id, fingerprint, data)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        session_id = "session_700c65e1-85e2-465a-b9ac-ecb5ec2c9881"
        fingerprint = 524653764345

        data = "Hey there! Need help?"

        client.website.update_message_in_conversation(website_id, session_id, fingerprint, data);
        ```
        </details>

    * **Compose A Message In Conversation** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#compose-a-message-in-conversation)
      * `client.website.compose_message_in_conversation(website_id, session_id, data)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        session_id = "session_700c65e1-85e2-465a-b9ac-ecb5ec2c9881"

        data = {
          "type": "start",
          "from": "operator"
        }

        client.website.compose_message_in_conversation(website_id, session_id, data);
        ```
        </details>

    * ⭐ **Mark Messages As Read In Conversation** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#mark-messages-as-read-in-conversation)
      * `client.website.mark_messages_read_in_conversation(website_id, session_id, data)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        session_id = "session_700c65e1-85e2-465a-b9ac-ecb5ec2c9881"

        data = {
          "from": "operator",
          "origin": "urn:crisp.im:slack:0",
          "fingerprints": [
            "5719231201"
          ]
        }

        client.website.mark_messages_read_in_conversation(website_id, session_id, data);
        ```
        </details>

    * ⭐ **Mark Messages As Delivered In Conversation** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#mark-messages-as-delivered-in-conversation)
      * `client.website.mark_messages_delivered_in_conversation(website_id, session_id, data)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        session_id = "session_700c65e1-85e2-465a-b9ac-ecb5ec2c9881"

        data = {
          "from": "operator",
          "origin": "urn:crisp.im:slack:0",
          "fingerprints": [
            "5719231201"
          ]
        }

        client.website.mark_messages_delivered_in_conversation(website_id, session_id, data);
        ```
        </details>

    * ⭐ **Get Conversation Routing Assign** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#get-conversation-routing-assign)
      * `client.website.get_conversation_routing_assign(website_id, session_id)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        session_id = "session_700c65e1-85e2-465a-b9ac-ecb5ec2c9881"

        client.website.get_conversation_routing_assign(website_id, session_id);
        ```
        </details>

    * ⭐ **Assign Conversation Routing** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#assign-conversation-routing)
      * `client.website.assign_conversation_routing(website_id, session_id, data)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        session_id = "session_700c65e1-85e2-465a-b9ac-ecb5ec2c9881"

        data = {
          "assigned": {
            "user_id": "a4c32c68-be91-4e29-8a05-976e93abbe3f"
          }
        }

        client.website.assign_conversation_routing(website_id, session_id, data);
        ```
        </details>

    * ⭐ **Get Conversation Metas** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#get-conversation-metas)
      * `client.website.get_conversation_metas(website_id, session_id)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        session_id = "session_700c65e1-85e2-465a-b9ac-ecb5ec2c9881"

        client.website.get_conversation_metas(website_id, session_id);
        ```
        </details>

    * ⭐ **Update Conversation Metas** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#update-conversation-metas)
      * `client.website.update_conversation_metas(website_id, session_id, data)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        session_id = "session_700c65e1-85e2-465a-b9ac-ecb5ec2c9881"

        data = {
          "nickname": "John Doe",
          "email": "john.doe@acme-inc.com",
          "segments": [
            "happy",
            "customer",
            "love"
          ],
          "data": {
            "type": "customer",
            "signup": "finished"
          }
        }

        client.website.update_conversation_metas(website_id, session_id, data);
        ```
        </details>

    * **List Conversation Pages** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#list-conversation-pages)
      * `client.website.list_conversation_pages(website_id, session_id, page_number)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        session_id = "session_700c65e1-85e2-465a-b9ac-ecb5ec2c9881"
        page_number = 1

        client.website.list_conversation_pages(website_id, session_id, page_number);
        ```
        </details>

    * **List Conversation Events** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#list-conversation-events)
      * `client.website.list_conversation_events(website_id, session_id, page_number)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        session_id = "session_700c65e1-85e2-465a-b9ac-ecb5ec2c9881"
        page_number = 1

        client.website.list_conversation_events(website_id, session_id, page_number);
        ```
        </details>

    * **List Conversation Files** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#list-conversation-files)
      * `client.website.list_conversation_files(website_id, session_id, page_number)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        session_id = "session_700c65e1-85e2-465a-b9ac-ecb5ec2c9881"
        page_number = 1

        client.website.list_conversation_files(website_id, session_id, page_number);
        ```
        </details>

    * **Get Conversation State** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#get-conversation-state)
      * `client.website.get_conversation_state(website_id, session_id)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        session_id = "session_700c65e1-85e2-465a-b9ac-ecb5ec2c9881"

        client.website.get_conversation_state(website_id, session_id);
        ```
        </details>

    * ⭐ **Change Conversation State** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#change-conversation-state)
      * `client.website.change_conversation_state(website_id, session_id, data)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        session_id = "session_700c65e1-85e2-465a-b9ac-ecb5ec2c9881"

        data = "unresolved"

        client.website.change_conversation_state(website_id, session_id, data);
        ```
        </details>

    * **Get Block Status For Conversation** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#get-block-status-for-conversation)
      * `client.website.get_block_status_for_conversation(website_id, session_id)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        session_id = "session_700c65e1-85e2-465a-b9ac-ecb5ec2c9881"

        client.website.get_block_status_for_conversation(website_id, session_id);
        ```
        </details>

    * **Block Incoming Messages For Conversation** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#block-incoming-messages-for-conversation)
      * `client.website.block_incoming_messages_for_conversation(website_id, session_id, data)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        session_id = "session_700c65e1-85e2-465a-b9ac-ecb5ec2c9881"

        data = true

        client.website.block_incoming_messages_for_conversation(website_id, session_id, data);
        ```
        </details>

    * **Request Email Transcript For Conversation** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#request-email-transcript-for-conversation)
      * `client.website.request_email_transcript_for_conversation(website_id, session_id, data)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        session_id = "session_700c65e1-85e2-465a-b9ac-ecb5ec2c9881"

        data = {
          "to": "operator",
          "email": "valerian@crisp.chat"
        }

        client.website.request_email_transcript_for_conversation(website_id, session_id, data);
        ```
        </details>


  * **Website People** _(these are your end-users)_
    * **Get People Statistics** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#get-people-statistics)
      * `client.website.get_people_statistics(website_id)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"

        client.website.get_people_statistics(website_id);
        ```
        </details>

    * **List People Segments** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#list-suggested-people-segments)
      * `client.website.list_people_segments(website_id, page_number)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        page_number = 1

        client.website.list_people_segments(website_id, page_number);
        ```
        </details>

    * ⭐ **List People Profiles** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#list-people-profiles)
      * `client.website.list_people_profiles(website_id, page_number)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        page_number = 1

        client.website.list_people_profiles(website_id, page_number);
        ```
        </details>

    * ⭐ **Add New People Profile** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#add-new-people-profile)
      * `client.website.add_new_people_profile(website_id, data)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"

        data = {
          "email": "valerian@crisp.chat",
          "person": {
            "nickname": "Valerian Saliou"
          }
        }

        client.website.add_new_people_profile(website_id, data);
        ```
        </details>

    * ⭐ **Check If People Profile Exists** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#check-if-people-profile-exists)
      * `client.website.check_people_profile_exists(website_id, people_id)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        people_id = "c5a2f70c-f605-4648-b47f-8c39d4b03a50"

        client.website.check_people_profile_exists(website_id, people_id);
        ```
        </details>

    * ⭐ **Get People Profile** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#get-people-profile)
      * `client.website.get_people_profile(website_id, people_id)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        people_id = "c5a2f70c-f605-4648-b47f-8c39d4b03a50"

        client.website.get_people_profile(website_id, people_id);
        ```
        </details>

    * ⭐ **Save People Profile** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#save-people-profile)
      * `client.website.save_people_profile(website_id, people_id, data)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        people_id = "c5a2f70c-f605-4648-b47f-8c39d4b03a50"

        data = {
          "email": "valerian@crisp.chat",
          "person": {
            "nickname": "Valerian Saliou"
          }
        }

        client.website.save_people_profile(website_id, people_id, data);
        ```
        </details>

    * ⭐ **Update People Profile** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#update-people-profile)
      * `client.website.update_people_profile(website_id, people_id, data)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        people_id = "c5a2f70c-f605-4648-b47f-8c39d4b03a50"

        data = {
          "email": "valerian@crisp.chat",
          "person": {
            "nickname": "Valerian Saliou"
          }
        }

        client.website.update_people_profile(website_id, people_id, data);
        ```
        </details>

    * ⭐ **Remove People Profile** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#remove-people-profile)
      * `client.website.remove_people_profile(website_id, people_id)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        people_id = "c5a2f70c-f605-4648-b47f-8c39d4b03a50"

        client.website.remove_people_profile(website_id, people_id);
        ```
        </details>

    * **List People Conversations** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#list-people-conversations)
      * `client.website.list_people_conversations(website_id, people_id, page_number)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        people_id = "c5a2f70c-f605-4648-b47f-8c39d4b03a50"
        page_number = 1

        client.website.list_people_conversations(website_id, people_id, page_number);
        ```
        </details>

    + **Add A People Event** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#add-a-people-event)
      * `client.website.add_people_event(website_id, people_id, data)`
    + **List People Events** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#list-people-events)
      * `client.website.list_people_events(website_id, people_id, page_number)`
    + **Get People Data** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#get-people-data)
      * `client.website.get_people_data(website_id, people_id)`
    + **Save People Data** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#save-people-data)
      * `client.website.save_people_data(website_id, people_id, data)`
    + **Get People Subscription Status** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#get-people-subscription-status)
      * `client.website.get_people_subscription_status(website_id, people_id)`
    + **Update People Subscription Status** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#update-people-subscription-status)
      * `client.website.update_people_subscription_status(website_id, people_id, data)`

  _👉 Notice: The `peopleID` argument can be an email or the `peopleID`._


  * **Website Base**
    * **Create Website** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#create-website)
      * `client.website.create_website(data)`
      * <details>
        <summary>See Example</summary>

        ```python
        client.website.create_website(data);
        ```
        </details>

    * **Get A Website** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#get-a-website)
      * `client.website.get_website(website_id)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"

        client.website.get_website(website_id);
        ```
        </details>

    * **Delete A Website** [`user`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#delete-a-website)
      * `client.website.delete_website(website_id)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"

        client.website.delete_website(website_id);
        ```
        </details>


  * **Website Batch**
    * **Batch Resolve Items** [`user`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#batch-resolve-items)
      * `client.website.batch_resolve_items(website_id, data)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"

        client.website.batch_resolve_items(website_id, data);
        ```
        </details>

    * **Batch Read Items** [`user`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#batch-read-items)
      * `client.website.batch_read_items(website_id, data)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"

        client.website.batch_read_items(website_id, data);
        ```
        </details>

    * **Batch Remove Items** [`user`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#batch-remove-items)
      * `client.website.batch_remove_items(website_id, data)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"

        data = [
          "session_19e5240f-0a8d-461e-a661-a3123fc6eec9",
          "session_700c65e1-85e2-465a-b9ac-ecb5ec2c9881"
        ]

        client.website.batch_remove_items(website_id, data);
        ```
        </details>


  * **Website Availability**
    * **Get Website Availability Status** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#get-website-availability-status)
      * `client.website.get_website_availability_status(website_id)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"

        client.website.get_website_availability_status(website_id);
        ```
        </details>


  * **Website Operator**
    * **List Website Operators** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#list-website-operators)
      * `client.website.list_website_operators(website_id)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"

        client.website.list_website_operators(website_id);
        ```
        </details>

    * **List Last Active Website Operators** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#list-last-active-website-operators)
      * `client.website.list_last_active_website_operators(website_id)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"

        client.website.list_last_active_website_operators(website_id);
        ```
        </details>


  * **Website Settings**
    * **Get Website Settings** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#get-website-settings)
      * `client.website.get_website_settings(website_id)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"

        client.website.get_website_settings(website_id);
        ```
        </details>

    * **Update Website Settings** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#update-website-settings)
      * `client.website.update_website_settings(website_id, data)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"

        data = {
          "name": "Crisp",
          "domain": "crisp.chat",
          "logo": "https://storage.crisp.chat/users/avatar/website/8c842203-7ed8-4e29-a608-7cf78a7d2fcc/b6c2948d-b061-405e-91a9-2fdf855d1cc0.png",
          "contact": {
            "email": "contact@crisp.chat",
            "phone": "+33757905447"
          },
          "inbox": {
            "lock_removal": false,
            "force_operator_token": false
          },
          "emails": {
            "rating": true,
            "transcript": true,
            "enrich": true,
            "junk_filter": true
          },
          "chatbox": {
            "tile": "default",
            "wait_game": false,
            "last_operator_face": false,
            "ongoing_operator_face": true,
            "activity_metrics": true,
            "operator_privacy": false,
            "availability_tooltip": true,
            "hide_vacation": false,
            "hide_on_away": false,
            "hide_on_mobile": false,
            "position_reverse": false,
            "email_visitors": false,
            "phone_visitors": false,
            "force_identify": false,
            "ignore_privacy": false,
            "visitor_compose": false,
            "file_transfer": true,
            "helpdesk_link": true,
            "helpdesk_only": false,
            "status_health_dead": true,
            "check_domain": false,
            "color_theme": "blue",
            "text_theme": "default",
            "welcome_message": "default",
            "locale": "en",
            "allowed_pages": [],
            "blocked_pages": [
              "status/*/",
              "docs.crisp.chat/*",
              "crisp.chat/terms/",
              "https://crisp.chat/privacy/"
            ],
            "blocked_countries": [
              "IT"
            ],
            "blocked_locales": [
              "fa",
              "he"
            ],
            "blocked_ips": [
              "8.8.8.8",
              "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
              "192.168.1.1/24"
            ]
          }
        }

        client.website.update_website_settings(website_id, data);
        ```
        </details>


  * **Website Visitors**
    * **Count Visitors** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#count-visitors)
      * `client.website.count_visitors(website_id)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"

        client.website.count_visitors(website_id);
        ```
        </details>

    * **List Visitors** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#list-visitors)
      * `client.website.list_visitors(website_id, page_number)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        page_number = 1

        client.website.list_visitors(website_id, page_number);
        ```
        </details>




  * **Plugin Connect**
    * **Get Plugin Connect Account** [`plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#get-connect-account)
      * `client.plugin.get_connect_account()`
      * <details>
        <summary>See Example</summary>

        ```python
        client.plugin.get_connect_account();
        ```
        </details>

    * **Check Plugin Connect Session Validity** [`plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#check-connect-session-validity)
      * `client.plugin.check_connect_session_validity()`
      * <details>
        <summary>See Example</summary>

        ```python
        client.plugin.check_connect_session_validity();
        ```
        </details>

    * **List All Connected Websites** [`plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#list-all-connect-websites)
      * `client.plugin.list_all_connect_websites(page_number, filter_configured)`
      * <details>
        <summary>See Example</summary>

        ```python
        page_number = 1

        client.plugin.list_all_connect_websites(page_number, filter_configured);
        ```
        </details>


  * **Plugin Subscription**
    * **List All Active Subscriptions** [`user`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#list-all-active-subscriptions)
      * `client.plugin.list_all_active_subscriptions()`
      * <details>
        <summary>See Example</summary>

        ```python
        client.plugin.list_all_active_subscriptions();
        ```
        </details>

    * **List Subscriptions For Website** [`user`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#list-subscriptions-for-a-website)
      * `client.plugin.list_subscriptions_website(website_id)`
    * **Get Subscription Details** [`user`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#get-subscription-details)
      * `client.plugin.get_subscription_details(website_id, plugin_id)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        plugin_id = "c64f3595-adee-425a-8d3a-89d47f7ed6bb"

        client.plugin.get_subscription_details(website_id, plugin_id);
        ```
        </details>

    * **Subscribe Website To Plugin** [`user`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#subscribe-website-to-plugin)
      * `client.plugin.subscribe_plugin_to_website(website_id)`
    * **Unsubscribe Plugin From Website** [`user`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#unsubscribe-plugin-from-website)
      * `client.plugin.unsubscribe_plugin_from_website(website_id, plugin_id)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        plugin_id = "c64f3595-adee-425a-8d3a-89d47f7ed6bb"

        client.plugin.unsubscribe_plugin_from_website(website_id, plugin_id);
        ```
        </details>

    * **Get Subscription Settings** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#get-subscription-settings)
      * `client.plugin.get_subscription_settings(website_id, plugin_id)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        plugin_id = "c64f3595-adee-425a-8d3a-89d47f7ed6bb"

        client.plugin.get_subscription_settings(website_id, plugin_id);
        ```
        </details>

    * **Save Subscription Settings** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#save-subscription-settings)
      * `client.plugin.save_subscription_settings(website_id, plugin_id, settings)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        plugin_id = "c64f3595-adee-425a-8d3a-89d47f7ed6bb"

        settings = {
          "chatbox": {
            "25": "#bbbbbb"
          }
        }

        client.plugin.save_subscription_settings(website_id, plugin_id, settings);
        ```
        </details>

    * **Update Subscription Settings** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#update-subscription-settings)
      * `client.plugin.update_subscription_settings(website_id, plugin_id, settings)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        plugin_id = "c64f3595-adee-425a-8d3a-89d47f7ed6bb"

        settings = {
          "chatbox": {
            "25": "#bbbbbb"
          }
        }

        client.plugin.update_subscription_settings(website_id, plugin_id, settings);
        ```
        </details>

    * **Forward Plugin Payload To Channel** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#forward-plugin-payload-to-channel)
      * `client.plugin.forward_plugin_payload_to_channel(website_id, plugin_id, data)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        plugin_id = "c64f3595-adee-425a-8d3a-89d47f7ed6bb"

        data = {
          "namespace": "bot:step",
          "payload": {
            "step": 1
          }
        }

        client.plugin.forward_plugin_payload_to_channel(website_id, plugin_id, data);
        ```
        </details>

    * **Dispatch Plugin Event** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#dispatch-plugin-event)
      * `client.plugin.dispatch_plugin_event(website_id, plugin_id, data)`
      * <details>
        <summary>See Example</summary>

        ```python
        website_id = "8c842203-7ed8-4e29-a608-7cf78a7d2fcc"
        plugin_id = "c64f3595-adee-425a-8d3a-89d47f7ed6bb"

        data = {
          "name": "bot-is-running",
          "data": {
            "bot": "Sales",
            "email": "valerian@crisp.chat"
          }
        }

        client.plugin.dispatch_plugin_event(website_id, plugin_id, data);
        ```
        </details>




  * **Bucket URL**
    * **Generate Bucket URL** [`user`, `plugin`]: [Reference](https://docs.crisp.chat/references/rest-api/v1/#generate-bucket-url)
      * `client.bucket.generate_bucket_url(data)`
      * <details>
        <summary>See Example</summary>

        ```python
        client.bucket.generate_bucket_url(data);
        ```
        </details>


pkgId: 893038435009b9fc7f1508973402a16ed9e028822f8abfa037d53fa7837e4dc4
name: python-crispr-millipede
arch: src
version: 0.1.102
epoch: 0
release: 1
url: https://pypi.org/project/crispr-millipede/
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crispr-millipede-0.1.102-1.src.rpm
checksum_type: sha256
summary:
  Calculate the enrichment scores of CRISPR alleles and variants from direct target amplicon-sequencing data using Bayesian linear regression model 'millipede'

description:
  <img src="https://github.com/user-attachments/assets/d54fbe8f-2c0e-4354-a209-eab031c3bd64" alt="CRISPR-Millipede logo" width="500"></img>



  **CRISPR-Millipede** was developed by the *Pinello Lab* as an easy-to-use Python package for <ins> processing targeted amplicon-sequencing of tiled sequences from base-editing tiling screens to identify functional nucleotides</ins>. By providing amplicon-sequencing of installed alleles from multiple phenotypic populations, CRISPR-Millipede identifies the single-variants that contribute to differences in phenotype. See [this preprint](https://www.biorxiv.org/content/10.1101/2024.09.09.612085v1) for more information on this method! It is expected that you are familiar with Python, command-line tools, and CRISPR screens to follow this guide.



  **Sections**
  - [Notes on Experimental Design and Expected Inputs](#notes-on-experimental-design-and-expected-inputs)
  - [Installation](#installation)
  - [System Requirements](#system-requirements)
  - [Instructions](#instructions)
    -  [STEP 1: Run CRISPResso2 to generate allele tables](#step-1-run-crispresso2-to-generate-allele-tables)
    -  [STEP 2: Encode the CRISPResso2 outputs into matrices](#step-2-encode-the-crispresso2-outputs-into-matrices)
    -  [STEP 3: Perform modelling of the encoded dataset](#step-3-perform-modelling-of-the-encoded-dataset)
    -  [STEP 4: Visualization using boardplots](#step-4-generate-board-plots)
    -  [STEP 5: PyDESEQ2 allelic analysis](#step-5-PyDESEQ-based-analysis)


  *Skip this and scroll further down if interested in the tool usage*
  - This tool is best used for pooled CRISPR saturation mutagenesis screens of a single focused region.
  - The length of the mutagenized region depends on the desired sequencing read length (i.e. paired-end 150bp sequencing has a max mutagenesis length of 300bp, however, it is desired that there is as much overlap of the paired-ends to maximize sequencing quality). You will perform targeted amplicon-sequencing of your intended mutagenized region. Ensure that no editing occurs at the primer binding sites, and ensure that the primers are tested and optimized beforehand (i.e. difficult-to-amplify or difficult-to-sequence regions may not be suitable for this method, therefore it is essential that this is tested prior to screening).
  - It is suggested that you also perform the standard sequencing of the guide RNA to calculate guide RNA enrichment scores in tandem. Therefore, you will split your genomic DNA into two different library preparation approaches: guide RNA sequencing and the aforementioned direct target sequencing.
  - The type of mutagenesis is best suited to single-nucleotide mutagenesis (i.e. base-editing and prime-editing). The method has not been extensively tested on in-del mutagenesis.
  - This model was developed and tested on FACS-sorted based screens rather than proliferation screens, however the model may still work for proliferation screens by comparing samples between two separate timepoints.
  - Ensure that you have sufficient cell coverage for sequencing, especially if doing both guide RNA and direct target sequencing. You should preferably have roughly 1000 cells * number of guide RNAs in your library for EACH guide RNA and direct sequencing approach (therefore 2000 cells * number of guide RNAs if doing both sequencing approaches) for EACH sample. The cell coverage depends on the editing efficiency and the expected effect sizes. Typically, the sorted population with the phenotypic change from the baseline after perturbation will have the lowest coverage, therefore you should ensure that you have sufficient cell counts in all populations prior to sequencing (by modifying your FACS gates while still maintaining separation between your negative and positive control gRNAs or by simply increasing input cell amount at the expense of longer sort time).
  - Ensure that you have sufficient biological replicates (at least 3 replicates).
  - It is not necessary to haploidize your region to have single-copy alleles, though this may reduce the noise of the phenotypic scores for each sequenced allele due to certain homozygosity of the sequenced allele.
  - While this method is robust to biases in different editing efficiencies among your guide RNAs since alleles are directly sequenced, ensuring high editing efficiency will increase the per-allele coverage in your samples thereby reducing the necessary cell coverage and increasing statistical power.

  See **Figure a** below for a schematic of the experimental design:

    <img src="https://github.com/user-attachments/assets/6ec0a352-aeb2-453b-81d4-ab812c88399b" alt="CRISPR-CLEAR framework" width="300"></img>

    <em>**Figure a:** The workflow illustrates the key steps from guide RNA design to data analysis. First, cells stably expressing a base editor are transduced with a library of guide RNAs tiling the regulatory sequence. After editing, cells are FACS-sorted based on the expression of the target protein. Genomic DNA is extracted from sorted cells. Next-generation libraries are prepared to quantify sgRNA counts and to measure the distribution of edits at the endogenous sequence in the sorted population of cells. The left pathway shows the standard approach using sgRNA count-based readout and the CRISPR-SURF pipeline for deconvolution of functional regions. The right pathway depicts the CRISPR-CLEAR approach using direct allele-based readout and the CRISPR-Millipede pipeline, enabling precise genotype-to-phenotype linkage through per-allele and per-nucleotide analysis.</em>

  After performing the screen, you should have targetted amplicon-sequencing FASTQs for each of your phenotypic populations (i.e. different FACS gates along with the pre-sort sample) for multiple biological replicates. An overview of the pipeline is to 1) first quality-control using FASTQC to ensure sufficient read quality of all samples, 2) run all the samples through CRISPResso2 to characterize the introduced alleles in your samples, 3) encode the alleles in a numerical representation for Millipede modelling 4) and lastly perform the Millipede modelling to attain your results. See **Figure b** below for a schematic of the pipeline steps:

  <img src="https://github.com/user-attachments/assets/0cbb44c8-e073-44c3-be54-fa6239871895" alt="CRISPR-CLEAR framework" width="300"></img>

  <em>**Figure b:** Schematic of CRISPR-Millipede workflow.</em>



  CRISPResso2 is required for first step (a *Pinello Lab* tool), to prepare the input for CRISPR-Millipede. See the [CRISPResso2 repository](https://github.com/pinellolab/CRISPResso2) for installation instructions. You can install this in a different conda environment than CRISPR-Millipede (Preferred). If you want it in the same environment install CRISRPresso2 before CRISPR-Millipede.

  CRISPR-Millipede requires **Python versions >=3.10,<3.12** which can be installed from the [Python download page](https://www.python.org/downloads/) or via **Conda** (see installation of Conda [here](https://docs.conda.io/projects/conda/en/latest/user-guide/install/index.html)). Optionally, can use [**mamba**](https://github.com/mamba-org/mamba/blob/main/README.md) for faster installation. For installing Python via Conda:

  ```conda install python=3.10```.

  Additionally, CRISPR-Millipede requires the **PyTorch**, which can be installed via **Conda**. If your computer does not have a CPU, install the CPU-version of PyTorch:

  ```conda install pytorch```

  If you have a GPU, ensure that you have CUDA installed by checking the CUDA version (for example version 11.8):

  ```nvcc --version```

  If you don't have CUDA installed, follow the [NVIDIA CUDA installation guide](https://docs.nvidia.com/cuda/cuda-installation-guide-microsoft-windows/index.html).

  Then, install the appropriate GPU version of PyTorch with the correct version of the **pytorch-cuda** based on the CUDA version installed on your OS (for example version 11.8):

  ```conda install pytorch torchvision torchaudio pytorch-cuda=11.8 -c pytorch -c nvidia```

  Once you have all Python and PyTorch dependencies installed, CRISPR-Millipede can easily be installed from PyPi which should only take a few minutes. PIP will ensure that all Python package dependencies are installed:

  ```pip install crispr-millipede==0.1.97```,

  ***Did you also directly sequence your guide RNAs?*** It is recommended you do so to compare against the CRISPR-Millipede results from target amplicon-sequencing. You could map your guide sequences using tools from the *Pinello Lab* such as [CRISPR-Correct](https://github.com/pinellolab/CRISPR-Correct) and analyze the resulting counts using [CRISPR-SURF](https://github.com/pinellolab/CRISPR-SURF/tree/master) as done in the original paper!

  PyDESeq2 can also be installed from PyPi, using the following command:

  ```pip install pydeseq2```


  CRISPR-Millipede can run on [any operating system where Python versions >=3.10,<3.12 can be installed](https://www.python.org/downloads/operating-systems/) and where [PyTorch can be installed](https://pytorch.org/get-started/locally/). To speed up model performance, CRISPR-Millipede can utilize both CPUs (for multi-threading) and GPUs (for model training) and is highly recommended to allow the pipeline to run in the span of a couple hours, though the tool can still work on single core non-GPU computers but may run in the span of a day for each run attempt depending on the FASTQ sizes.


  On a Macbook Pro (M2 Chip with 32 GB ram)
  - Installation takes about 1 min 20 secs via pip after installing PyTorch
  - Running Step 1 (CRISPResso2) takes about 5 mins on sg218 example
  - Running Step 2 (Encoding) takes about 20 mins on sg218 example
  - Running Step 3 (Millipede: model_run = cmm.MillipedeModelExperimentalGroup(experiments_inputdata=model_input_data, device=cmm.MillipedeComputeDevice.CPU) takes about 2 minutes for the sg218 example in the notebook





  *We need to take the raw amplicon-sequencing data and encode it into an input that CRISPR-Millipede accepts. It is suggested that your amplicon-sequencing data is quality-controlled using [FASTQC](https://www.bioinformatics.babraham.ac.uk/projects/fastqc/) to ensure sequencing quality.*

  CRISPR-Millipede's encoding step takes in as input the allele frequency tables produced from [CRISPResso2](https://github.com/pinellolab/CRISPResso2), a *Pinello Lab* tool for processing amplicon-sequencing data from CRISPR experiments. Refer to the [CRISPResso2 documentation](https://github.com/pinellolab/CRISPResso2) for instructions on how to run CRISPResso2, which may depend on the type of CRISPR editing performed in your experiment.


  Example command for a base-editing experiment:
  ```
  CRISPRessoBatch
    -bs {FASTQ_FILENAME} -a {AMPLICON_SEQUENCE} -an {AMPLICON_NAME}
    -q {QUALITY}
    --exclude_bp_from_left {EX_LEFT} --exclude_bp_from_right {EX_RIGHT}
    --no_rerun -n {SCREEN_NAME}
    --min_frequency_alleles_around_cut_to_plot 0.001
    --max_rows_alleles_around_cut_to_plot 500
    -p 20 --plot_window_size 4 --base_editor_output -w 0
    -bo {OUTPUT_DIRECTORY}
  ```

  Run CRISPResso2 for all samples and replicates. For each sample, CRISPResso2 will produce an allele frequency table named "Alleles_frequency_table.zip" which is used as input to the CRISPR-Millipede package. You will need these files in the next step. CRISPResso2 will also produce several other plots characterizing the editing patterns of your samples which will be useful for initial exploration of your data prior to modelling!


  *The CRISPResso2 output contains a table of alleles and their read counts for each sample. The alleles are represented as strings, though the strings must be encoded into a numerical representation for CRISPR-Millipede modelling.*

  Import and prepare the parameters of the encoding step by passing in the amplicon sequence (required), the acceptable variant types (optional), predicted editing sites (optional), population colummn suffixes for indexing (required), and encoding edge trimming for reducing sequencing background (optional) to the `EncodingParameters` class.

  Below contains the class definition (and default values) of the `EncodingParameters` that you will need to instantiate:

  ```
  @dataclass
  class EncodingParameters:
      complete_amplicon_sequence: str # Amplicon sequence string
      population_baseline_suffix: Optional[str] = "_baseline" # Typically the population that unedited cells are primarily in. Suffix label
      population_target_suffix: Optional[str] = "_target" # The population used to calculate variant enrichment relative to the baseline population. Suffix label
      population_presort_suffix: Optional[str] = "_presort" # The un-sorted population used to calculate total editing efficiencies. Suffix label
      wt_suffix: Optional[str] = "_wt" # An unedited population to calculate the sequencing error background. Suffix label
      guide_edit_positions: List[int] = field(default_factory=list) # Position of expected editing sites. Positions are relative to the amplicon sequence. 0-based.
      guide_window_halfsize: int = 3 # Expected editing window size. Only edits in range(guide_edit_position-guide_window_halfsize,guide_edit_position+guide_window_halfsize+1) for all positions will be considered for modelling
      minimum_editing_frequency: float = 0 # Frequency of variants to consider for editing, may be useful for removing sequencing background.
      minimum_editing_frequency_population: List[str] = field(default_factory=list) # Population to consider for removal of variants by frequency, i.e. ["presort"]
      variant_types: List[Tuple[str, str]] = field(default_factory=list) #  List of variants to consider for modelling. Variants represented as two-value tuple where first index is REF and second index is ALT. i.e.  [("A", "G"), ("T", "C")] for adenine base-editing variants.
      trim_left: int = 0 # Filtering positions on left side of amplicon
      trim_right: int = 0 # Filtering positions on right side of amplicon
      remove_denoised: bool = False # Remove filtered features (from above criteria) from model input.
  ```


  Example of setting encoding parameters:
  ```
  from crispr_millipede import encoding as cme

  AMPLICON = "ACTGACTGACTGACTGACTGACTG" # Put your complete reference amplicon-sequence here
  ABE_VARIANT_TYPES = [("A", "G"), ("T", "C")] # Optional: If using an adenine base-editor
  CBE_VARIANT_TYPES = [("C", "T"), ("G", "A")] # Optional: If using a cytosine base-editor
  encoding_parameters = cme.EncodingParameters(complete_amplicon_sequence=AMPLICON,
                              population_baseline_suffix="_baseline",
                              population_target_suffix="_target",
                              population_presort_suffix="_presort",
                              wt_suffix="_wt",
                              trim_left=20,
                              trim_right=20,
                              variant_types=ABE_VARIANT_TYPES,
                              remove_denoised=True)
  ```


  To load the CRISPResso2 allele frequency tables into CRISPR-Millipede from STEP 1, pass in the `EncodingParameters` object and the CRISPResso2 allele frequency table filenames from STEP 1 for each population. For each population, provide a list of filenames corresponding to each replicate:

  ```
  encoding_dataframes = cme.EncodingDataFrames(encoding_parameters=encoding_parameters, #  From example above
                                                   reference_sequence=encoding_parameters.complete_amplicon_sequence,
                                                   population_baseline_filepaths=["CRISPResso_on_sample_baseline_1/Alleles_frequency_table.zip",
                                                                                  "CRISPResso_on_sample_baseline_2/Alleles_frequency_table.zip",
                                                                                  "CRISPResso_on_sample_baseline_3/Alleles_frequency_table.zip"],
                                                   population_target_filepaths=["CRISPResso_on_sample_target_1/Alleles_frequency_table.zip",
                                                                                "CRISPResso_on_sample_target_2/Alleles_frequency_table.zip",
                                                                                "CRISPResso_on_sample_target_3/Alleles_frequency_table.zip"],
                                                   population_presort_filepaths=["CRISPResso_on_sample_presort_1/Alleles_frequency_table.zip",
                                                                                 "CRISPResso_on_sample_presort_2/Alleles_frequency_table.zip",
                                                                                 "CRISPResso_on_sample_presort_3/Alleles_frequency_table.zip"],
                                                   wt_filepaths=[root_dir + "CRISPResso_on_sample_wt_1/Alleles_frequency_table.zip"])
  ```


  Perform the encoding:
  ```
  encoding_dataframes.read_crispresso_allele_tables() # This reads in the CRISPResso2 table
  encoding_dataframes.encode_crispresso_allele_table(progress_bar=True, cores={CPUS}) # Performs the initial encoding. Replace {CPUs} with the number of CPUs for parallelization on your system.
  encoding_dataframes.postprocess_encoding() # Postprocesses the encoding with the filtering criteria from above.
  ```

  Highly suggested to save the results of the encodings to your drive. Encouraged to include a prefix to version the results. These files will be used as input to the next modelling STEP 3.
  ```
  prefix_label ="20240916_v1_example_"

  cme.save_encodings(encoding_dataframes.encodings_collapsed_merged, sort_column="#Reads_presort", filename=prefix_label + "encoding_dataframes_editor_encodings_rep{}.tsv")
  cme.save_encodings(encoding_dataframes.population_wt_encoding_processed, sort_column="#Reads_wt", filename=prefix_label + "encoding_dataframes_wt_encodings_rep{}.tsv")
  cme.save_encodings_df(encoding_dataframes.population_baseline_encoding_processed, filename=prefix_label + "encoding_dataframes_baseline_editor_encodings_rep{}.pkl")
  cme.save_encodings_df(encoding_dataframes.population_target_encoding_processed, filename=prefix_label + "encoding_dataframes_target_editor_encodings_rep{}.pkl")
  cme.save_encodings_df(encoding_dataframes.population_presort_encoding_processed, filename=prefix_label + "encoding_dataframes_presort_editor_encodings_rep{}.pkl")
  cme.save_encodings_df(encoding_dataframes.population_wt_encoding_processed, filename=prefix_label + "encoding_dataframes_wt_encodings_rep{}.pkl")
  ```


  *Now that we have the encoded representation of the alleles, we will now perform Millipede modelling off of this representation. For documentation on the Millipede model sub-package, see [here](https://millipede.readthedocs.io/en/latest/getting_started.html).*

  **Set the model parameters:** Below contains the class definition (and default values) of the `MillipedeDesignMatrixProcessingSpecification` that you will need to instantiate:

  ```
  @dataclass
  class MillipedeDesignMatrixProcessingSpecification:
      wt_normalization: bool = True # Normalize the read count base on the unedited allele counts
      total_normalization: bool = False # Normalize the read count based on the total sum of all allele counts
      sigma_scale_normalized: bool = False # If using the NormalLikelihoodVariableSelector, determine if the sigma_scale factor will be based on the normalized read count
      decay_sigma_scale: bool = True # Set the sigma_scale factor based on the decay function
      K_enriched: Union[float, List[float], List[List[float]]] = 5 # Set the K_enriched value of the decay function
      K_baseline: Union[float, List[float], List[List[float]]] = 5 # Set the K_baseline value of the decay function
      a_parameter: Union[float, List[float], List[List[float]]] = 300 # Set the a_parameter of the decay function
  ```

  Additionally, you will need to specify the type of model as well. Below contains the class definition (and default values) of the `MillipedeModelSpecification` that you will need to instantiate:

  ```
  @dataclass
  class MillipedeModelSpecification:
      """
          Defines all specifications to produce Millipede model(s)
      """
      model_types: List[MillipedeModelType]
      replicate_merge_strategy: MillipedeReplicateMergeStrategy
      experiment_merge_strategy: MillipedeExperimentMergeStrategy
      cutoff_specification: MillipedeCutoffSpecification
      design_matrix_processing_specification: MillipedeDesignMatrixProcessingSpecification
      shrinkage_input: Union[MillipedeShrinkageInput, None] = None
      S: float = 1.0 #S parameter
      tau: float = 0.01 #tau parameter
      tau_intercept: float = 1.0e-4
  ```

  There are sub-classes you will need to instantiate. For instance, the `MillipedeReplicateMergeStrategy` specifies how multiple replicates are handled during modelling:
  ```
  class MillipedeReplicateMergeStrategy(Enum):
      """
          Defines how separate replicates will be treated during modelling
      """
      SEPARATE = "SEPARATE" # Replicates are modelled separately; one model per replicate
      SUM = "SUM" # (Normalized) counts for all replicates are summed together; one model for all replicates
      COVARIATE = "COVARIATE" # Replicates are jointly modelled, though replicate ID is included in the model design matrix
  ```

  *Recommended to run one version in `MillipedeReplicateMergeStrategy.SEPARATE` to assess individual replicate consistency, then if successful, run a final model in `MillipedeReplicateMergeStrategy.COVARIATE`*

  Likewise, the `MillipedeExperimentMergeStrategy` specifies how multiple experiments (i.e. screens with different editors) are handled during modelling.
  ```
  class MillipedeExperimentMergeStrategy(Enum):
      """
          Defines how separate experiments will be treated during modelling
      """
      SEPARATE = "SEPARATE"
      SUM = "SUM"
      COVARIATE = "COVARIATE"
  ```

  The `MillipedeModelType` specifies what likelihoood function to use for model fitting. See the [Millipede documentation](https://millipede.readthedocs.io/en/latest/selection.html) for more information.
  ```
  class MillipedeModelType(Enum):
      """
          Defines the Millipede model likelihood function used
      """
      NORMAL = "NORMAL"
      NORMAL_SIGMA_SCALED = "NORMAL_SIGMA_SCALED"
      BINOMIAL = "BINOMIAL"
      NEGATIVE_BINOMIAL = "NEGATIVE_BINOMIAL"
  ```
  *We recommend using the NORMAL_SIGMA_SCALED model, you will need to define the K_enriched, K_baseline, a, and decay_sigma_scale paramters to specify how the sigma_scale_factor is calculated.*

  Here is an example of specifying the complete input parameters for modelling:
  ```
  from crispr_millipede import encoding as cme
  from crispr_millipede import modelling as cmm

  design_matrix_spec = cmm.MillipedeDesignMatrixProcessingSpecification(
      wt_normalization=False,
      total_normalization=True,
      sigma_scale_normalized=True,
      decay_sigma_scale=True,
      K_enriched=5,
      K_baseline=5,
      a_parameter=0.0005
  )

  millipede_model_specification_set = {
      "model_specification_1" : cmm.MillipedeModelSpecification(
          model_types=[cmm.MillipedeModelType.NORMAL_SIGMA_SCALED],
          replicate_merge_strategy=cmm.MillipedeReplicateMergeStrategy.COVARIATE,
          experiment_merge_strategy=cmm.MillipedeExperimentMergeStrategy.SEPARATE,
          S = 5,
          tau = 0.01,
          tau_intercept = 0.0001,
          cutoff_specification=cmm.MillipedeCutoffSpecification(
              per_replicate_each_condition_num_cutoff = 0,
              per_replicate_all_condition_num_cutoff = 1,
              all_replicate_num_cutoff = 0,
              all_experiment_num_cutoff = 0,
              baseline_pop_all_condition_each_replicate_num_cutoff = 3,
              baseline_pop_all_condition_acceptable_rep_count = 2,
              enriched_pop_all_condition_each_replicate_num_cutoff = 3,
              enriched_pop_all_condition_acceptable_rep_count = 2,
              presort_pop_all_condition_each_replicate_num_cutoff = 3,
              presort_pop_all_condition_acceptable_rep_count = 2
          ),
          design_matrix_processing_specification=design_matrix_spec
      )
  }
  ```

  **Load in the encoding data:** Now that you have specified the model inputs, let's load the encoding data in, which should be straightforward:

  ```
  prefix_label ="20240916_v1_example_"
  encoding_filename = prefix_label + "encoding_dataframes_editor_encodings_rep{}.tsv"


  model_input_data = cmm.MillipedeInputDataExperimentalGroup(
      data_directory="./",
      enriched_pop_fn_experiment_list = [encoding_filename],
      enriched_pop_df_reads_colname = "#Reads_target",
      baseline_pop_fn_experiment_list = [encoding_filename],
      baseline_pop_df_reads_colname = "#Reads_baseline",
      presort_pop_fn_experiment_list = [encoding_filename],
      presort_pop_df_reads_colname = '#Reads_presort',
      experiment_labels = ["editor"],
      reps = [0,1,2],
      millipede_model_specification_set = millipede_model_specification_set
     )
  ```

  **Run the model:** Now that you have specified the inputs, we will now run the model. You have the option to use the CPU or GPU for modelling.

  ```
  model_run = cmm.MillipedeModelExperimentalGroup(experiments_inputdata=model_input_data, device=cmm.MillipedeComputeDevice.GPU)
  ```

  **Explore the results:** The model will provide posterior inclusion probabilities (PIP) and beta coefficient scores for each feature/variant that was included in the model and not filtered out during the encoding step:

  ```
  beta_df = paired_end_experiments_models_denoised.millipede_model_specification_set_with_results['model_specification_1'].millipede_model_specification_result_input[0].millipede_model_specification_single_matrix_result[cmm.MillipedeModelType.NORMAL_SIGMA_SCALED].beta
  pip_df = paired_end_experiments_models_denoised.millipede_model_specification_set_with_results['model_specification_1'].millipede_model_specification_result_input[0].millipede_model_specification_single_matrix_result[cmm.MillipedeModelType.NORMAL_SIGMA_SCALED].pip
  sigma_hit_table = paired_end_experiments_models_denoised.millipede_model_specification_set_with_results["joint_replicate_per_experiment_models"].millipede_model_specification_result_input[0].millipede_model_specification_single_matrix_result[cmm.MillipedeModelType.NORMAL_SIGMA_SCALED].summary

  sigma_hit_table.to_csv('MillipedeOutput.csv', index=True)

  ```
  **Model Output Table:** The output table (sigma_hit_table) will look like this where for each covariate you are given a PIP, Beta, Conditional PIP, and Conditional Beta

  <img width="721" alt="Screenshot 2024-10-08 at 5 17 55 PM" src="https://github.com/user-attachments/assets/9b946fc2-c7dd-43c6-98e7-4bf90864de01">



  **Board Plots:** Board Plots can be generated by using the board plot function provided in CRISPR-Millipede. Board Plots require the millipede table, presort, and wt editing frequencies which can be generated using the functions below.

  ```
  paired_merged_raw_encodings = cmm.RawEncodingDataframesExperimentalGroup().read_in_files_constructor(
      enriched_pop_fn_encodings_experiment_list = ["./encoding_dataframes_target_editor_encodings_rep{}.pkl"],
      baseline_pop_fn_encodings_experiment_list = ["./encoding_dataframes_baseline_editor_encodings_rep{}.pkl"],
      presort_pop_fn_encodings_experiment_list = ["./encoding_dataframes_presort_editor_encodings_rep{}.pkl"],
      experiment_labels = ["ABE8e"],
      ctrl_pop_fn_encodings="./encoding_dataframes_wt_editor_encodings_rep{}.pkl",
      ctrl_pop_labels="WT",
      reps = [0,1,2],
     )
  paired_merged_raw_encodings_editing_freqs.presort_pop_encoding_editing_per_variant_freq_avg[0].to_csv('presort_editing_freqs_avg_editor.csv')
  paired_merged_raw_encodings_editing_freqs.baseline_pop_encoding_editing_per_variant_freq_avg[0].to_csv('baseline_editing_freqs_avg_editor.csv')
  paired_merged_raw_encodings_editing_freqs.enriched_pop_encoding_editing_per_variant_freq_avg[0].to_csv('target_editing_freqs_avg_editor.csv')
  paired_merged_raw_encodings_editing_freqs.ctrl_pop_encoding_editing_per_variant_freq_avg[0].to_csv('wt_editing_freqs_avg_editor.csv')

  cmm.plot_millipede_boardplot(editorName (ABE8e or evoCDA), 'MillipedeOutput.csv', 'presort_editing_freqs_avg_editor.csv' , 'wt_editing_freqs_avg_editor.csv', start,end, AMPLICON, outputPath = "Boardplot.svg")

  ```
  <img width="668" alt="Screenshot 2024-10-09 at 2 37 18 PM" src="https://github.com/user-attachments/assets/a698298c-3d54-49b6-b94b-cdf3c6d329e4">


  The encoded representation of the alleles can also be fed into PyDESeq2, to calculate the differential distribution of each allele across the sorted populations. For documentation on PyDESeq2, see [here](https://pydeseq2.readthedocs.io/en/latest/index.html#).

  PyDESeq2 takes in a count and design matrix, along with several parameters:

  ```
  inference = DefaultInference(n_cpus=8)
  dds = DeseqDataSet(
      counts=count_df,
      metadata=metadata_df,
      design_factors="condition",
      refit_cooks=True,
      inference=inference,
      
  )
  ```
  **See [notebooks/STEP5_ABE8e_DESeq2_Demo.ipynb](https://github.com/pinellolab/CRISPR-millipede-target/blob/master/notebooks/STEP5_ABE8e_DESeq2_Demo.ipynb) for instructions on how to format the input matrices and run PyDESeq2.**

  After running pyDESeq2, we can visualize a volcano plot of the per-allele scores derived through the model:

  ```
  def contains_edit_special(edit, edit2):
      colors = []
      sizes = []

      subset_df = results_df.copy()

      for index, row in subset_df.iterrows():
          if len(set(edit).intersection(set(index.split(",")))) > 0:
              colors.append("#00AEEF")
              sizes.append(40)
          elif len(set(edit2).intersection(set(index.split(",")))) > 0:
              colors.append("#EC008C")
              sizes.append(40)
          else:
              colors.append("gray")
              sizes.append(40)
              subset_df.drop(index, inplace=True)

      
      plt.figure(figsize=(8, 5))

      
      plt.scatter(results_df['log2FoldChange'] * -1,
                  results_df['-10 * log(pvalue)'],
                  c=colors, s=sizes, alpha=0.3)

      
      plt.xscale('symlog', base=2)

      
      plt.xlabel("Log2 Fold Change [CD19+ vs CD19-]", fontsize=14)
      plt.ylabel("-10 * log10(pvalue)", fontsize=14)
      plt.title("Volcano Plot", fontsize=16)

      
      plt.xlim(-10, 10)

      
      plt.ylim(0, 30)
      ax = plt.gca()  # Get current axis
      ax.spines['top'].set_visible(False)
      ax.spines['right'].set_visible(False)

      
      plt.savefig("ABE8e_allelic_analysis_w_MillipedeHits.svg")

      
      plt.tight_layout()
      plt.show()

      
      display(subset_df)
  ```

  The parameters "edit1" and "edit2" can be used to selectively color alleles that exhibit certain sets of edits:

  ```
  contains_edit_special(["223A>G", "230A>G"], ["151A>G"])
  ```

  ![image](https://github.com/user-attachments/assets/32c9451a-bf65-45f4-bf2c-87317ef920fa)


pkgId: b06bfc55afcc0a89c4b61334221d417ea563c2be22390c6ce488390e1fc2cd93
name: python-crispy-bootstrap3
arch: src
version: 2024.1
epoch: 0
release: 1
summary: Bootstrap3 template pack for django-crispy-forms
url: https://github.com/django-crispy-forms/crispy-bootstrap3
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crispy-bootstrap3-2024.1-1.src.rpm
checksum_type: sha256
description:
  [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/django-crispy-forms/crispy-bootstrap3/blob/main/LICENSE)

  Bootstrap3 template pack for django-crispy-forms. This template pack was
  included with the core django-crispy-forms package until version 2.0.



  Install this plugin using `pip`:

  ```bash
      $ pip install crispy-bootstrap3
  ```



  You will need to update your project's settings file to add `crispy_forms`
  and `crispy_bootstrap3` to your projects `INSTALLED_APPS`. Also set
  `bootstrap3` as and allowed template pack and as the default template pack
  for your project:

  ```python
      INSTALLED_APPS = (
          ...
          "crispy_forms",
          "crispy_bootstrap3",
          ...
      )

      CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap3"

      CRISPY_TEMPLATE_PACK = "bootstrap3"
  ```


pkgId: bbf14d54693a412b8e23325a11f9cd97c88e8405c10b53f8aa4eed1ad46cbfc3
name: python-crispy-bootstrap4
arch: src
version: 2024.1
epoch: 0
release: 1
summary: Bootstrap4 template pack for django-crispy-forms
url: https://github.com/django-crispy-forms/crispy-bootstrap4
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crispy-bootstrap4-2024.1-1.src.rpm
checksum_type: sha256
description:
  [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/smithdc1/crispy-bootstrap4/blob/main/LICENSE)

  Bootstrap4 template pack for django-crispy-forms. This template pack was
  included with the core django-crispy-forms package until version 2.0.



  Install this plugin using `pip`:

  ```bash
      $ pip install crispy-bootstrap4
  ```



  You will need to update your project's settings file to add `crispy_forms`
  and `crispy_bootstrap4` to your projects `INSTALLED_APPS`. Also set
  `bootstrap4` as and allowed template pack and as the default template pack
  for your project:

  ```python
      INSTALLED_APPS = (
          ...
          "crispy_forms",
          "crispy_bootstrap4",
          ...
      )

      CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap4"

      CRISPY_TEMPLATE_PACK = "bootstrap4"
  ```


pkgId: 069b1d8f753ac54597b1b09aef454cd284b0dcb9d8f116e03d6a1d38e2fff984
name: python-crispy-bootstrap5
arch: src
version: 2024.10
epoch: 0
release: 1
summary: Bootstrap5 template pack for django-crispy-forms
url: https://github.com/django-crispy-forms/crispy-bootstrap5
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crispy-bootstrap5-2024.10-1.src.rpm
checksum_type: sha256
description:
  [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/smithdc1/crispy-bootstrap5/blob/main/LICENSE)

  Bootstrap5 template pack for django-crispy-forms



  Install this plugin using `pip`:
  ```bash
  $ pip install crispy-bootstrap5
  ```



  You will need to update your project's settings file to add ``crispy_forms``
  and ``crispy_bootstrap5`` to your projects ``INSTALLED_APPS``. Also set
  ``bootstrap5`` as and allowed template pack and as the default template pack
  for your project

  ```python
  INSTALLED_APPS = (
      ...
      "crispy_forms",
      "crispy_bootstrap5",
      ...
  )

  CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5"

  CRISPY_TEMPLATE_PACK = "bootstrap5"
  ```



  Bootstrap 5 introduces [floating labels](https://getbootstrap.com/docs/5.0/forms/floating-labels/).
  This template pack include a layout object to use this input type

  ```python
  from crispy_bootstrap5.bootstrap5 import FloatingField


  ... Layout(
      FloatingField("first_name"),
  )
  ```

  Accordions also have new features, such as [Accordion flush](https://getbootstrap.com/docs/5.0/components/accordion/#flush) and [Always open](https://getbootstrap.com/docs/5.0/components/accordion/#always-open).
  There is a new layout object to use them

  ```python
  from crispy_bootstrap5.bootstrap5 import BS5Accordion



  ... Layout(
      BS5Accordion(
          AccordionGroup("group name", "form_field_1", "form_field_2"),
          AccordionGroup("another group name", "form_field"),
          flush=True,
          always_open=True
      )
  )
  ```

  Support is added for [Switches](https://getbootstrap.com/docs/5.2/forms/checks-radios/#switches). Switches are a custom
  checkbox rendered as a toggle switch. The widget for these fields should be
  a [CheckboxInput](https://docs.djangoproject.com/en/4.2/ref/forms/widgets/#django.forms.CheckboxInput).

  ```python
  from crispy_bootstrap5.bootstrap5 import Switch

  ... Layout(Switch("is_company"))
  ```




  To contribute to this library, first checkout the code. Then create a new virtual environment:

  ```bash
  cd crispy-bootstrap5
  python -m venv venv
  source venv/bin/activate
  ```

  Or if you are using `pipenv`:
  ```bash
  pipenv shell
  ```

  Now install the dependencies and tests:
  ```bash
  pip install -e '.[test]'
  ```

  To run the tests:
  ```bash
  pytest
  ```


pkgId: 70bbbd30f42f208b9041f5d89a9cbdd7642510bb57e055f3016e358281fdbdd7
name: python-crispy-bootstrap5
arch: src
version: 2024.2
epoch: 0
release: 1
summary: Bootstrap5 template pack for django-crispy-forms
url: https://github.com/django-crispy-forms/crispy-bootstrap5
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crispy-bootstrap5-2024.2-1.src.rpm
checksum_type: sha256
description:
  [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/smithdc1/crispy-bootstrap5/blob/main/LICENSE)

  Bootstrap5 template pack for django-crispy-forms



  Install this plugin using `pip`:
  ```bash
  $ pip install crispy-bootstrap5
  ```



  You will need to update your project's settings file to add ``crispy_forms``
  and ``crispy_bootstrap5`` to your projects ``INSTALLED_APPS``. Also set
  ``bootstrap5`` as and allowed template pack and as the default template pack
  for your project

  ```python
  INSTALLED_APPS = (
      ...
      "crispy_forms",
      "crispy_bootstrap5",
      ...
  )

  CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5"

  CRISPY_TEMPLATE_PACK = "bootstrap5"
  ```



  Bootstrap 5 introduces [floating labels](https://getbootstrap.com/docs/5.0/forms/floating-labels/).
  This template pack include a layout object to use this input type

  ```python
  from crispy_bootstrap5.bootstrap5 import FloatingField


  ... Layout(
      FloatingField("first_name"),
  )
  ```

  Accordions also have new features, such as [Accordion flush](https://getbootstrap.com/docs/5.0/components/accordion/#flush) and [Always open](https://getbootstrap.com/docs/5.0/components/accordion/#always-open).
  There is a new layout object to use them

  ```python
  from crispy_bootstrap5.bootstrap5 import BS5Accordion



  ... Layout(
      BS5Accordion(
          AccordionGroup("group name", "form_field_1", "form_field_2"),
          AccordionGroup("another group name", "form_field"),
          flush=True,
          always_open=True
      )
  )
  ```

  Support is added for [Switches](https://getbootstrap.com/docs/5.2/forms/checks-radios/#switches). Switches are a custom
  checkbox rendered as a toggle switch. The widget for these fields should be
  a [CheckboxInput](https://docs.djangoproject.com/en/4.2/ref/forms/widgets/#django.forms.CheckboxInput).

  ```python
  from crispy_bootstrap5.bootstrap5 import Switch

  ... Layout(Switch("is_company"))
  ```




  To contribute to this library, first checkout the code. Then create a new virtual environment:

  ```bash
  cd crispy-bootstrap5
  python -mvenv venv
  source venv/bin/activate
  ```

  Or if you are using `pipenv`:
  ```bash
  pipenv shell
  ```

  Now install the dependencies and tests:
  ```bash
  pip install -e '.[test]'
  ```

  To run the tests:
  ```bash
  pytest
  ```


pkgId: 31964c569503dff35193114bbd564b86710f236461e15cb6bf7452ae053c9815
name: python-crispy-daisyui
arch: src
version: 0.7.0
epoch: 0
release: 1
summary: A DaisyUI package for Django Crispy Forms
url: https://github.com/fabge/crispy-daisyui
rpm_license: Apache-2.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crispy-daisyui-0.7.0-1.src.rpm
checksum_type: sha256
description:
  A [`daisyUI`](https://daisyui.com) template pack for the wonderful [django-crispy-forms](https://github.com/django-crispy-forms/django-crispy-forms).

  This repository is a fork of [`crispy-tailwind`](https://github.com/django-crispy-forms/crispy-tailwind) and has been modified just enough to suit my needs.
  It works well for the most common forms elements.



  Install via pip:

  ```bash
  pip install crispy-daisyui
  ```

  You will need to update your project's settings file to add ``crispy_forms``
  and ``crispy_daisyui`` to your project's ``INSTALLED_APPS`` setting. Also set
  ``daisyui`` as an allowed template pack and as the default template pack
  for your project:

  ```python
  INSTALLED_APPS = [
      
      'crispy_forms',
      'crispy_daisyui',
      
  ]

  CRISPY_ALLOWED_TEMPLATE_PACKS = 'daisyui'
  CRISPY_TEMPLATE_PACK = 'daisyui'
  ```



  Current functionality allows the ``|crispy`` filter to be used to style your
  form. In your template:

  1. Load the filter: ``{% load daisyui_filters %}``
  2. Apply the crispy filter: ``{{ form|crispy }}``

  We can also use the ``{% crispy %}`` tag to allow usage of crispy-forms'
  ``FormHelper`` and ``Layout``. In your template:

  1. Load the crispy tag: ``{% load crispy_forms_tags %}``
  2. Add ``FormHelper`` to your form and use crispy-forms to set-up your form
  3. Use the crispy tag ``{% crispy form %}`` in your template


pkgId: dbb38135bbed2027e3a915fd6ba8b84f0847c4395a42aa7aff2875ed5b157aee
name: python-crispy-forms-semantic-ui
arch: src
version: 0.2.0
epoch: 0
release: 1
summary: Semantic UI templates for django-crispy-forms.
url: https://github.com/acidjunk/crispy-forms-semanticUI-templates
rpm_license: GPLv3 License
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-crispy-forms-semantic-ui-0.2.0-1.src.rpm
checksum_type: sha256
description:
  crispy-forms-semantic-ui contains a set of templates that can be used to get
  semantic UI form layouts and error handling in [`django-crispy-forms`](https://github.com/maraujop/django-crispy-forms).
  Tested with Semantic-UI 2.2.4.


pkgId: 7c9e7ba9c18c71f42f2d1f05eb204fd0784f5c5e5667405799916a89918f245c
name: python-criteo-api-marketingsolutions-sdk
arch: src
version: 2024.10.0.241029
epoch: 0
release: 1
summary: Criteo API SDK
url: https://github.com/criteo/criteo-api-python-sdk
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-criteo-api-marketingsolutions-sdk-2024.10.0.241029-1.src.rpm
checksum_type: sha256
description:
  IMPORTANT: This Python package links to Criteo production environment. Any test applied here will thus impact real data.





  ```sh
  pip install criteo-api-marketingsolutions-sdk==2024.10.0.241029
  ```
  (you may need to run `pip` with root permission: `sudo pip install criteo-api-marketingsolutions-sdk==2024.10.0.241029`)

  Then import the package:
  ```python
  import criteo_api_marketingsolutions_v2024_10
  ```

  Full documentation on [Github](https://github.com/criteo/criteo-api-python-sdk).



  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: 02bdead611737b97a20cefeddbd2b16ab0493547d345804198bc60dbc50be001
name: python-criteo-api-marketingsolutions-sdk
arch: src
version: 2024.7.0.240808
epoch: 0
release: 1
summary: Criteo API SDK
url: https://github.com/criteo/criteo-api-python-sdk
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-criteo-api-marketingsolutions-sdk-2024.7.0.240808-1.src.rpm
checksum_type: sha256
description:
  IMPORTANT: This Python package links to Criteo production environment. Any test applied here will thus impact real data.





  ```sh
  pip install criteo-api-marketingsolutions-sdk==2024.07.0.240808
  ```
  (you may need to run `pip` with root permission: `sudo pip install criteo-api-marketingsolutions-sdk==2024.07.0.240808`)

  Then import the package:
  ```python
  import criteo_api_marketingsolutions_v2024_07
  ```

  Full documentation on [Github](https://github.com/criteo/criteo-api-python-sdk).



  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: 2e9b4143a9c570352b91744748ef42d974b291cdfcb8bf1629da1a8a08c80ac2
name: python-criteo-api-retailmedia-sdk
arch: src
version: 2024.10.0.241029
epoch: 0
release: 1
summary: Criteo API SDK
url: https://github.com/criteo/criteo-api-python-sdk
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-criteo-api-retailmedia-sdk-2024.10.0.241029-1.src.rpm
checksum_type: sha256
description:
  IMPORTANT: This Python package links to Criteo production environment. Any test applied here will thus impact real data.





  ```sh
  pip install criteo-api-retailmedia-sdk==2024.10.0.241029
  ```
  (you may need to run `pip` with root permission: `sudo pip install criteo-api-retailmedia-sdk==2024.10.0.241029`)

  Then import the package:
  ```python
  import criteo_api_retailmedia_v2024_10
  ```

  Full documentation on [Github](https://github.com/criteo/criteo-api-python-sdk).



  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: 74d2384e2db66aab4b90f9488b27ca75ca17ef37ff01c130949dcdebe1d9f6ce
name: python-criteo-api-retailmedia-sdk
arch: src
version: 2024.7.0.240808
epoch: 0
release: 1
summary: Criteo API SDK
url: https://github.com/criteo/criteo-api-python-sdk
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-criteo-api-retailmedia-sdk-2024.7.0.240808-1.src.rpm
checksum_type: sha256
description:
  IMPORTANT: This Python package links to Criteo production environment. Any test applied here will thus impact real data.





  ```sh
  pip install criteo-api-retailmedia-sdk==2024.07.0.240808
  ```
  (you may need to run `pip` with root permission: `sudo pip install criteo-api-retailmedia-sdk==2024.07.0.240808`)

  Then import the package:
  ```python
  import criteo_api_retailmedia_v2024_07
  ```

  Full documentation on [Github](https://github.com/criteo/criteo-api-python-sdk).



  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.


