# packages

pkgId: 2877bb10504e2bc35b6186f5260c7a39e794a21cecda6ab5a0d2c187d2cb388a
name: python-ciscopykit
arch: src
version: 2.3.2
epoch: 0
release: 1
url: https://github.com/Vincent-de-Torres-Portfolio/ciscopykit
rpm_license: MIT License
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ciscopykit-2.3.2-1.src.rpm
checksum_type: sha256
summary:
  A network management toolkit for Cisco devices keeping track of devices when using GNS3 / Cisco Packet Tracer

description:
  A network management toolkit for Cisco devices. It provides classes and methods to manage network devices, interfaces, and configurations.


pkgId: a8fff7492076fdea755320a099642126ac3581110b0f4c8dac722c76baaf2e25
name: python-cisort
arch: src
version: 1.1.15
epoch: 0
release: 1
summary: cpp include sort
url: https://pypi.org/project/cisort/
rpm_license: UNKNOWN
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-cisort-1.1.15-1.src.rpm
checksum_type: sha256
description:
  <img src="https://i.imgur.com/LsH6pj8.gif" alt="example" width="500"/>



  This is a tool that allows you to quickly and
  conveniently sort all libraries included in the project in
  alphabetical order.


  <img src="https://i.imgur.com/GLgtBDH.gif" alt="example" width="500"/>


  ```c++













  int main(){
  	std::cout << "Hello, World!" << std::endl;
  }
  ```

  ```c++













  int main(){
  	std::cout << "Hello, World!" << std::endl;
  }
  ```



  ```python
  pip install cisort
  ```


  ```cisort [flags] [path]```

  Flags:\
          `-r` `--recursive` - recursive searching C/C++ files\
          `-ls` - show info about sorted files\
          `-h` `--help` - to get help\
          `-c` `--comments` - add comments to sorted blocks\n'





  [VK][1], [Telegram][2], [Discord][3]

  [1]: https://vk.com/pavel.cmake
  [2]: https://t.me/pavel_cpp
  [3]: https://discordapp.com/users/427479608321900545/


pkgId: a20cfc314bfeb477587be9acc93ccf473496547042413666d28bd4d564c38c01
name: python-cit-pydata
arch: src
version: 0.0.1.dev5
epoch: 0
release: 1
url: https://github.com/EAB-IT-DEV/cit-pydata
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-cit-pydata-0.0.1.dev5-1.src.rpm
checksum_type: sha256
summary:
  Python clients for commonly used api services including Salesforce, SQL, Marketo, Box, SFSync*, and JobLog*

description:
  This repo provides Python clients for commonly used api services including Salesforce, SQL, Marketo, Box, SFSync*, and JobLog*.

  *SFSync = custom Salesforce <> MSQ SQL integration
  *JobLog = custom centralized logging for data integration jobs


pkgId: c7eafbf26f5ef0e1a7dcd1fc14119f8f9a423d2c0ff790930ecf419f5db88bee
name: python-citableclass
arch: src
version: 0.0.21
epoch: 0
release: 1
summary: Tool for data request to Edition Topoi
url: http://pypi.python.org/pypi/citableclass/
rpm_license: LICENSE.txt
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-citableclass-0.0.21-1.src.rpm
checksum_type: sha256
description:
  A tool to load all kind of resources
  The tool provides routines to request digital resources via DOI.


pkgId: 0d319d75805c6b89caa8f92e50ef6f984de1c927e1bd09fdf447c140b0723534
name: python-citation-crawler
arch: src
version: 2.10.3
epoch: 0
release: 1
summary: Asynchronous high-concurrency citation crawler, use with caution!
url: https://github.com/yindaheng98/citation-crawler
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-citation-crawler-2.10.3-1.src.rpm
checksum_type: sha256
description:
  Asynchronous high-concurrency citation crawler, use with caution!

  异步高并发引文数据爬虫，慎用

  Only support Semantic Scholar currently.

  目前支持从Semantic Scholar上爬references和citations

  Crawl papers based on BFS(Breath First Search) from the citation network and connect them into an undirected graph. Each edge is a paper, each node is an author.

  基于广度优先搜索爬引文数据并将其组织为无向图。图的节点是文章，边是引用关系

  Neo4J output compatible with [dblp-crawler](https://github.com/yindaheng98/dblp-crawler)

  Neo4J形式的输出和[dblp-crawler](https://github.com/yindaheng98/dblp-crawler)兼容，可以自动识别相同paper不产生重复节点，并可以匹配数据库中已记录的作者，从而为新加入数据库的paper连接作者

  ![](asserts/graph.png)



  ```sh
  pip install citation-crawler
  ```



  ```sh
  python -m citation_crawler -h
  usage: __main__.py [-h] [-y YEAR] [-l LIMIT] -k KEYWORD [-p PID] [-a AID] {networkx,neo4j} ...

  positional arguments:
    {networkx,neo4j}      sub-command help
      networkx            Write results to a json file.
      neo4j               Write result to neo4j database

  optional arguments:
    -h, --help            show this help message and exit
    -y YEAR, --year YEAR  Only crawl the paper after the specified year.
    -l LIMIT, --limit LIMIT
                          Limitation of BFS depth.
    -k KEYWORD, --keyword KEYWORD
                          Specify keyword rules.
    -p PID, --pid PID     Specified a list of paperId to start crawling.
    -a AID, --aid AID     Specified a list of authorId to start crawling.
  ```

  ```sh
  python -m citation_crawler networkx -h
  usage: __main__.py networkx [-h] --dest DEST

  optional arguments:
    -h, --help   show this help message and exit
    --dest DEST  Path to write results.
  ```

  ```sh
  python -m citation_crawler neo4j -h
  usage: __main__.py neo4j [-h] [--auth AUTH] --uri URI

  optional arguments:
    -h, --help           show this help message and exit
    --username USERNAME  Auth username to neo4j database.
    --password PASSWORD  Auth password to neo4j database.
    --uri URI            URI to neo4j database.
  ```



  * `CITATION_CRAWLER_MAX_CACHE_DAYS_AUTHORS`:
    * save cache for a paper authors page (to get authors of a published paper) for how many days
    * default: `-1` (cache forever, since authors of a paper are not likely to change)
  * `CITATION_CRAWLER_MAX_CACHE_DAYS_REFERENCES`:
    * save cache for a reference page (to get references of a published paper) for how many days
    * default: `-1` (cache forever, since references of a paper are not likely to change)
  * `CITATION_CRAWLER_MAX_CACHE_DAYS_CITATIONS`
    * save cache for a citation page (to get citations of a published paper) for how many days
    * default: `7` (citations of a paper may change frequently)
  * `CITATION_CRAWLER_MAX_CACHE_DAYS_PAPER`
    * save cache for a paper detail page (to get details of a paper) for how many days
    * default: `-1` (cache forever, since detailed information of a published paper are not likely to change)
  * `CITATION_CRAWLER_MAX_CACHE_DAYS_INIT_AUTHOR`
    * save cache for an author page (to init papers from specified author by `-a`) for how many days
    * default: `7` (author may publish frequently)
  * `HTTP_PROXY`
    * Set it `http://your_user:your_password@your_proxy_url:your_proxy_port` if you want to use proxy
  * `HTTP_TIMEOUT`
    * Timeout for each http request, in seconds
  * `HTTP_CONCORRENT`
    * Concurrent HTTP requests
    * default: `8`
  * `HTTP_HEADERS`
    * Headers for HTTP requests
    * default: `None`
  * `HTTP_SLEEP`
    * Sleep after request (in seconds)
    * default: `0`



  e.g. write to `summary.json`:

  ```sh
  python -m citation_crawler -k video -k edge -p 27d5dc70280c8628f181a7f8881912025f808256 -a 1681457 networkx --dest summary.json
  ```



  ```json
  {
    "nodes": {
      "<paperId of a paper in Semantic Scholar>": {
        "paperId": "<paperId of this paper in Semantic Scholar>",
        "dblp_key": "<dblp id of this paper>",
        "title": "<title of this paper>",
        "year": "int <publish year of this paper>",
        "doi": "<doi of this paper>",
        "authors": [
          {
            "authorId": "<authorId of this person in Semantic Scholar>",
            "name": "<name of this person>",
            "dblp_name": [
              "<disambiguation name of this person in dblp>",
              "<disambiguation name of this person in dblp>",
              "<disambiguation name of this person in dblp>",
              "......"
            ]
          },
          { ...... },
          { ...... },
          ......
        ]
      },
      "<paperId of a paper in Semantic Scholar>": { ...... },
      "<paperId of a paper in Semantic Scholar>": { ...... },
      ......
    },
    "edges": [
      [
          "<paperId of a paper in Semantic Scholar>",
          "<paperId of a reference in the above paper>"
      ],
      [ ...... ],
      [ ...... ],
      ......
    ]
  ```



  ```sh
  docker pull neo4j
  docker run --rm -it -p 7474:7474 -p 7687:7687 -v $(pwd)save/neo4j:/data -e NEO4J_AUTH=none neo4j
  ```

  e.g. write to `neo4j://localhost:7687`:

  ```sh
  python -m dblp_crawler -k video -k edge -p 27d5dc70280c8628f181a7f8881912025f808256 -a 1681457 neo4j --uri neo4j://localhost:7687
  ```



  Without index, NEO4J query will be very very slow. So before you start, you should add some index:

  ```cql
  CREATE TEXT INDEX publication_title_hash_text_index FOR (p:Publication) ON (p.title_hash);
  CREATE INDEX publication_title_hash_index FOR (p:Publication) ON (p.title_hash);
  CREATE INDEX publication_dblp_key_index FOR (p:Publication) ON (p.dblp_key);
  CREATE INDEX publication_paper_id_index FOR (p:Publication) ON (p.paperId);
  CREATE INDEX person_author_id_index FOR (p:Person) ON (p.authorId);
  CREATE INDEX person_dblp_pid_index FOR (p:Person) ON (p.dblp_pid);
  ```



  ```sh
  python -m dblp_crawler -k video -k edge -a "importlib.import_module('citation_crawler.init').papers_in_neo4j('neo4j://localhost:7687')" neo4j --uri neo4j://localhost:7687
  ```

  ```sh
  python -m dblp_crawler -k video -k edge -p "importlib.import_module('citation_crawler.init').authors_in_neo4j('neo4j://localhost:7687')" neo4j --uri neo4j://localhost:7687
  ```

  `importlib.import_module` is flexible, you can import your own variables through this.


pkgId: eb7a7dc4da24508691c4496ac0b664c48f5250a9fa7b0999c7a55313fd6070ba
name: python-citation-map
arch: src
version: 4.3
epoch: 0
release: 1
summary: A simple tool to generate your Google Scholar citation world map.
url: https://github.com/ChenLiu-1996/CitationMap
rpm_license: CC BY-NC-SA
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-citation-map-4.3-1.src.rpm
checksum_type: sha256
description:
      scholar_id: str
          Your Google Scholar ID.
      output_path: str
          (default is 'citation_map.html')
          The path to the output HTML file.
      csv_output_path: str
          (default is 'citation_info.csv')
          The path to the output csv file.
      cache_folder: str
          (default is 'cache')
          The folder to save intermediate results, after finding (author, paper) but before finding the affiliations.
          This is because the user might want to try the aggressive vs. conservative approach.
          Set to None if you do not want caching.
      affiliation_conservative: bool
          (default is False)
          If true, we will use a more conservative approach to identify affiliations.
          If false, we will use a more aggressive approach to identify affiliations.
      num_processes: int
          (default is 16)
          Number of processes for parallel processing.
      use_proxy: bool
          (default is False)
          If true, we will use a scholarly proxy.
          It is necessary for some environments to avoid blocks, but it usually makes things slower.
      pin_colorful: bool
          (default is True)
          If true, the location pins will have a variety of colors.
          Otherwise, it will only have one color.
      print_citing_affiliations: bool
          (default is True)
          If true, print the list of citing affiliations (affiliations of citing authors).
      ```

  1. This tool is purely based on Google Scholar. As a result, you are expected to have underestimations due to reasons such as:
      - Your Google Scholar profile is not up-to-date.
      - Some papers citing you are not indexed by Google Scholar.
      - Some authors citing you do not have Google Scholar profiles.
      - Some authors citing you do not report their affiliations.
  2. Webscraping is performed, and CAPTCHA or robot check can often get us, especially if we crawl frequently. This is more often seen in highly cited users. Unless you are blocked by Google Scholar, at worst you will end up with missing several citing authors, which is not likely a huge deal for highly cited users anyways.
  3. Affiliation identification and geolocating issues. This is a joint effect between affiliation identification and geolocating. The number of citing affiliations will be:
      - Underestimated if some affiliations are not found by `geopy.geocoders`.
      - Underestimated if we experience communication errors with `geopy.geocoders`.
      - (Aggressive approach only) Overestimated if non-affiliation phrases are incorrectly identified as locations by `geopy.geocoders`.
      - (Conservative approach only) Underestimated if the citer did not verify with an email address under a matching affiliation domain.
      - (Conservative approach only) Underestimated because all non-primary (with verified email address) affiliations are ignored.
      **Please raise an issue or submit a pull request if you have some good idea to better process the affiliation string. Note that currently I am not considering any paid service or tools that pose extra burden on the users, such as GPT API.**

  1. `MaxTriesExceededException` or `Exception: Failed to fetch the Google Scholar page` or (`[WARNING!] Blocked by CAPTCHA or robot check` for all entries).
      - From my experience, these are good indicators that your IP address is blocked by Google Scholar due to excessive crawling (using the `scholarly` package).
      - One hot fix I found was to hop on a University VPN and run again. I typically experience this error after running the tool twice, and I need to disconnect and reconnect my VPN to "unblock" myself.
      - In case this does not help, you can try to change IP adress and reduce the number of processes (e.g., setting `num_processes=1`).
      - If you get `[WARNING!] Blocked by CAPTCHA or robot check` no more than several times, it's not a big deal especially if you have many citing authors.
  2. `An attempt has been made to start a new process before the current process has finished its bootstrapping phase.`
      - I believe this is because you did not protect your main function with `if __name__ == '__main__'`. You can take a look at the recommended script again.
      - If this still does not help, you might want to write your script slightly differently. Credit to [dk-liang](https://github.com/dk-liang) in [Issue #4](https://github.com/ChenLiu-1996/CitationMap/issues/4#issuecomment-2257572672).
        ```
        from citation_map import generate_citation_map
        def main():
            
            scholar_id = '3rDjnykAAAAJ'
            generate_citation_map(scholar_id)
        if __name__ == '__main__':
            import multiprocessing
            multiprocessing.freeze_support()
            main()
        ```

  <details>
  <summary>Version 4.0 (Aug 2, 2024)</summary>
  <br>
  1. **Now you can trade off between precision and recall as we identify the affiliations.**
  2. Added caching before identifying the affiliations, since users might want to try both the conservative and aggressive approaches.
  3. Slight optimization in the affiliation to geocode stage by adding early breaking if successful.
  </details>
  <details>
  <summary>Version 3.11 (Jul 28, 2024)</summary>
  <br>
  **Additional output CSV that records citation information.**
  </details>
  <details>
  <summary>Version 3.10 (Jul 28, 2024)</summary>
  <br>
  In 3.10, I slightly improved the logic for affiliation extraction.
  In 3.8, I removed multiprocessing for `geopy.geocoders` as per their official documentation. Also I cleaned up some unnecessary `scholarly` calls which further helps us not get blacklisted by Google Scholar.
  In 3.7, I updated the logic for webscraping and avoided using `scholarly.citeby()` which is the biggest trigger of blacklisting from Google Scholar.
  **Now we should be able to handle users with more citations than before. I tested on a profile with 1000 citations without running into any issue.**
  </details>
  <details>
  <summary>Version 3.0 (Jul 27, 2024)</summary>
  <br>
  I realized a problem with how I used `geopy.geocoders`. A majority of the authors' affiliations include details that are irrelevant to the affiliation itself. Therefore, they are not successfully found in the system and hence are not converted to geographic coordinates on the world map.
  For example, we would want the substring "Yale University" from the string "Assistant Professor at Yale University".
  I applied a simple fix with some rule-based natural language processing. This helps us identify many missing citing locations.
  **Please raise an issue or submit a pull request if you have some good idea to better process the affiliation string. Note that currently I am not considering any paid service or tools that pose extra burden on the users, such as GPT API.**
  </details>
  <details>
  <summary>Version 2.0 (Jul 27, 2024)</summary>
  <br>
  I finally managed to **drastically speed up** the process using multiprocessing, in a way that avoids being blocked by Google Scholar.
  On my personal computer, processing my profile with 100 citations took 1 hour with version 1.0 while it's now taking 5 minutes with version 2.0.
  With that said, please be careful and do not run this tool frequently. I can easily get on Google Scholar's blacklist after a few runs.
  </details>
  <details>
  <summary>Version 1.0 (Jul 26, 2024)</summary>
  <br>
  Very basic functionality.
  This script is a bit slow. On my personal computer, it takes half a minute to process each citation. If you have thousands of citations, it may or may not be a good idea to use this script.
  I tried to use multiprocessing, but unfortunately the excessive visits get me blocked by Google Scholar.
  </details>

  Dependencies (`scholarly`, `geopy`, `folium`, `tqdm`, `requests`, `bs4`, `pycountry`, `pandas`) are already taken care of when you install via pip.

  This script was written under the assistance of ChatGPT-4o, but of course after intense debugging.


pkgId: 9bcd949913ce5986b17ed0057fb4690498c37670424fd8604ab35e6cf26c10d1
name: python-citation-map
arch: src
version: 4.5
epoch: 0
release: 1
summary: A simple tool to generate your Google Scholar citation world map.
url: https://github.com/ChenLiu-1996/CitationMap
rpm_license: CC BY-NC-SA
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-citation-map-4.5-1.src.rpm
checksum_type: sha256
description:
      scholar_id: str
          Your Google Scholar ID.
      output_path: str
          (default is 'citation_map.html')
          The path to the output HTML file.
      csv_output_path: str
          (default is 'citation_info.csv')
          The path to the output csv file.
      cache_folder: str
          (default is 'cache')
          The folder to save intermediate results, after finding (author, paper) but before finding the affiliations.
          This is because the user might want to try the aggressive vs. conservative approach.
          Set to None if you do not want caching.
      affiliation_conservative: bool
          (default is False)
          If true, we will use a more conservative approach to identify affiliations.
          If false, we will use a more aggressive approach to identify affiliations.
      num_processes: int
          (default is 16)
          Number of processes for parallel processing.
      use_proxy: bool
          (default is False)
          If true, we will use a scholarly proxy.
          It is necessary for some environments to avoid blocks, but it usually makes things slower.
      pin_colorful: bool
          (default is True)
          If true, the location pins will have a variety of colors.
          Otherwise, it will only have one color.
      print_citing_affiliations: bool
          (default is True)
          If true, print the list of citing affiliations (affiliations of citing authors).
      ```

  1. This tool is purely based on Google Scholar. As a result, you are expected to have underestimations due to reasons such as:
      - Your Google Scholar profile is not up-to-date.
      - Some papers citing you are not indexed by Google Scholar.
      - Some authors citing you do not have Google Scholar profiles.
      - Some authors citing you do not report their affiliations.
  2. Webscraping is performed, and CAPTCHA or robot check can often get us, especially if we crawl frequently. This is more often seen in highly cited users. Unless you are blocked by Google Scholar, at worst you will end up with missing several citing authors, which is not likely a huge deal for highly cited users anyways.
  3. Affiliation identification and geolocating issues. This is a joint effect between affiliation identification and geolocating. The number of citing affiliations will be:
      - Underestimated if some affiliations are not found by `geopy.geocoders`.
      - Underestimated if we experience communication errors with `geopy.geocoders`.
      - (Aggressive approach only) Overestimated if non-affiliation phrases are incorrectly identified as locations by `geopy.geocoders`.
      - (Conservative approach only) Underestimated if the citer did not verify with an email address under a matching affiliation domain.
      - (Conservative approach only) Underestimated because all non-primary (with verified email address) affiliations are ignored.
      **Please raise an issue or submit a pull request if you have some good idea to better process the affiliation string. Note that currently I am not considering any paid service or tools that pose extra burden on the users, such as GPT API.**

  1. `MaxTriesExceededException` or `Exception: Failed to fetch the Google Scholar page` or (`[WARNING!] Blocked by CAPTCHA or robot check` for all entries).
      - From my experience, these are good indicators that your IP address is blocked by Google Scholar due to excessive crawling (using the `scholarly` package).
      - One hot fix I found was to hop on a University VPN and run again. I typically experience this error after running the tool twice, and I need to disconnect and reconnect my VPN to "unblock" myself.
      - In case this does not help, you can try to change IP adress and reduce the number of processes (e.g., setting `num_processes=1`).
      - If you get `[WARNING!] Blocked by CAPTCHA or robot check` no more than several times, it's not a big deal especially if you have many citing authors.
  2. `An attempt has been made to start a new process before the current process has finished its bootstrapping phase.`
      - I believe this is because you did not protect your main function with `if __name__ == '__main__'`. You can take a look at the recommended script again.
      - If this still does not help, you might want to write your script slightly differently. Credit to [dk-liang](https://github.com/dk-liang) in [Issue #4](https://github.com/ChenLiu-1996/CitationMap/issues/4#issuecomment-2257572672).
        ```
        from citation_map import generate_citation_map
        def main():
            
            scholar_id = '3rDjnykAAAAJ'
            generate_citation_map(scholar_id)
        if __name__ == '__main__':
            import multiprocessing
            multiprocessing.freeze_support()
            main()
        ```

  <details>
  <summary>Version 4.5 (Dec 6, 2024)</summary>
  <br>
  1. **Support manual edit of the csv.** Note you do need to manually correct the coordinates too if you choose to use this functionality. You can run `generate_citation_map` first, and get the csv and HTML. Then, you can manually modify the csv content, and generate an updated HTML by running `generate_citation_map` again with `parse_csv=True`.
  2. Slight optimization on caching.
  </details>
  <details>
  <summary>Version 4.0 (Aug 2, 2024)</summary>
  <br>
  1. **Now you can trade off between precision and recall as we identify the affiliations.**
  2. Added caching before identifying the affiliations, since users might want to try both the conservative and aggressive approaches.
  3. Slight optimization in the affiliation to geocode stage by adding early breaking if successful.
  </details>
  <details>
  <summary>Version 3.11 (Jul 28, 2024)</summary>
  <br>
  **Additional output CSV that records citation information.**
  </details>
  <details>
  <summary>Version 3.10 (Jul 28, 2024)</summary>
  <br>
  In 3.10, I slightly improved the logic for affiliation extraction.
  In 3.8, I removed multiprocessing for `geopy.geocoders` as per their official documentation. Also I cleaned up some unnecessary `scholarly` calls which further helps us not get blacklisted by Google Scholar.
  In 3.7, I updated the logic for webscraping and avoided using `scholarly.citeby()` which is the biggest trigger of blacklisting from Google Scholar.
  **Now we should be able to handle users with more citations than before. I tested on a profile with 1000 citations without running into any issue.**
  </details>
  <details>
  <summary>Version 3.0 (Jul 27, 2024)</summary>
  <br>
  I realized a problem with how I used `geopy.geocoders`. A majority of the authors' affiliations include details that are irrelevant to the affiliation itself. Therefore, they are not successfully found in the system and hence are not converted to geographic coordinates on the world map.
  For example, we would want the substring "Yale University" from the string "Assistant Professor at Yale University".
  I applied a simple fix with some rule-based natural language processing. This helps us identify many missing citing locations.
  **Please raise an issue or submit a pull request if you have some good idea to better process the affiliation string. Note that currently I am not considering any paid service or tools that pose extra burden on the users, such as GPT API.**
  </details>
  <details>
  <summary>Version 2.0 (Jul 27, 2024)</summary>
  <br>
  I finally managed to **drastically speed up** the process using multiprocessing, in a way that avoids being blocked by Google Scholar.
  On my personal computer, processing my profile with 100 citations took 1 hour with version 1.0 while it's now taking 5 minutes with version 2.0.
  With that said, please be careful and do not run this tool frequently. I can easily get on Google Scholar's blacklist after a few runs.
  </details>
  <details>
  <summary>Version 1.0 (Jul 26, 2024)</summary>
  <br>
  Very basic functionality.
  This script is a bit slow. On my personal computer, it takes half a minute to process each citation. If you have thousands of citations, it may or may not be a good idea to use this script.
  I tried to use multiprocessing, but unfortunately the excessive visits get me blocked by Google Scholar.
  </details>

  Dependencies (`scholarly`, `geopy`, `folium`, `tqdm`, `requests`, `bs4`, `pycountry`, `pandas`) are already taken care of when you install via pip.

  This script was written under the assistance of ChatGPT-4o, but of course after intense debugging.


pkgId: 38aa768985d8f15816c0eca740754db4d2f7b0065caa7ff80cb997dcf1c7729c
name: python-citation-rabbot
arch: src
version: 3.19.7
epoch: 0
release: 1
summary: A telegram bot jumping in your citation database like a rabbit!
url: https://github.com/yindaheng98/citation-rabbot
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-citation-rabbot-3.19.7-1.src.rpm
checksum_type: sha256
description:
  A telegram bot jumping in your citation database like a rabbit!



  fulltext index for title and abstract is necessary for `/search_by_abstract`:

  ```cql
  CREATE FULLTEXT INDEX publication_title_fulltext_index FOR (p:Publication) ON EACH [p.title];
  CREATE FULLTEXT INDEX publication_abstract_fulltext_index FOR (p:Publication) ON EACH [p.abstract];
  ```

  For faster search, you can add text index for title:

  ```cql
  CREATE TEXT INDEX publication_title_hash_text_index FOR (p:Publication) ON (p.title_hash);
  ```


pkgId: 23daea60495f9a7421e7bdc3b00138e81cb2f3515f5d1f0631dbe9b5a0058067
name: python-citerate
arch: src
version: 0.1.1
epoch: 0
release: 1
url: https://github.com/markmelnic/citerate
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-citerate-0.1.1-1.src.rpm
checksum_type: sha256
summary:
  Python bi-dimensional matrix iterator starting from any point (x, y) iterating layer by layer around some starting coordinates.

description:
  Python bi-dimensional matrix iterator starting from any point (x, y) iterating layer by layer around some starting coordinates.



      pip install citerate

  As of __14 july 2021__ it contains one method `citerator`

      from citerate import citerator



  Using the example data set:

      DATA = [
          [10, 11, 12, 13, 14],
          [25, 2,  3,  4,  15],
          [24, 9,  1,  5,  16],
          [23, 8,  7,  6,  17],
          [22, 21, 20, 19, 18],
      ]

  Iterate over the set layer by layer starting from coordinates (x=2, y=2) and print each layer as a list of it's corresponding values.

      for layer in citerator(DATA, x=2, y=2, layer=True):
          print(layer)

  Yields:

      [1]
      [2, 3, 4, 5, 6, 7, 8, 9]
      [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]


  Iterate over the set value by value starting from coordinates (x=2, y=2) and print each value individually.

      for value in citerator(DATA, x=2, y=2):
          print(value, end=' ')

  Yields:

      1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25



  - It is NOT mandatory to iterate starting from the central coordinates or for the matrix to be uniform.
  - It HAS to be bi-dimenstional and follow a "list of lists" pattern.


pkgId: c7356f92b15338c7b9d04a5fcd7ffe1e6d0431311421d5ac561e4fcadd0cf03a
name: python-citlalicue
arch: src
version: 0.7.1
epoch: 0
release: 1
summary: Create stellar light curves!
url: https://github.com/oscaribv/citlalicue
rpm_license: GNU General Public License v3 (GPLv3)
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-citlalicue-0.7.1-1.src.rpm
checksum_type: sha256
description:
  *_Citlalicue_* is the name of the Aztec Goddess who created the stars.
  This code allows you to mimic Citlalicue powers to create and manipulate stellar light curves.

  The actual version of the code allows you to create synthetic stellar light curves (transits, stellar variability and white noise)
  and detrend light curves using Gaussian Processes (GPs).



  * Numpy
  * Matplotlib
  * Scipy
  * [PyTransit](https://github.com/hpparvi/PyTransit)
  * [george](https://github.com/dfm/george)




  Install it by typing

  ```
  pip install citlalicue
  ```



  Transits are implemented using [PyTransit](https://github.com/hpparvi/PyTransit),
  while the stellar variability is added from samples of a Quasi-Periodic Kernel with covariance given by

  <a href="https://www.codecogs.com/eqnedit.php?latex=\gamma(t_i,t_j)&space;=&space;A&space;\exp&space;\left[&space;-&space;\frac{\sin^2[\pi(t_i&space;-&space;t_j)/P_{\rm&space;GP}]}{2&space;\lambda_{\rm&space;P}^2}&space;-&space;\frac{(t_i&space;-&space;t_j)^2}{2\lambda_{\rm&space;e}^2}&space;\right]" target="_blank"><img src="https://latex.codecogs.com/gif.latex?\gamma(t_i,t_j)&space;=&space;A&space;\exp&space;\left[&space;-&space;\frac{\sin^2[\pi(t_i&space;-&space;t_j)/P_{\rm&space;GP}]}{2&space;\lambda_{\rm&space;P}^2}&space;-&space;\frac{(t_i&space;-&space;t_j)^2}{2\lambda_{\rm&space;e}^2}&space;\right]" title="\gamma(t_i,t_j) = A \exp \left[ - \frac{\sin^2[\pi(t_i - t_j)/P_{\rm GP}]}{2 \lambda_{\rm P}^2} - \frac{(t_i - t_j)^2}{2\lambda_{\rm e}^2} \right]" /></a>

  Check the example of how to use Citlalicue to create light curves in the link
  [example_light_curves.ipynb](https://github.com/oscaribv/citlalicue/blob/master/example_light_curves.ipynb).



  Check the example of how to use Citlalicue to detrend light curves in the link
  [example_detrending.ipynb](https://github.com/oscaribv/citlalicue/blob/master/example_detrending.ipynb).


pkgId: 221e107f3715a0d4610513b3bca244e3e9b1c50d99aa1b3c03fd638ea5f5b581
name: python-citrine
arch: src
version: 3.11.0
epoch: 0
release: 1
summary: Python library for the Citrine Platform
url: http://github.com/CitrineInformatics/citrine-python
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-citrine-3.11.0-1.src.rpm
checksum_type: sha256
description:
  `citrine-python` is the Python library for the Citrine Platform. To get started, install `citrine-python`:

  ```bash
  pip install citrine
  ```

  Detailed instructions on installation and usage can be found in the complete [citrine-python docs](https://citrineinformatics.github.io/citrine-python/index.html)



  To find detailed contributing guidelines, please see the [contributing documentation](https://github.com/CitrineInformatics/citrine-python/blob/main/CONTRIBUTING.md).

  _Copyright 2022 Citrine Informatics_


pkgId: 82598277970cf205c6feecab00ecab9abaa61fecb7195962b68ee20d800db09a
name: python-citros
arch: src
version: 0.2.64
epoch: 0
release: 1
summary: A cli entrypoint for the citros system.
url: https://citros.io
rpm_license: LICENSE
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-citros-0.2.64-1.src.rpm
checksum_type: sha256
description:
  analyze the ROS2 project and initialize the .citros folder with all the files needed to operate citros
  ```bash
  citros init
      [-d | --destination] <repository folder>
  ```

  checks for problems in .citros folder and suggests fixes
  ```bash
  citros doctor
      [-d | --destination] <repository folder>
  ```

  starts a simulation locally or on remote
  ```bash
  citros run
      [-gh | --github] #iniate an action that will runs the simulation on github as a workflow.
      [-c] #completions
      [-o] #destination folder defaults to .citros/runs
      [-D] #dockerized - we will run dockerzed version of the simulation (can run parallel simulations on the same machine)
      [-p] #parallelism ? do we need it or can we know how many cpu available and devide it by the requested number of cpus per cpu 8 (available cpu) / 2 (requested cpu) = 4 (number of parallel runs)
      [-r] #remote run
      [-s] #simulation name
      [-t] #time limit
      [-v] #verbose
      [-w] #workflow
  ```

  all batch operations
  ```python

  citros batch get <id>

  citros batch list

  citros batch delete <id> | <simulation>/<name>
  ```

  This DB will be used wo store the indexed bags for the
  ```bash

  citros data access
      [-p] #port
      [-v] #verbose
      [-D] #dockerized

  citros data status


  citros data create
      [-n] #name of the DB
      [-p] #port of the DB
      [-u] #user of the DB
      [-P] #password of the DB
      [-v] #verbose
      [-D] #dockerized

  citros data clean
      [-d] #days
      [-h] #hours
      [-m] #minutes
      [-v] #verbose
      [-D] #dockerized
  ```
  <details>
  <summary>REST API details</summary>
  The user can check the availability of the data in a rest api that will be created by the service.

  GET http://{domain}:{port}/{batch run name}
  ```json
  {
      "status": "unloaded",
      "last access": "2020-01-01 00:00:00",
  }
  ```

  POST http://{domain}:{port}/{batch run name}
  ```json
  {
      "status": "loading",
      "last access": "2020-01-01 00:00:00",
  }
  ```
  </details>

  A report is a signed set of generated notebooks with batch run data.
  this report can be shared trough CITROR or sent as a file.
  ```bash

  citros report generate notebook.ipynb simulation/batch_run_name

  citros report generator report_name
  ```

  start a node that will measue system / ros metrics and publish all to a topic
  ```bash
  citros observability
      [-c] #channel
      [-t] #topic
      [-v] #verbose
  ```


pkgId: fe1a5f1788a99ac243eef99bf1d907c460a24dd3fc6bc1f1940ae09e76283fd0
name: python-citrusdb
arch: src
version: 0.6.9
epoch: 0
release: 1
summary: open-source vector database. store and retrieve embeddings for your next ai project!
url: https://github.com/0xDebabrata/citrus
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-citrusdb-0.6.9-1.src.rpm
checksum_type: sha256
description:
  ```bash
  pip install citrusdb
  ```




  ```py
  import citrusdb


  citrus = citrusdb.Client()


  citrus.create_index(
    name="example",
    max_elements=1000,            # increases dynamically as you insert more vectors
  )
  ```


  ```py
  ids = [1, 2, 3]
  documents = [
    "Your time is limited, so don't waste it living someone else's life",
    "I'd rather be optimistic and wrong than pessimistic and right.",
    "Running a start-up is like chewing glass and staring into the abyss."
  ]

  citrus.add(index="example", ids=ids, documents=documents)
  ```
  You can directly pass vector embeddings as well. If you're passing a list of strings like we have done here, ensure you have your `OPENAI_API_KEY` in the environment. By default we use OpenAI to to generate the embeddings. Please reach out if you're looking for support from a different provider!


  ```py
  results = citrus.query(
      index="example",
      documents=["What is it like to launch a startup"],
      k=1,
      include=["document", "metadata"]
  )

  print(results)
  ```
  You can specify if you want the associated text document and metadata to be returned.
  By default, only the IDs are returned.

  Go launch a repl on [Replit](https://replit.com) and see what result you get after running the query! `result` will contain the `ids` of the top `k` search hits.


  [chat w/ replit ai podcast](https://replit.searchcitrus.com)

  [pokedex search](https://replit.com/@debabratajr/pokedex-search)


  Feel free to open issues on this repository! Discord server coming soon!

  *PS: citrus isn't fully distributed just yet. We're getting there though ;)*


pkgId: 7490d565e254498f19951a7631b3e8e8c754bd0400852a154b1071736dc3853f
name: python-city-scrapers-core
arch: src
version: 0.10.1
epoch: 0
release: 1
summary: Core functionality for City Scrapers projects
url: https://github.com/City-Bureau/city-scrapers-core
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-city-scrapers-core-0.10.1-1.src.rpm
checksum_type: sha256
description:
  [![Build status](https://github.com/City-Bureau/city-scrapers-core/workflows/CI/badge.svg)](https://github.com/City-Bureau/city-scrapers-core/actions)
  [![Documentation Status](https://readthedocs.org/projects/city-scrapers-core/badge/?version=latest)](https://city-scrapers-core.readthedocs.io/en/latest/?badge=latest)
  [![pypi](https://img.shields.io/pypi/v/city-scrapers-core)](https://pypi.org/project/city-scrapers-core/)

  Core functionality for creating public meetings web scrapers for the [City Scrapers](https://cityscrapers.org/) project.

  See the [documentation](https://city-scrapers-core.readthedocs.io/) for more details.



  ```bash

  pip install city-scrapers-core

  pip install 'city-scrapers-core[aws]'
  pip install 'city-scrapers-core[azure]'
  pip install 'city-scrapers-core[gcs]'
  ```


pkgId: 95c47af660f61b380b495ce25db44acf3874de914238533a6559f2a65d286601
name: python-cityblocks
arch: src
version: 0.0.2
epoch: 0
release: 1
summary: Python workflow to generate LCZ tiles for rendering in 3D in QGIS
url: https://pypi.org/project/cityblocks/
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-cityblocks-0.0.2-1.src.rpm
checksum_type: sha256
description:
  Python utility to:

  - Download global LCZ map from [Demuzere et al.](https://zenodo.org/records/7670653).
  - Extract an area of interest
  - Generate a new dataset where each pixel is replaced by a 2D tile corresponding to the LCZ type

  The generated file can be displayed in QGIS to create stunning visualizations in 3D.



  ```sh

  pip install git+https://github.com/Urban-M4/cityblocks.git


  cityblocks download


  cityblocks extract "4.724808,52.273620,5.182114,52.458729"


  cityblocks convert
  ```

  Data is downloaded in folder where the command is executed.



  Then, import the dataset in QGIS and visualize it. We created a QGIS styling file [cityblocks_LCZ.qml](qgis_files/cityblocks_LCZ.qml), which you can load as follows:

  1. Load layer in [QGIS](https://qgis.org/) (we used 3.34.8 LTR)
  ![Load layer in QGIS](images/1.png)

  2. Go to properties:
  ![Go to properties](images/2.png)

  3. Load Style from [cityblocks_LCZ.qml](\qgis_files\cityblocks_LCZ.qml)
  ![Load style](images/3.png)

  4. You can modify the style as you like
  ![modify the style](images/4.png)

  5. Create a 3D map view
  ![Create a 3D map view](images/5.png)

  6. Browse through you Local Climate Zones Cityblocks!
  ![Go to properties](images/6.png)

  Note that you can add styled 2D layers in your QGIS environment to show them in your 3D render.




  The file generated by the cityblocks command line utility looks like this when imported in QGIS.

  ![2d version of LCZ tiles](images/Amsterdam_2D.png)

  By extruding the surface and applying a bit of styling, we can generate images like below:

  ![3d version of LCZ tiles](images/Amsterdam_3D.png)

  The tiles can also be combined with other map layers:

  ![3d tiles with background image](images/Amsterdam_3D_bg.png)


pkgId: d0712500b3a73a9646f1faa507be560dc74f7056498553feb763a1502771aca0
name: python-citybrain-platform
arch: src
version: 0.4.3
epoch: 0
release: 1
summary: This library provides convenient access to the Citybrain Platform API
url: https://github.com/citybrain-platform/python-library
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-citybrain-platform-0.4.3-1.src.rpm
checksum_type: sha256
description:
  The Citybrain Platform Python Library provides convenient access to the Citybrain Platform API from applications written in the Python language.



  If you just want to use the package, just run:

  ```sh
  pip install --upgrade citybrain-platform
  ```



  The library needs to be configured with your account's secret key which is available on [www.citybrain.org](https://www.citybrain.org/#/settings). Either set it as the `CITYBRAIN_APIKEY` environment variable before using the library:

  ```sh
  export CITYBRAIN_APIKEY='...'
  ```

  Or set `citybrain_platform.api_key` to its value:

  ```python
  import citybrain_platform

  citybrain_platform.api_key = "..."
  ```



  Examples of how to use this Python library to accomplish various tasks.





  ```python
  import citybrain_platform

  res = citybrain_platform.Storage.upload_file(remote_path="test/test/test.file", local_file="test.localfile")
  print(res)
  ```



  ```python
  import citybrain_platform

  citybrain_platform.Storage.download_file(remote_path="test/test/test.file", local_file="test.localfile")
  ```



  ```python
  import citybrain_platform

  res = citybrain_platform.Storage.delete_file(remote_path="test/test/test.file")
  print(res)
  ```



  ```python
  import citybrain_platform

  res = citybrain_platform.Storage.list_files(prefix="testprefix", direct_only=False)
  print(res)
  ```





  ```python
  result = citybrain_platform.Computing.create_function(
      name="test_udf", # function name
      class_file="testudf.py", # the file where the class is located
      class_name="TestUDF2", # class name
      comment="test function",
      resources=["testudf.py", "other.py"] # resources used by this function
  )
  print(result)
  ```



  ```python
  from citybrain_platform import ResourceType

  result = citybrain_platform.Computing.create_resource(
      name="testudf.py", # resource name, must contain extension
      type=ResourceType.PY, # resource type
      comment="test resource",
      local_file="udf.py" # local resource file
  )
  print(result)
  ```





  ```python
  import citybrain_platform
  from citybrain_platform.computing.data_types import Column, ColumnType

  columns = [
      Column("col_str", ColumnType.STRING, "this is a comment"),
      Column("col_id", ColumnType.BIGINT),
  ]

  partition_columns = [
      Column("col_pt", ColumnType.INT, "a column for partitioning")
  ]

  ok = citybrain_platform.Computing.create_table(
      name="test_tbl",
      columns=columns,
      partition_columns=partition_columns,

      
      
      
  )
  print(ok)
  ```



  ```python
  import citybrain_platform

  schema = citybrain_platform.Computing.get_table_schema(name="test_tbl")
  print(schema)
  ```



  ```python
  import citybrain_platform

  result = citybrain_platform.Computing.upload_table_data(name="test_tbl", append=True, csv_filepath="aa.csv", partition_key={"col_pt": "19"})
  print(result)
  ```



  ```python
  import citybrain_platform

  result = citybrain_platform.Computing.truncate_table(name="test_tbl", partition_key={"col_pt": "19"})
  print(result)
  ```



  ```python
  import citybrain_platform

  result = citybrain_platform.Computing.drop_table(name="test_tbl")
  print(result)
  ```



  ```python
  import citybrain_platform

  public_table_name = citybrain_platform.Computing.update_table_status(name="test_tbl", public=False)
  print(public_table_name)
  ```



  ```python
  import citybrain_platform

  tables = citybrain_platform.Computing.list_tables()
  print(tables)
  ```





  ```python
  import citybrain_platform

  job_id = citybrain_platform.Computing.create_job(sql="select col_str from test_tbl limit 12;")
  print(job_id)
  ```



  ```python
  import citybrain_platform

  job_status = citybrain_platform.Computing.get_job_status(job_id="...")
  print(job_status)
  ```



  ```python
  import citybrain_platform

  result = citybrain_platform.Computing.stop_job(job_id="...")
  print(result)
  ```




  ```python
  import citybrain_platform

  citybrain_platform.Computing.get_job_results(job_id="...", filepath="results.csv")
  ```





  ```python
  import citybrain_platform

  citybrain_platform.Data.add_storage(name="", description="", file_path="")
  ```



  ```python
  import citybrain_platform

  citybrain_platform.Data.add_remote(name="", description="", remote_url="")
  ```



  ```python
  import citybrain_platform

  citybrain_platform.Data.download(data_address="...", save_file="test.txt")
  ```


pkgId: 700fac64a968586b8bdf4d5c86cdc3f64c5c4d9f0c1b0c87a518cd57c7465edc
name: python-cityenergyanalyst
arch: src
version: 3.11.0
epoch: 0
release: 1
summary: City Energy Analyst
url: http://cityenergyanalyst.com
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-cityenergyanalyst-3.11.0-1.src.rpm
checksum_type: sha256
description:
  The  `City Energy Analyst (CEA) <https://www.cityenergyanalyst.com/>`_ is an urban energy simulation platform and one
  of the first open-source computational tools for the design of low-carbon and highly efficient neighborhoods and districts
  The CEA combines knowledge of urban planning and energy systems engineering in an integrated framework. This
  allows to study the effects, trade-offs and synergies of urban design options, building retrofits and energy infrastructure plans.
  * Click `here <https://city-energy-analyst.readthedocs.io/en/latest/index.html>`__  for installation manual and tutorials
  * Click `here <https://github.com/architecture-building-systems/CityEnergyAnalyst/issues>`__ to report an issue
  * Click `here <mailto:cea@arch.ethz.ch>`__ to contact us
                 tutorials nor advice on how to use this interface. You could still use this interface at your own risk.
                 We invite all CEA users to get acquainted with the CEA Dashboard. The CEA dashboard is our new 100% open source user interface.
                 We will aim to create a first tutorial on how to use this interface by mid-april of 2019.


pkgId: 2c870ba10bd3b60fc7473d53adf37c9a545c200de3cf05eeff70872cbf7b4ca5
name: python-cityhash
arch: src
version: 0.4.7
epoch: 0
release: 1
summary: Python bindings for CityHash and FarmHash
url: https://github.com/escherba/python-cityhash
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-cityhash-0.4.7-1.src.rpm
checksum_type: sha256
description:
  Python wrapper for [FarmHash](https://github.com/google/farmhash) and
  [CityHash](https://github.com/google/cityhash), a family of fast
  non-cryptographic hash functions.

  [![Build Status](https://img.shields.io/github/actions/workflow/status/escherba/python-cityhash/build.yml?branch=master)](https://github.com/escherba/python-cityhash/actions/workflows/build.yml)
  [![PyPI Version](https://img.shields.io/pypi/v/cityhash.svg)](https://pypi.python.org/pypi/cityhash)
  [![Conda-Forge Version](https://anaconda.org/conda-forge/python-cityhash/badges/version.svg)](https://anaconda.org/conda-forge/python-cityhash)
  [![Downloads](https://img.shields.io/pypi/dm/cityhash.svg)](https://pypistats.org/packages/cityhash)
  [![License](https://img.shields.io/pypi/l/cityhash.svg)](https://opensource.org/licenses/mit-license)
  [![Supported Python Versions](https://img.shields.io/pypi/pyversions/cityhash.svg)](https://pypi.python.org/pypi/cityhash)



  To install from PyPI:

  ``` bash
  pip install cityhash
  ```

  To install in a Conda environment:

  ``` bash
  conda install -c conda-forge python-cityhash
  ```

  The package exposes Python APIs for CityHash and FarmHash under `cityhash` and
  `farmhash` namespaces, respectively. Each provides 32-, 64- and 128-bit
  implementations.





  Usage example for FarmHash:

  ``` python
  >>> from farmhash import FarmHash32, FarmHash64, FarmHash128
  >>> FarmHash32("abc")
  1961358185
  >>> FarmHash64("abc")
  2640714258260161385
  >>> FarmHash128("abc")
  76434233956484675513733017140465933893

  ```



  Fingerprints are seedless hashes that are guaranteed to be hardware- and
  platform-independent. This can be useful for networking applications which
  require persisting hashed values.

  ``` python
  >>> from farmhash import Fingerprint128
  >>> Fingerprint128("abc")
  76434233956484675513733017140465933893

  ```



  CityHash and FarmHash do not support incremental hashing and thus are not ideal
  for hashing of character streams. If you require incremental hashing, consider
  another hashing library, such as
  [MetroHash](https://github.com/escherba/python-metrohash) or
  [xxHash](https://github.com/ifduyue/python-xxhash).



  The [Buffer Protocol](https://docs.python.org/3/c-api/buffer.html) allows
  Python objects to expose their data as raw byte arrays for fast access without
  having to copy to a separate location in memory. NumPy is one well-known
  library that extensively uses this protocol.

  All hashing functions in this package will read byte arrays from objects that
  expose them via the buffer protocol. Here is an example showing hashing of a
  four-dimensional NumPy array:

  ``` python
  >>> import numpy as np
  >>> from farmhash import FarmHash64
  >>> arr = np.zeros((256, 256, 4))
  >>> FarmHash64(arr)
  1550282412043536862

  ```

  The NumPy arrays need to be contiguous for this to work. To convert a
  non-contiguous array, use NumPy's `ascontiguousarray()` function.



  For x86-64 platforms, the PyPI repository for this package includes wheels
  compiled with SSE4.2 support.  The 32- and 64-bit (but not the 128-bit)
  variants of FarmHash significantly benefit from SSE4.2 instructions.

  The vanilla CityHash functions (under `cityhash` module) do not take advantage
  of SSE4.2. Instead, one can use the `cityhashcrc` module provided with this
  package which exposes 128- and 256-bit CRC functions that do harness SSE4.2.
  These functions are very fast, and beat `FarmHash128` on speed (FarmHash does
  not include a 256-bit function). Since FarmHash is the intended successor of
  CityHash, I would be careful before using the CityHash-CRC functions, however,
  and would verify whether they provide sufficient randomness for your intended
  application.





  For those wanting to contribute, here is a quick start using Make commands:

  ``` bash
  git clone https://github.com/escherba/python-cityhash.git
  cd python-cityhash
  make env           # create a virtual environment
  make test          # run Python tests
  make cpp-test      # run C++ tests
  make shell         # enter IPython shell
  ```

  To find out which Make targets are available, enter:

  ``` bash
  make help
  ```



  The package wheels are built using
  [cibuildwheel](https://cibuildwheel.readthedocs.io/) and are distributed to
  PyPI using GitHub actions. The wheels contain compiled binaries and are
  available for the following platforms: windows-amd64, ubuntu-x86,
  linux-x86\_64, linux-aarch64, and macosx-x86\_64.



  For other fast non-cryptographic hash functions available as Python extensions,
  see [MetroHash](https://github.com/escherba/python-metrohash),
  [MurmurHash](https://github.com/hajimes/mmh3), and
  [xxHash](https://github.com/ifduyue/python-xxhash).



  The original CityHash Python bindings are due to Alexander \[Amper\] Marshalov.
  They were rewritten in Cython by Eugene Scherba, who also added the FarmHash
  bindings. The CityHash and FarmHash algorithms and their C++ implementation are
  by Google.



  This software is licensed under the [MIT
  License](http://www.opensource.org/licenses/mit-license). See the included
  LICENSE file for details.


pkgId: ae1156486b249dc6ecf1477d9f190c9b494348b32eb1e245de1cfe5b5842be32
name: python-cityscapesScripts
arch: src
version: 2.2.4
epoch: 0
release: 1
summary: Scripts for the Cityscapes Dataset
url: https://github.com/mcordts/cityscapesScripts
rpm_license: https://github.com/mcordts/cityscapesScripts/blob/master/LICENSE
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-cityscapesScripts-2.2.4-1.src.rpm
checksum_type: sha256
description:
  This repository contains scripts for inspection, preparation, and evaluation of the Cityscapes dataset. This large-scale dataset contains a diverse set of stereo video sequences recorded in street scenes from 50 different cities, with high quality pixel-level annotations of 5 000 frames in addition to a larger set of 20 000 weakly annotated frames.

  Details and download are available at: www.cityscapes-dataset.com




  The folder structure of the Cityscapes dataset is as follows:
  ```
  {root}/{type}{video}/{split}/{city}/{city}_{seq:0>6}_{frame:0>6}_{type}{ext}
  ```

  The meaning of the individual elements is:
   - `root`  the root folder of the Cityscapes dataset. Many of our scripts check if an environment variable `CITYSCAPES_DATASET` pointing to this folder exists and use this as the default choice.
   - `type`  the type/modality of data, e.g. `gtFine` for fine ground truth, or `leftImg8bit` for left 8-bit images.
   - `split` the split, i.e. train/val/test/train_extra/demoVideo. Note that not all kinds of data exist for all splits. Thus, do not be surprised to occasionally find empty folders.
   - `city`  the city in which this part of the dataset was recorded.
   - `seq`   the sequence number using 6 digits.
   - `frame` the frame number using 6 digits. Note that in some cities very few, albeit very long sequences were recorded, while in some cities many short sequences were recorded, of which only the 19th frame is annotated.
   - `ext`   the extension of the file and optionally a suffix, e.g. `_polygons.json` for ground truth files

  Possible values of `type`
   - `gtFine`       the fine annotations, 2975 training, 500 validation, and 1525 testing. This type of annotations is used for validation, testing, and optionally for training. Annotations are encoded using `json` files containing the individual polygons. Additionally, we provide `png` images, where pixel values encode labels. Please refer to `helpers/labels.py` and the scripts in `preparation` for details.
   - `gtCoarse`     the coarse annotations, available for all training and validation images and for another set of 19998 training images (`train_extra`). These annotations can be used for training, either together with gtFine or alone in a weakly supervised setup.
   - `gtBbox3d`     3D bounding box annotations of vehicles. Please refer to [Cityscapes 3D (Gählert et al., CVPRW '20)](https://arxiv.org/abs/2006.07864) for details.
   - `gtBboxCityPersons` pedestrian bounding box annotations, available for all training and validation images. Please refer to `helpers/labels_cityPersons.py` as well as [CityPersons (Zhang et al., CVPR '17)](https://bitbucket.org/shanshanzhang/citypersons) for more details. The four values of a bounding box are (x, y, w, h), where (x, y) is its top-left corner and (w, h) its width and height.
   - `leftImg8bit`  the left images in 8-bit LDR format. These are the standard annotated images.
   - `leftImg8bit_blurred`  the left images in 8-bit LDR format with faces and license plates blurred. Please compute results on the original images but use the blurred ones for visualization. We thank [Mapillary](https://www.mapillary.com/) for blurring the images.
   - `leftImg16bit` the left images in 16-bit HDR format. These images offer 16 bits per pixel of color depth and contain more information, especially in very dark or bright parts of the scene. Warning: The images are stored as 16-bit pngs, which is non-standard and not supported by all libraries.
   - `rightImg8bit`  the right stereo views in 8-bit LDR format.
   - `rightImg16bit` the right stereo views in 16-bit HDR format.
   - `timestamp`     the time of recording in ns. The first frame of each sequence always has a timestamp of 0.
   - `disparity`     precomputed disparity depth maps. To obtain the disparity values, compute for each pixel p with p > 0: d = ( float(p) - 1. ) / 256., while a value p = 0 is an invalid measurement. Warning: the images are stored as 16-bit pngs, which is non-standard and not supported by all libraries.
   - `camera`        internal and external camera calibration. For details, please refer to [csCalibration.pdf](docs/csCalibration.pdf)
   - `vehicle`       vehicle odometry, GPS coordinates, and outside temperature. For details, please refer to [csCalibration.pdf](docs/csCalibration.pdf)

  More types might be added over time and also not all types are initially available. Please let us know if you need any other meta-data to run your approach.

  Possible values of `split`
   - `train`       usually used for training, contains 2975 images with fine and coarse annotations
   - `val`         should be used for validation of hyper-parameters, contains 500 image with fine and coarse annotations. Can also be used for training.
   - `test`        used for testing on our evaluation server. The annotations are not public, but we include annotations of ego-vehicle and rectification border for convenience.
   - `train_extra` can be optionally used for training, contains 19998 images with coarse annotations
   - `demoVideo`   video sequences that could be used for qualitative evaluation, no annotations are available for these videos






  Install `cityscapesscripts` with `pip`
  ```
  python -m pip install cityscapesscripts
  ```

  Graphical tools (viewer and label tool) are based on Qt5 and can be installed via
  ```
  python -m pip install cityscapesscripts[gui]
  ```



  The installation installs the cityscapes scripts as a python module named `cityscapesscripts` and exposes the following tools
  - `csDownload`: Download the cityscapes packages via command line.
  - `csViewer`: View the images and overlay the annotations.
  - `csLabelTool`: Tool that we used for labeling.
  - `csEvalPixelLevelSemanticLabeling`: Evaluate pixel-level semantic labeling results on the validation set. This tool is also used to evaluate the results on the test set.
  - `csEvalInstanceLevelSemanticLabeling`: Evaluate instance-level semantic labeling results on the validation set. This tool is also used to evaluate the results on the test set.
  - `csEvalPanopticSemanticLabeling`: Evaluate panoptic segmentation results on the validation set. This tool is also used to evaluate the results on the test set.
  - `csEvalObjectDetection3d`: Evaluate 3D object detection on the validation set. This tool is also used to evaluate the results on the test set.
  - `csCreateTrainIdLabelImgs`: Convert annotations in polygonal format to png images with label IDs, where pixels encode "train IDs" that you can define in `labels.py`.
  - `csCreateTrainIdInstanceImgs`: Convert annotations in polygonal format to png images with instance IDs, where pixels encode instance IDs composed of "train IDs".
  - `csCreatePanopticImgs`: Convert annotations in standard png format to [COCO panoptic segmentation format](http://cocodataset.org/#format-data).
  - `csPlot3dDetectionResults`: Visualize 3D object detection evaluation results stored in .json format.




  The package is structured as follows
   - `helpers`: helper files that are included by other scripts
   - `viewer`: view the images and the annotations
   - `preparation`: convert the ground truth annotations into a format suitable for your approach
   - `evaluation`: validate your approach
   - `annotation`: the annotation tool used for labeling the dataset
   - `download`: downloader for Cityscapes packages

  Note that all files have a small documentation at the top. Most important files
   - `helpers/labels.py`: central file defining the IDs of all semantic classes and providing mapping between various class properties.
   - `helpers/labels_cityPersons.py`: file defining the IDs of all CityPersons pedestrian classes and providing mapping between various class properties.
   - `setup.py`: run `CYTHONIZE_EVAL= python setup.py build_ext --inplace` to enable cython plugin for faster evaluation. Only tested for Ubuntu.




  Once you want to test your method on the test set, please run your approach on the provided test images and submit your results:
  [Submission Page](www.cityscapes-dataset.com/submit)

  The result format is described at the top of our evaluation scripts:
  - [Pixel Level Semantic Labeling](cityscapesscripts/evaluation/evalPixelLevelSemanticLabeling.py)
  - [Instance Level Semantic Labeling](cityscapesscripts/evaluation/evalInstanceLevelSemanticLabeling.py)
  - [Panoptic Semantic Labeling](cityscapesscripts/evaluation/evalPanopticSemanticLabeling.py)
  - [3D Object Detection](cityscapesscripts/evaluation/evalObjectDetection3d.py)

  Note that our evaluation scripts are included in the scripts folder and can be used to test your approach on the validation set. For further details regarding the submission process, please consult our website.



  The dataset itself is released under custom [terms and conditions](https://www.cityscapes-dataset.com/license/).

  The Cityscapes Scripts are released under MIT license as found in the [license file](LICENSE).



  Please feel free to contact us with any questions, suggestions or comments:

  * Marius Cordts, Mohamed Omran
  * mail@cityscapes-dataset.net
  * www.cityscapes-dataset.com


pkgId: 6d4b3b41ff84f7d1aab2c1733c0b55f06895fe5ce550aeb5688916d986291ce5
name: python-cityview
arch: src
version: 0.2.0
epoch: 0
release: 1
summary: CityJSON renderer for Jupyter Notebook / JupyterLab
url: https://github.com/ozekik/cityview/
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-cityview-0.2.0-1.src.rpm
checksum_type: sha256
description:
  [![PyPI](https://img.shields.io/pypi/v/cityview.svg)](https://pypi.org/project/cityview/)
  [![npm](https://img.shields.io/npm/v/three-cityjson)](https://www.npmjs.com/package/three-cityjson)

  CityJSON loader and renderer for three.js, react-three-fiber, and Jupyter Notebook / JupyterLab.

  Supports [CityJSON format](https://www.cityjson.org/) and [CityJSONSeq format](https://www.cityjson.org/cityjsonseq/).



  - [Packages](#packages)
  - [Installation](#installation)
  - [Usage](#usage)
  - [Roadmap](#roadmap)
  - [License](#license)



  |  Package Name  | Description |
  |----------------|-------------|
  | [cityview](https://github.com/ozekik/cityview) (top-level package) | Python package |
  | [three-cityjson](https://github.com/ozekik/cityview/tree/master/packages/three-cityjson) | JavaScript / TypeScript package |



  ```bash
  pip install cityview
  ```







  ```python
  import cityview as cv

  view = cv.VirtualView(theme="light")

  with open("./packages/three-cityjson/public/sample/daiba_sta.city.jsonl", "r") as f:
      data = f.read()

  view.layers = [
      cv.CityJSONLayer(data=data, format="cityjsonseq")
  ]

  view.update()

  view
  ```

  ![VirtualView](./assets/virtualview-light-sshot_01.png)



  ```python
  import cityview as cv

  view = cv.MapView(theme="dark")

  with open("./packages/three-cityjson/public/sample/daiba_sta.city.jsonl", "r") as f:
      data = f.read()

  view.layers = [
      cv.CityJSONLayer(data=data, format="cityjsonseq")
  ]

  view.update()

  view
  ```

  ![VirtualView](./assets/mapview-dark-sshot_01.png)



  ```python
  import cityview as cv

  view = cv.VirtualView(theme="light")

  with open("./packages/three-cityjson/public/sample/daiba_sta.city.jsonl", "r") as f:
      data = f.read()

  def handler(change):
      print(change["new"])

  view.observe(handler, names="click")

  view.layers = [
      cv.CityJSONLayer(data=data, format="cityjsonseq")
  ]

  view.update()

  view
  ```




  - [ ] Online viewer



  MIT


pkgId: 3968b6c017e3bfc9e8fc2db501c429b4b7b3e8b33096becb4612542b3fca424f
name: python-ciuy
arch: src
version: 1.0.0
epoch: 0
release: 1
summary: Python package for validating Uruguayan identity document numbers.
url: https://github.com/ismaelpadilla/ciuy_py
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ciuy-1.0.0-1.src.rpm
checksum_type: sha256
description:
  Package for validating Uruguayan identity document numbers. Full documentation is available [here](https://ciuy.readthedocs.io/es/latest/).
  The functions in this package work with strings and ignore any non-digit characters. Numbers are valid too. So for example, the following expressions represent the same document number:
  ```
  '1.234.567-2'
  '12345672'
  12345672
  ```
  This package includes the following functions:
  `validate_ci(ci: str) -> bool`: Returns true if `ci` is a valid document number, returns false otherwise. `ci` is a string which represents a document number, including the validation digit. `ci` can be a number as well.
  `validation_digit(ci: str) -> str`: Returns the validation digit for `ci`.
  `random() -> str`: Returns a random document number (including validation digit) in the (100.000, 9.999.999) range.

  ```
  $ pip install ciuy
  ```

  ```
  >>> import ciuy
  >>> ciuy.validate_ci("1.234.567-2")
  True
  >>> ciuy.validation_digit("1.234.567")
  '2'
  >>> ciuy.random()
  '82405816'
  ```

  This package includes some doctests, as well as unit tests that can be run with `pytest`.
  After cloning the repository, you can run the doctests with:
  ```
  $ python3 -m doctest ./ciuy/__init__.py -v
   (several lines ommited)
  11 passed and 0 failed.
  Test passed.
  ```
  Use `py.test` to run the unit tests:
  ```


pkgId: cdfb1fba337313832943943cdfa36f9abf9914b68ff207086188fa74b8fcbd45
name: python-civic-scraper
arch: src
version: 0.2.10
epoch: 0
release: 1
summary: Tools for downloading agendas, minutes and other documents produced by local government
url: https://github.com/biglocalnews/civic-scraper
rpm_license: Apache 2.0 license
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-civic-scraper-0.2.10-1.src.rpm
checksum_type: sha256
description:
  - Documentation: [civic-scraper.readthedocs.io](http://civic-scraper.readthedocs.io/)
  - Repository: [github.com/biglocalnews/civic-scraper](https://github.com/biglocalnews/civic-scraper)
  - Packaging: [pypi.python.org/pypi/civic-scraper](https://pypi.python.org/pypi/civic-scraper)


pkgId: 7081c16a4a921226dbc4359ba622eef7afc4b3ad992c84223fdb4b114f2e5353
name: python-civicpy
arch: src
version: 3.1.2
epoch: 0
release: 1
summary: CIViC variant knowledgebase analysis toolkit.
url: http://civicpy.org
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-civicpy-3.1.2-1.src.rpm
checksum_type: sha256
description:
  [![Build Status](https://travis-ci.org/griffithlab/civicpy.svg?branch=master)](https://travis-ci.org/griffithlab/civicpy) [![Coverage Status](https://coveralls.io/repos/github/griffithlab/civicpy/badge.svg?branch=master)](https://coveralls.io/github/griffithlab/civicpy?branch=master)


  You have reached the code repository for CIViCpy, a python client and analysis toolkit for
   the Clinical Interpretations of Variants in Cancer knowledgebase ([CIViC](https://civicdb.org)).

   Please visit our [project homepage](http://civicpy.org) to get started.


pkgId: d5321e0c6846ca8df51e37f61b5601ae4f83b7cac24a40a86c80a22ee77d72a4
name: python-civics-cdf-validator
arch: src
version: 1.47
epoch: 0
release: 1
summary: Checks if an election feed follows best practices
url: https://github.com/google/civics_cdf_validator
rpm_license: Apache License
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-civics-cdf-validator-1.47-1.src.rpm
checksum_type: sha256
description:
  civics_cdf_validator is a script that checks if an election data feed follows best practices and outputs errors, warnings and info messages for common issues.


pkgId: 9be3b0c022853b84c4836fa1cbb0060a444a573ceb60584531897a3cdefb2b4f
name: python-civilpy
arch: src
version: 0.0.101
epoch: 0
release: 1
summary: Civil Engineering Tools in Python
url: https://daneparks.com/Dane/civilpy
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-civilpy-0.0.101-1.src.rpm
checksum_type: sha256
description:
  ![PyPI - License](https://img.shields.io/pypi/l/civilpy)
  <img alt="Project badge" aria-hidden="" class="project-badge" src="https://daneparks.com/Dane/civilpy/badges/master/pipeline.svg">
  <img alt="PyPI - Python Version" src="https://img.shields.io/pypi/pyversions/civilpy">
  <img alt="Project badge" aria-hidden="" class="project-badge" src="https://daneparks.com/Dane/civilpy/badges/master/coverage.svg">
  ![PyPI - Downloads](https://img.shields.io/pypi/dm/CivilPy)




  Code snippets for Civil Engineering related tasks



  Welcome to the CivilPy repository.  This is a simple software package to give civil engineers cleaner access
  to some of the packages from the python ecosystem.  The package is focused on civil engineering related tasks such as
  file management, pdf data extraction, image manipulation mapping and unit conversions.  I did my best to make the user
  interface obvious to use and tried to keep the functionality compatible with tools available to the average Civil
  engineer.



  This repository was created in order for me to gain a better understanding of software development work flows and how they can be
  re-purposed for civil engineering related tasks.  This is by no means a comprehensive or even functional repository but
  is more a way for me to track my progress while learning more about another industry.  There may occasionally be how-tos
  and other code posted here but this repository is not meant as tutorial or in depth explanation for how coding works.
  For those types of things I highly suggest you instead check <a href=https://www.youtube.com/>Youtube</a> for general
  lessons or <a href=https://stackoverflow.com/>Stack Overflow</a> for specific issues.  I highly recommend the
  <a href=https://www.youtube.com/user/cs50tv>Harvard CS50 YouTube Channel</a> for conceptual level programming lessons or
  <a href=https://www.youtube.com/user/schafer5>CoreyMS's Youtube Channel</a> for lessons in practical uses of
  programming.

  For an interesting somewhat working examples see the files `Useful Tricks and Tools.ipynb` and `NBI STandards - Conversion`
  files to have a better understanding of what function the DOT/SNBI files are performing.



  Run the following code to install the package:

  ```bash
  $ pip install civilpy
  ```



  to check the package installed correctly, run:

  ```python
  from civilpy.structural.steel import hello_world


  hello_world()
  ```

  ```python
  from civilpy.structural.steel import W


  W40X390 = W("W40X390")
  W40X390.A
  ```



  Here is the decision tree for function organization within the package, the goal
  is to keep importing and running functions as simple as possible for non-programmers,
  while maintaining an organizational structure capable of supporting many tools.

  i.e., the end user should be able to access any of your functions from a simple import:

  ```python
  from civilpy.state.ohio.dot import help_function
  ```

  <div class="center">

  ```mermaid
  graph TD
      A[Does the function more relate to a particular state<br> requirement/system, or a branch of Civil Engineering?] --> |State| B("Does it apply state wide <br> or a specific department?")
      A --> |Branch| C("Which branch does it most closely fit? ")
      C --> |construction| D(Save under <br> civilpy.construction)
      C --> |structural| E(Save under <br> civilpy.structural)
      C --> |geotechnical| F(Save under <br> civilpy.geotechnical)
      C --> |environmental| G(Save under <br> civilpy.environmental)
      C --> |transportation| H(Save under <br> civilpy.transportation)
      C --> |water_resources| I(Save under <br> civilpy.water_resources)
      A --> |Neither| P
      D --> K("Is it related to a particular standard, (i.e. AASHTO)")
      E --> K
      F --> K
      G --> K
      H --> K
      I --> K
      B --> |Statewide| L("civilpy.[state].__init__.py")
      B --> |Department| M("civilpy.[state].department")
      K --> |Yes| N("Save under a file for the standard<br>i.e. civilpy.structural.aisc")
      K --> |No| O("save to the relevant __init__.py")
      P("Save under civilpy.general.[relevant_file]")
      N --> |Doesn't make sense to put it there| P
      O --> |Doesn't make sense to put it there|P
  ```
  </div>


pkgId: 7354dd929e5c0dd9b1e846ddd78c7b21d6cc557371a99113051b632e8f24b5e4
name: python-civipy
arch: src
version: 0.0.6
epoch: 0
release: 1
summary: CiviCRM v3/v4 REST API Python wrapper
url: https://github.com/indepndnt/civipy
rpm_license: GPLv3
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-civipy-0.0.6-1.src.rpm
checksum_type: sha256
description:
  This is a brand-new project and code is subject to change at any time.

  Install with `python3 -m pip install civipy`. If you are using a Python version
  older than 3.11 and want to use `pyproject.toml` configuration, install with
  `python3 -m pip install civipy[pyproject]`.



  Configure your credentials in environment variables, a `.civipy` file, or in
  `pyproject.toml` in a `tools.civipy` section. By default, CiviPy will read a `.civipy`
  file anywhere in the current working directory up to your project root, or your
  project's `pyproject.toml` file, or a `.civipy` file in the user's home folder.
  Settings in environment variables will overwrite any file settings. Alternatively,
  you can call `civipy.config.SETTINGS.init()` to set the configuration values.

  | Setting                         | Environment Variable | `.civipy` File             | `pyproject.toml` File          |
  |---------------------------------|----------------------|----------------------------|--------------------------------|
  |                                 |                      |                            | `[tool.civipy]`                |
  | Connection *(required)*         | `CIVI_REST_BASE`     | `rest_base=http://civi.py` | `rest-base = "http://civi.py"` |
  | API Version                     | `CIVI_API_VERSION`   | `api_version=4`            | `api-version = "4"`            |
  | Access Token *(required)*       | `CIVI_USER_KEY`      | `user_key=...`             | `user-key = "..."`             |
  | Site Token *(required for v3)*  | `CIVI_SITE_KEY`      | `site_key=...`             | `site-key = "..."`             |
  | Log File                        | `CIVI_LOG_FILE`      | `log_file=/tmp/civipy.log` | `log-file = "/tmp/civipy.log"` |
  | Log Level                       | `CIVI_LOG_LEVEL`     | `log_level=WARNING`        | `log-level = "WARNING"`        |
  | Config File                     | `CIVI_CONFIG`        |                            |                                |


  The Connection setting lets you specify the URL of your REST API, or the `cv` or
  `drush` or `wp-cli` executable on your file system. If "http" is found in the setting,
  the system will use http calls to the REST API. If the string "drush" is found, it
  will use drush. If the string "wp" is found, it will use wp-cli. And if none of these
  are found, it will attempt to call the cv command line API.


  Set to "3" to use the CiviCRM v3 API, or "4" (the default) to use the CiviCRM v4 API.


  To log to a file instead of the screen, set the Log File setting to the file path
  you want to log to.


  You can specify in an environment variable either a directory to find a `.civipy`
  configuration file in, or a file to read as a `.civipy` configuration file.


  There is a Django-style `.objects` attribute on each record model with `filter`, `values`,
  `order_by`, and `all` methods for querying; and `create`, `delete`, and `update` methods
  for making changes. Model instances also have `save` and `delete` methods.

  ```python
  from civipy import CiviContact

  contact = CiviContact.objects.filter(email_primary__email="ana@ananelson.com")[0]
  contact.nick_name = "Ana"
  contact.save()
  ```

  Each CiviCRM Entity is represented by a subclass of CiviCRMBase; if you need an entity
  that is not in the project, you can easily add it by subclassing CiviCRMBase and naming
  it the entity name prepended with "Civi", e.g.

  ```python
  import civipy

  class CiviNewEntity(civipy.CiviCRMBase):
      pass
  ```


  civipy Copyright &copy; 2020 Ana Nelson

  Licensed under the GPL v3

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <https://www.gnu.org/licenses/>.

  <https://www.gnu.org/licenses/gpl-3.0.txt>


pkgId: c5bb68f8bd015866bd6ea224b8d744288ebfe3a6bfc938514d7453dcbd23d386
name: python-civis
arch: src
version: 2.3.0
epoch: 0
release: 1
summary: Civis API Python Client
url: https://www.civisanalytics.com
rpm_license: BSD-3-Clause
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-civis-2.3.0-1.src.rpm
checksum_type: sha256
description:
  |PyPI| |PyVersions| |CircleCI| |Documentation|
  The Civis API Python client is a Python package that helps analysts
  and developers interact with Civis Platform programmatically. The package includes a set of
  tools around common workflows as well as a convenient interface to make
  requests directly to the Civis API.
  Please see the
  `full documentation <https://civis-python.readthedocs.io>`_ for more details.


pkgId: 89e0ddd60befbc953b755f1a0798cf44b959e9d267aaa08d83784a5c6d0b961b
name: python-civitai-models-manager
arch: src
version: 0.8.5
epoch: 0
release: 1
summary: CLI tool for managing AI models from the CivitAI platform.
description: CLI tool for managing AI models from the CivitAI platform.
url: https://pypi.org/project/civitai-models-manager/
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-civitai-models-manager-0.8.5-1.src.rpm
checksum_type: sha256
rpm_license:
  Copyright 2024 Regi E Ellis  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: b8f7ce70dad8b14a810046cd4bd2fc2beec8da9c81648e0ef1bc5306c866b0bd
name: python-civitai-py
arch: src
version: 0.1.10
epoch: 0
release: 1
summary: Civitai Python SDK
url: https://github.com/civitai/civitai-python
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-civitai-py-0.1.10-1.src.rpm
checksum_type: sha256
description:
  A Python client for Civitai's generator to run Civitai models from your Python code.



  To get started with the Civitai Generator Python Client, you can use the following resources:

  - **Google Colab Notebook**: Jump into a pre-configured environment with a live notebook to try out the Civitai SDK.

    <a target="_blank" href="https://colab.research.google.com/github/civitai/civitai-python/blob/main/examples/text2img.ipynb">
    <img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/>
  </a>

  - **Streamlit Demo**: See the Civitai SDK in action with a live Streamlit app demo. [View Streamlit Demo](https://civitai.streamlit.app/)



  ```python
  pip install civitai-py
  ```



  Before running any Python scripts that use the API, you need to set your Civitai API token in your environment.

  Grab your token from [your Civitai account](https://civitai.com/user/account) and set it as an environment variable:

  ```bash
  export CIVITAI_API_TOKEN=<your token>
  ```



  - Python 3.7+





  ```python
  import civitai
  ```



  ```python
  input = {
      "model": "urn:air:sd1:checkpoint:civitai:4384@128713",
      "params": {
          "prompt": "RAW photo, face portrait photo of woman, wearing black dress, happy face, hard shadows, cinematic shot, dramatic lighting",
          "negativePrompt": "(deformed, distorted, disfigured:1.3)",
          "scheduler": "EulerA",
          "steps": 20,
          "cfgScale": 7,
          "width": 512,
          "height": 512,
          "clipSkip": 2
      }
  }
  ```

  Run a model:

  ```python
  response = civitai.image.create(input)
  ```

  Then, fetch the result later:

  ```python
  response = civitai.jobs.get(token=response.token)
  ```

  Or wait for the job to finish by running the generation in the background a.k.a long polling. You can add the `wait=True` flag to the method. It has a default timeout of 5 minutes.

  ```python
  response = civitai.image.create(input, wait=True)
  ```



  The SDK supports additional networks: LoRA, VAE, Hypernetwork, Textual Inversion, LyCORIS, Checkpoint, and LoCon.

  To use any of the networks availabe on Civitai, simply add the `additionalNetworks` field into the input:

  ```python
  input = {
      "model": "urn:air:sd1:checkpoint:civitai:4384@128713",
      "params": {
          "prompt": "masterpiece, best quality, 1girl, IncrsAhri, multiple tails, fox tail, korean clothes, skirt, braid, arms behind back",
          "negativePrompt": "(worst quality:1.4), (low quality:1.4), simple background, bad anatomy",
          "scheduler": "EulerA",
          "steps": 25,
          "cfgScale": 7,
          "width": 512,
          "height": 768,
          "seed": -1,
          "clipSkip": 2
      },
      "additionalNetworks": {
          
          "urn:air:sd1:lora:civitai:82098@87153": {
              "strength": 1.0
          }
      }
  }
  ```

  In the case of `Lora` and `LoCon` networks, set the `strength` of the network; for `TextualInversion`, set the `triggerWord` of the network.

  <br/>



  Run a model with inputs you provide.

  ```python
  response = civitai.image.create(options)
  ```

  | name                    | type                                                                      | description                                                                                                                                                                                                                                                                                                                               |
  | ----------------------- | ------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | `model`                 | string \| null                                                            | **Required**. The Civitai model to use for generation.                                                                                                                                                                                                                                                                                    |
  | `params.prompt`         | string \| null                                                            | **Required**. The main prompt for the image generation.                                                                                                                                                                                                                                                                                   |
  | `params.negativePrompt` | string \| null                                                            | Optional. The negative prompt for the image generation.                                                                                                                                                                                                                                                                                   |
  | `params.scheduler`      | [Scheduler](civitai/models/Scheduler.py) \| null                          | Optional. The scheduler algorithm to use. <br/> <br/>Possible values are: `EulerA`, `Euler`, `LMS`, `Heun`, `DPM2`, `DPM2A`, `DPM2SA`, `DPM2M`, `DPMSDE`, `DPMFast`, `DPMAdaptive`, `LMSKarras`, `DPM2Karras`, `DPM2AKarras`, `DPM2SAKarras`, `DPM2MKarras`, `DPMSDEKarras`, `DDIM`, `PLMS`, `UniPC`, `Undefined`, `LCM`, `DDPM`, `DEIS`. |
  | `params.steps`          | number \| null                                                            | Optional. The number of steps for the image generation process.                                                                                                                                                                                                                                                                           |
  | `params.cfgScale`       | number \| null                                                            | Optional. The CFG scale for the image generation.                                                                                                                                                                                                                                                                                         |
  | `params.width`          | number                                                                    | **Required**. The width of the generated image.                                                                                                                                                                                                                                                                                           |
  | `params.height`         | number                                                                    | **Required**. The height of the generated image.                                                                                                                                                                                                                                                                                          |
  | `params.seed`           | number \| null                                                            | Optional. The seed for the image generation process.                                                                                                                                                                                                                                                                                      |
  | `params.clipSkip`       | number \| null                                                            | Optional. The number of CLIP skips for the image generation.                                                                                                                                                                                                                                                                              |
  | `callbackUrl`           | string \| null                                                            | Optional. URL that will be invoked upon completion of this job                                                                                                                                                                                                                                                                            |
  | `additionalNetworks`    | [ImageJobNetworkParams](civitai/models/ImageJobNetworkParams.py) \| null  | Optional. An associative list of additional networks, keyed by the AIR of the network. Each network is of type [AssetType](civitai/models/asset_type.py).                                                                                                                                                                                 |
  | `controlNets`           | Array<[ImageJobControlNet](civitai/models/ImageJobControlNet.py)> \| null | Optional. An associative list of additional networks.                                                                                                                                                                                                                                                                                     |



  | `additionalNetworks` | Record<string, [ImageJobNetworkParams](civitai/models/ImageJobNetworkParams.py)> | Optional. An associative list of additional networks, keyed by the AIR of the network. Each network is described by an `ImageJobNetworkParams` object. |
  | -------------------- | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
  | `strength`           | number                                                                           | Optional. In case of Lora and LoCon, set the strength of the network.                                                                                  |
  | `triggerWord`        | string                                                                           | Optional. In case of a TextualInversion, set the trigger word of the network.                                                                          |



  | `controlNets`  | Array<[ImageJobControlNet](civitai/models/ImageJobControlNet.py)> | Optional. An array of control networks that can be applied to the image generation process. <br/><br/>Each `ImageJobControlNet` object in the array can have the following properties: |
  | -------------- | ----------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | `preprocessor` | [ImageTransformer](civitai/models/ImageTransformer.py) \| null    | Optional. Specifies the image transformer to be applied as a preprocessor. <br/><br/>Possible values are `Canny`, `DepthZoe`, `SoftedgePidinet`, `Rembg`.                              |
  | `weight`       | number \| null                                                    | Optional. The weight of the control net.                                                                                                                                               |
  | `startStep`    | number \| null                                                    | Optional. The step at which the control net starts to apply.                                                                                                                           |
  | `endStep`      | number \| null                                                    | Optional. The step at which the control net stops applying.                                                                                                                            |
  | `imageUrl`     | string \| null                                                    | Optional. The URL of the image associated with the controlnet.                                                                                                                         |



  Fetches job details based on a provided token or job ID. If both are provided, the token takes precedence.

  ```python
  job_id = "your_job_id_here"
  response = civitai.jobs.get(job_id=job_id)



  token = "your_token_here"
  response = civitai.jobs.get(token=token)



  response = civitai.jobs.get(token=token, job_id=job_id)
  ```



  Retrieve a collection of jobs by querying properties, e.g., userId. You can optionally include a `detailed` boolean flag to get detailed information about the jobs.

  ```python
  query = {
      "properties": {
          "userId": 4  # Querying by userId
      }
  }

  detailed = False  # Optional boolean flag to get detailed job definitions. False by default.

  response = civitai.jobs.query(detailed=detailed, query_jobs_request=query)
  ```



  Cancel a job by its jobId.

  ```python
  response = civitai.jobs.cancel(job_id)

  ```

  This method cancels a job that is currently scheduled or running. It requires the `jobId` of the job you wish to cancel. On successful cancellation, it returns a response object indicating the cancellation status.



  After making your changes:

  1. Push your changes to your fork.
  2. Open a pull request against the main repository.
  3. Describe your changes and how they improve the project or fix issues.

  Your contributions will be reviewed, and if accepted, merged into the project.



  - Include unit tests for new features or bug fixes.
  - Update the documentation if necessary.

  Thank you for contributing to the Civitai Generator Python Client! 🥹🤭


pkgId: 1f366e4ed82edd3bff11982d79c78983a680bfa0bb47783716a02466d3b5f226
name: python-cj-package
arch: src
version: 1.0.50
epoch: 0
release: 1
summary: cj package.
url: https://pypi.org/project/cj-package/
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-cj-package-1.0.50-1.src.rpm
checksum_type: sha256
description:
  阿里云相关功能方法 SlsLogStore(key) 实例化
  > 1.杭州ingress日志查询方法  hz_ingress_log
  > 1.杭州service日志查询方法  hz_service_log
  > 2.硅谷ingress日志查询方法  usa_ingress_log
  > 2.硅谷service日志查询方法  usa_service_log


  excel相关功能方法
  > 1.将字典列表写入到excel文件中 write_list_dict_excel
  > 2.将列表元组写入到excel文件中 write_list_tuple_excel


  企业微信
  > 1.markdown格式的企业微信通知 send_markdown_message


  subprocess执行shell命令
  > 1.通过subprocess执行shell命令 exec_command
  > 2.通过subprocess执行shell命令支持实时输出 exec_command_realtime_output


  域名相关功能方法
  > 1.获取域名解析的IP地址 get_ip_list
  > 2.获取域名解析的证书及过期天数 get_cert_details


  执行mysql相关的sql
  > 1.执行sql exec_mysql


  发送邮件 Mail(host, user, password, port, ssl)初始化
  > 1.发送文本邮件 send_msg_mail(title: str, msg: str, receivers: list)
  > 2.发送带有附件邮件 send_file_mail(title: str, msg: str, file_path: str, receivers: list)


  工具箱
  > 1.md5加密 md5_encrypt
  > 2.base64编码 base64_encode
  > 3.base64解码 base64_decode
  > 4.生成随机Fernet密钥 fernet_generate_key
  > 4.使用fernet加密数据 fernet_jiami
  > 4.使用fernet解密数据 fernet_jiemi
  > 5.进度条 process_with_progress
  > 6.复制数据到粘贴板  copy_to_clipboard


pkgId: 68dfea9e4cc7537d41a76b4694b09ca1495ec9903e7fe8797824a8c3a21c377e
name: python-cjapy
arch: src
version: 0.2.4
epoch: 0
release: 1
summary: Adobe Customer Journey Analytics (CJA) wrapper
url: https://github.com/pitchmuc/cjapy
rpm_license: Apache License 2.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-cjapy-0.2.4-1.src.rpm
checksum_type: sha256
description:
  This is a python wrapper for the Adobe Customer Journey API.\
  One important element when starting with CJA API is that you need to have your adobe console.io Project containing access to AEP **and** CJA.\
  You cannot use the API without having access to both elements.

  Documentation is split in different places:
  * Core methods to setup `cjapy`: [main documentation](./docs/main.md)
  * Methods provided by the CJA class instance: [cja documentation](./docs/cja.md)
  * Workspace class documentation: [Workspace class](./docs/workspace.md)
  * RequestCreator class documentation: [RequestCreator class](./docs/requestCreator.md)
  * Project class documentation : [Project class](./docs/projects.md)

  A documentation about the releases information can be found here : [cjapy releases](./docs/releases.md)

  Functionalities that are covered :
  * Get Dimensions & Metrics
  * Get, Update and Delete Tags & Shares
  * Get, Update and Delete Dataview
  * Get, Update and Delete Date Ranges
  * Get, Update and Delete Filters
  * Get Top items for a dimension
  * Get, Update and delete projects
  * Digest Project Information and analyse them via the `Project` class
  * Run a report (by default returning a Workspace instance)
  * (BETA) Run a multi dimensional report

  A documentation is provided to get started quickly with the CJA API wrapper in python.\
  You can find it here: [get started on `cjapy`](./docs/getting_started.md)\
  To install the library with PIP use:
  ```cli
  pip install cjapy
  ```
  or, to get the latest version from github
  ```cli
  python -m pip install --upgrade git+<https://github.com/pitchmuc/cjapy.git#egg=cjapy>
  ```

  A logging capability is present on the module for debugging purposes.\
  There is a proper documentation in place to understand how you can add the logging messages to your runtime.\
  [Documentation on logging in cjapy](./docs/logging.md)

  In order to use this API in python, you would need to have those libraries installed :
  * pandas
  * requests
  * json
  * PyJWT
  * PyJWT[crypto]
  * pathlib
  * pytest

  TBW

  You can find information about the CJA API here :
  * [https://www.adobe.io/cja-apis/docs/api/]
  * [https://www.adobe.io/cja-apis/docs/use-cases/]
  [1]: https://www.datanalyst.info


pkgId: 63284925f7aa7fa94135893d4637ac8b1e6ae3731b5a458f3e21d3876285b40f
name: python-cjdb
arch: src
version: 2.1.0
epoch: 0
release: 1
summary: CJDB is a tool that enables CityJSON integration with a PostgreSQL database
url: https://github.com/tudelft3d/cjdb
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-cjdb-2.1.0-1.src.rpm
checksum_type: sha256
description:
  [![MIT badge](https://img.shields.io/pypi/l/cjdb)](LICENSE) &nbsp; [![PyPI](https://img.shields.io/pypi/v/cjdb)](https://pypi.org/project/cjdb)

  `cjdb` is a Python-based importer/exporter of [CityJSONL files (CityJSON Lines)](https://www.cityjson.org/cityjsonl/) to and from a PostgreSQL database.
  It requires the [PostGIS](https://postgis.net/) extension.



  ```bash
  pip install cjdb
  ```
  It is recommended to install it in an isolated environment.




  Check our [docs online](https://cityjson.github.io/cjdb/cjdb.html)  or

  ```bash
  cjdb --help
  ```



  Sample CityJSON data can be downloaded from [the 3DBAG download service](https://3dbag.nl/).
  For example, [download the tile "9-284-556"](https://data.3dbag.nl/cityjson/v20230622/tiles/9/284/556/9-284-556.city.json), within which part of TU Delft is located.
  Then, having downloaded the CityJSON file, you need a combination of [cjio](https://github.com/cityjson/cjio) (external CityJSON processing library) and cjdb to import it to a schema in a database.  Here is a step-by-step guide:

  1. Convert CityJSON to CityJSONL

  ```bash
  cjio --suppress_msg 9-284-556.json export jsonl 9-284-556.jsonl
  ```

  2. Create a new database called "testcjdb"

  If you installed PostgreSQL you should have the program 'createdb', so `createdb testcjdb`

  Alternatively, you can use PgAdmin, [see how](https://postgis.net/workshops/postgis-intro/creating_db.html).

  3. Import CityJSONL to the database in the schema "cjdb"
  ```bash
  cjdb import -H localhost -U postgres -d testcjdb -s cjdb  -f 9-284-556.jsonl
  ```

  **Alternatively steps 1 and 3 in a single command:**

  ```bash
  cjio --suppress_msg 9-284-556.json export jsonl stdout | cjdb import -H localhost -U postgres -d postgres -s cjdb
  ```

  The metadata and the objects can then be found in the tables in the specified schema (`cjdb` in this example).

  The password can be specified in the `PGPASSWORD` environment variable. If not specified, the app will prompt for the password.

  4. If you want to export from the database you have two options. You can export the whole database in a CityJSONL file with:
  ```bash
  cjdb export -H localhost -U postgres -d testcjdb -s cjdb -o result.jsonl
  ```
  or export only part of it, using a select query as input. The select query should return the ids of the objects to be exported:

  ```bash
  cjdb export -H localhost -U postgres -d testcjdb -s cjdb -o result.jsonl -q "SELECT 'NL.IMBAG.Pand.1655100000500568' as object_id"
  ```

  5. If you want to convert from CityJSONFeatures to city json you can use `cjio`:
  ```bash
  cat /path/to/result.city.jsonl | cjio  stdin save /path/to/output.city.json
  ```


  Build:
  ```bash
  docker build -t cjdb:latest .
  ```

  Run:
  ```bash
  docker run --rm -it cjdb cjdb --help
  ```

  To import some files, the `-v` option is needed to mount our local file directory in the container:
  ```bash
  docker run -v {MYDIRECTORY}:/data --rm -it --network=host cjdb cjdb import -H localhost -U postgres -d postgres -W postgres -f /data/5870_ext.jsonl
  ```




  The `cjdb` importer loads the data in accordance with a [specific data model](cjdb/model/README.md).

  For example SQL queries on the tables see [here](cjdb/model/BASICQUERIES.md)



  Some indexes are created when a new schema is created (refer to [Data Model](cjdb/model/README.md)).

  In addition to these indexes, the user can add more indexes on certain  CityObject attributes with the `-x/--attr-index` or the `-px/--partial-attr-index` flags.
  We recommend these additional indexes for attributes that are frequently queried.
  The second option uses a partial index with a `not null` condition on the attribute.
  This saves disk space when indexing an attribute that is not present among all the imported CityObjects.
  This is often the case with CityJSON, because in a single dataset there can be different object types, with different attributes.




  It is recommended to group together semantically coherent objects, by importing them to the same database schema.
  One database can have different schemas.

  While the current data model supports the import of any type of CityJSON objects together (`Building` and `SolitaryVegetationObject`), the data becomes harder to manage for the user.
  Example of this would be having different attributes for the same CityObject type (which should be consistent for data coming from the same source).



  The importer works only on with [*CityJSONL* files](https://www.cityjson.org/specs/#text-sequences-and-streaming-with-cityjsonfeature), which are CityJSON files decomposed into their *features* (`CityJSONFeature`).

  The easiest way to create these from a CityJSON file is with [cjio](https://github.com/cityjson/cjio), by following [these instructions](https://github.com/cityjson/cjio#stdin-and-stdout).

  The importer supports 3 kinds of input:
    1. a single CityJSONL file (only those as the output of cjio currently work)
    1. a directory of CityJSONL files (all files with *jsonl* extensions are located and imported)
    1. STDIN using the pipe operator: `cat file.jsonl | cjdb ...`



  The `cjdb` importer does not allow inconsistent CRSs (coordinate reference systems) within the same database schema. For storing data in different CRSs, you have to create different schemas.

  The data needs to be either harmonized beforehand, or the `--transform` flag can be used upon import, to reproject all the geometries to the CRS of the existing schema.
  Specifying a 2D CRS (instead of a 3D one) will cause the Z-coordinates to remain unchanged.

  **Note:** reprojections slow down the import significantly.

  **Note:** Source data with missing `"metadata"/"referenceSystem"` cannot be reprojected due to unknown source reference system.
  You can use the `-I/--srid` flag to set the SRID of the input file.



  [`pyproj`](https://pyproj4.github.io/pyproj/stable/) is used for CRS reprojections.
  While it supports 3D CRS transformations between different systems, sometimes downloading additional [grids](https://pyproj4.github.io/pyproj/stable/transformation_grids.html) is required.
  The importer will attempt to download the grids needed for the reprojection, with the following message:

  ```
  Attempting to download additional grids required for CRS transformation.
  This can also be done manually, and the files should be put in this folder:
          {pyproj_directory}
  ```

  If that fails, the user will have to download the required grids and put them in the printed `{pyproj_directory}` themselves.



  If [CityJSON Extensions](https://www.cityjson.org/extensions/) are present in the imported files, they can be found listed in the `extensions` column in the `cj_metadata` table.

  The [CityJSON specifications](https://www.cityjson.org/specs/#extensions) mention 3 different extendable features, and the `cjdb` importer deals with them as follows:

  1. Complex attributes

  No action is taken. These attributes end up in the `attributes` JSONB column.

  2. Additional root properties

  Additional root properties are placed in the `extra properties` JSONB column in the `cj_metadata` table.

  3. Additional CityObject type

  Additional CityObject types are appended to the list of allowed CityJSON objects.


  [Geometry templates](https://www.cityjson.org/specs/1.1.2/#geometry-templates)
  are resolved for each object geometry, so that the object in the table ends up with its real-world coordinates (instead of vertex references or relative template coordinates).


  The importer does not validate the structure of the file. It is assumed that the input file is schema-valid ([CityJSON validator](https://validator.cityjson.org/)).
  It sends out warnings when:
  - CityObject types appear which are defined neither in the main CityJSON specification nor in any of the supplied extensions.
  - the specified target CRS does not have the Z-axis defined
  - the source dataset does not have a CRS defined at all


  The importer does not check if an object with a specific ID exists already in the database - every imported object gets and new id. However, at the time of import the importer will detect previously detected files with the same filename. The user can choose to run the import with either the `-g, --ignore-repeated-file` option to import files with the same filename under a different id or `--overwrite` to overwrite *all* previously imported objects with this filename.




  This project started as a group project in the [MSc Geomatics at TUDelft](https://geomatics.tudelft.nl/).
  The original code for the project can be found [here](https://github.com/leoleonsio/cjdb), and the authors were:
  [@cynthiacai56](https://github.com/cynthiacai56), [@LanYan1110](https://github.com/LanYan1110), [@YitongXia](https://github.com/YitongXia), [@Topher2k](https://github.com/Topher2k), [@siebren014](https://github.com/siebren014), [@leoleonsio](https://github.com/leoleonsio)

  This version has been improved and will be maintained by [@GinaStavropoulou](https://github.com/GinaStavropoulou), and [@hugoledoux](https://github.com/hugoledoux).


pkgId: 4f2bf9cb9e7b3f880412ee002f5c12c94d97c23d6d0001c5c98b55a9dfe53654
name: python-cjen
arch: src
version: 1.0.15
epoch: 0
release: 1
summary: automation test helper
url: https://github.com/thcpc/cjen
rpm_license: MIT License
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-cjen-1.0.15-1.src.rpm
checksum_type: sha256
description:
  <!--
   * @Author: your name
   * @Date: 2022-02-05 00:15:52
   * @LastEditTime: 2022-02-28 14:09:40
   * @LastEditors: Please set LastEditors
   * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
   * @FilePath: \PyPackage\cjen\README.md
  -->

  该项目封装了测试人员写自动化代码的常用功能作为装饰器，
  目标是能让测试人员更关注业务逻辑的实现，隐藏和业务逻辑无关的细节。
  GitHub地址：https://github.com/thcpc/cjen


  get_mapping, put_mapping, post_mapping, delete_mapping, upload_mapping 增加json_clazz参数，作用同operate.json.factory


  - 1. 修改metaMysql 没有数据时，是警告信息而不是错误信息

  - 2. 方便批量检查，增加了 context["cursor"]


  - 1. 修改了创建metaMysql后，直接释放数据库连接池（临时修改方案）


  - 1. 上传的文件支持sql


  - 1. 修改了文件的判断


  - 1. 测试http请求的写日志文件


  - 1. fix a bug


  - 1. 增加了http请求的日志文件


  - 1. 增加了封装操作步骤


  - 1. 修复了文件下载日志的bug 和对是否是文件下载的判断


  - 1. 取消了文件下载请求响应的日志


  - 1. 增加了Step的装饰器


  - 1. bug：不管step是否运行都会注册到BigTangerine
       修复：调用接口时才会注册到BigTangerine中


  - 1. scenario 中的step 都应该使用相同的service, 所以在构造函数中增加了service参数，同时兼容以前的方法


  - 1. 取消FormData中,文件作为必填项


  - 1. 修复了upload 会修改service中的全局headers


  - 1. 增加了测试装饰器


  - 1. 在Scenario中增加了测试用例的注册机制

  - 1. 修复一些低级错误


  - 1 . 针对 mysql 增加可通过函数参数传递查询参数，而不是一定需要通过上下文传递


  - 1 . 修改查询参数为空时，设置查询参数为

  - 1 . xlsx读取装饰器
  - 2 . list_eql 函数

  - 1 . 增加了通用数据结构 树

  - 1 . xlsx 读取装饰器，支持在函数中指定文件路径

  - 1 . property 校验装饰器
  - # Release 1.0.13
  - 1 . 增加DBBigTangerine
  - # Release 1.0.14
  - 1 . 修复了DatabaseInfo port的BUG

  - # Release 1.0.15
  - 1 . 增加对数据库字段byte转为Bool


pkgId: 48f768279e1c8e9b7387f361642fed55ace48698ed0244b0db315db23fe96dad
name: python-cjio
arch: src
version: 0.9.0
epoch: 0
release: 1
summary: CLI to process and manipulate CityJSON files
url: https://github.com/cityjson/cjio
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-cjio-0.9.0-1.src.rpm
checksum_type: sha256
description:
  |License: MIT| |image1|
  Python CLI to process and manipulate `CityJSON <http://www.cityjson.org>`_ files.
  The different operators can be chained to perform several processing operations in one step, the
  CityJSON model goes through them and different versions of the CityJSON model can be saved as files along the pipeline.


pkgId: 6f6c1d33eabf1948aaabf38b165d3779a27d0124b9196fca5abf438cc65d8820
name: python-cjm-pil-utils
arch: src
version: 0.0.9
epoch: 0
release: 1
summary: Some PIL utility functions I frequently use.
url: https://github.com/cj-mills/cjm-pil-utils
rpm_license: Apache Software License 2.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-cjm-pil-utils-0.0.9-1.src.rpm
checksum_type: sha256
description:
  <!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->



  ``` sh
  pip install cjm_pil_utils
  ```





  ``` python
  from cjm_pil_utils.core import get_img_files
  from pathlib import Path
  ```

  ``` python
  img_dir = Path('../images/')
  img_paths = get_img_files(img_dir)
  img_paths
  ```

      [PosixPath('../images/cat.jpg'), PosixPath('../images/depth-cat.png')]



  ``` python
  from cjm_pil_utils.core import resize_img
  from PIL import Image  # For working with images
  ```

  ``` python
  img_path = img_paths[0]
  src_img = Image.open(img_path).convert('RGB')
  print(f"Image Size: {src_img.size}")

  resized_img = resize_img(src_img, target_sz=384, divisor=32)
  print(f"New Image Size: {resized_img.size}")
  ```

      Image Size: (768, 512)
      New Image Size: (576, 384)



  ``` python
  from cjm_pil_utils.core import stack_imgs
  ```

  ``` python
  stacked_imgs = stack_imgs([resized_img, resized_img])
  print(f"Stacked Image Size: {stacked_imgs.size}")
  ```

      Stacked Image Size: (576, 768)



  ``` python
  from cjm_pil_utils.core import avg_images
  ```

  ``` python
  img_1, img_2 = (Image.open(path) for path in img_paths)
  avg_img = avg_images(img_1, img_2, 0.5)
  ```



  ``` python
  from cjm_pil_utils.core import crop_square
  ```

  ``` python
  crop_square(src_img).size
  ```

      (512, 512)


pkgId: f4443d78d90786a047441a8ceeaa65c6e6a0602e9dc13133385435f27e72e310
name: python-cjm-psl-utils
arch: src
version: 0.0.4
epoch: 0
release: 1
summary: Some utility functions using the Python Standard Library.
url: https://github.com/cj-mills/cjm-psl-utils
rpm_license: Apache Software License 2.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-cjm-psl-utils-0.0.4-1.src.rpm
checksum_type: sha256
description:
  <!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

  This file will become your README and also the index of your
  documentation.



  ``` sh
  pip install cjm_psl_utils
  ```





  ``` python
  from cjm_psl_utils.core import get_source_code
  ```

  ``` python
  get_source_code(get_source_code, markdown=True)
  ```

  ``` python
  def get_source_code(obj:object, # The object whose source code you want to retrieve.
                      markdown=False, # Return the source code formatted as markdown
                      remove_documentation=False): # Remove docstrings and comments
      """
      Returns the source code of an object, with an optional markdown formatting.
      """
      
      source = inspect.getsource(obj)

      
      if remove_documentation:
          in_docstring = False
          lines = source.split('\n')
          source = ''
          
          for line in lines:
              if line.strip().startswith(('\'\'\'', '\"\"\"')):
                  in_docstring = not in_docstring
              elif not in_docstring:
                  source += line + '\n'
          
          source = '\n'.join([line for line in source.split('\n')
                              if not line.strip().startswith(('#'))])
          source = source.replace('\n\n', '\n')

      if markdown:
          
          source = f"```python\n{source}\n```"

          
          try:
              get_ipython
              from IPython.display import Markdown
              
              source = Markdown(source)
          except NameError:
              
              pass
      
      return source
  ```



  ``` python
  from cjm_psl_utils.core import file_extract
  from pathlib import Path
  ```

  ``` python
  fname = "../images/images.zip"
  dest = Path("./images")
  ```

  ``` python
  print(dest.exists())
  file_extract(fname, dest)
  print(dest.exists())
  print(list(os.walk(dest))[0][2])
  ```

      False
      True
      ['cat.jpg']


pkgId: fb089dfa12293e285f489e59d89eff40518291c0e86fba5136b1d9d1b02b3ca2
name: python-cjm-pytorch-utils
arch: src
version: 0.0.8
epoch: 0
release: 1
summary: Some utility functions for working with PyTorch.
url: https://github.com/cj-mills/cjm-pytorch-utils
rpm_license: Apache Software License 2.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-cjm-pytorch-utils-0.0.8-1.src.rpm
checksum_type: sha256
description:
  <!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->



  ``` sh
  pip install cjm_pytorch_utils
  ```





  ``` python
  from cjm_pytorch_utils.core import set_seed
  ```

  ``` python
  seed = 1234
  set_seed(seed)
  ```



  ``` python
  from cjm_pytorch_utils.core import pil_to_tensor
  from PIL import Image
  from torchvision import transforms
  ```

  ``` python
  img_path = img_path = '../images/cat.jpg'
  src_img = Image.open(img_path).convert('RGB')
  print(f"Source Image Size: {src_img.size}")

  img_tensor = pil_to_tensor(src_img, [0.5], [0.5])
  img_tensor.shape, img_tensor.min(), img_tensor.max()
  ```

      Source Image Size: (768, 512)

      (torch.Size([1, 3, 512, 768]), tensor(-1.), tensor(1.))



  ``` python
  from cjm_pytorch_utils.core import tensor_to_pil
  ```

  ``` python
  tensor_img = tensor_to_pil(transforms.ToTensor()(src_img))
  tensor_img
  ```

  ![](index_files/figure-commonmark/cell-8-output-1.png)



  ``` python
  from cjm_pytorch_utils.core import iterate_modules
  import torch
  from torchvision import models
  ```

  ``` python
  vgg = models.vgg16(weights=models.VGG16_Weights.IMAGENET1K_V1).features

  for index, module in enumerate(iterate_modules(vgg)):
      if type(module) == torch.nn.modules.activation.ReLU:
          print(f"{index}: {module}")
  ```

      1: ReLU(inplace=True)
      3: ReLU(inplace=True)
      6: ReLU(inplace=True)
      8: ReLU(inplace=True)
      11: ReLU(inplace=True)
      13: ReLU(inplace=True)
      15: ReLU(inplace=True)
      18: ReLU(inplace=True)
      20: ReLU(inplace=True)
      22: ReLU(inplace=True)
      25: ReLU(inplace=True)
      27: ReLU(inplace=True)
      29: ReLU(inplace=True)



  ``` python
  from cjm_pytorch_utils.core import tensor_stats_df
  ```

  ``` python
  tensor_stats_df(torch.randn(1, 3, 256, 256))
  ```

  <div>
  <style scoped>
      .dataframe tbody tr th:only-of-type {
          vertical-align: middle;
      }
  &#10;    .dataframe tbody tr th {
          vertical-align: top;
      }
  &#10;    .dataframe thead th {
          text-align: right;
      }
  </style>

  |       | 0                |
  |-------|------------------|
  | mean  | 0.003342         |
  | std   | 0.99868          |
  | min   | -4.558271        |
  | max   | 4.815985         |
  | shape | (1, 3, 256, 256) |

  </div>



  ``` python
  from cjm_pytorch_utils.core import get_torch_device
  ```

  ``` python
  get_torch_device()
  ```

      'cuda'



  ``` python
  from cjm_pytorch_utils.core import denorm_img_tensor
  ```

  ``` python
  tensor_to_pil(img_tensor)
  ```

  ![](index_files/figure-commonmark/cell-20-output-1.png)

  ``` python
  tensor_to_pil(denorm_img_tensor(img_tensor, [0.5], [0.5]))
  ```

  ![](index_files/figure-commonmark/cell-21-output-1.png)


pkgId: 10f6accdcd13516db5be26d21561ee053f57921d459988ff4838e830fa567702
name: python-cjm-torchvision-tfms
arch: src
version: 0.0.11
epoch: 0
release: 1
summary: Some custom Torchvision tranforms.
url: https://github.com/cj-mills/cjm-torchvision-tfms
rpm_license: Apache Software License 2.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-cjm-torchvision-tfms-0.0.11-1.src.rpm
checksum_type: sha256
description:
  <!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->



  ``` sh
  pip install cjm_torchvision_tfms
  ```



  ``` python
  from PIL import Image

  img_path = './images/call-hand-gesture.png'


  sample_img = Image.open(img_path).convert('RGB')


  print(f"Image Dims: {sample_img.size}")


  sample_img
  ```

      Image Dims: (384, 512)

  ![](index_files/figure-commonmark/cell-2-output-2.png)

  ``` python
  from cjm_torchvision_tfms.core import ResizeMax, PadSquare, CustomTrivialAugmentWide

  import torch
  from torchvision import transforms
  from cjm_pytorch_utils.core import tensor_to_pil
  from cjm_pil_utils.core import stack_imgs
  ```

  ``` python
  target_sz = 384
  ```

  ``` python
  print(f"Source image: {sample_img.size}")


  resize_max = ResizeMax(max_sz=target_sz)


  img_tensor = transforms.PILToTensor()(sample_img)[None]
  print(f"Image tensor: {img_tensor.shape}")


  resized_tensor = resize_max(img_tensor)
  print(f"Padded tensor: {resized_tensor.shape}")


  tensor_to_pil(resized_tensor)
  ```

      Source image: (384, 512)
      Image tensor: torch.Size([1, 3, 512, 384])
      Padded tensor: torch.Size([1, 3, 384, 288])

  ![](index_files/figure-commonmark/cell-6-output-2.png)

  ``` python
  print(f"Resized tensor: {resized_tensor.shape}")


  pad_square = PadSquare(shift=True)


  padded_tensor = pad_square(resized_tensor)
  print(f"Padded tensor: {padded_tensor.shape}")


  stack_imgs([tensor_to_pil(pad_square(resized_tensor)) for i in range(3)])
  ```

      Resized tensor: torch.Size([3, 384, 288])
      Padded tensor: torch.Size([3, 384, 384])

  ![](index_files/figure-commonmark/cell-8-output-2.png)

  ``` python
  num_bins = 31

  custom_augmentation_space = {
      
      "Identity": (torch.tensor(0.0), False),

      
      "ShearX": (torch.linspace(0.0, 0.25, num_bins), True),
      "ShearY": (torch.linspace(0.0, 0.25, num_bins), True),

      
      "TranslateX": (torch.linspace(0.0, 32.0, num_bins), True),
      "TranslateY": (torch.linspace(0.0, 32.0, num_bins), True),

      
      "Rotate": (torch.linspace(0.0, 45.0, num_bins), True),

      
      "Brightness": (torch.linspace(0.0, 0.75, num_bins), True),
      "Color": (torch.linspace(0.0, 0.99, num_bins), True),
      "Contrast": (torch.linspace(0.0, 0.99, num_bins), True),
      "Sharpness": (torch.linspace(0.0, 0.99, num_bins), True),

      
      "Posterize": (8 - (torch.arange(num_bins) / ((num_bins - 1) / 6)).round().int(), False),

      
      "Solarize": (torch.linspace(255.0, 0.0, num_bins), False),

      
      "AutoContrast": (torch.tensor(0.0), False),

      
      "Equalize": (torch.tensor(0.0), False),
  }


  trivial_aug = CustomTrivialAugmentWide(op_meta=custom_augmentation_space)


  aug_tensor = trivial_aug(resized_tensor)
  print(f"Augmented tensor: {aug_tensor.shape}")


  stack_imgs([tensor_to_pil(trivial_aug(resized_tensor)) for i in range(3)])
  ```

      Augmented tensor: torch.Size([3, 384, 288])

  ![](index_files/figure-commonmark/cell-10-output-2.png)


pkgId: 276d42a38357cf1d9e635dbee4e355c6979e16aeb8c4425a67199011fcf43bc0
name: python-cjops
arch: src
version: 1.0.87
epoch: 0
release: 1
summary: cj ops.
url: https://pypi.org/project/cjops/
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-cjops-1.0.87-1.src.rpm
checksum_type: sha256
description:
  阿里云相关功能方法 SlsLogStore(key) 实例化
  > 1.杭州ingress日志查询方法  hz_ingress_log
  > 1.杭州service日志查询方法  hz_service_log
  > 2.硅谷ingress日志查询方法  usa_ingress_log
  > 2.硅谷service日志查询方法  usa_service_log


  excel相关功能方法
  > 1.将字典列表写入到excel文件中 write_list_dict_excel
  > 2.将列表元组写入到excel文件中 write_list_tuple_excel


  企业微信
  > 1.markdown格式的企业微信通知 send_markdown_message


  subprocess执行shell命令
  > 1.通过subprocess执行shell命令 exec_command
  > 2.通过subprocess执行shell命令支持实时输出 exec_command_realtime_output


  域名相关功能方法
  > 1.获取域名解析的IP地址 get_ip_list
  > 2.获取域名解析的证书及过期天数 get_cert_details


  执行mysql相关的sql
  > 1.执行sql exec_mysql


  发送邮件 Mail(host, user, password, port, ssl)初始化
  > 1.发送文本邮件 send_msg_mail(title: str, msg: str, receivers: list)
  > 2.发送带有附件邮件 send_file_mail(title: str, msg: str, file_path: str, receivers: list)


  csv相关功能方法
  > 1.将数据写入到csv中 write_csv


  线程相关功能方法
  > 1.多线程运行任务 run_multithreaded


  工具箱
  > 1.md5加密 md5_encrypt
  > 2.base64编码 base64_encode
  > 3.base64解码 base64_decode
  > 4.生成随机Fernet密钥 fernet_generate_key
  > 4.使用fernet加密数据 fernet_jiami
  > 4.使用fernet解密数据 fernet_jiemi
  > 5.进度条 process_with_progress
  > 6.复制数据到粘贴板  copy_to_clipboard


pkgId: 0a1323276541a8bfb432017ada9ff367f2c3a0d0dee08a83c9d040fabd74c8af
name: python-cjtool
arch: src
version: 0.29.10
epoch: 0
release: 1
summary: Provide some tools in C++ development
url: https://pypi.org/project/cjtool/
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-cjtool-0.29.10-1.src.rpm
checksum_type: sha256
description:
  Provide some tools in C++ development.

  - Extracted raw strings from the C++ code


  The source code is [here](https://github.com/Junch/cjtool). The python package is [here](https://pypi.org/project/cjtool).



  ```
  pip install cjtool
  ```



  A new command `stringrep.exe` is added after the installation.

  - The command `stringrep` is to replace the raw string to a pointer. For example

  ```cpp
      auto m = py::module::import("test_cmake_build");
      // convert to the line below
      auto m = py::module::import(pStrTest_cmake_build);

      // the definiation of the string is as below
      constexpr char* pStrTest_cmake_build = "test_cmake_build";
  ```


  - Help message from the command `stringrep` is as below.

  ```
  $ stringrep -h
  usage: stringrep [-h] [-i] [-c] [-g] [-p PREFIX] file

  positional arguments:
    file                  set the cpp file name

  optional arguments:
    -h, --help            show this help message and exit
    -i, --inplace         replace the file in place (default: False)
    -c, --capitalize      capitalize the captured word, for example,
                          "tom" turns to "Tom" (default: False)
    -g, --generate        generate the header lines for the captured
                          strings (default: False)
    -p PREFIX, --prefix PREFIX
                          set the prefix for raw string (default: pStr)
  ```



  ```bash
  python -m build --sdist --wheel
  twine upload dist/*
  ```



  ```bash
  python -m pip install --editable .
  ```


pkgId: a1cc7f185379a4b6ede67b1cf604dc28f795e33354a5d990f14f5a8cf34f176e
name: python-cjunct
arch: src
version: 2.2.2
epoch: 0
release: 1
summary: Declarative task runner
url: https://github.com/reartnew/cjunct
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-cjunct-2.2.2-1.src.rpm
checksum_type: sha256
description:
  Cjunct (pronounced *SEE-jen*) is an extensible declarative task runner,
  aimed to make complex routine jobs easier to configure.

  [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/cjunct)](https://pypi.python.org/pypi/cjunct/)
  [![License](https://img.shields.io/pypi/l/cjunct.svg)](https://opensource.org/license/mit/)
  [![PyPI version](https://badge.fury.io/py/cjunct.svg)](https://pypi.python.org/pypi/cjunct/)
  [![Tests](https://github.com/reartnew/cjunct/workflows/main/badge.svg)](https://github.com/reartnew/cjunct/actions/workflows/main.yml)
  [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)

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

  1. [Installation](#installation)
  2. [Usage](#usage)
  3. [How to contribute](#contribute)

  </details>

  <div id="installation"></div>



  ```shell

  pip install cjunct


  pip install "cjunct[docker]"
  ```

  <div id="usage"></div>





  ```shell


  cjunct run


  cjunct --help
  ```

  Options are configured either via environment variables or via command-line switches. The most common are:

  - `CJUNCT_LOG_LEVEL`: Set log level.
  - `CJUNCT_LOG_FILE`: Set log file.
  - `CJUNCT_WORKFLOW_FILE`: Set the workflow file path explicitly.
  - `CJUNCT_STRATEGY_NAME`: Manage execution strategy.
  - `CJUNCT_ACTIONS_CLASS_DEFINITIONS_DIRECTORY`: Where to look for custom action runners.
  - `CJUNCT_STRICT_OUTCOMES_RENDERING`: Manage failure behaviour when an outcome key is missing.

  Full list of used environment variable names can be obtained with this command:

  ```shell
  cjunct info env-vars
  ```

  <div id="contribute"></div>





  Requires system-wide poetry>=1.3.2, see [official documentation](https://python-poetry.org).

  ```shell
  poetry env use python3.8
  poetry install --no-root --sync --all-extras
  ```

  The root directory for the source code is `src`,
  thus one may add it to the project's python path
  for better IDE integration.



  ```shell
  poetry run pytest --cov --cov-report=html:.coverage_report
  ```



  ```shell
  poetry run tox
  ```


pkgId: 6f5ff4ce2435fc3735d7e3e2f9f542539034a21a5883efae6256a2626a42ab8f
name: python-ck
arch: src
version: 2.6.4
epoch: 0
release: 1
url: https://github.com/mlcommons/ck
rpm_license: Apache 2.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ck-2.6.4-1.src.rpm
checksum_type: sha256
summary:
  Collective Knowledge - a lightweight knowledge manager to organize, cross-link, share and reuse artifacts and workflows based on FAIR principles

description:
  <br>
  <br>
  <br>

  **Note that this directory is in the archive mode since the Collective Knowledge framework (v1 and v2)
    is now officially discontinued in favour of the new, light-weight, non-intrusive and technology-agnostic
    [Collective Mind workflow workflow automation framework ](../cm). You can learn more about the motivation
    behind CK in this [ACM TechTalk](https://www.youtube.com/watch?v=7zpeIVwICa4)
    and the [journal article](https://doi.org/10.1098/rsta.2020.0211).**

  <br>
  <br>
  <br>



  [![Downloads](https://pepy.tech/badge/ck)](https://pepy.tech/project/ck)
  [![PyPI version](https://badge.fury.io/py/ck.svg)](https://badge.fury.io/py/ck)
  [![Python Version](https://img.shields.io/badge/python-2.7%20|%203.4+-blue.svg)](https://pypi.org/project/ck)

  [![Build Status](https://travis-ci.com/ctuning/ck.svg?branch=master)](https://travis-ci.com/ctuning/ck)
  [![Windows Build status](https://ci.appveyor.com/api/projects/status/iw2k4eajy54xrvqc?svg=true)](https://ci.appveyor.com/project/gfursin/ck)
  [![Coverage Status](https://coveralls.io/repos/github/ctuning/ck/badge.svg)](https://coveralls.io/github/ctuning/ck)

  [![Documentation Status](https://readthedocs.org/projects/ck/badge/?version=latest)](https://ck.readthedocs.io/en/latest/?badge=latest)
  [![Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/1Fp6uxCqTazmCSSl8v-nY93VVmcOoLiXi?usp=sharing)
  [![Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/1a761nKgoHlJAy6gOXh-c9H4WkLV8nzRU?usp=sharing)






  * **2022 May:** [Grigori Fursin](https://cKnowledge.org/gfursin)
    started prototyping the new [Collective Mind framework](https://doi.org/10.5281/zenodo.8105339)
    within the [MLCommons Task Force on Automation and Reproducibility](../../docs/taskforce.md)
    from scratch based on the feedback from the users and MLCommons members.

  * **2022 April 3:** We presented the CK concept to bridge the growing gap between ML Systems research and production
    at the HPCA'22 workshop on [benchmarking deep learning systems](https://sites.google.com/g.harvard.edu/mlperf-bench-hpca22/home).

  * **2022 March:** We presented the [CK concept to enable collaborative and reproducible ML Systems R&D](https://meetings.siam.org/sess/dsp_programsess.cfm?SESSIONCODE=73126)
    at the SIAM'22 workshop on "Research Challenges and Opportunities within Software Productivity, Sustainability, and Reproducibility"

  * **2022 March:** we've released the first prototype of [the Collective Mind toolkit (CK2)](https://github.com/mlcommons/ck/tree/master/ck2)
    based on your feedback and our practical experience [reproducing 150+ ML and Systems papers and validating them in the real world](https://www.youtube.com/watch?v=7zpeIVwICa4).



  While Machine Learning is becoming more and more important in everyday life, designing efficient ML Systems and deploying them in the real world
  is becoming increasingly challenging, time consuming and costly.
  Researchers and engineers must keep pace with rapidly evolving software stacks and a Cambrian explosion of hardware platforms from the cloud to the edge.
  Such platforms have their own specific libraries, frameworks, APIs and specifications and often require repetitive, tedious and ad-hoc optimization
  of the whole model/software/hardware stack to trade off accuracy, latency, throughout, power consumption, size and costs depending on user requirements and constraints.



  *The Collective Knowledge framework (CK)* is our attempt to develop a common plug&play infrastructure that can be used
  by the community similar to Wikipedia to learn how to solve above challenges and make it easier to co-design,
  benchmark, optimize and deploy Machine Learning Systems in the real world across continuously evolving software,
  hardware and data sets (see our [ACM TechTalk](https://www.youtube.com/watch?v=7zpeIVwICa4) for more details):

  * CK aims at providing a simple playground with minimal software dependencies to help researchers and practitioners share their knowledge
    in the form of reusable automation recipes with a unified Python API, CLI and meta description:
    - [Stable CK automation recipes](https://github.com/mlcommons/ck/tree/master/ck/repo/module)
    - [MLPerf&trade; benchmark automation recipes](https://github.com/mlcommons/ck/tree/master/ck-mlops/repo/module)

  * CK helps to organize software projects and Git repositories as a database of above automation recipes
    and related artifacts based on [FAIR principles](https://www.nature.com/articles/sdata201618)
    as described in our [journal article](https://arxiv.org/pdf/2011.01149.pdf) ([shorter pre-print]( https://arxiv.org/abs/2006.07161 )).
    See examples of CK-compatible GitHub repositories:
    - [MLPerf/MLOps automation](https://github.com/mlcommons/ck-mlops)
    - [ACM REQUEST tournament for collaborative and reproducible ML/SW/HW co-design](https://github.com/ctuning/ck-request)



  We collaborated with the community to reproduce [150+ ML and Systems papers](https://cTuning.org/ae)
  and implement the following reusable automation recipes in the CK format:

  * Portable meta package manager to automatically detect, install or rebuild various ML artifacts
    (ML models, data sets, frameworks, libraries, etc) across different platform and operating systems including Linux, Windows, MacOS and Android:
    - [ML artifact detection plugins](https://github.com/mlcommons/ck-mlops/tree/main/soft)
    - [ML meta package installation plugins](https://github.com/mlcommons/ck-mlops/tree/main/package)
    - OS descriptions: [Linux/MacOS/Android](https://github.com/mlcommons/ck-mlops/tree/main/os) ; [Windows](https://github.com/ctuning/ck-win/tree/main/os)

  * Portable manager for Python virtual environments: [CK repo](https://github.com/mlcommons/ck-venv).

  * Portable workflows to support collaborative, reproducible and cross-platform benchmarking:
    - [ML Systems benchmarking](https://github.com/mlcommons/ck-mlops/tree/main/program)
    - [Compiler benchmarking](https://github.com/ctuning/ctuning-programs/tree/master/program)

  * Portable workflows to automate MLPerf&trade; benchmark:
    - [End-to-end submission suite used by multiple organizations to automate the submission of MLPerf inference benchmark](https://github.com/mlcommons/ck/blob/master/docs/mlperf-automation/README.md)
      - MLPerf inference v1.1 results: [MLCommons press-release](https://mlcommons.org/en/news/mlperf-inference-v11),
        [Datacenter results](https://mlcommons.org/en/inference-datacenter-11),
        [Edge results](https://mlcommons.org/en/inference-edge-11)
    - [Reproducibility studies for MLPerf inference benchmark v1.1 automated by CK](https://github.com/mlcommons/ck/tree/master/docs/mlperf-automation/reproduce#reproducibility-reports-mlperf-inference-benchmark-v11)
    - [Design space exploration of ML/SW/HW stacks and customizable visualization](https://cknow.io/result/crowd-benchmarking-mlperf-inference-classification-mobilenets-all)


  Please contact [Grigori Fursin](https://www.linkedin.com/in/grigorifursin) if you are interested to join this community effort!



  * [CK automations for unified benchmarking]( https://colab.research.google.com/drive/1a761nKgoHlJAy6gOXh-c9H4WkLV8nzRU?usp=sharing )
  * [CK-based MLPerf inference benchmark automation example]( https://colab.research.google.com/drive/1Fp6uxCqTazmCSSl8v-nY93VVmcOoLiXi?usp=sharing )
    * [CK-based MLPerf inference vision benchmark v1.1 automation (TVM)]( https://colab.research.google.com/drive/1aywGlyD1ZRDtQTrQARVgL1882JcvmFK-?usp=sharing )
    * [CK-based MLPerf inference vision benchmark v1.1 automation (ONNX)]( https://colab.research.google.com/drive/1ij1rWoqje5-Sn6UsdFj1OzYakudI2RIS?usp=sharing )
  * [CK basics]( https://colab.research.google.com/drive/15lQgxuTSkEPqi4plaat1_v2gJcfIrATF?usp=sharing )





  The latest version of the CK automation suite supported by MLCommons&trade;:
  * [CK framework v2.6.1 (Apache 2.0 license)](https://github.com/mlcommons/ck/releases/tag/V2.6.1)
  * [CK automation suite for MLPerf&trade; and ML/SW/HW co-design](https://github.com/mlcommons/ck-mlops)



  * [Automating MLPerf(tm) inference benchmark and packing ML models, data sets and frameworks as CK components with a unified API and meta description](https://github.com/mlcommons/ck/blob/master/docs/mlperf-automation/README.md)
  * Developing customizable dashboards for MLPerf&trade; to help end-users select ML/SW/HW stacks on a Pareto frontier: [aggregated MLPerf&trade; results]( https://cknow.io/?q="mlperf-inference-all" )
  * Providing a common format to share artifacts at ML, systems and other conferences: [video](https://youtu.be/DIkZxraTmGM), [Artifact Evaluation](https://cTuning.org/ae)
  * Redesigning CK together with the community based on user feedback: [incubator](https://github.com/mlcommons/ck/tree/master/incubator)
  * [Other real-world use cases](https://cKnowledge.org/partners.html) from MLPerf&trade;, Qualcomm, Arm, General Motors, IBM, the Raspberry Pi foundation, ACM and other great partners;



  * [Online CK documentation]( https://ck.readthedocs.io )
    * [Why CK?]( https://ck.readthedocs.io/en/latest/src/introduction.html )
    * [CK Basics](https://michel-steuwer.github.io/About-CK)
    * [Try CK]( https://ck.readthedocs.io/en/latest/src/first-steps.html )
  * [Publications](https://github.com/mlcommons/ck/wiki/Publications)



  Follow [this guide](https://ck.readthedocs.io/en/latest/src/installation.html)
  to install CK framework on your platform.

  CK supports the following platforms:

  |               | As a host platform | As a target platform |
  |---------------|:------------------:|:--------------------:|
  | Generic Linux | ✓ | ✓ |
  | Linux (Arm)   | ✓ | ✓ |
  | Raspberry Pi  | ✓ | ✓ |
  | MacOS         | ✓ | ± |
  | Windows       | ✓ | ✓ |
  | Android       | ± | ✓ |
  | iOS           | TBD | TBD |
  | Bare-metal (edge devices)   | - | ± |





  Here we show how to pull a GitHub repo in the CK format
  and use a unified CK interface to compile and run
  any program (image corner detection in our case)
  with any compatible data set on any compatible platform:

  ```bash
  python3 -m pip install ck

  ck pull repo:mlcommons@ck-mlops

  ck ls program:*susan*

  ck search dataset --tags=jpeg

  ck pull repo:ctuning-datasets-min

  ck search dataset --tags=jpeg

  ck detect soft:compiler.gcc
  ck detect soft:compiler.llvm

  ck show env --tags=compiler

  ck compile program:image-corner-detection --speed

  ck run program:image-corner-detection --repeat=1 --env.MY_ENV=123 --env.TEST=xyz
  ```

  You can check output of this program in the following directory:
  ```bash
  cd `ck find program:image-corner-detection`/tmp
  ls

  processed-image.pgm
  ```

  You can now view this image with detected corners.


  Check [CK docs](https://ck.readthedocs.io/en/latest/src/introduction.html) for further details.



  * [Current coverage](https://github.com/mlcommons/ck/tree/master/docs/mlperf-automation#readme)
  * [MLPerf inference v1.1 workflows](https://github.com/mlcommons/ck/blob/master/docs/mlperf-automation/reproduce/README.md#reproducibility-reports-mlperf-inference-benchmark-v11)



  We have prepared adaptive CK containers to demonstrate MLOps capabilities:
  * https://github.com/mlcommons/ck-mlops/tree/main/docker

  You can run them as follows:

  ```bash
  ck pull repo:mlcommons@ck-mlops
  ck build docker:ck-template-mlperf --tag=ubuntu-20.04
  ck run docker:ck-template-mlperf --tag=ubuntu-20.04
  ```



  You can create multiple [virtual CK environments](https://github.com/mlcommons/ck-venv) with templates
  to automatically install different CK packages and workflows, for example for MLPerf&trade; inference:

  ```
  ck pull repo:mlcommons@ck-venv
  ck create venv:test --template=mlperf-inference-main
  ck ls venv
  ck activate venv:test

  ck pull repo:mlcommons@ck-mlops
  ck install package --ask --tags=dataset,coco,val,2017,full
  ck show env

  ```



  All CK modules, automation actions and workflows are accessible as a micro-service with a unified JSON I/O API
  to make it easier to integrate them with web services and CI platforms as described
  [here](https://github.com/mlcommons/ck/blob/master/docs/mlperf-automation/tools/continuous-integration.md).






  * [List of various use cases]( https://ck.readthedocs.io/en/latest/src/introduction.html#ck-showroom )









  We use the [cKnowledge.io portal](https://cknow.io) to help the community
  organize and find all the CK workflows and components similar to PyPI:

  * [Search CK components](https://cknow.io)
  * [Browse CK components](https://cknow.io/browse)
  * [Find reproduced results from papers]( https://cknow.io/reproduced-results )
  * [Test CK workflows to benchmark and optimize ML Systems]( https://cknow.io/demo )





  The community provides Docker containers to test CK and components using different ML/SW/HW stacks (DSE).

  * A set of Docker containers to test the basic CK functionality
    using some MLPerf inference benchmark workflows:
    https://github.com/mlcommons/ck-mlops/tree/main/docker/test-ck





  We would like to thank all [collaborators and contributors](CONTRIBUTING.md)
  for their support, fruitful discussions, and useful feedback!
  See more acknowledgments in this [journal article](https://doi.org/10.1098/rsta.2020.0211)
  and [ACM TechTalk'21](https://www.youtube.com/watch?v=7zpeIVwICa4).


pkgId: 2f4b252f3e798068354f054746fa1d3a243453b8dd4e9e1adbc80d250216cbc9
name: python-ck-apstra-api
arch: src
version: 0.4.28
epoch: 0
release: 1
summary: An implementation to use Apstra API
url: https://pypi.org/project/ck-apstra-api/
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ck-apstra-api-0.4.28-1.src.rpm
checksum_type: sha256
description:
  https://github.com/kimcharli/ck-apstra-api





  [ChangeLog](./ChangeLog.md)


  install python3.11: https://www.python.org/downloads/windows/





  https://git-scm.com/download/win




  ```
  ckim@ckim-mbp:sandbox % mkdir test
  ckim@ckim-mbp:sandbox % cd test
  ckim@ckim-mbp:test % python -m venv .venv
  ckim@ckim-mbp:test % source .venv/bin/activate
  (.venv) ckim@ckim-mbp:test % pip install ck-apstra-api==0.4.13
  ...
  (.venv) ckim@ckim-mbp:test %
  ```



  ```
  cd test
  py -m venv .venv
  .venv\Scripts\activate
  pip install ck-apstra-api==0.4.13
  ```




  ```
  (.venv) ckim@ckim-mbp:ck-apstra-api % ck-cli --version
  ck_apstra_api, 0.4.12
  (.venv) ckim@ckim-mbp:ck-apstra-api %
  ```

  ```
  (.venv) ckim@ckim-mbp:ck-apstra-api % ck-cli --help
  Usage: ck-cli [OPTIONS] COMMAND [ARGS]...

    A CLI tool for interacting with ck-apstra-api

  Options:
    --host-ip TEXT        Host IP address
    --host-port INTEGER   Host port
    --host-user TEXT      Host username
    --host-password TEXT  Host password
    --version             Show the version and exit.
    --help                Show this message and exit.

  Commands:
    check-apstra           Test the connectivity to the server
    check-blueprint        Test the connectivity to the blueprint
    export-blueprint       Export a blueprint into a json file
    export-device-configs  Export a device configurations into multiple files
    export-generic-system  Export generic systems to a CSV file
    export-systems         Export systems of a blueprint to a CSV file
    import-blueprint       Import a blueprint from a json file
    import-generic-system  Import generic systems from a CSV file
    relocate-vn            Move a Virtual Network to the target Routing Zone
    test-get-temp-vn       Test get_temp_vn
  (.venv) ckim@ckim-mbp:ck-apstra-api %
  ```





  |line|blueprint|server       |ext|tags_server|ae   |lag_mode   |ct_names    |tags_ae|speed|ifname|switch  |switch_ifname|tags_link|comment|
  |----|---------|-------------|---|-----------|-----|-----------|------------|-------|-----|------|--------|-------------|---------|-------|
  |1   |terra    |single-home-1|   |single     |     |           | vn20       |single |10g  |eth0  |server_1|xe-0/0/11    |         |       |
  |2   |terra    |dual-home-1  |   |dual       |ae101|lacp_active|vn20 , vn101|dual   |10g  |eth0  |server_1|xe-0/0/12    |forceup  |       |
  |3   |terra    |dual-home-1  |   |dual       |ae101|lacp_active|vn20,vn101  |dual   |10g  |eth1  |server_2|xe-0/0/12    |         |       |

  [gs_sample.csv](./tests/fixtures/gs_sample.csv)




  ```
  (.venv) ckim@ckim-mbp:ck-apstra-api % ck-cli import-generic-system --help
  Usage: ck-cli import-generic-system [OPTIONS]

    Import generic systems from a CSV file

  Options:
    --gs-csv-in TEXT  Path to the CSV file for generic systems
    --help            Show this message and exit.
  (.venv) ckim@ckim-mbp:ck-apstra-api %
  (.venv) ckim@ckim-mbp:ck-apstra-api % ck-cli --host-ip 10.85.192.45 --host-password admin import-generic-system --gs-csv-in ~/Downloads/gs_sample.csv
  2024-06-29 17:51:43,445 - INFO     - import_generic_system - add_generic_systems ServerBlueprint._bps={'terra': ServerBlueprint(blueprint='terra')} (cli.py:246)
  2024-06-29 17:51:43,445 - INFO     - import_generic_system - ServerBlueprint:fetch_apstra() self.blueprint='terra' (cli.py:246)
  2024-06-29 17:51:43,956 - INFO     - import_generic_system - LinkMember(server_1:xe-0/0/11:eth0)::fetch_apstra() done LinkMember(line='1', speed='10G', ifname='eth0', switch='server_1', switch_ifname='xe-0/0/11', tags_link=[], comment='', fetched_server_ifname=None, fetched_server_intf_id=None, fetched_switch_id='2QKZLUzqCO0ZJ73Fb1I', fetched_switch_intf_id=None, fetched_tags_link=None, fetched_link_id=None) (cli.py:246)
  2024-06-29 17:51:43,956 - INFO     - import_generic_system - LinkGroup(____1)::fetch_apstra() done LinkGroup(ae='____1', lag_mode='', ct_names=['vn20'], tags_ae=['single'], fetched_ae_id=None, fetched_lag_mode=None, fetched_ct_names=[], fetched_tags=None) (cli.py:246)
  2024-06-29 17:51:43,956 - INFO     - import_generic_system - text GenericSystem(single-home-1)::fetch_apstra() done GenericSystem(server='single-home-1', ext='', tags_server=['single'], gs_id=None, fetched_server_tags=None) (cli.py:250)
  2024-06-29 17:51:44,223 - INFO     - import_generic_system - LinkMember(server_1:xe-0/0/12:eth0)::fetch_apstra() done LinkMember(line='2', speed='10G', ifname='eth0', switch='server_1', switch_ifname='xe-0/0/12', tags_link=['forceup'], comment='', fetched_server_ifname=None, fetched_server_intf_id=None, fetched_switch_id='2QKZLUzqCO0ZJ73Fb1I', fetched_switch_intf_id=None, fetched_tags_link=None, fetched_link_id=None) (cli.py:246)
  2024-06-29 17:51:44,374 - INFO     - import_generic_system - LinkMember(server_2:xe-0/0/12:eth1)::fetch_apstra() done LinkMember(line='3', speed='10G', ifname='eth1', switch='server_2', switch_ifname='xe-0/0/12', tags_link=[], comment='', fetched_server_ifname=None, fetched_server_intf_id=None, fetched_switch_id='qCc9ps52vPppDp2b6rk', fetched_switch_intf_id=None, fetched_tags_link=None, fetched_link_id=None) (cli.py:246)
  2024-06-29 17:51:44,375 - INFO     - import_generic_system - LinkGroup(ae101)::fetch_apstra() done LinkGroup(ae='ae101', lag_mode='lacp_active', ct_names=['vn20', 'vn101'], tags_ae=['dual'], fetched_ae_id=None, fetched_lag_mode=None, fetched_ct_names=[], fetched_tags=None) (cli.py:246)
  2024-06-29 17:51:44,375 - INFO     - import_generic_system - text GenericSystem(dual-home-1)::fetch_apstra() done GenericSystem(server='dual-home-1', ext='', tags_server=['dual'], gs_id=None, fetched_server_tags=None) (cli.py:250)
  2024-06-29 17:51:44,375 - INFO     - import_generic_system - add_generic_systems fetched ServerBlueprint._bps={'terra': ServerBlueprint(blueprint='terra')} (cli.py:246)
  2024-06-29 17:51:51,000 - INFO     - import_generic_system - GenericSystem(single-home-1)::create() creating generic_system_spec={'links': [{'switch': {'system_id': '2QKZLUzqCO0ZJ73Fb1I', 'transformation_id': 1, 'if_name': 'xe-0/0/11'}, 'system': {'system_id': None}, 'lag_mode': None, 'link_group_label': None}], 'new_systems': [{'system_type': 'server', 'label': 'single-home-1', 'port_channel_id_min': 0, 'port_channel_id_max': 0, 'logical_device': {'display_name': 'ck-auto-1x10', 'id': 'ck-auto-1x10', 'panels': [{'panel_layout': {'row_count': 1, 'column_count': 1}, 'port_indexing': {'order': 'T-B, L-R', 'start_index': 1, 'schema': 'absolute'}, 'port_groups': [{'count': 1, 'speed': {'unit': 'G', 'value': 10}, 'roles': ['leaf', 'access']}]}]}}]} (cli.py:246)
  2024-06-29 17:51:52,321 - INFO     - import_generic_system - GenericSystem(single-home-1)::create() created (cli.py:246)
  2024-06-29 17:51:52,659 - INFO     - import_generic_system - GenericSystem(dual-home-1)::create() creating generic_system_spec={'links': [{'switch': {'system_id': '2QKZLUzqCO0ZJ73Fb1I', 'transformation_id': 1, 'if_name': 'xe-0/0/12'}, 'system': {'system_id': None}, 'lag_mode': None, 'link_group_label': None}, {'switch': {'system_id': 'qCc9ps52vPppDp2b6rk', 'transformation_id': 1, 'if_name': 'xe-0/0/12'}, 'system': {'system_id': None}, 'lag_mode': None, 'link_group_label': None}], 'new_systems': [{'system_type': 'server', 'label': 'dual-home-1', 'port_channel_id_min': 0, 'port_channel_id_max': 0, 'logical_device': {'display_name': 'ck-auto-2x10', 'id': 'ck-auto-2x10', 'panels': [{'panel_layout': {'row_count': 1, 'column_count': 2}, 'port_indexing': {'order': 'T-B, L-R', 'start_index': 1, 'schema': 'absolute'}, 'port_groups': [{'count': 2, 'speed': {'unit': 'G', 'value': 10}, 'roles': ['leaf', 'access']}]}]}}]} (cli.py:246)
  2024-06-29 17:51:53,984 - INFO     - import_generic_system - GenericSystem(dual-home-1)::create() created (cli.py:246)
  2024-06-29 17:51:53,985 - INFO     - import_generic_system - add_generic_systems generic_systems added ServerBlueprint._bps={'terra': ServerBlueprint(blueprint='terra')} (cli.py:246)
  2024-06-29 17:51:53,985 - INFO     - import_generic_system - ServerBlueprint:fetch_apstra() self.blueprint='terra' (cli.py:246)
  2024-06-29 17:51:54,399 - INFO     - import_generic_system - LinkMember(server_1:xe-0/0/11:eth0)::fetch_apstra() done LinkMember(line='1', speed='10G', ifname='eth0', switch='server_1', switch_ifname='xe-0/0/11', tags_link=[], comment='', fetched_server_ifname=None, fetched_server_intf_id='Eoj5YQ2DufOIkAwqJFs', fetched_switch_id='2QKZLUzqCO0ZJ73Fb1I', fetched_switch_intf_id='wHrEU9Ogsu5PT3rX5ZU', fetched_tags_link=None, fetched_link_id='server_1<->single-home-1(link-000000001)[1]') (cli.py:246)
  2024-06-29 17:51:54,526 - INFO     - import_generic_system - LinkGroup(____1)::fetch_apstra() done LinkGroup(ae='____1', lag_mode='', ct_names=['vn20'], tags_ae=['single'], fetched_ae_id='wHrEU9Ogsu5PT3rX5ZU', fetched_lag_mode=None, fetched_ct_names=[], fetched_tags=None) (cli.py:246)
  2024-06-29 17:51:54,662 - INFO     - import_generic_system - text GenericSystem(single-home-1)::fetch_apstra() done GenericSystem(server='single-home-1', ext='', tags_server=['single'], gs_id='vjdUZp5Bzan9ly5CGMg', fetched_server_tags=[]) (cli.py:250)
  2024-06-29 17:51:54,791 - INFO     - import_generic_system - LinkMember(server_1:xe-0/0/12:eth0)::fetch_apstra() done LinkMember(line='2', speed='10G', ifname='eth0', switch='server_1', switch_ifname='xe-0/0/12', tags_link=['forceup'], comment='', fetched_server_ifname=None, fetched_server_intf_id='MxGkufPpO905ZT0vyT4', fetched_switch_id='2QKZLUzqCO0ZJ73Fb1I', fetched_switch_intf_id='92L4PECw70iubqVgl88', fetched_tags_link=None, fetched_link_id='server_1<->dual-home-1(link-000000001)[1]') (cli.py:246)
  2024-06-29 17:51:54,791 - INFO     - import_generic_system - LinkMember(server_2:xe-0/0/12:eth1)::fetch_apstra() done LinkMember(line='3', speed='10G', ifname='eth1', switch='server_2', switch_ifname='xe-0/0/12', tags_link=[], comment='', fetched_server_ifname=None, fetched_server_intf_id='619M5CRWBvhqPtzhzsM', fetched_switch_id='qCc9ps52vPppDp2b6rk', fetched_switch_intf_id='FlQxBvVV_uVaV_g1VPI', fetched_tags_link=None, fetched_link_id='server_2<->dual-home-1(link-000000002)[1]') (cli.py:246)
  2024-06-29 17:51:54,792 - INFO     - import_generic_system - LinkGroup(ae101)::fetch_apstra() done LinkGroup(ae='ae101', lag_mode='lacp_active', ct_names=['vn20', 'vn101'], tags_ae=['dual'], fetched_ae_id=None, fetched_lag_mode=None, fetched_ct_names=[], fetched_tags=None) (cli.py:246)
  2024-06-29 17:51:54,916 - INFO     - import_generic_system - text GenericSystem(dual-home-1)::fetch_apstra() done GenericSystem(server='dual-home-1', ext='', tags_server=['dual'], gs_id='l1zH-lTraCUodsjRCGQ', fetched_server_tags=[]) (cli.py:250)
  2024-06-29 17:51:54,916 - INFO     - import_generic_system - add_generic_systems after generic system creation - fetched ServerBlueprint._bps={'terra': ServerBlueprint(blueprint='terra')} (cli.py:246)
  2024-06-29 17:51:54,916 - INFO     - import_generic_system - LinkGroup(____1)::form_lacp() self.ae='____1' is not for lag. Skipping (cli.py:246)
  2024-06-29 17:51:55,982 - WARNING  - import_generic_system - LinkGroup(ae101)::form_lacp() self.ae='ae101' has no ae_id. Skipping (cli.py:248)
  2024-06-29 17:51:55,982 - INFO     - import_generic_system - add_generic_systems lacp formed ServerBlueprint._bps={'terra': ServerBlueprint(blueprint='terra')} (cli.py:246)
  2024-06-29 17:51:55,982 - INFO     - import_generic_system - ServerBlueprint:fetch_apstra() self.blueprint='terra' (cli.py:246)
  2024-06-29 17:51:56,344 - INFO     - import_generic_system - LinkMember(server_1:xe-0/0/11:eth0)::fetch_apstra() done LinkMember(line='1', speed='10G', ifname='eth0', switch='server_1', switch_ifname='xe-0/0/11', tags_link=[], comment='', fetched_server_ifname=None, fetched_server_intf_id='Eoj5YQ2DufOIkAwqJFs', fetched_switch_id='2QKZLUzqCO0ZJ73Fb1I', fetched_switch_intf_id='wHrEU9Ogsu5PT3rX5ZU', fetched_tags_link=None, fetched_link_id='server_1<->single-home-1(link-000000001)[1]') (cli.py:246)
  2024-06-29 17:51:56,469 - INFO     - import_generic_system - LinkGroup(____1)::fetch_apstra() done LinkGroup(ae='____1', lag_mode='', ct_names=['vn20'], tags_ae=['single'], fetched_ae_id='wHrEU9Ogsu5PT3rX5ZU', fetched_lag_mode=None, fetched_ct_names=[], fetched_tags=None) (cli.py:246)
  2024-06-29 17:51:56,588 - INFO     - import_generic_system - text GenericSystem(single-home-1)::fetch_apstra() done GenericSystem(server='single-home-1', ext='', tags_server=['single'], gs_id='vjdUZp5Bzan9ly5CGMg', fetched_server_tags=[]) (cli.py:250)
  2024-06-29 17:51:56,720 - INFO     - import_generic_system - LinkMember(server_1:xe-0/0/12:eth0)::fetch_apstra() done LinkMember(line='2', speed='10G', ifname='eth0', switch='server_1', switch_ifname='xe-0/0/12', tags_link=['forceup'], comment='', fetched_server_ifname=None, fetched_server_intf_id='MxGkufPpO905ZT0vyT4', fetched_switch_id='2QKZLUzqCO0ZJ73Fb1I', fetched_switch_intf_id='92L4PECw70iubqVgl88', fetched_tags_link=None, fetched_link_id='server_1<->dual-home-1(link-000000001)[1]') (cli.py:246)
  2024-06-29 17:51:56,720 - INFO     - import_generic_system - LinkMember(server_2:xe-0/0/12:eth1)::fetch_apstra() done LinkMember(line='3', speed='10G', ifname='eth1', switch='server_2', switch_ifname='xe-0/0/12', tags_link=[], comment='', fetched_server_ifname=None, fetched_server_intf_id='619M5CRWBvhqPtzhzsM', fetched_switch_id='qCc9ps52vPppDp2b6rk', fetched_switch_intf_id='FlQxBvVV_uVaV_g1VPI', fetched_tags_link=None, fetched_link_id='server_2<->dual-home-1(link-000000002)[1]') (cli.py:246)
  2024-06-29 17:51:56,840 - INFO     - import_generic_system - LinkGroup(ae101)::fetch_apstra() done LinkGroup(ae='ae1', lag_mode='lacp_active', ct_names=['vn20', 'vn101'], tags_ae=['dual'], fetched_ae_id='QsX0BGRzwmP3ZVcNzYA', fetched_lag_mode='lacp_active', fetched_ct_names=[], fetched_tags=None) (cli.py:246)
  2024-06-29 17:51:56,974 - INFO     - import_generic_system - text GenericSystem(dual-home-1)::fetch_apstra() done GenericSystem(server='dual-home-1', ext='', tags_server=['dual'], gs_id='l1zH-lTraCUodsjRCGQ', fetched_server_tags=[]) (cli.py:250)
  2024-06-29 17:51:56,974 - INFO     - import_generic_system - add_generic_systems after form lag - fetched ServerBlueprint._bps={'terra': ServerBlueprint(blueprint='terra')} (cli.py:246)
  2024-06-29 17:51:56,975 - INFO     - import_generic_system - LinkGroup(____1)::rename_interfaces() self.ae='____1' rename_spec={'links': [{'endpoints': [{'interface': {'id': 'wHrEU9Ogsu5PT3rX5ZU'}}, {'interface': {'id': 'Eoj5YQ2DufOIkAwqJFs', 'if_name': 'eth0'}}], 'id': 'server_1<->single-home-1(link-000000001)[1]'}]} (cli.py:246)
  2024-06-29 17:51:57,819 - INFO     - import_generic_system - LinkGroup(____1) self.ae='____1' rename done (cli.py:246)
  2024-06-29 17:51:57,819 - INFO     - import_generic_system - LinkGroup(ae101)::rename_interfaces() self.ae='ae1' rename_spec={'links': [{'endpoints': [{'interface': {'id': '92L4PECw70iubqVgl88'}}, {'interface': {'id': 'MxGkufPpO905ZT0vyT4', 'if_name': 'eth0'}}], 'id': 'server_1<->dual-home-1(link-000000001)[1]'}, {'endpoints': [{'interface': {'id': 'FlQxBvVV_uVaV_g1VPI'}}, {'interface': {'id': '619M5CRWBvhqPtzhzsM', 'if_name': 'eth1'}}], 'id': 'server_2<->dual-home-1(link-000000002)[1]'}]} (cli.py:246)
  2024-06-29 17:51:58,989 - INFO     - import_generic_system - LinkGroup(ae101) self.ae='ae1' rename done (cli.py:246)
  2024-06-29 17:51:58,989 - INFO     - import_generic_system - add_generic_systems interfaces renamed ServerBlueprint._bps={'terra': ServerBlueprint(blueprint='terra')} (cli.py:246)
  2024-06-29 17:51:59,267 - INFO     - import_generic_system - GenericSystem(single-home-1) done - 1 vlans (cli.py:246)
  2024-06-29 17:51:59,524 - INFO     - import_generic_system - GenericSystem(dual-home-1) done - 1 vlans (cli.py:246)
  2024-06-29 17:51:59,524 - INFO     - import_generic_system - add_generic_systems vlans added ServerBlueprint._bps={'terra': ServerBlueprint(blueprint='terra')} (cli.py:246)
  (.venv) ckim@ckim-mbp:ck-apstra-api %
  ```



  Below is an example code to call add_generic_systems from a script.
  ```python
  def import_generic_system(ctx, gs_csv_in: str):
      """
      Import generic systems from a CSV file
      """
      from ck_apstra_api.generic_system import GsCsvKeys, add_generic_systems
      from ck_apstra_api.apstra_session import CkApstraSession
      from result import Ok, Err
      import logging

      logger = logging.getLogger('import_generic_system')
      logger.setLevel(logging.INFO)
      

      host_ip = ctx.obj['HOST_IP']
      host_port = ctx.obj['HOST_PORT']
      host_user = ctx.obj['HOST_USER']
      host_password = ctx.obj['HOST_PASSWORD']

      
      

      session = CkApstraSession(host_ip, host_port, host_user, host_password)
      gs_csv_path = os.path.expanduser(gs_csv_in)

      links_to_add = []
      with open(gs_csv_path, 'r') as csvfile:
          csv_reader = csv.reader(csvfile)
          headers = next(csv_reader)  # Read the header row
          expected_headers = [header.value for header in GsCsvKeys]
          if headers != expected_headers:
              raise ValueError("CSV header mismatch. Expected headers: " + ', '.join(expected_headers))

          for row in csv_reader:
              links_to_add.append(dict(zip(headers, row)))

      for res in add_generic_systems(session, links_to_add):
          if isinstance(res, Ok):
              logger.info(res.ok_value)
          elif isinstance(res, Err):
              logger.warning(res.err_value)
          else:
              logger.info(f"text {res}")
  ```



  Currenly only takes care of VLANs.


  ```
  ckim@ckim-mbp:ck-apstra-api % ck-cli relocate-vn --help
  Usage: ck-cli relocate-vn [OPTIONS]

    Move a Virtual Network to the target Routing Zone

    The virtual network move involves deleting and recreating the virtual
    network in the target routing zone. To delete the virtual network, the
    associated CT should be taken care of. Either deassign and delete them and
    later do reverse. This CT handling trouble can be mitigated with a temporary
    VN to replace the original VN in the CT. Later, to be reversed later.

  Options:
    --virtual-network TEXT  Subject Virtual Network name  [required]
    --routing-zone TEXT     Destination Routing Zone name  [required]
    --blueprint TEXT        Blueprint name  [required]
    --help                  Show this message and exit.
  ckim@ckim-mbp:ck-apstra-api %
  ```


  ```
  (.venv) ckim@ckim-mbp:ck-apstra-api % ck-cli --host-ip 10.85.192.45 --host-password admin relocate-vn --virtual-network vn2222 --blueprint terra --routing-zone vrf
  2024-07-03 18:47:07,957 - INFO     - immigrate_vn() - Took order blueprint='terra' virtual_network='vn2222' routing_zone='vrf' (cli.py:333)
  2024-07-03 18:47:09,195 - INFO     - immigrate_vn() - Temporary VN x-vn2222 not found. Creating... (cli.py:391)
  2024-07-03 18:47:10,208 - INFO     - immigrate_vn() - Temporary VN x-vn2222:the_order.test_vn_id='mTlYxQM-bvG1oP6mhZQ' created vn_temp_created=<Response [201]> (cli.py:408)
  2024-07-03 18:47:10,208 - INFO     - immigrate_vn() - Ready execute: Order: self.target_vn='vn2222' self.target_vn_id='BPB80Tuop2qUINeUZOU' self.test_vn='x-vn2222' self.test_vn_id='mTlYxQM-bvG1oP6mhZQ' self.target_rz='vrf' self.terget_rz_id='S2WY6qMrf9J6cvoZfeY' (cli.py:410)
  2024-07-03 18:47:12,048 - INFO     - immigrate_vn() - CkApstraBlueprint(terra)::swap_ct_vns(from_vn_id='BPB80Tuop2qUINeUZOU', to_vn_id='mTlYxQM-bvG1oP6mhZQ') patched: ct['id']='1604b264-fa4a-46ec-a47f-1d237b2c5a3f' attr={'tag_type': 'vlan_tagged', 'vn_node_id': 'BPB80Tuop2qUINeUZOU'} patched=<Response [204]> (cli.py:414)
  2024-07-03 18:47:13,360 - INFO     - immigrate_vn() - VN vn2222:BPB80Tuop2qUINeUZOU deleted: deleted=<Response [204]> (cli.py:418)
  2024-07-03 18:47:14,552 - INFO     - immigrate_vn() - VN vn2222:tzPJy0Myr5_b2pP9x1M created: created=<Response [201]> under RZ:vrf (cli.py:424)
  2024-07-03 18:47:14,552 - INFO     - immigrate_vn() - Restoring CTs with new VN x-vn2222:mTlYxQM-bvG1oP6mhZQ (cli.py:427)
  2024-07-03 18:47:16,414 - INFO     - immigrate_vn() - CkApstraBlueprint(terra)::swap_ct_vns(from_vn_id='mTlYxQM-bvG1oP6mhZQ', to_vn_id='tzPJy0Myr5_b2pP9x1M') patched: ct['id']='1604b264-fa4a-46ec-a47f-1d237b2c5a3f' attr={'tag_type': 'vlan_tagged', 'vn_node_id': 'mTlYxQM-bvG1oP6mhZQ'} patched=<Response [204]> (cli.py:429)
  2024-07-03 18:47:17,538 - INFO     - immigrate_vn() - Temporary VN x-vn2222:mTlYxQM-bvG1oP6mhZQ deleted: deleted=<Response [204]> (cli.py:433)
  2024-07-03 18:47:17,538 - INFO     - immigrate_vn() - Order completed: Order: self.target_vn='vn2222' self.target_vn_id='tzPJy0Myr5_b2pP9x1M' self.test_vn='x-vn2222' self.test_vn_id='mTlYxQM-bvG1oP6mhZQ' self.target_rz='vrf' self.terget_rz_id='S2WY6qMrf9J6cvoZfeY' (cli.py:435)
  (.venv) ckim@ckim-mbp:ck-apstra-api %
  ```



  ```python
  @cli.command()
  @click.option('--virtual-network', type=str, required=True, help='Subject Virtual Network name')
  @click.option('--routing-zone', type=str, required=True, help='Destination Routing Zone name')
  @click.option('--blueprint', type=str, required=True, help='Blueprint name')
  @click.pass_context
  def relocate_vn(ctx, blueprint: str, virtual_network: str, routing_zone: str):
      """
      Move a Virtual Network to the target Routing Zone

      The virtual network move involves deleting and recreating the virtual network in the target routing zone.
      To delete the virtual network, the associated CT should be taken care of. Either deassign and delete them and later do reverse.
      This CT handling trouble can be mitigated with a temporary VN to replace the original VN in the CT. Later, to be reversed later.

      """
  from ck_apstra_api.apstra_session import CkApstraSession, prep_logging
      from ck_apstra_api.apstra_blueprint import CkApstraBlueprint

      from result import Ok, Err

      logger = prep_logging('INFO', 'relocate_vn()')
      logger.info(f"Took order {blueprint=} {virtual_network=} {routing_zone=}")

      NODE_NAME_RZ = 'rz'

      host_ip = ctx.obj['HOST_IP']
      host_port = ctx.obj['HOST_PORT']
      host_user = ctx.obj['HOST_USER']
      host_password = ctx.obj['HOST_PASSWORD']

      session = CkApstraSession(host_ip, host_port, host_user, host_password)
      bp = CkApstraBlueprint(session, blueprint)

      @dataclass
      class Order(object):
          target_vn: str = virtual_network
          target_vn_id: str = None
          target_vn_spec: dict = None
          test_vn: str = None
          test_vn_id: str = None
          test_vn_spec: dict = None
          target_rz: str = routing_zone
          terget_rz_id: str = None

          def summary(self):
              return f"Order: {self.target_vn=} {self.target_vn_id=} {self.test_vn=} {self.test_vn_id=} {self.target_rz=} {self.terget_rz_id=}"
      the_order = Order()

      
      found_rz = bp.query(f"node('security_zone', name='{NODE_NAME_RZ}', label='{routing_zone}')").ok_value
      the_order.terget_rz_id = found_rz[0][NODE_NAME_RZ]['id']

      
      found_vns_dict = bp.get_item('virtual-networks')['virtual_networks']

      
      target_vn_node = [vn for vn in found_vns_dict.values() if vn['label'] == virtual_network]
      if len(target_vn_node) == 0:
          logger.error(f"Virtual Network {virtual_network} not found")
          return
      the_order.target_vn_spec = target_vn_node[0]
      the_order.target_vn_id = the_order.target_vn_spec['id']
      
      if the_order.target_vn_spec['security_zone_id'] == the_order.terget_rz_id:
          logger.warning(f"Virtual Network {virtual_network} already in the target Routing Zone {routing_zone}")
          return

      for res in bp.get_temp_vn(the_order.target_vn):
          if isinstance(res, dict):
              the_order.test_vn_spec = res
              the_order.test_vn_id = res['id']
              the_order.test_vn = res['label']
          else:
              logger.info(res)

      logger.info(f"Ready to relocate vn {virtual_network}: {the_order.summary()}")

      
      for res in bp.swap_ct_vns(the_order.target_vn_id, the_order.test_vn_id):
          logger.info(res)

      
      deleted = bp.delete_item(f"virtual-networks/{the_order.target_vn_id}")
      logger.info(f"VN {the_order.target_vn}:{the_order.target_vn_id} deleted: {deleted=}")

      
      the_order.target_vn_spec['security_zone_id'] = the_order.terget_rz_id
      created = bp.post_item('virtual-networks', the_order.target_vn_spec)
      the_order.target_vn_id = created.json()['id']
      logger.info(f"VN {the_order.target_vn}:{the_order.target_vn_id} created: {created=} under RZ:{the_order.target_rz}")

      
      logger.info(f"Restoring CTs with new VN {the_order.test_vn}:{the_order.test_vn_id}")
      for res in bp.swap_ct_vns(the_order.test_vn_id, the_order.target_vn_id):
          logger.info(res)

      
      deleted = bp.delete_item(f"virtual-networks/{the_order.test_vn_id}")
      logger.info(f"Temporary VN {the_order.test_vn}:{the_order.test_vn_id} deleted: {deleted=}")

      logger.info(f"Order completed: {the_order.summary()}")
      session.logout()

  ```



  ```
  .venv) ckim@ckim-mbp:ck-apstra-api % ck-cli export-device-configs --help
  Usage: ck-cli export-device-configs [OPTIONS]

    Export a device configurations into multiple files

    The folder for each device will be created with the device name.
    0_load_override_pristine.txt (if the device is managed)
    0_load_override_freeform.txt (if case of freeform) 1_load_merge_intended.txt
    2_load_merge_configlet.txt (if applicable) 3_load_set_configlet-set.txt (if
    applicable)

  Options:
    --bp-name TEXT     Blueprint name
    --out-folder TEXT  Folder name to export
    --help             Show this message and exit.
  (.venv) ckim@ckim-mbp:ck-apstra-api %
  (.venv) ckim@ckim-mbp:ck-apstra-api % ck-cli export-device-configs --bp-name dh --out-folder ~/Downloads/dev1
  2024-07-17 19:02:23,828 - INFO     - export_device_configs() - bp_name='dh' out_folder='/Users/ckim/Downloads/dev1' (cli.py:280)
  2024-07-17 19:02:23,952 - INFO     - export_device_configs() - system_label='dh_border2' (cli.py:301)
  2024-07-17 19:02:24,501 - INFO     - export_device_configs() - write_to_file(): rendered.txt (cli.py:291)
  2024-07-17 19:02:24,502 - INFO     - export_device_configs() - write_to_file(): 1_load_merge_intended.txt (cli.py:291)
  2024-07-17 19:02:24,502 - INFO     - export_device_configs() - write_to_file(): 2_load_merge_configlet.txt (cli.py:291)
  2024-07-17 19:02:24,503 - INFO     - export_device_configs() - system_label='spine1' (cli.py:301)
  2024-07-17 19:02:24,715 - INFO     - export_device_configs() - write_to_file(): 0_load_override_pristine.txt (cli.py:291)
  2024-07-17 19:02:25,173 - INFO     - export_device_configs() - write_to_file(): rendered.txt (cli.py:291)
  2024-07-17 19:02:25,174 - INFO     - export_device_configs() - write_to_file(): 1_load_merge_intended.txt (cli.py:291)
  2024-07-17 19:02:25,175 - INFO     - export_device_configs() - write_to_file(): 2_load_merge_configlet.txt (cli.py:291)
  2024-07-17 19:02:25,175 - INFO     - export_device_configs() - system_label='spine2' (cli.py:301)
  2024-07-17 19:02:25,654 - INFO     - export_device_configs() - write_to_file(): rendered.txt (cli.py:291)
  2024-07-17 19:02:25,655 - INFO     - export_device_configs() - write_to_file(): 1_load_merge_intended.txt (cli.py:291)
  2024-07-17 19:02:25,655 - INFO     - export_device_configs() - write_to_file(): 2_load_merge_configlet.txt (cli.py:291)
  2024-07-17 19:02:25,656 - INFO     - export_device_configs() - system_label='dh_border1' (cli.py:301)
  2024-07-17 19:02:25,868 - INFO     - export_device_configs() - write_to_file(): 0_load_override_pristine.txt (cli.py:291)
  2024-07-17 19:02:26,414 - INFO     - export_device_configs() - write_to_file(): rendered.txt (cli.py:291)
  2024-07-17 19:02:26,414 - INFO     - export_device_configs() - write_to_file(): 1_load_merge_intended.txt (cli.py:291)
  2024-07-17 19:02:26,415 - INFO     - export_device_configs() - write_to_file(): 2_load_merge_configlet.txt (cli.py:291)
  2024-07-17 19:02:26,415 - INFO     - export_device_configs() - write_to_file(): 3_load_set_configlet-set.txt (cli.py:291)
  2024-07-17 19:02:26,415 - INFO     - export_device_configs() - system_label='terra-border1' (cli.py:301)
  2024-07-17 19:02:26,533 - INFO     - export_device_configs() - system_label='terra-border2' (cli.py:301)
  (.venv) ckim@ckim-mbp:ck-apstra-api % ls ~/Downloads/dev1/dh
  dh_border1    dh_border2    spine1        spine2        terra-border1 terra-border2
  (.venv) ckim@ckim-mbp:ck-apstra-api %
  ```




  ```
  (.venv) ckim@ckim-mbp:ck-apstra-api % ck-cli export-systems --help
  Usage: ck-cli export-systems [OPTIONS]

    Export systems of a blueprint to a CSV file

    The CSV file will have below columns: system, asn, lo0, rack, device_profile

  Options:
    --bp-name TEXT      Blueprint name
    --systems-csv TEXT  The CSV file path to create  [required]
    --help              Show this message and exit.
  (.venv) ckim@ckim-mbp:ck-apstra-api %
  (.venv) ckim@ckim-mbp:ck-apstra-api % python src/ck_apstra_api/cli.py export-systems --systems-csv ~/Downloads/system.csv
  2024-07-09 19:27:19,866 - INFO     - export_systems() - systems_csv_path='/Users/ckim/Downloads/system.csv' writing to /Users/ckim/Downloads/system.csv (cli.py:276)
  (.venv) ckim@ckim-mbp:ck-apstra-api %
  ```


  ```
  (.venv) ckim@ckim-mbp:ck-apstra-api % ck-cli export-blueprint --help
  Usage: ck-cli export-blueprint [OPTIONS]

    Export a blueprint into a json file The blueprint label -
    job_env.main_blueprint_name The json file - job_env.bp_json_file

  Options:
    --bp-name TEXT    Blueprint name
    --json-file TEXT  Blueprint name
    --help            Show this message and exit.
  (.venv) ckim@ckim-mbp:ck-apstra-api %
  (.venv) ckim@ckim-mbp:ck-apstra-api % ck-cli export-blueprint --json-file ~/Downloads/dh.json --bp-name dh
  2024-07-17 18:18:29,465 - INFO     - export_blueprint() - bp_name='dh' json_file='/Users/ckim/Downloads/dh.json' (cli.py:191)
  (.venv) ckim@ckim-mbp:ck-apstra-api %
  ```



  ```
  ck-apstra-api-py3.11ckim@ckim-mbp:ck-apstra-api % ck-cli import-iplink-ct --help
  Usage: ck-cli import-iplink-ct [OPTIONS]

    Import IpLink CT from a CSV file

  Options:
    --csv-in TEXT  Path to the CSV file for iplink CT
    --help         Show this message and exit.
  ck-apstra-api-py3.11ckim@ckim-mbp:ck-apstra-api %
  ```

  [Example csv file](./tests/fixtures/iplink_ct_sample.csv)




  This repository is maintained on a best-effort basis. Comments and bug reports are encouraged and welcomed.


pkgId: 233220834b99e5d57135e829044f2676ab144fbbcd60316a70a96f2c5af7bb21
name: python-ckan
arch: src
version: 2.11.0
epoch: 0
release: 1
summary: CKAN Software
url: http://ckan.org/
rpm_license: AGPL
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckan-2.11.0-1.src.rpm
checksum_type: sha256
description:
  **CKAN is the world’s leading open-source data portal platform**.
  CKAN makes it easy to publish, share and work with data. It's a data management
  system that provides a powerful platform for cataloging, storing and accessing
  datasets with a rich front-end, full API (for both data and catalog), visualization
  tools and more. Read more at `ckan.org <http://ckan.org/>`_.


pkgId: 981e318c9503e715ad3f52c1610c1424dafac49f8588e566305f8b10fc1f995f
name: python-ckanext-admin-panel
arch: src
version: 1.1.19
epoch: 0
release: 1
summary: Custom admin panel for CKAN to expand default functionality
url: https://github.com/DataShades/ckanext-admin-panel
rpm_license: AGPL
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-admin-panel-1.1.19-1.src.rpm
checksum_type: sha256
description:
  [![Tests](https://github.com/DataShades/ckanext-admin-panel/workflows/Tests/badge.svg?branch=main)](https://github.com/DataShades/ckanext-admin-panel/actions)



  Next generation admin interface for CKAN. See the [extended documentation](https://datashades.github.io/ckanext-admin-panel/) for more information.


  This extension is under development, so there are many things to do:

  - CKAN forms:
  	 - What do we want to do, if we are editing an entity from admin panel? Use default form or replace it with an admin version?
  - Users:
  	 - Add `User edit` page
  - Recent log messages:
  	 - We have  some types, that we don't want to include in list. E.g xloader resources. Research what is better to do with them.
  	 - Rework the pagination approach, because the current naive one will work very slow on big amount of data
  - Rewrite `user_list` action. Currently it's just a copy of contrib one with one small change. Maybe it's a good idea to write
    our own versatile version.
  - Think about configuration section pages. Do we need a separate page for a section?
  - Work on `Extensions` page. What do we want: replace `status_show`. This page should be more informative. Show here what extensions we are using with the respective versions. For now we don't have a standartized mechanism to retrieve versions from extensions, think about it.
  - Work on `Available updates?` page. Show user if he could upgrade an extension or CKAN to a new version.
  - Work on `Appearance` page. TODO
  - Work on `Help` page. TODO



  [AGPL](https://www.gnu.org/licenses/agpl-3.0.en.html)


pkgId: e698308f392dab77277b4e2670acd11850347e4dba885a3a8b1518f0ae81eae9
name: python-ckanext-attribution
arch: src
version: 1.2.13
epoch: 0
release: 1
summary: A CKAN extension that adds support for complex attribution.
url: https://pypi.org/project/ckanext-attribution/
rpm_license: GPL-3.0-or-later
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-attribution-1.2.13-1.src.rpm
checksum_type: sha256
description:
  <!--header-start-->
  <picture>
    <source media="(prefers-color-scheme: dark)" srcset="https://data.nhm.ac.uk/images/nhm_logo.svg">
    <source media="(prefers-color-scheme: light)" srcset="https://data.nhm.ac.uk/images/nhm_logo_black.svg">
    <img alt="The Natural History Museum logo." src="https://data.nhm.ac.uk/images/nhm_logo_black.svg" align="left" width="150px" height="100px" hspace="40">
  </picture>



  [![Tests](https://img.shields.io/github/actions/workflow/status/NaturalHistoryMuseum/ckanext-attribution/tests.yml?style=flat-square)](https://github.com/NaturalHistoryMuseum/ckanext-attribution/actions/workflows/tests.yml)
  [![Coveralls](https://img.shields.io/coveralls/github/NaturalHistoryMuseum/ckanext-attribution/main?style=flat-square)](https://coveralls.io/github/NaturalHistoryMuseum/ckanext-attribution)
  [![CKAN](https://img.shields.io/badge/ckan-2.9.7-orange.svg?style=flat-square)](https://github.com/ckan/ckan)
  [![Python](https://img.shields.io/badge/python-3.6%20%7C%203.7%20%7C%203.8-blue.svg?style=flat-square)](https://www.python.org/)
  [![Docs](https://img.shields.io/readthedocs/ckanext-attribution?style=flat-square)](https://ckanext-attribution.readthedocs.io)

  _A CKAN extension that adds support for complex attribution._

  <!--header-end-->



  <!--overview-start-->
  This extension standardises author/contributor attribution for datasets, enabling enhanced metadata
  and greater linkage between datasets. It currently integrates with the [ORCID](https://orcid.org)
  and [ROR](https://ror.org) APIs; contributors ('agents') can be added directly from these databases,
  or manually.

  Contributors can be added and edited via actions or via a Vue app that can be inserted into
  the `package_metadata_fields.html` template snippet.

  ![A screenshot of the form for adding contributors when editing a package. At the top is a preview of the citation in APA format, then there are three example agents with their affiliations and contribution activities.](.github/screenshots/form-overview.png)



  The schema is (partially) based on
  the [RDA/TDWG recommendations](https://github.com/tdwg/attribution). Three new models are
  added: `Agent` (contributors), `ContributionActivity`, and `Affiliation` (plus small linking models
  between these and `Package` records).



  Defines _one_ agent.

  | Field                | Type   | Values                   | Notes                                                                                                                                                                                                                                               |
  |----------------------|--------|--------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
  | `agent_type`         | string | 'person', 'org', 'other' |                                                                                                                                                                                                                                                     |
  | `family_name`        | string |                          | only used for 'person' records                                                                                                                                                                                                                      |
  | `given_names`        | string |                          | only used for 'person' records                                                                                                                                                                                                                      |
  | `given_names_first`  | bool   | True, False              | only used for 'person' records; if the given names should be displayed first according to the person's culture/language (default True)                                                                                                              |
  | `name`               | string |                          | used for non-'person' records                                                                                                                                                                                                                       |
  | `location`           | string |                          | used for non-person records, optional; a location to display for the organisation to help differentiate between similar names (e.g. 'Natural History Museum (_London_)' and 'Natural History Museum (_Dublin_)')
   `external_id`        | string |                          | an identifier from an external service like ORCID or ROR
   `external_id_scheme` | string | 'orcid', 'ror', other    | the scheme for the `external_id`; currently only 'orcid' and 'ror' are fully supported, though basic support for others can be implemented by adding to the `attribution_controlled_lists` [action](ckanext/attribution/logic/actions/extra.py#L14)
   `user_id`            | string | `User.id` foreign key    | link to a user account on the CKAN instance



  Defines _one_ activity performed by _one_ agent on _one_ specific dataset.

  | Field      | Type     | Values                        | Notes                                                                                                                                                                                                                                                                                                                                  |
  |------------|----------|-------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
  | `activity` | string   | [controlled vocabulary]       | the activity/role the agent is associated with, e.g. 'Editor', 'Methodology'; roles are defined in the `attribution_controlled_lists` [action](ckanext/attribution/logic/actions/extra.py#L14), which currently lists the [Datacite](https://datacite.org) and [CRediT](https://credit.niso.org) role taxonomies (but can be expanded) |
  | `scheme`   | string   | [controlled vocabulary]       | name of the defined scheme from [`attribution_controlled_lists`](ckanext/attribution/logic/actions/extra.py#L14)                                                                                                                                                                                                                       |
  | `level`    | string   | 'Lead', 'Equal', 'Supporting' | optional degree of contribution (from [CRediT](http://credit.niso.org/implementing-credit))                                                                                                                                                                                                                                            |
  | `time`     | datetime |                               | optional date/time of the activity                                                                                                                                                                                                                                                                                                     |
  | `order`    | integer  |                               | order of the agent within all who are associated with the same activity, e.g. 1st Editor, 3rd DataCollector (optional)                                                                                                                                                                                                                 |

  A specialised `ContributionActivity` entry with a '[citation]' activity is used to define the order
  in which contributors should be cited (and/or if they should be cited at all).



  Defines a relationship between _two_ agents, either as a 'universal' (persistent) affiliation or for
  a single package (e.g. a project affiliation).

  | Field              | Type   | Values                   | Notes                                                                              |
  |--------------------|--------|--------------------------|------------------------------------------------------------------------------------|
  | `agent_a_id`       | string | `Agent.id` foreign key   | one of the two agents (a/b order does not matter)                                  |
  | `agent_b_id`       | string | `Agent.id` foreign key   | one of the two agents (a/b order does not matter)                                  |
  | `affiliation_type` | string |                          | very short description (1 or 2 words) of affiliation, e.g. 'employment' (optional) |
  | `description`      | string |                          | longer description of affiliation (optional)                                       |
  | `start_date`       | date   |                          | date at which the relationship began, e.g. employment start date (optional)        |
  | `end_date`         | date   |                          | date at which the relationship ended (optional)                                    |
  | `package_id`       | string | `Package.id` foreign key | links affiliation to a specific package/dataset (optional)                         |

  <!--overview-end-->



  <!--installation-start-->
  Path variables used below:
  - `$INSTALL_FOLDER` (i.e. where CKAN is installed), e.g. `/usr/lib/ckan/default`
  - `$CONFIG_FILE`, e.g. `/etc/ckan/default/development.ini`



  ```shell
  pip install ckanext-attribution

  pip install ckanext-attribution[cli]
  ```



  1. Clone the repository into the `src` folder:
     ```shell
     cd $INSTALL_FOLDER/src
     git clone https://github.com/NaturalHistoryMuseum/ckanext-attribution.git
     ```

  2. Activate the virtual env:
     ```shell
     . $INSTALL_FOLDER/bin/activate
     ```

  3. Install via pip:
     ```shell
     pip install $INSTALL_FOLDER/src/ckanext-attribution
     
     pip install $INSTALL_FOLDER/src/ckanext-attribution[cli]
     ```



  Installing from a `pyproject.toml` in editable mode (i.e. `pip install -e`) requires `setuptools>=64`; however, CKAN 2.9 requires `setuptools==44.1.0`. See [our CKAN fork](https://github.com/NaturalHistoryMuseum/ckan) for a version of v2.9 that uses an updated setuptools if this functionality is something you need.



  1. Add 'attribution' to the list of plugins in your `$CONFIG_FILE`:
     ```ini
     ckan.plugins = ... attribution
     ```

  2. Install `lessc` globally:
     ```shell
     npm install -g "less@~4.1"
     ```

  3. Add this block to `package_metadata_fields.html` to show the Vue app:
     ```jinja2
     {% block package_custom_fields_agent %}
          {{ super() }}
     {% endblock %}
     ```

  4. Change the `authors` field in your SOLR `schema.xml` to set up faceting.
     ```xml
     <schema>
         <fields>
             <...>
             <field name="author" type="string" indexed="true" stored="true" multiValued="true"/>
             <...>
         </fields>
         <...>
         <copyField source="author" dest="text"/>
     </schema>
     ```

     After making the changes, restart SOLR and reindex (`ckan -c $CONFIG_FILE search-index rebuild`).
     You will also have to enable the config option (see below) to see this in the UI.

  <!--installation-end-->



  <!--configuration-start-->
  These are the options that can be specified in your .ini config file. NB:
  setting `ckanext.attribution.debug` to `True` means that the API
  accesses [sandbox.orcid.org](https://sandbox.orcid.org) instead of [orcid.org](https://orcid.org).
  Although both run by the ORCID organisation, these are _different websites_ and you will need a
  separate account/set of credentials for each. It is also worth noting that you will not have access
  to the full set of authors on the sandbox.



  | Name                               | Description                  | Options |
  |------------------------------------|------------------------------|---------|
  | `ckanext.attribution.orcid_key`    | Your ORCID API client ID/key |         |
  | `ckanext.attribution.orcid_secret` | Your ORCID API client secret |         |



  | Name                                  | Description                                                           | Options    | Default |
  |---------------------------------------|-----------------------------------------------------------------------|------------|---------|
  | `ckanext.attribution.debug`           | If true, use sandbox.orcid.org (for testing)                          | True/False | True    |
  | `ckanext.attribution.enable_faceting` | Enable filtering by contributor name (requires change to SOLR schema) | True/False | False   |

  <!--configuration-end-->



  <!--usage-start-->


  This extension adds numerous new actions. These are primarily CRUD actions for managing models, with
  inline documentation and predictable interactions. It's probably more helpful to only go over the
  more "unusual" new actions here.



  Search for agents by name or external ID, or just list all agents.

  ```python
  data_dict = {
      'q': 'QUERY',  # optional; searches in name, family_name, given_names, and external_id
  }

  toolkit.get_action('agent_list')({}, data_dict)
  ```



  Show all contribution records for a package, grouped by agent. Optionally provide a limit and offset
  for pagination.

  ```python
  data_dict = {
      'id': 'PACKAGE_ID',
      'limit': 'PAGE_SIZE',
      'offset': 'OFFSET'
  }

  toolkit.get_action('package_contributions_show')({}, data_dict)
  ```

  Returns a dict:

  ```python
  {
      'contributions': [
          {
              'agent': {
                  
              },
              'activities': [
                  
              ],
              'affiliations': [
                  {
                      'affiliation': {
                          
                      },
                      'other_agent': {
                          
                      }
                  },
                  
              ]
          },
          
      ],
      'total': total,
      'offset': offset,
      'page_size': limit or total
  }
  ```



  Show all affiliations for a given agent, optionally limited to a specific dataset/package (plus '
  global' affiliations).

  ```python
  data_dict = {
      'agent_id': 'AGENT_ID',
      'package_id': 'PACKAGE_ID'  # optional
  }

  toolkit.get_action('agent_affiliations')({}, data_dict)
  ```

  Returns a list of records formatted as such:

  ```python
  {
      'affiliation': {
          
      },
      'other_agent': {
          
      }
  }
  ```



  Returns collections of defined values (which can be modified by using `@toolkit.chained_action`).

  ```python
  data_dict = {
      'lists': ['NAME1', 'NAME2']  # optional; only return these lists
  }

  toolkit.get_action('attribution_controlled_lists')({}, data_dict)
  ```

  There are four collections:

  1. `agent_types` describes valid types for agents and adds additional detail;
  2. `contribution_activity_types` contains role/activity taxonomies (i.e. Datacite and CRediT) and
     lists the available activity values;
  3. `contribution_activity_levels` is a list of contribution levels (i.e. 'lead', 'equal', and '
     supporting', from CRediT);
  4. `agent_external_id_schemes` describes valid schemes for external IDs (currently, ORCID and ROR).

  These collections are useful for validation and frontend connectivity/standardisation. They are
  contained within an action to _a._ enable frontend access via AJAX requests, and _b._ allow users to
  override values as needed.



  Search external sources (ORCID and ROR) for agent data. Ignores records that already exist in the
  database.

  ```python
  data_dict = {
      'q': 'QUERY_STRING',
      'sources': ['SOURCE1', 'SOURCE2']  # optional; only search these sources
  }

  toolkit.get_action('agent_external_search')({}, data_dict)
  ```

  Results are returned formatted as such:

  ```python
  {
      'SCHEME_NAME': {
          'records': [
              
          ]
          'remaining': 10000  # number of other records found
      }
  }
  ```



  Read data from an external source like ORCID or ROR, either from an existing record or a new
  external ID.

  ```python

  data_dict_existing = {
      'agent_id': 'AGENT_ID',
      'diff': False
      
  }


  data_dict_new = {
      'external_id': 'EXTERNAL_ID',
      'external_id_scheme': 'orcid'  # or 'ror', etc.
  }

  toolkit.get_action('agent_external_read')({}, data_dict)
  ```



  **NB**: you will have to install the optional `[cli]` packages to use several of these commands.


  ```shell
  ckan -c $CONFIG_FILE attribution initdb
  ```
  Initialise database tables.


  ```shell
  ckan -c $CONFIG_FILE attribution sync $OPTIONAL_ID $ANOTHER_OPTIONAL_ID
  ```
  Retrieve up-to-date information from external APIs for contributors with an external ID set.


  ```shell
  ckan -c $CONFIG_FILE attribution refresh-packages $OPTIONAL_ID $ANOTHER_OPTIONAL_ID
  ```
  Update the author string for all (or the specified) packages.


  ```shell
  ckan -c $CONFIG_FILE attribution agent-external-search --limit 10 $OPTIONAL_ID $ANOTHER_OPTIONAL_ID
  ```
  Search external APIs for contributors without an external ID set. Run `refresh-packages` and rebuild the search index after this command.


  ```shell
  ckan -c $CONFIG_FILE attribution merge-agents --q $SEARCH_QUERY --match-threshold 75
  ```
  Find agents with similar names (optionally matching the search query) and merge them. Run `refresh-packages` and rebuild the search index after this command.


  ```shell
  ckan -c $CONFIG_FILE attribution migratedb --limit 10 --dry-run --no-search-api
  ```
  Attempt to extract names of contributors from author fields and convert them to the new format.
  - `--limit` will only convert a certain number of packages at a time.
  - `--dry-run` prevents saving to the database.
  - `--no-search-api` just extracts the names, without searching external APIs for contributors after.

  It is recommended to run `merge-agents`, `refresh-packages`, and rebuild the search index after running this command.

  <!--usage-end-->



  <!--testing-start-->
  There is a Docker compose configuration available in this repository to make it easier to run tests. The ckan image uses the Dockerfile in the `docker/` folder.

  To run the tests against ckan 2.9.x on Python3:

  1. Build the required images:
     ```shell
     docker compose build
     ```

  2. Then run the tests.
     The root of the repository is mounted into the ckan container as a volume by the Docker compose
     configuration, so you should only need to rebuild the ckan image if you change the extension's
     dependencies.
     ```shell
     docker compose run ckan
     ```

  <!--testing-end-->


pkgId: 5af26e52ae7c995b9fc2c258b31965b33c9c805825376402ca22543565dab8f6
name: python-ckanext-charts
arch: src
version: 1.1.2
epoch: 0
release: 1
summary: please add a summary manually as the author left a blank one
url: https://github.com/DataShades/ckanext-charts
rpm_license: AGPL
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-charts-1.1.2-1.src.rpm
checksum_type: sha256
description:
  [![Tests](https://github.com/DataShades/ckanext-charts/actions/workflows/test.yml/badge.svg)](https://github.com/DataShades/ckanext-charts/actions/workflows/test.yml)



  This extension, ckanext-charts, provides additional functionality for working with charts in CKAN. It allows users to create, manage, and visualize charts based on data stored in CKAN datasets.

  The extension includes features such as chart creation, chart editing, chart embedding, and chart sharing. It also supports various chart types, including bar charts, line charts, pie charts, and more.

  With ckanext-charts, users can easily generate interactive and visually appealing charts to enhance data analysis and presentation in CKAN.

  See the [documentation](https://datashades.github.io/ckanext-charts/) for more information.



  - Install it with `PyPi` with `pip install ckanext-charts[pyarrow]`
  - Add `charts_view` to the list of plugins in your CKAN config (`ckan.plugins = charts_view charts_builder_view`)





  To install `ckanext-charts` for development, activate your CKAN virtualenv and
  do:

      git clone https://github.com/DataShades/ckanext-charts.git
      cd ckanext-charts
      pip install -e '.[dev]'



  To run the tests, do:

      pytest --ckan-ini=test.ini




  [AGPL](https://www.gnu.org/licenses/agpl-3.0.en.html)


pkgId: a0f094d04b0f36f681afc6f1ffa37a605c8e52a8b9decfe3fc0ed40ac788ea33
name: python-ckanext-check-link
arch: src
version: 0.2.2
epoch: 0
release: 1
summary: Resource URL checker
url: https://github.com/DataShades/ckanext-check-link
rpm_license: AGPL
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-check-link-0.2.2-1.src.rpm
checksum_type: sha256
description:
  [![Tests](https://github.com/DataShades/ckanext-check-link/workflows/Tests/badge.svg?branch=main)](https://github.com/DataShades/ckanext-check-link/actions)



  Link checker for CKAN.

  Provides API, CLI commands, and views for:

  * checking availability of the file, refereed by resource
  * checking availability of any arbitrary link.
  * storing results of these checks
  * visualizing stored results

  <!-- * downloading a report based on the stored results -->



  * [Requirements](#requirements)
  * [Installation](#installation)
  * [Config settings](#config-settings)
  * [UI](#ui)
  * [CLI](#cli)
  * [API](#api)



  Compatibility with core CKAN versions:

  | CKAN version | Compatible? |
  |--------------|-------------|
  | 2.9          | yes         |
  | 2.10         | yes         |



  1. Install `ckanext-check-link`
     ```
     pip install ckanext-check-link
     ```

  1. Add `check_link` and `collection` to the `ckan.plugins` setting in your CKAN config file.




  ```ini



  ckanext.check_link.user_can_check_url = yes



  ckanext.check_link.report.base_template = /ckan-admin/link-state



  ckanext.check_link.report.base_template = check_link/base.html

  ```







  Paginated listing of all the "broken" links. Access is controlled by the
  `check_link_view_report_page` auth function, which can be bypassed only by
  sysadmin.



  CLI commands are registered under `ckan check-link` route.




  Check every resource inside each package.

  The scope can be narrowed via arbitrary number of arguments, specifying the package's ID or name.

  ```sh

  $ ckan check-link check-packages


  $ ckan check-link check-packages --include-private


  $ ckan check-link check-packages --include-draft


  $ ckan check-link check-packages pkg-id-one pkg-name-two

  ```


  Check every resource on the portal.

  Scope can be narrowed via arbitary number of arguments, specifying resource's ID


  Delete check-link reports.

  ```sh

  $ ckan check-link delete-reports


  $ ckan check-link delete-reports --orphans-only
  ```

  Scope can be narrowed via arbitary number of arguments, specifying resource's ID
















  TBA



  [AGPL](https://www.gnu.org/licenses/agpl-3.0.en.html)


pkgId: d4f89765a6e051304a1f05487c4fdf1755583e86beee4d49ad8f3fbbf92eb9b3
name: python-ckanext-collection
arch: src
version: 0.2.1
epoch: 0
release: 1
summary: please add a summary manually as the author left a blank one
url: https://github.com/DataShades/ckanext-collection
rpm_license: AGPL
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-collection-0.2.1-1.src.rpm
checksum_type: sha256
description:
  [![Tests](https://github.com/DataShades/ckanext-collection/workflows/Tests/badge.svg?branch=main)](https://github.com/DataShades/ckanext-collection/actions)



  Tools for building interfaces for data collections using declarative style.

  This extension simplifies describing series of items, such as datasets from
  search page, users registered on portal, rows of CSV file, tables in DB,
  etc. Once you defined the way of fetching items from data source, you'll get
  generic interface for pagination, search and displaying data in any format:
  HTML page, CSV document, JSON list, or any other custom format that you can
  describe.

  Read the [documentation](https://datashades.github.io/ckanext-collection/) for
  a full user guide.




  Install the extension

  ```sh
  pip install ckanext-collection
  ```

  Add `collection` to the `ckan.plugins` setting in your CKAN config file

  Define the collection

  ```python
  from ckan import model
  from ckanext.collection.shared import collection, data, columns, serialize



  class MyCollection(collection.Collection):
      DataFactory = data.ModelData.with_attributes(model=model.Resource)
      
      
      ColumnsFactory = columns.Columns.with_attributes(names=["name", "size"])


  class MyCollection(collection.Collection):
      DataFactory = data.ApiSearchData.with_attributes(action="package_search")
      ColumnsFactory = columns.Columns.with_attributes(names=["name", "title"])


  class MyCollection(collection.Collection):
      DataFactory = data.CsvFileData.with_attributes(source="/path/to/file.csv")
      ColumnsFactory = columns.Columns.with_attributes(names=["a", "b"])

  ```

  Initialize collection object and work with data:

  ```python


  col = MyCollection()
  items = list(col)


  col = MyCollection("", {"page": 3})
  items = list(col)




  col = MyCollection()
  items = list(col.data)


  items = list(col.data[8:12])


  print(col.data.total)

  ```

  Serialize data using `Serializer` service:

  ```python


  serializer = serialize.JsonSerializer(col)


  serializer = serialize.CsvSerializer(col)


  serializer = serialize.DictListSerializer(col)


  print(serializer.serialize())

  ```



  [AGPL](https://www.gnu.org/licenses/agpl-3.0.en.html)


pkgId: 9eb5f81d731c1f9b8c539282ebbe40034e2f015f260a8292e6e54bd3b2e48fe8
name: python-ckanext-comments
arch: src
version: 0.3.1.post1
epoch: 0
release: 1
summary: please add a summary manually as the author left a blank one
url: https://github.com/DataShades/ckanext-comments
rpm_license: AGPL
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-comments-0.3.1.post1-1.src.rpm
checksum_type: sha256
description:
  [![Tests](https://github.com/DataShades/ckanext-comments/actions/workflows/test.yml/badge.svg)](https://github.com/DataShades/ckanext-comments/actions/workflows/test.yml)



  Add comment-trees to CKAN pages.

  This plugins provides comment threads linked to any of the main CKAN entities:

  * datasets
  * resources
  * groups
  * organizations
  * users.

  All the features are API-first, so anything you can do via UI, can be done via API.

  No changes to the WebUI are done by default. One have to include a snippet into
  Jinja2 template in order to show the comments on a page.
  ```jinja2
  {# subject_type := package | group | resource | user #}
  {% snippet 'comments/snippets/thread.html', subject_id=pkg.id, subject_type='package' %}
  ```

  :info: For the datasets it also can be achieved by enabling
  `ckanext.comments.enable_default_dataset_comments` option.



  * python >= 3.7
  * CKAN >= 2.9



  To install ckanext-comments:

  1. Install python package
    ```sh
    pip install ckanext-comments
    ```

  1. Add `comments` to the `ckan.plugins` setting in your CKAN
     config file

  1. Apply database migrations
    ```sh
    ckan db upgrade -p comments
    ```

  1. Add `cooments/snippets/thread.html` to your `package/read.html` template, like this:
    ```jinja2
    {% ckan_extends %}

    {% block primary_content_inner %}
      {{ super() }}
      {% snippet 'comments/snippets/thread.html', subject_id=pkg.id, subject_type='package' %}
    {% endblock primary_content_inner %}
    ```


  ```ini



  ckanext.comments.require_approval = false



  ckanext.comments.draft_edits = true



  ckanext.comments.draft_edits_by_author = false



  ckanext.comments.approved_edits = false



  ckanext.comments.approved_edits_by_author = false



  ckanext.comments.mobile_depth_threshold = 3



  ckanext.comments.enable_default_dataset_comments = true




  ckanext.comments.subject.question_getter = ckanext.msf_ask_question.model.question_getter
  ```






  Create a thread for the subject.

  Args:
  * subject_id(str): unique ID of the commented entity
  * subject_type(str:package|resource|user|group): type of the commented entity


  Show the subject's thread.

  Args:
  * subject_id(str): unique ID of the commented entity
  * subject_type(str:package|resource|user|group): type of the commented entity
  * init_missing(bool, optional): return an empty thread instead of 404
  * include_comments(bool, optional): show comments from the thread
  * include_author(bool, optional): show authors of the comments
  * combine_comments(bool, optional): combine comments into a tree-structure
  * after_date(str:ISO date, optional): show comments only since the given date


  Delete the thread.

  Args:
  * id(str): ID of the thread


  Add a comment to the thread.

  Args:
  * subject_id(str): unique ID of the commented entity
  * subject_type(str:package|resource|user|group): type of the commented entity
  * content(str): comment's message
  * reply_to_id(str, optional): reply to the existing comment
  * create_thread(bool, optional): create a new thread if it doesn't exist yet


  Show the details of the comment

  Args:
  * id(str): ID of the comment


  Approve draft comment

  Args:
  * id(str): ID of the comment


  Remove existing comment

  Args:
  * id(str): ID of the comment


  Update existing comment

  Args:
  * id(str): ID of the comment
  * content(str): comment's message




  To run the tests, do:
  ```sh
  pytest
  ```




  [AGPL](https://www.gnu.org/licenses/agpl-3.0.en.html)


pkgId: 1dee8c79966e5cc747c2ec48e3091fb13b84f099f7f47ea337b2c9bacb515b6b
name: python-ckanext-composite-search
arch: src
version: 0.3.3
epoch: 0
release: 1
summary: please add a summary manually as the author left a blank one
url: https://github.com/DataShades/ckanext-composite-search
rpm_license: AGPL
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-composite-search-0.3.3-1.src.rpm
checksum_type: sha256
description:
  [![Tests](https://github.com/DataShades/ckanext-composite-search/workflows/Tests/badge.svg?branch=main)](https://github.com/DataShades/ckanext-composite-search/actions)



  Complex search form for the dataset search page.

  Filter by field, search by multiple criteria, combine filter with the AND/OR operators and
  forget about Lucene queries



  Compatibility with core CKAN versions:

  | CKAN version    | Compatible? |
  |-----------------|-------------|
  | 2.9             | yes         |
  | 2.10            | yes         |
  |                 |             |




  To install ckanext-composite-search:

  1. Install the extension
       ```sh
  	pip install ckanext-composite-search
       ```

  1. Add `composite_search default_composite_search` to the `ckan.plugins`
     setting in your CKAN config file.





  ```ini



  ckanext.composite_search.prefix = ext_p_



  ckanext.composite_search.plugin.default.literal_quotes = single




  ckanext.composite_search.plugin.default.keyword_fields = tags groups

  ```



  [AGPL](https://www.gnu.org/licenses/agpl-3.0.en.html)


pkgId: 861fbb461321597f8884a611b64d03fd5ae9863021bed8009d2c7b76e899c965
name: python-ckanext-contact
arch: src
version: 2.4.3
epoch: 0
release: 1
summary: A CKAN extension for adding popup contact forms to pages.
url: https://pypi.org/project/ckanext-contact/
rpm_license: GPL-3.0-or-later
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-contact-2.4.3-1.src.rpm
checksum_type: sha256
description:
  <!--header-start-->
  <picture>
    <source media="(prefers-color-scheme: dark)" srcset="https://data.nhm.ac.uk/images/nhm_logo.svg">
    <source media="(prefers-color-scheme: light)" srcset="https://data.nhm.ac.uk/images/nhm_logo_black.svg">
    <img alt="The Natural History Museum logo." src="https://data.nhm.ac.uk/images/nhm_logo_black.svg" align="left" width="150px" height="100px" hspace="40">
  </picture>



  [![Tests](https://img.shields.io/github/actions/workflow/status/NaturalHistoryMuseum/ckanext-contact/tests.yml?style=flat-square)](https://github.com/NaturalHistoryMuseum/ckanext-contact/actions/workflows/tests.yml)
  [![Coveralls](https://img.shields.io/coveralls/github/NaturalHistoryMuseum/ckanext-contact/main?style=flat-square)](https://coveralls.io/github/NaturalHistoryMuseum/ckanext-contact)
  [![CKAN](https://img.shields.io/badge/ckan-2.9.7-orange.svg?style=flat-square)](https://github.com/ckan/ckan)
  [![Python](https://img.shields.io/badge/python-3.6%20%7C%203.7%20%7C%203.8-blue.svg?style=flat-square)](https://www.python.org/)
  [![Docs](https://img.shields.io/readthedocs/ckanext-contact?style=flat-square)](https://ckanext-contact.readthedocs.io)

  _A CKAN extension for adding popup contact forms to pages._

  <!--header-end-->



  <!--overview-start-->
  Borrows much of the contact form code from [ckanext-surrey](https://github.com/CityofSurrey/ckanext-surrey).

  An example can be seen on the Natural History Museum's [Data Portal](https://data.nhm.ac.uk) when clicking "_Contact dataset curator._"

  This extension now includes Google's [reCAPTCHA](https://www.google.com/recaptcha) for preventing spam submissions.

  <!--overview-end-->



  <!--installation-start-->
  Path variables used below:
  - `$INSTALL_FOLDER` (i.e. where CKAN is installed), e.g. `/usr/lib/ckan/default`
  - `$CONFIG_FILE`, e.g. `/etc/ckan/default/development.ini`



  ```shell
  pip install ckanext-contact
  ```



  1. Clone the repository into the `src` folder:
     ```shell
     cd $INSTALL_FOLDER/src
     git clone https://github.com/NaturalHistoryMuseum/ckanext-contact.git
     ```

  2. Activate the virtual env:
     ```shell
     . $INSTALL_FOLDER/bin/activate
     ```

  3. Install via pip:
     ```shell
     pip install $INSTALL_FOLDER/src/ckanext-contact
     ```



  Installing from a `pyproject.toml` in editable mode (i.e. `pip install -e`) requires `setuptools>=64`; however, CKAN 2.9 requires `setuptools==44.1.0`. See [our CKAN fork](https://github.com/NaturalHistoryMuseum/ckan) for a version of v2.9 that uses an updated setuptools if this functionality is something you need.



  1. Add 'contact' to the list of plugins in your `$CONFIG_FILE`:
     ```ini
     ckan.plugins = ... contact
     ```

  2. To use reCAPTCHA, you must register a site with the Google [reCAPTCHA](https://www.google.com/recaptcha) service and add your API key and secret in the [configuration](#configuration).

  <!--installation-end-->



  <!--configuration-start-->
  These are the options that can be specified in your .ini config file.



  | Name                                       | Description                                       | Default                         |
  |--------------------------------------------|---------------------------------------------------|---------------------------------|
  | `ckanext.contact.mail_to`                  | Email address to submit to                        | `email_to`                      |
  | `ckanext.contact.recipient_name`           | Name of the recipient                             | `ckan.site_title`               |
  | `ckanext.contact.subject`                  | Email subject for the submitted form              | 'Contact/Question from visitor' |
  | `ckanext.contact.add_timestamp_to_subject` | Whether to append a timestamp to the subject line | `false`                         |
  | `ckanext.contact.subject_prefix`           | A prefix to add to the subject before sending     | ''                              |



  | Name                                  | Description                              | Default               |
  |---------------------------------------|------------------------------------------|-----------------------|
  | `ckanext.contact.recaptcha_v3_key`    | API key for the reCAPTCHA service.       | False (i.e. disabled) |
  | `ckanext.contact.recaptcha_v3_secret` | API secret for the reCAPTCHA service.    | False (i.e. disabled) |
  | `ckanext.contact.recaptcha_v3_action` | `data-module-action` for the form/button |                       |



  | Name                          | Description                                                                                          | Default             |
  |-------------------------------|------------------------------------------------------------------------------------------------------|---------------------|
  | `ckanext.contact.check_email` | Set to False to disable checking email addresses via [pyIsEmail](https://pypi.org/project/pyIsEmail) | True (i.e. enabled) |

  <!--configuration-end-->



  <!--usage-start-->
  Add the following HTML where you want the contact button to appear:

  ```html+jinja
  {% set params = {...} %}

  <a class="btn btn-primary" data-module="modal-contact" data-module-template="{{ h.get_contact_form_template_url(params) }}" href="{{ h.url_for('contact.form', **params) }}" title="{{ _('Contact') }}">
      <i class="fas fa-envelope"></i>{{ link_text if link_text else _('CONTACT BUTTON TEXT') }}
  </a>

  {% asset 'ckanext-contact/main' %}
  ```

  Where `params` is a dict with three entries: package_id, resource_id, record_id (all of which are optional).

  <!--usage-end-->



  <!--testing-start-->
  There is a Docker compose configuration available in this repository to make it easier to run tests. The ckan image uses the Dockerfile in the `docker/` folder.

  To run the tests against ckan 2.9.x on Python3:

  1. Build the required images:
     ```shell
     docker compose build
     ```

  2. Then run the tests.
     The root of the repository is mounted into the ckan container as a volume by the Docker compose
     configuration, so you should only need to rebuild the ckan image if you change the extension's
     dependencies.
     ```shell
     docker compose run ckan
     ```

  <!--testing-end-->


pkgId: 04e7a2d040ebba2a97377505216cf3356b174ba8c42d8c07cd33a364efb26253
name: python-ckanext-datagovcatalog
arch: src
version: 0.1.1
epoch: 0
release: 1
summary: Catalog customizations
url: https://github.com/GSA/ckanext-datagovcatalog
rpm_license: AGPL
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-datagovcatalog-0.1.1-1.src.rpm
checksum_type: sha256
description:
  [ckanext-harvest](https://github.com/ckan/ckanext-harvest/)            | This currently has two different version for py2 and py3 until [this PR](https://github.com/ckan/ckanext-harvest/pull/450) is merged upstream
  [ckanext-envvars](https://github.com/okfn/ckanext-envvars)             | This is necessary based on how the testing environment is set up.

  [comment]: <> (Add any additional install steps to the list below.
     For example installing any non-Python dependencies or adding any required
     config settings.)


pkgId: 78028887bbabcbb6a060f508ef17e0e1d66bff206d00eb0da73af74ee10f0188
name: python-ckanext-datagovtheme
arch: src
version: 0.2.34
epoch: 0
release: 1
summary: CKAN Extension to manage data.gov theme
url: https://github.com/GSA/ckanext-datagovtheme/
rpm_license: Public Domain
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-datagovtheme-0.2.34-1.src.rpm
checksum_type: sha256
description:
  <=2.8        | no
  2.9          | 0.1.27 (last supported)
  2.10         | >=0.2.0

  [Optional]
  `ckanext.datagovtheme.js_recent_view = true`
  This defaults to `false`. If displaying the recent view count slows down page loading, the optional parameter can be set to `true` to make the recent view count an AJAX call, improving page loading speed. If the recent view count information (package['tracking_summary']) is already present, the AJAX call is disabled to reduce overhead. Therefore, the built-in recent view count rendering must be disabled for this mechanism to take effect. For catalog.data.gov, it means set setting `ckanext.datagovcatalog.add_packages_tracking_info` to false.
  **TODO**: re-evaluate the need for this customization after ckan 2.11 release, as described in ticket https://github.com/GSA/data.gov/issues/4798.


  - GNU Make
  - Docker Compose

  Build the docker containers. You'll want to do this anytime the dependencies
  change (requirements.txt, dev-requirements.txt).
      $ make build
  Start the containers.
      $ make up
  CKAN will start at [localhost:5000](http://localhost:5000).
  Clean up the environment.
      $ make down
  Open a shell to run commands in the container.
      $ docker-compose exec ckan bash
  If you're unfamiliar with docker-compose, see our
  [cheatsheet](https://github.com/GSA/datagov-deploy/wiki/Docker-Best-Practices#cheatsheet)
  and the [official docs](https://docs.docker.com/compose/reference/).
  For additional make targets, see the help.
      $ make help

  They follow the guidelines for [testing CKAN extensions](https://docs.ckan.org/en/2.8/extensions/testing-extensions.html#testing-extensions).
  To run the extension tests:
      $ make test
  Lint your code.
      $ make lint

  We have seen issues with `datagovtheme not installed`.
  If this is the case, run `python setup.py develop` in the container.

  The development environment drops as many dependencies as possible. It is
  not meant to have feature parity with
  [GSA/catalog.data.gov](https://github.com/GSA/catalog.data.gov/) or
  [GSA/inventory-app](https://github.com/GSA/inventory-app/). Tests should mock
  external dependencies where possible.
  In order to support multiple versions of CKAN, or even upgrade to new versions
  of CKAN, we support development and testing through the `CKAN_VERSION`
  environment variable.
      $ make CKAN_VERSION=2.10.1 test


pkgId: f3bf96950d580b1e774a026a04b5a2197edb385dca655f979c36578a5c7c2589
name: python-ckanext-datajson
arch: src
version: 0.1.27
epoch: 0
release: 1
summary: CKAN extension to generate /data.json
url: https://github.com/GSA/ckanext-datajson
rpm_license: Public Domain
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-datajson-0.1.27-1.src.rpm
checksum_type: sha256
description:
  <=2.7          | :x:
  2.8            | :warning:
  2.9.5          | :heavy_check_mark:
  2.9.6          | :heavy_check_mark:

  To install, activate your CKAN virtualenv, install dependencies, and
  install the module in develop mode, which just puts the directory in your
  Python path.
  	. path/to/pyenv/bin/activate
  	pip install -r requirements.txt
  	python setup.py develop
  Then in your CKAN .ini file, add `datajson`
  to your ckan.plugins line:
  	ckan.plugins = (other plugins here...) datajson
  That's the plugin for /data.json output. To make the harvester available,
  also add:
  	ckan.plugins = (other plugins here...) harvest datajson_harvest
  To make the datajson validator route and web form available, also add:
  	ckan.plugins = (other plugins here...) datajson_validator
  [ Optional ] Set the resource count limit allowed in one record so that fetch-consumer does not run out of memory during harvesting. Default is unlimited. Once set, records with higher resource count will see import errors.
   `ckanext.datajson.max_resource_count = 1000`


  Build the docker containers.
      $ make build
  Start the docker containers.
      $ make up
  CKAN will start at [localhost:5000](http://localhost:5000/).
  Clean up any containers and volumes.
      $ make clean
  Open a shell to run commands in the container.
      $ docker-compose exec app /bin/bash
  If you're unfamiliar with docker-compose, see our
  [cheatsheet](https://github.com/GSA/datagov-deploy/wiki/Docker-Best-Practices#cheatsheet)
  and the [official docs](https://docs.docker.com/compose/reference/).
  For additional make targets, see the help.
      $ make help

  They follow the guidelines for [testing CKAN
  extensions](https://docs.ckan.org/en/2.9/extensions/testing-extensions.html#testing-extensions).
  To run the extension tests, start the containers with `make up`, then:
      $ make test
  Lint the code.
      $ make lint

  The test development environment drops as many dependencies as possible. It is
  not meant to have feature parity with
  [GSA/catalog.data.gov](https://github.com/GSA/catalog.data.gov/). Tests should
  mock external dependencies where possible.
  In order to support multiple versions of CKAN, or even upgrade to new versions
  of CKAN, we support development and testing through the `CKAN_VERSION`
  environment variable.
      $ make CKAN_VERSION=2.9.5 test
      $ make CKAN_VERSION=2.9 test
  Note: When testing patch versions of CKAN, the services may not have patch releases.
  So, take note of the `SERVICES_VERSION` variable which tracks the minor release to
  pull for the `db` and `solr` images.

  Original work written by the HealthData.gov team. It has been modified in support of Data.gov.
  As a work of the United States Government, this package is in the public
  domain within the United States. Additionally, we waive copyright and
  related rights in the work worldwide through the CC0 1.0 Universal
  public domain dedication (which can be found at http://creativecommons.org/publicdomain/zero/1.0/).

  We're so glad you're thinking about contributing to ckanext-datajson!
  Before contributing to ckanext-datajson we encourage you to read our
  [CONTRIBUTING](CONTRIBUTING.md) guide, our [LICENSE](LICENSE.md), and our README
  (you are here), all of which should be in this repository. If you have any
  questions, you can email the Data.gov team at
  [datagov@gsa.gov](mailto:datagov@gsa.gov).


pkgId: 02326d0bfee29771acec4a8580d1e1b942fa5bcde9441282e2d4ad75b2f7838d
name: python-ckanext-dc-serve
arch: src
version: 0.16.3
epoch: 0
release: 1
summary: Serve DC on DCOR data via the CKAN API interface
url: https://pypi.org/project/ckanext-dc-serve/
rpm_license: GNU Affero General Public License v3 or later (AGPLv3+)
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-dc-serve-0.16.3-1.src.rpm
checksum_type: sha256
description:
  |PyPI Version| |Build Status| |Coverage Status|
  This CKAN plugin provides an API for accessing DC data. The python
  package dclab implements a client library (``dclab.rtdc_dataset.fmt_dcor``)
  to access this API. Shape-Out 2 offers a GUI via *File - Load DCOR data*.
  This plugin implements:
  - The DCOR API for accessing DC datasets online (dcserv).
  - A background job that generates a condensed dataset after a resource
    has been created.
  - A background job that uploads the condensed dataset to the S3 object
    store. The temporary location of the condensed dataset that is created
    can be set by setting the `ckanext.dc_serve.tmp_dir` configuration
    option.
  - A route that makes the condensed dataset available via
    "/dataset/{id}/resource/{resource_id}/condensed.rtdc"
    (S3 object store data is made available via a redirect)
  - A route overriding the default route for downloading a resource via
    "/dataset/{id}/resource/{resource_id}/download/resource_name"
    (S3 object store data is made available via a redirect)
  - Extends the template to show a condensed resource download button
  - CLI:
    - add CKAN command `run-jobs-dc-serve` that runs all background
      jobs for all resources (if not already done)
  - Configuration keywords:
    - the ``ckanext.dc_serve.create_condensed_datasets`` boolean
      parameter can be set to False to prevent DCOR from generating condensed
      resource files
    - ``ckanext.dc_serve.tmp_dir`` specifies the location of a directory
      used for creating temporary files when condensing datasets; if not
      specified, a temporary directory is used


pkgId: fd1e6d21c1de2c31f5e0dbac6aa240e20decf4e57f4ca0e2909d372f066e4e7d
name: python-ckanext-dc-view
arch: src
version: 0.10.2
epoch: 0
release: 1
summary: Preview DC data on DCOR
url: https://pypi.org/project/ckanext-dc-view/
rpm_license: GNU Affero General Public License v3 or later (AGPLv3+)
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-dc-view-0.10.2-1.src.rpm
checksum_type: sha256
description:
  |PyPI Version| |Build Status| |Coverage Status|
  A CKAN resource view for DC data. The preview includes metadata from
  the HDF5 attributes and a summary plot (scatter plot of brightness vs. area
  and image, contour, mask, and fluorescence data for one event). This plugin
  registers a background job for generating the overview plot after a DC
  resource has been created.
  This extensione implements:
  - A default view for RT-DC (mimetype) resources
  - A background job that generates the preview image
  - A background job that uploads preview images to the S3 object store
  - A route that makes the preview image available via
    "/dataset/{id}/resource/{resource_id}/preview.jpg"
  - CLI:
    - add CKAN command `run-jobs-dc-view` that runs all background
      jobs for all resources (if not already done)


pkgId: 27669bb198986728e0d053cd7c42c9e0267fa3996a0dd216bf10f818483b7aec
name: python-ckanext-dcat-usmetadata
arch: src
version: 0.6.0
epoch: 0
release: 1
summary: DCAT USMetadata Form App for CKAN
url: https://github.com/GSA/ckanext-dcat_usmetadata
rpm_license: AGPL
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-dcat-usmetadata-0.6.0-1.src.rpm
checksum_type: sha256
description:
  [![Github Actions](https://github.com/GSA/ckanext-dcat_usmetadata/actions/workflows/test.yml/badge.svg)](https://github.com/GSA/ckanext-dcat_usmetadata/actions)
  [![PyPI version](https://badge.fury.io/py/ckanext-dcat_usmetadata.svg)](https://badge.fury.io/py/ckanext-dcat_usmetadata)



  This extension provides a new dataset form for [inventory.data.gov](https://inventory.data.gov/). The form is tailored to managing metadata meeting the [DCAT-US Schema](https://resources.data.gov/resources/dcat-us/).





  This module currently depends on the [USMetadata app](https://github.com/GSA/USMetadata) for server-side validation and rendering.
  Make sure it is enabled in CKAN's plugins.

  This extension is compatible with these versions of CKAN.

  | CKAN version | Compatibility |
  | ------------ | ------------- |
  | >=2.9        | yes           |
  | >=3.0        | no            |



  Add `ckanext-dcat-usmetadata` to your requirements.txt, and then pip install

  In your CKAN .ini file add `dcat_usmetadata` to your enabled plugins:

  `ckan.plugins = [YOUR PLUGINS HERE...] dcat_usmetadata`





  This extension adds a new CLI command for importing publishers linked to CKAN
  organizations. The [list of
  publishers](https://docs.google.com/spreadsheets/d/1BWpXWswnnMRaNazMCYrzl4W5JMWpGuyW0Wo2YaNH9jY/edit?usp=sharing)
  should be exported in a CSV data and it should have the following structure
  (note the headers):

  ```
  organization,publisher,publisher_1,publisher_2,publisher_3,publisher_4,publisher_5
  agricultural-marketing-service-department-of-agriculture,Department of Agriculture,Agricultural Marketing Service,,,,
  ars-usda-gov,Department of Agriculture,Agricultural Research Service,,,,
  aphis-usda-gov,Department of Agriculture,Animal and Plant Health Inspection Service,,,,
  risk-management-agency-department-of-agriculture,Department of Agriculture,Departmental Management,,,,
  usda-gov,Department of Agriculture,Office of Chief Information Officer,,,,
  usda-gov,Department of Agriculture,Economic Research Service,,,,
  usda-gov,Department of Agriculture,Farm Service Agency,,,,
  usda-gov,Department of Agriculture,Food and Nutrition Service,,,,
  usda-gov,Department of Agriculture,Food Safety and Inspection Service,,,,
  usda-gov,Department of Agriculture,Foreign Agricultural Service,,,,
  usda-gov,Department of Agriculture,National Agricultural Statistics Service,,,,
  usda-gov,Department of Agriculture,National Institute of Food and Agriculture,,,,
  usda-gov,Department of Agriculture,Natural Resources Conservation Service,Colorado State University,,,
  usda-gov,Department of Agriculture,Rural Development,,,,
  usda-gov,Department of Agriculture,GIPSA,Federal Grain Inspection Service,,,
  usda-gov,Department of Agriculture,Natural Resources Conservation Service,,,,
  usda-gov,Department of Agriculture,US Forest Service,,,,
  ```

  Each CKAN organization must have its own list of publishers.

  Example of running the command:

      $ ckan dcat-usmetadata import-publishers /path/to/publishers.csv





  These tools are required for development.

  - [Node.js](https://nodejs.org/) 12.x
  - [Yarn](https://yarnpkg.com/) 1.22.x
  - [Cypress](https://www.cypress.io/) 6.0.0+



  Install Node.js dependencies.

  ```bash
  yarn install
  ```

  Build the JS application. The new build files can be found in `ckanext/dcat_usmetadata/public` folder.

  - Pass the `--emptyOutDir` flag to replace an existing build.

  ```bash
  yarn build
  ```

  Build and start the docker containers.

  ```bash
  yarn build:docker
  yarn up
  ```



  There are several levels of testing:

  | Suite                     | Description                  | Command                  |
  | ------------------------- | ---------------------------- | ------------------------ |
  | Unit tests for the JS app | Tests for the React app.     | `yarn test:metadata-app` |
  | CKAN extension tests      | Python tests using Nosetests | `yarn test`              |
  | End to end tests          | Cypress tests                | `yarn e2e`               |



  Lint the python code.

  ```bash
  yarn lint:python
  ```

  Lint the JavaScript code.

  ```bash
  yarn lint:js
  ```



  The Metadata app was a [Create React App](https://create-react-app.dev/)-bootstrapped project converted to use [Vite](https://vitejs.dev/) as the build tool.

  To run the app use `yarn && yarn start` command.

  _TODO briefly describe how the metadata application relates to the CKAN
  extension._



  This project uses [cosmos](https://reactcosmos.org/) for development.

  Run CKAN locally (`yarn up`), get the Admin user's API Key and add it in `/metadata-app/public/index.html` as `data-apiKey` attribute of the `div` element. Add a test org for development purposes.

  Run `yarn && yarn cosmos` to start the cosmos server, which will watch the `metadata-app/src` directory for changes.

  Run the unit tests:

  ```bash
  yarn test:metadata-app

  yarn test:metadata-app:watch
  ```



  Some tests render a fixture component with [Jest](https://jestjs.io/) and then
  match against a known good snapshot (HTML rendering) of the component. When you
  edit a component, you'll usually have to update the snapshot and inspect the
  diff to make sure all changes are as intended.

  ```bash
  yarn test:metadata-app --updateSnapshot
  ```



  To build the latest JS code and update assets in the CKAN extension, you can run the following command from the root directory of this project:

  ```
  yarn build
  ```

  For convenience, we have prepared a single script that you can run to perform end-to-end tests locally. Don't forget to `yarn build` prior to running e2e tests, otherwise, the tests could run against older builds:

  ```bash
  yarn e2e
  ```

  Note, it may be necessary to remove cached images when rebuilding the docker container, in order to ensure that the new usmetadata-app template is included in the build. If you want to make sure that you aren't using cached builds, you can try:

  ```bash
  docker-compose build --no-cache --pull ckanext-dcat_usmetadata_app
  ```

  To run e2e tests interactively use:

  ```bash
  yarn e2e:interactive
  ```



  You can install this extension locally (to [inventory app](https://github.com/GSA/inventory-app), for example), but you must `yarn install` and then `yarn build` the JS/CSS prior to launching the app locally.



  We publish this extension to PyPI - https://pypi.org/project/ckanext-dcat-usmetadata/. This is done by CI job that is triggered on tagged commit on master branch. When you need to release a new version of the extension, you need to:

  0. Create a new branch for releasing a new version of the extension. You can name your branch with the following convention: `release/x.y.z`;
  1. Update version in `setup.py`;
  2. Get your PR merged to master branch;
  3. Tag the merged commit with the new version (`git tag $version`).

  In the CI job, the following is done for tagged commits:

  - It builds the JS bundles and puts them into the relevant directory so the extension can use them;
  - It runs integration tests to make sure everything is working as expected;
  - It packages the extension and publishes it to PyPI.

  Below is a sequence diagram demonstrating the flow (you need to have `github + mermaid` chrome extension to view it):

  ```mermaid
  sequenceDiagram
      Developer->>Git: Push tagged commit to master branch
      Git-->>CI/CD: Trigger deployment
      CI/CD-->>CI/CD: Build assets (JS bundles)
      CI/CD-->>CI/CD: Build python package
      CI/CD-->>CI/CD: Run tests
      CI/CD-->>PyPI: Publish the package
      Inventory-->>PyPI: Install
  ```



  The Data.gov team manages all Data.gov updates, bugs, and feature additions via GitHub's public [issue tracker](https://github.com/GSA/ckanext-dcat_usmetadata/issues) in this repository.

  If you do not already have a GitHub account, you can [sign up for GitHub here](https://github.com/). In the spirit of open source software, everyone is encouraged to help improve this project. Here are some ways you can contribute:

  - by reporting bugs
  - by suggesting new features
  - by translating content to a new language
  - by writing or editing documentation
  - by writing specifications
  - by writing code and documentation (no pull request is too small: fix typos, add code comments, clean up inconsistent whitespace)
  - by reviewing pull requests.
  - by closing issues



  - Before submitting a new issue, check to make sure a similar issue isn't already open. If one is, contribute to that issue thread with your feedback.
  - When submitting a bug report, please try to provide as much detail as possible, i.e. a screenshot or gist that demonstrates the problem, the technology you are using, and any relevant links.



  Issues labeled [help wanted](https://github.com/GSA/data.gov/labels/help%20wanted) make it easy for you to find ways you can contribute today.



  This project constitutes a work of the United States Government and is not subject to domestic copyright protection under 17 USC § 105. Additionally, we waive copyright and related rights in the work worldwide through the CC0 1.0 [Universal public domain dedication](https://creativecommons.org/publicdomain/zero/1.0/).

  All contributions to this project will be released under the CC0 dedication. By submitting a pull request, you are agreeing to comply with this waiver of copyright interest.


pkgId: f10d02a829a969d405ed66d6d63bb92dc04489337e5b80d2fe86baec7ae33445
name: python-ckanext-dcor-depot
arch: src
version: 0.15.4
epoch: 0
release: 1
summary: Manages data storage for DCOR
url: https://pypi.org/project/ckanext-dcor-depot/
rpm_license: GNU Affero General Public License v3 or later (AGPLv3+)
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-dcor-depot-0.15.4-1.src.rpm
checksum_type: sha256
description:
  |PyPI Version| |Build Status| |Coverage Status|
  This plugin manages how data are stored in DCOR. There are two types of
  files in DCOR:
  1. Resources uploaded by users, imported from figshare, or
     imported from a data archive
  2. Ancillary files that are generated upon resource creation, such as
     condensed DC data, preview images (see
     `ckanext-dc_view <https://github.com/DCOR-dev/ckanext-dc_view>`_).
  This plugin implements:
  - Data storage management. All resources uploaded by a user are moved
    to ``/data/users-HOSTNAME/USERNAME-ORGNAME/PK/ID/PKGNAME_RESID_RESNAME``
    and symlinks are created in ``/data/ckan-HOSTNAME/resources/RES/OUR/CEID``
    via a background job.
    CKAN itself will not notice this. The idea is to have a filesystem overview
    about the datasets of each user.
  - A backround job that uploads resources to S3 in `after_resource_create`
    if the resources were uploaded via the legacy upload route.
  - A background job that backs up resources from S3 to local block storage
    if the resources were uploaded via the S3 upload route.
  - Import datasets from figshare. Existing datasets from figshare are
    downloaded to the ``/data/depots/figshare`` directory and, upon resource
    creation, symlinked there from  ``/data/ckan-HOSTNAME/resources/RES/OUR/CEID``
    (Note that this is an exemption of the data storage management described
    above). When running the following command, the "figshare-import" organization
    is created and the datasets listed in ``figshare_dois.txt`` are added to CKAN:
       ckan import-figshare
  - CLI for symlinking datasets that have failed to symlink before:
       ckan run-jobs-dcor-depot
  - CLI for appending a resource to a dataset
       ckan append-resource /path/to/file dataset_id --delete-source
  Please make sure that the necessary file permissions are given in ``/data``.
  In 2023, it was decided that the huge block storage of DCOR
  should be replaced with an S3-compatible object store, because block storage
  does not scale well. This partially deprecates some of the commands above
  which might be removed or modified to support object storage directly.
  - CLI for migrating data from block storage to an S3-compatible object storage
    service. For this, the following configuration keys must be specified in
    the ``ckan.ini`` file::
      dcor_object_store.access_key_id = ACCESS_KEY_ID
      dcor_object_store.secret_access_key = SECRET_ACCESS_KEY
      dcor_object_store.endpoint_url = S3_ENDPOINT_URL
      dcor_object_store.ssl_verify = true
      
      
      dcor_object_store.bucket_name = circle-{organization_id}
    Usage::
      ckan dcor-migrate-resources-to-object-store


pkgId: 24b61f42a968059f0f64847932e31b155ce85e6bcbc23dbf28ec08e3c7d5d838
name: python-ckanext-dcor-schemas
arch: src
version: 0.20.2
epoch: 0
release: 1
summary: Introduces or lifts restrictions (authorization) for managing data and metadata on DCOR
url: https://pypi.org/project/ckanext-dcor-schemas/
rpm_license: GNU Affero General Public License v3 or later (AGPLv3+)
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-dcor-schemas-0.20.2-1.src.rpm
checksum_type: sha256
description:
  |PyPI Version| |Build Status| |Coverage Status|
  This module introduces/lifts restrictions (authorization) for the management
  of data and meta data on DCOR. The corresponding UI elements are modified
  accordingly:
  - Authorization (auth.py)
    - datasets: do not allow deleting datasets unless they are drafts
    - datasets: allow purging of deleted datasets
    - datasets: do not allow switching to a more restrictive license
    - datasets: do not allow changing the name (slug)
    - datasets: do not allow adding resources to non-draft datasets
    - datasets: do not allow to set the visibility of a public dataset to private
    - datasets: do not allow uploading datasets via the web interface
    - organization: do not allow bulk_update_delete (e.g. datasets by organization admins)
    - resources: do not allow deleting resources unless they are drafts
    - resources: only allow changing the "description"
    - resources: do not allow setting a resource id when uploading
    - user: allow all logged-in users to create datasets, circles, and collections
  - Validation (validate.py)
    - datasets: force user to select authors
    - datasets: author list "authors" is CSV
    - datasets: parse DOI field (remove URL part)
    - datasets: force user to select a license
    - datasets: restrict to basic CC licenses
    - datasets: automatically generate dataset name (slug) using random characters
      if necessary (does not apply to admins)
    - datasets: a dataset without resources is considered to be a draft;
      it's state cannot be set to "active"
    - datasets: the state of a dataset that does not contain at least one
      valid .rtdc resource cannot be set to "active"
    - resources: do not allow uploading resources with the same name
      for a dataset (important for ckanext-dcor_depot)
    - resources: make sure the resource name matches the file name of the
      upload; this is actually implemented in plugin.before_create
      (IResourceController) and not in validate.py
    - resources: custom resource name is overridden during upload
    - resources: do not allow weird characters in resource names
    - resources: restrict upload data extensions to .'.rtdc', '.ini', '.csv',
      '.tsv', '.pdf', '.txt', '.jpg', '.png', '.tif', '.py', '.ipynb', '.poly',
      '.sof', '.so2'
    - resources: configuration metadata (using `dclab.dfn.config_funcs`)
    - resources: 's3_available' and 's3_url' for identifying objects that
      are available on S3 and for downloading public datasets.
  - IPermissionLabels (plugin.py)
    - Allow a user A to see user B's private dataset if the private dataset
      is in a group that user A is a member of.
  - UI Dataset:
    - hide "add new resource" button in ``templates/package/resources.html``
    - add field ``authors`` (csv list)
    - add field ``doi`` (validator parses URLs)
    - add field ``references`` (parses arxiv, bioRxiv, DOI, links)
    - add CC license file ``licenses.json`` (only show less restrictive licenses
      when editing the dataset)
  - UI Organization:
    - remove "Delete" button in bulk view
  - UI Resource:
    - Do not show these variables (because they are redundant):
      ['last modified', 'revision id', 'url type', 'state', 'on same domain']
      (``templates/package/resource_read.html``)
    - Show DC config data via "toggle-more"
    - Add supplementary resource schema via json files located in
      `dcor_schemas/resource_schema_supplements`
  - Background jobs:
    - set the mimetype for each dataset
    - populate "dc:sec:key" metadata for each DC dataset
    - generates sha256 hash upon resource creation
    - populate etag resource property from S3 storage upon resource creation
  - Configuration keywords:
    - the ``ckanext.dcor_schemas.allow_content_listing_for_anon`` boolean
      parameter can be set to False to prevent anonymous users to see
      circles, colletions, and other content.
    - the ``ckanext.dcor_schemas.allow_public_datasets`` boolean parameter
      can be used to disable the creation of public datasets (e.g. for DCOR-med).
    - the ``ckanext.dcor_schemas.json_resource_schema_dir`` parameter
      can be used to specify a directory containing .json files that
      define the supplementary resource schema. The default is
      ``package`` which means that the supplementary resource schema of
      this extension is used.
    - These DCOR-wide configuratio options for accessing S3 object storage
      - ``endpoint_url``
      - ``bucket_name``
      - ``access_key_id``
      - ``secret_access_key``
      - ``ssl_verify``
  - API extensions:
    - ``resource_upload_s3_urls`` returns a dictionary containing the upload
      URLs (single file or multipart) required for uploading a new resource
      directly to S3
    - ``resource_schema_supplements`` returns a dictionary of the
      current supplementary resource schema
    - ``supported_resource_suffixes`` returns a list of supported
      resource suffixes
  - CLI:
    - CKAN command `list-circles` returns the list of DCOR circles
    - CKAN command `list-collections` returns the list of DCOR collections
    - CKAN command `list-group-resources <NAME>` returns the list of resources in
      a DCOR circle or collection
    - CKAN command `list-zombie-users` for users with no datasets and
      no activity for a certain amount of time
    - CKAN command `run-jobs-dcor-schemas` that runs all background
      jobs for all resources (if not already done)
    - CKAN command `dcor-move-dataset-to-circle` for moving a dataset to
      a different circle


pkgId: dd94d3c1512dd928c4d18aa625bebacbc7fbd537f5adb9f2862fb21bf31c47a9
name: python-ckanext-dcor-theme
arch: src
version: 0.8.2
epoch: 0
release: 1
summary: The DCOR CKAN theme
url: https://pypi.org/project/ckanext-dcor-theme/
rpm_license: GNU Affero General Public License v3 or later (AGPLv3+)
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-dcor-theme-0.8.2-1.src.rpm
checksum_type: sha256
description:
  |PyPI Version| |Build Status| |Coverage Status|
  The CKAN theme of DCOR. What this plugin does:
  - remove the language selection from footer.html
  - remove links from footer.html
  - set the title of the page to "DCOR"
  - insert a custom about text
  - remove social media buttons
  - change icons / logo
  - use i18n to change the terms "Organization" -> "Circle",
    "Group" -> "Collection", etc.::
       ckan dcor-theme-i18n-branding
  - create a custom theme based on the default main.css file
    (hide action buttons (Fullscreen, Embed) in resource view via css,
    change colors) using::
      ckan dcor-theme-main-css-branding


pkgId: 3ee0c51798bcb97536debe5bf3c4fceb51ce1cbe19aa1188364781f1b28cd247
name: python-ckanext-doi
arch: src
version: 3.1.17
epoch: 0
release: 1
url: https://pypi.org/project/ckanext-doi/
rpm_license: GPL-3.0-or-later
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-doi-3.1.17-1.src.rpm
checksum_type: sha256
summary:
  A CKAN extension for assigning a digital object identifier (DOI) to datasets, using the DataCite DOI service.

description:
  <!--header-start-->
  <picture>
    <source media="(prefers-color-scheme: dark)" srcset="https://data.nhm.ac.uk/images/nhm_logo.svg">
    <source media="(prefers-color-scheme: light)" srcset="https://data.nhm.ac.uk/images/nhm_logo_black.svg">
    <img alt="The Natural History Museum logo." src="https://data.nhm.ac.uk/images/nhm_logo_black.svg" align="left" width="150px" height="100px" hspace="40">
  </picture>



  [![Tests](https://img.shields.io/github/actions/workflow/status/NaturalHistoryMuseum/ckanext-doi/tests.yml?style=flat-square)](https://github.com/NaturalHistoryMuseum/ckanext-doi/actions/workflows/tests.yml)
  [![Coveralls](https://img.shields.io/coveralls/github/NaturalHistoryMuseum/ckanext-doi/main?style=flat-square)](https://coveralls.io/github/NaturalHistoryMuseum/ckanext-doi)
  [![CKAN](https://img.shields.io/badge/ckan-2.9.9%20%7C%202.10.1-orange.svg?style=flat-square)](https://github.com/ckan/ckan)
  [![Python](https://img.shields.io/badge/python-3.6%20%7C%203.7%20%7C%203.8-blue.svg?style=flat-square)](https://www.python.org/)
  [![Docs](https://img.shields.io/readthedocs/ckanext-doi?style=flat-square)](https://ckanext-doi.readthedocs.io)

  _A CKAN extension for assigning a digital object identifier (DOI) to datasets, using the DataCite DOI service._

  <!--header-end-->



  <!--overview-start-->
  This extension assigns a digital object identifier (DOI) to datasets, using the DataCite DOI service.

  When a new dataset is created it is assigned a new DOI. This DOI will be in the format:

  `https://doi.org/[prefix]/[8 random alphanumeric characters]`

  If the new dataset is active and public, the DOI and metadata will be registered with DataCite.

  If the dataset is draft or private, the DOI will not be registered with DataCite. When the dataset is made active & public, the DOI will be registered.
  This allows datasets to be embargoed, but still provides a DOI to be referenced in publications.

  You will need a DataCite account to use this extension.



  This extension currently uses [DataCite Metadata Schema v4.2](https://schema.datacite.org/meta/kernel-4.2/index.html).

  Dataset package fields and CKAN config settings are mapped to the DataCite Schema with default values, but these can be overwritten by [implementing `IDoi` interface methods](https://ckanext-doi.readthedocs.io/en/latest/usage/#interfaces).



  | CKAN Field                    | DataCite Schema |
  |-------------------------------|-----------------|
  | dataset:title                 | title           |
  | dataset:author                | creator         |
  | config:ckanext.doi.publisher  | publisher       |
  | dataset:metadata_created.year | publicationYear |
  | dataset:type                  | resourceType    |

  See [`metadata.py`](https://github.com/NaturalHistoryMuseum/ckanext-doi/blob/main/ckanext/doi/lib/metadata.py) for full mapping details.

  <!--overview-end-->



  <!--installation-start-->
  Path variables used below:
  - `$INSTALL_FOLDER` (i.e. where CKAN is installed), e.g. `/usr/lib/ckan/default`
  - `$CONFIG_FILE`, e.g. `/etc/ckan/default/development.ini`



  ```shell
  pip install ckanext-doi
  ```



  1. Clone the repository into the `src` folder:
     ```shell
     cd $INSTALL_FOLDER/src
     git clone https://github.com/NaturalHistoryMuseum/ckanext-doi.git
     ```

  2. Activate the virtual env:
     ```shell
     . $INSTALL_FOLDER/bin/activate
     ```

  3. Install via pip:
     ```shell
     pip install $INSTALL_FOLDER/src/ckanext-doi
     ```



  Installing from a `pyproject.toml` in editable mode (i.e. `pip install -e`) requires `setuptools>=64`; however, CKAN 2.9 requires `setuptools==44.1.0`. See [our CKAN fork](https://github.com/NaturalHistoryMuseum/ckan) for a version of v2.9 that uses an updated setuptools if this functionality is something you need.



  1. Add 'doi' to the list of plugins in your `$CONFIG_FILE`:
     ```ini
     ckan.plugins = ... doi
     ```

  2. Initialise the database:
     ```shell
     ckan -c $CONFIG_FILE doi initdb
     ```

  3. This extension will only work if you have signed up for an account with [DataCite](https://datacite.org). You will need a development/test account to use this plugin in test mode, and a live account to mint active DOIs.

  <!--installation-end-->



  <!--configuration-start-->
  These are the options that can be specified in your .ini config file.



  DataCite Repository account credentials are used to register DOIs. A Repository account is administered by a DataCite Member.

  | Name                           | Description                                                                                             | Example    |
  |--------------------------------|---------------------------------------------------------------------------------------------------------|------------|
  | `ckanext.doi.account_name`     | Your DataCite Repository account name                                                                   | `ABC.DEFG` |
  | `ckanext.doi.account_password` | Your DataCite Repository account password                                                               |            |
  | `ckanext.doi.prefix`           | The prefix taken from your DataCite Repository account (from your test account if running in test mode) | `10.1234`  |



  You also need to provide the name of the institution publishing the DOIs (e.g. Natural History Museum).

  | Name                    | Description                                    |
  |-------------------------|------------------------------------------------|
  | `ckanext.doi.publisher` | The name of the institution publishing the DOI |



  If test mode is set to true, the DOIs will use the DataCite test site. The test site uses a separate account, so you must also change your credentials and prefix.

  | Name                    | Description          | Options    |
  |-------------------------|----------------------|------------|
  | `ckanext.doi.test_mode` | Enable dev/test mode | True/False |

  Note that the DOIs will still display on your web interface as `https://doi.org/YOUR-DOI`, but they _will not resolve_. Log in to your test account to view all your minted test DOIs, or replace `https://doi.org/` with `https://doi.test.datacite.org/dois/` in a single URL to view a specific DOI.



  | Name                     | Description                                | Default         |
  |--------------------------|--------------------------------------------|-----------------|
  | `ckanext.doi.site_url`   | Used to build the link back to the dataset | `ckan.site_url` |
  | `ckanext.doi.site_title` | Site title to use in the citation          | None            |

  <!--configuration-end-->



  <!--usage-start-->




  1. `delete-dois`: delete all DOIs from the database (_not_ datacite).
      ```bash
      ckan -c $CONFIG_FILE doi delete-dois
      ```

  2. `update-doi`: update the datacite metadata for one or all packages.
      ```bash
      ckan -c $CONFIG_FILE doi update-doi [PACKAGE_ID]
      ```



  The `IDoi` interface allows plugins to extend the `build_metadata_dict` and `build_xml_dict`
  methods.



  **Breaking changes from v1:**

  1. previously called `build_metadata`
  2. new parameter: `errors`
  3. new return value: tuple of `metadata_dict`, `errors`

  Extracts metadata from a pkg_dict for use in generating datacite DOIs. The base method from this extension is run first, then the metadata dict is passed through all the implementations of this method. After running these, if any of the required values (see above) are still in the `errors` dict (i.e. they still could not be handled by any other extension), a `DOIMetadataException` will be thrown.

  | Parameter       | Description                                                                                                                                               |
  |-----------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------|
  | `pkg_dict`      | The original package dictionary from which the metadata were extracted.                                                                                   |
  | `metadata_dict` | The current metadata dict, created by the ckanext-doi extension and any previous plugins implementing IDoi.                                               |
  | `errors`        | A dictionary of metadata keys and errors generated by previous plugins; this method should remove any keys that it successfully processes and overwrites. |



  **Breaking changes from v1:**

  1. previously called `metadata_to_xml`
  2. parameters rearranged (previously `xml_dict`, `metadata`)

  Converts the metadata_dict into an xml_dict that can be passed to the `datacite` library's `schema42.tostring()` and `schema42.validate()` methods. The base method from this extension is run first, then the xml dict is passed through all the implementations of this method.

  | Parameter       | Description                                                                                            |
  |-----------------|--------------------------------------------------------------------------------------------------------|
  | `metadata_dict` | The original metadata dictionary from which the xml attributes are extracted.                          |
  | `xml_dict`      | The current xml dict, created by the ckanext-doi extension and any previous plugins implementing IDoi. |





  ```html+jinja
  {% snippet "doi/snippets/package_citation.html", pkg_dict=g.pkg_dict %}
  ```



  ```html+jinja
  {% snippet "doi/snippets/resource_citation.html", pkg_dict=g.pkg_dict, res=res %}
  ```

  <!--usage-end-->



  <!--testing-start-->
  There is a Docker compose configuration available in this repository to make it easier to run tests. The ckan image uses the Dockerfile in the `docker/` folder.

  To run the tests can be run against ckan 2.9.x and 2.10.x on Python3:

  1. Build the required images:
     ```shell
     docker compose build
     ```

  2. Then run the tests.
     The root of the repository is mounted into the ckan container as a volume by the Docker compose configuration, so you should only need to rebuild the ckan image if you change the extension's dependencies.
     ```shell
     
     docker compose run latest

     
     docker compose run next
     ```

  Note that the tests mock the DataCite API and therefore don't require an internet connection nor your DataCite credentials to run.

  <!--testing-end-->


pkgId: 1a65de1ecbd3c85a6c01d41ba611a445a0509b0c5f95b63efdffca03e74f62f1
name: python-ckanext-drupal-api
arch: src
version: 0.7.2.post1
epoch: 0
release: 1
summary: please add a summary manually as the author left a blank one
url: https://github.com/DataShades/ckanext-drupal-api
rpm_license: AGPL
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-drupal-api-0.7.2.post1-1.src.rpm
checksum_type: sha256
description:
  The extension helps synchronize the header and footer between CKAN and Drupal.

  It uses two versions of the Drupal API - the core Rest API and the JSON:API.

  The extension receives data from the Drupal portal through an endpoint
  (which can be configured in the case of the core REST API) and caches it for
  a certain time, which can also be changed using the Cache TTL config option,
  specifying the value in seconds. If you want to synchronize data more often,
  you need to set a smaller value.




  * CKAN>=2.10
  * python>=3.7



  To install ckanext-drupal-api:

  1. Activate your CKAN virtual environment, for example:

       . /usr/lib/ckan/default/bin/activate

  2. Clone the source and install it on the virtualenv

      git clone https://github.com/DataShades/ckanext-drupal-api.git
      cd ckanext-drupal-api
      pip install -e .
  	pip install -r requirements.txt

  3. Add `drupal_api` to the `ckan.plugins` setting in your CKAN
     config file (by default the config file is located at
     `/etc/ckan/default/ckan.ini`).

  4. Restart CKAN. For example if you've deployed CKAN with Apache on Ubuntu:

      sudo service apache2 reload




  The extension provides next configuration options:

  	
  	ckanext.drupal_api.drupal_url = http://drupal.com

  	
      
  	ckanext.drupal_api.timeout = 10

  	
      
  	ckanext.drupal_api.cache.duration = 60

      
  	ckanext.drupal_api.request.user = username
      ckanext.drupal_api.request.pass = password

      
      
      ckanext.drupal_api.api_version = json

      
      
      ckanext.drupal_api.core.menu_export_endpoint = /api/v1/menu_export





  To install ckanext-drupal-api for development, activate your CKAN virtualenv and
  do:

      git clone https://github.com/DataShades/ckanext-drupal-api.git
      cd ckanext-drupal-api
      python setup.py develop
      pip install -r dev-requirements.txt




  To run the tests, do:

      pytest --ckan-ini=test.ini




  If ckanext-drupal-api should be available on PyPI you can follow these steps to publish a new version:

  1. Update the version number in the `setup.py` file. See [PEP 440](http://legacy.python.org/dev/peps/pep-0440/#public-version-identifiers) for how to choose version numbers.

  2. Make sure you have the latest version of necessary packages:

      pip install --upgrade setuptools wheel twine

  3. Create a source and binary distributions of the new version:

         python setup.py sdist bdist_wheel && twine check dist/*

     Fix any errors you get.

  4. Upload the source distribution to PyPI:

         twine upload dist/*

  5. Commit any outstanding changes:

         git commit -a
         git push

  6. Tag the new release of the project on GitHub with the version number from
     the `setup.py` file. For example if the version number in `setup.py` is
     0.0.1 then do:

         git tag 0.0.1
         git push --tags



  [AGPL](https://www.gnu.org/licenses/agpl-3.0.en.html)


pkgId: d65add2e27235c8f3b0f3896a606a02215f0501af446d0f1df53df196d6598d1
name: python-ckanext-event-audit
arch: src
version: 1.0.0
epoch: 0
release: 1
summary: please add a summary manually as the author left a blank one
url: https://github.com/DataShades/ckanext-event-audit
rpm_license: AGPL
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-event-audit-1.0.0-1.src.rpm
checksum_type: sha256
description:
  [![Tests](https://github.com/DataShades/ckanext-event-audit/actions/workflows/test.yml/badge.svg)](https://github.com/DataShades/ckanext-event-audit/actions/workflows/test.yml)



  This extension will capture and retain a comprehensive record of all changes within a CKAN app.

  Read the [documentation](https://datashades.github.io/ckanext-event-audit/) for a full user guide.

  TODO:
  - [ ] add config option to exclude result and payload fields from being stored
  - [ ] allow to restrict a list of available repos (security concern)
  - [ ] disable the admin interface by default (security concern)
  - [ ] update `remove_events` method to allow removing events by date range
  - [ ] add a cli command to remove events by date range



  1. Install the extension from `PyPI`:

      `pip install ckanext-event-audit`

  2. Enable the plugin in your CKAN configuration file (e.g. `ckan.ini` or `production.ini`):

      `ckan.plugins = ... event_audit ...`

  3. Run DB migrations. For CKAN 2.10+ we can run this command:

      `ckan db pending-migrations`

      CKAN 2.11+ allows us to run the following command to create the tables:

      `ckan db upgrade`

  4. Configure the extension up to your needs and you're ready to go. See the [documentation](https://datashades.github.io/ckanext-event-audit/) for more details about the configuration options.



  To install ckanext-event-audit for development, activate your CKAN virtualenv and
  do:

      pip install -e '.[dev, xlsx]'



  To run the tests, do:

      pytest --ckan-ini=test.ini



  [AGPL](https://www.gnu.org/licenses/agpl-3.0.en.html)


pkgId: 1a6732f3ad56ebfcc7125d709263d32c11bbba55efb204e744446add9c2df600
name: python-ckanext-feedback
arch: src
version: 1.3.6
epoch: 0
release: 1
url: https://github.com/c-3lab/ckanext-feedback/
rpm_license: AGPL-3.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-feedback-1.3.6-1.src.rpm
checksum_type: sha256
summary:
  The extension to feedback on CKAN datasets such as review, number of downloads,use-cases,resolved-problems, and way of use

description:
  [![codecov](https://codecov.io/github/c-3lab/ckanext-feedback/graph/badge.svg?token=8T2RIXPXOM)](https://codecov.io/github/c-3lab/ckanext-feedback)

  このCKAN Extensionはデータ利用者からのフィードバックを得るための機能を提供します。
  本Extensionの利用者からの意見・要望や活用事例の報告を受け付ける仕組み等によって、データ利用者はデータの理解が進みデータ利活用が促進され、データ提供者はデータのニーズ理解やデータ改善プロセスの効率化が行えます。

  This CKAN Extension provides functionality to obtain feedback from data users. The mechanism for receiving opinions/requests and reports on usage examples from users of this extension will help data users understand data and promote data utilization, while data providers will be able to understand data needs and improve the data improvement process. You can improve efficiency.

  フィードバックにより利用者と提供者間でデータを改善し続けるエコシステムを実現することができます。

  Feedback enables an ecosystem between users and providers that continually improves the data.



  * 👀 集計情報の可視化機能(ダウンロード数、利活用数、課題解決数)
    * Visualization function for aggregate information (number of downloads, number of uses, number of problems solved)
  * 💬 データおよび利活用方法に対するコメント・評価機能
    * Comment and evaluation function for data and usage methods
  * 🖼 データを利活用したアプリやシステムの紹介機能
    * Feature to introduce apps and systems that utilize data
  * 🏆 データを利活用したアプリやシステムの課題解決認定機能
    * Problem-solving certification function for apps and systems that utilize data



  1. CKANの仮想環境をアクティブにする(CKANコンテナ等の環境内で実行してください)

      ```bash
      . /usr/lib/ckan/venv/bin/activate
      ```

  2. 仮想環境にckanext-feedbackをインストールする

      ```bash
      pip install ckanext-feedback
      ```

  3. 以下のコマンドで設定を行うファイルを開く

      ```bash
      vim /etc/ckan/production.ini
      ```

  4. 以下の行に`feedback`を追加

      ```bash
      ckan.plugins = stats ・・・ recline_view feedback
      ```

  5. フィードバック機能に必要なテーブルを作成する

      ```bash
      ckan db upgrade -p feedback
      ```





  * [utilization](./docs/ja/utilization.md)
  * [resource](./docs/ja/resource.md)
  * [download](./docs/ja/download.md)



  * リソースや利活用方法へのコメントを管理することが出来ます
    * 詳しくは[管理者用画面ドキュメント](docs/ja/admin.md)をご覧ください

  * 特定のモジュールのみを利用することも可能です
    * 設定方法は[オンオフ機能の詳細ドキュメント](./docs/ja/switch_function.md)をご覧ください

  * ログインの有無やログインしているユーザーの権限(adminなど)によって、実行可能なアクションを設定しています
    * 権限に関する詳細は[管理者権限の詳細ドキュメント](./docs/ja/authority.md)をご覧ください





  1. `ckanext-feedback`をローカル環境にGitHub上からクローンする

      ```bash
      git clone https://github.com/c-3lab/ckanext-feedback.git
      ```

  2. `ckanext-feedback/development`下にある`container_setup.sh`を実行し、コンテナを起動

  3. ckanext-feedbackをインストールして必要なテーブルを作成するために、`ckanext-feedback/development`下にある`feedback_setup.sh`を実行する

  4. `http://localhost:5000`にアクセスする



  1. poetryをインストールする

      ```bash
      pip install poetry
      ```

  2. LinterとFomatterを使えるようにする

      ```bash
      poetry install
      poetry run pre-commit install
      ```

      * 以後、git commit 時に、staging されているファイルに対して isort, black, pflake8 が実行され、それらによる修正が発生すると、commit されなくなる。
      * 手動で isort, black, pflake8 を行いたい場合、poetry run pre-commit で可能。



  * [feedbackコマンド 詳細ドキュメント](./docs/ja/feedback_command.md)
  * [言語対応(i18n) 詳細ドキュメント](./docs/ja/i18n.md)



  1. 上記のビルド方法に従い、ビルドを行う

  2. コンテナ内に入る

      ```bash
      docker exec -it --user root ckan-docker-ckan-dev-1 /bin/bash
      ```

  3. その他の必要なものをインストールする

      ```bash
      pip install -r /srv/app/src/ckan/dev-requirements.txt
      pip install pytest-ckan
      ```

  4. ディレクトリを移動

      ```bash
      cd /usr/lib/python3.10/site-packages/ckanext/feedback/tests
      ```

  5. テストを実行

      ```bash
      CKAN_SQLALCHEMY_URL= CKAN_DATASTORE_READ_URL= CKAN_DATASTORE_WRITE_URL= pytest -s --ckan-ini=config/test.ini --cov=ckanext.feedback --cov-branch --disable-warnings ./
      ```



  [AGPLv3 LICENSE](https://github.com/c-3lab/ckanext-feedback/blob/feature/documentation-README/LICENSE)



  Copyright (c) 2023 C3Lab


pkgId: 43d025f1c954332ffbc5b003a7d71ca5fe9a6a30a7001ccbc9fad53cdeb78da6
name: python-ckanext-files
arch: src
version: 0.3.0
epoch: 0
release: 1
summary: please add a summary manually as the author left a blank one
url: https://github.com/DataShades/ckanext-files
rpm_license: AGPL
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-files-0.3.0-1.src.rpm
checksum_type: sha256
description:
  [![Tests](https://github.com/DataShades/ckanext-files/actions/workflows/test.yml/badge.svg?branch=storage)](https://github.com/DataShades/ckanext-files/actions/workflows/test.yml)



  Files as first-class citizens of CKAN. Upload, manage, remove files directly
  and attach them to datasets, resources, etc.



  Compatibility with core CKAN versions:

  | CKAN version | Compatible? |
  |--------------|-------------|
  | 2.8          | yes         |
  | 2.9          | yes         |
  | 2.10         | yes         |
  | master       | yes         |

  CKAN v2.8 and v2.9 are supported by ckanext-files v0.2. Starting from v1.0 this
  extension switches to CKAN support policy of two latest CKAN releases. I.e,
  ckanext-files v1.0 supports only CKAN v2.10 and v2.11.

  v0.* will not receive any new major features, only bug-fixes and small
  improvements.

  It's recommended to install the extension via pip, so you probably have all the
  requirements pinned already. If you are using GitHub version of this extension,
  stick to the vX.Y.Z tags to avoid breaking changes. Check the changelog before
  upgrading the extension.



  To install ckanext-files:

  1. Install the extension
     ```sh
     
     pip install ckanext-files

     
     pip install 'ckanext-files[gcs]'
     ```

  1. Add `files` to the `ckan.plugins` setting in your CKAN
     config file.

  1. Run DB migrations
     ```sh
     
     ckan db upgrade -p files

     
     paster --plugin=ckanext-files files -c ckan.ini initdb
     ```





  Before uploading any file, you have to configure a named **storage**. Tell
  extension which driver to use(i.e, where and how data will be stored), add few
  storage specific settings and you are ready to go. Let's start from the Redis
  driver, because it has minimal requirements in terms of configuration.

  Add the following line to the CKAN config file:

  ```ini
  ckanext.files.storage.my_storage.type = files:redis
  ```

  Look at this option. The prefix `ckanext.files.storage.` will be the same for
  every configuration option related to storage. Then comes `my_storage`. It's a
  name of your storage. It doesn't change the behavior of the storage, but
  determines how options are grouped together and helps you to use multiple
  storages simultaneously. For example the following configuration adds two
  different storages:`first_storage` with `prefix` set to `first:` and
  `second_storage` with prefix set to `second:`:

  ```ini
  ckanext.files.storage.first_storage.type = files:redis
  ckanext.files.storage.second_storage.type = files:redis

  ckanext.files.storage.first_storage.prefix = first:
  ckanext.files.storage.second_storage.prefix = second:
  ```

  Our storage is called `my_storage` and after the storage's name comes option's
  name `type`. And it's value `files:redis`. `type` option tells us which driver
  we are going to use for the storage. `files:redis` is the name of the driver.

  The recommended format of the driver name is
  `<EXTENSION_NAME>:<STORAGE_TYPE>`. But this format is not enforced, so you can
  see any value there. If you accidentally make a typo in the driver's name,
  starting from v2.10 CKAN will show you an error message on startup with the
  list of available drivers:

  ```sh
  Invalid configuration values provided:
  ckanext.files.storage.my_storage.type: Value must be one of ['files:bq_google_cloud_storage', 'files:fs', 'files:public_fs', 'files:redis', 'files:google_cloud_storage']
  Aborted!
  ```

  Storage is configured, so we can actually upload the file. Let's use
  [ckanapi](https://github.com/ckan/ckanapi) for this task. Files are created via
  `files_file_create` API action and this time we have to pass 3 parameters into it:

  * `name`: the name of uploaded file
  * `upload`: content of the file
  * `storage`: name of the storage that stores the file(we just configured `my_storage`)

  The final command is here:

  ```sh
  ckanapi action files_file_create \
      name=hello.txt \
      upload='hello world' \
      storage=my_storage
  ```

  And that's what you see as result:

  ```json
  {
    "atime": null,
    "completed": true,
    "ctime": "2024-03-12T22:08:05.185914",
    "id": "7f9a7676-5177-40f0-b610-0b47918fdccc",
    "mtime": null,
    "name": "hello.txt",
    "storage": "my_storage",
    "storage_data": {
      "content_type": "text/plain",
      "filename": "2f51aeff-96a5-4d79-8973-7867527d7f2e",
      "hash": "5eb63bbbe01eeed093cb22bb8f5acdc3",
      "size": 11
    }
  }
  ```

  Now go to Redis CLI and check the content of the file. Note, you cannot get the
  content via CKAN API, because it's JSON-based and downloading files doesn't
  suit its principles.

  By default, Redis driver puts the content under the key
  `<PREFIX><FILENAME>`. Pay attention to `FILENAME`. It's the value available as
  `storage_data.filename` in the API response(i.e,
  `2f51aeff-96a5-4d79-8973-7867527d7f2e` in our case), not the name of the real
  file you just uploaded.

  `PREFIX` can be configured, but we skipped this step and got the default value: `ckanext:files:default:file_content:`. So the final Redis key of our file is `ckanext:files:default:file_content:2f51aeff-96a5-4d79-8973-7867527d7f2e`

  ```sh
  redis-cli

  127.0.0.1:6379> GET ckanext:files:default:file_content:2f51aeff-96a5-4d79-8973-7867527d7f2e
  "hello world"

  ```

  And before we moved further, let's remove the file, using ID we got when it was created:

  ```sh
  ckanapi action files_file_delete id=7f9a7676-5177-40f0-b610-0b47918fdccc



  redis-cli

  127.0.0.1:6379> GET ckanext:files:default:file_content:2f51aeff-96a5-4d79-8973-7867527d7f2e
  (nil)

  ```



  If you are writing the code and you want to interact with the storage directly,
  without the API layer, you can do it via a number of public functions of the
  extension.

  Let's configure filesystem storage first. This time we are going to use the
  storage name `default`. This is "default" storage name - if you haven't
  specified explicitely the name of the storage when working with it(calling API
  actions, for example), `default` storage is used. So it's better to create this
  storage instead of making fancy names.

  Filesystem driver has a mandatory option `path` that controls path, where files
  are stored. If path does not exist, storage will raise an exception by
  default. But it can also create missing path if you enable `create_path`
  option. Here's our final version of settings:

  ```ini
  ckanext.files.storage.default.type = files:fs
  ckanext.files.storage.default.path = /tmp/example
  ckanext.files.storage.default.create_path = true
  ```

  Now we are going to connect to CKAN shell via `ckan shell` CLI command and
  create an instance of the storage:

  ```python
  from ckanext.files.shared import get_storage
  storage = get_storage('default')
  ```

  Because you have all configuration in place, the rest is fairly
  straightforward. We will upload the file, read it's content and remove it from
  the CKAN shell.

  Uploading is the most challenging step. As CKAN is based on Flask, we have to
  upload files as Flask does. For it we are going to create an instance of `werkzeug.datastructures.FileStorage` and pass bytes stream to its constructor. After that, we can pass the object into storage's `upload` method and specify the name of the upload.

  ```python
  from werkzeug.datastructures import FileStorage
  from io import BytesIO

  upload = FileStorage(BytesIO(b'hello world'))
  result = storage.upload('file.txt', upload, {})

  print(result)

  ... {'filename': 'd65da0fd-299a-433c-850e-086fdc5ebb7e',
  ...  'content_type': None,
  ...  'size': 11,
  ...  'hash': '5eb63bbbe01eeed093cb22bb8f5acdc3'}

  ```

  `result` contains minimal amount of information that is required by storage to
  manage the file. In case of FS storage, it includes `filename`. If you visit
  `/tmp/example` directory, that we specified as a `path` for our storage, you'll
  see there a file with the name matching `filename` from result. And its content
  matches the content of our upload, which is quite an expected outcome.

  But let's go back to the shell and try reading file from the python's
  code. We'll pass `result` to the storage's `stream` method, which produces a
  readable buffer based on our result. This buffer has `read` method so we can
  work with the buffer just as we usually do with IO streams:

  ```python
  buffer = storage.stream(result)
  content = buffer.read()
  print(content)

  ... b'hello world'
  ```

  And finally we need to remove the file

  ```python
  storage.remove(result)
  ```



  You can upload files using JavaScript CKAN modules. The extension extends
  CKAN's Sandbox object(available as `this.sandbox` inside the JS CKAN module),
  so we can use shortcut and upload file directly from the DevTools. Open any
  CKAN page, switch to JS console and create the sandbox instance. Inside it we
  have `files` object, which in turn contains `upload` method. This method
  accepts `File` object for upload(the same object you can get from the
  `input[type=file]`).

  ```js
  sandbox = ckan.sandbox()
  await sandbox.files.upload(
    new File(["content"], "file.txt")
  )

  ... {
  ...    "id": "d6fa3096-613a-4b16-a0eb-b7a6ec91d690",
  ...    "name": "file.txt",
  ...    "storage": "default",
  ...    "ctime": "2024-03-12T23:08:11.291971",
  ...    "mtime": null,
  ...    "atime": null,
  ...    "storage_data": {
  ...        "filename": "f484d116-cf6f-4238-80e5-905849873be0",
  ...        "content_type": "application/octet-stream",
  ...        "size": 7,
  ...        "hash": "9a0364b9e99bb480dd25e1f0284c8555"
  ...    },
  ...    "completed": true
  ... }
  ```

  If you are still using FS storage configured in previous section, switch to
  `/tmp/example` folder and check it's content:

  ```sh
  ls /tmp/example
  ... f484d116-cf6f-4238-80e5-905849873be0

  cat f484d116-cf6f-4238-80e5-905849873be0
  ... content
  ```

  And, as usually, let's remove file using the ID from the `upload` promise:

  ```js
  sandbox.client.call('POST', 'files_file_delete', {
    id: 'd6fa3096-613a-4b16-a0eb-b7a6ec91d690'
  })
  ```



  This extension provides a basic UI as an example and it's recommended to build
  your own UI if you need it. But we can still use default functionality for
  testing. Open the `/user/<YOUR USERNAME>/files` page of CKAN application in the
  browser.

  ![Empty files page](screenshots/1.png)

  Choose the file

  ![Selected file](screenshots/2.png)

  Click on play button(the one with triangle icon) and wait a bit. If nothing
  changes, check JS console, it can show some errors when storage is not properly
  configured.

  ![Uploaded file](screenshots/3.png)

  When upload finished, reload the page to see uploaded file.

  ![Reloaded page with a single upload](screenshots/4.png)



  There are two types of config options for ckanext-files:
  * Global configuration affects the common behavior of the extension
  * Storage configuration changes behavior of the specific storage and never
    affects anything outside of the storage

  Depending on the type of the storage, available options for storage change. For
  example, `files:fs` storage type requires `path` option that controls
  filesystem path where uploads are stored. `files:redis` storage type accepts
  `prefix` option that defines Redis' key prefix of files stored in Redis. All
  storage specific options always have form
  `ckanext.files.storage.<STORAGE>.<OPTION>`:

  ```ini
  ckanext.files.storage.memory.prefix = xxx:

  ckanext.files.storage.my_drive.path = /tmp/hello
  ```

  Below is the list of non-storage specific options. Details of the specific
  storage type can be found in the dedicated section of the storage type.

  ```ini



  ckanext.files.default_storage = default



  ckanext.files.storage.<NAME>.<OPTION> =

  ```

  Starting from CKAN v2.10 you can check all available options for the storage
  type via config declarations CLI. First, add the storage type to the config
  file:

  ```ini
  ckanext.files.storage.xxx.type = files:redis
  ```

  Now run the command that shows all available config option of the
  plugin.

  ```sh
  ckan config declaration files -d
  ```

  Because redis storage adapter is enabled, you'll see all the options
  regsitered by redis driver alongside with the global options:


  ```ini



  ckanext.files.storage.xxx.type = files:redis


  ckanext.files.storage.xxx.max_size = 0

  ckanext.files.storage.xxx.name = xxx

  ckanext.files.storage.xxx.prefix = ckanext:files:default:file_content:
  ```

  Sometimes you will see a validation error if storage has required config
  options. Let's try using `files:fs` storage instead of the redis:

  ```ini
  ckanext.files.storage.xxx.type = files:fs
  ```

  Now attempt to run `ckan config declaration files -d` will show an error,
  because required `path` option is missing:

  ```sh
  Invalid configuration values provided:
  ckanext.files.storage.xxx.path: Missing value
  Aborted!
  ```

  Add the required option to satisfy the application

  ```ini
  ckanext.files.storage.xxx.type = files:fs
  ckanext.files.storage.xxx.path = /tmp
  ```

  And run CLI command once again. This time you'll see the list of allowed
  options:

  ```ini



  ckanext.files.storage.xxx.type = files:fs


  ckanext.files.storage.xxx.max_size = 0

  ckanext.files.storage.xxx.name = xxx

  ckanext.files.storage.xxx.path =

  ckanext.files.storage.xxx.create_path = false
  ```


pkgId: c409f43111e87501a6f741466f1387f5df69962d9709687d617bc74daf47f85d
name: python-ckanext-flakes
arch: src
version: 0.4.5.post1
epoch: 0
release: 1
summary: please add a summary manually as the author left a blank one
url: https://github.com/DataShades/ckanext-flakes
rpm_license: AGPL
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-flakes-0.4.5.post1-1.src.rpm
checksum_type: sha256
description:
  [![Tests](https://github.com/DataShades/ckanext-flakes/workflows/Tests/badge.svg)](https://github.com/DataShades/ckanext-flakes/actions/workflows/test.yml)



  Tools for creating and managing independent chunks of data.

  This extension provides a base entity for storing arbitrary data. It can be
  used in a number of cases, especially, if you don't want yet to create a brand
  new model, database migrations and tables, but you have no other options.

  `ckanext-flakes` gives you a set of actions for creating and managing small
  dictionary-like objects(anything, that can be serialized into JSON). If you are
  using it and want to add an extra action, feel free to create a PR or an issue
  with your suggestion.



  * [Examples](#examples)
  * [Example plugins](#example-plugins)
  * [Requirements](#definition)
  * [Installation](#installation)
  * [Configuration](#configuration)
  * [Interfaces](#interfaces)
  * [API](#api)
    * [`flakes_flake_create`](#flakes_flake_create)
    * [`flakes_flake_show`](#flakes_flake_show)
    * [`flakes_flake_list`](#flakes_flake_list)
    * [`flakes_flake_update`](#flakes_flake_update)
    * [`flakes_flake_override`](#flakes_flake_override)
    * [`flakes_flake_delete`](#flakes_flake_delete)
    * [`flakes_flake_lookup`](#flakes_flake_lookup)
    * [`flakes_flake_validate`](#flakes_flake_validate)
    * [`flakes_data_validate`](#flakes_data_validate)
    * [`flakes_data_example`](#flakes_data_example)
    * [`flakes_flake_materialize`](#flakes_flake_materialize)
    * [`flakes_flake_combine`](#flakes_flake_combine)
    * [`flakes_flake_merge`](#flakes_flake_merge)
    * [`flakes_data_patch`](#flakes_data_patch)
    * [`flakes_extras_patch`](#flakes_extras_patch)





  Scenario: user needs a todo list

  Flakes created by any user are visible only to this user so flakes can be used
  as a storage for private data.

  Flakes can have `extras`, that plays a role of tags. `extras` represented by a
  dictionary and whenever user lists his flakes, he has an option to see only
  flakes that contains particular data inside extras.

  ```python
  flake_create = tk.get_action("flakes_flake_create")
  flake_list = tk.get_action("flakes_flake_create")


  flake_create(
      {"user": "john"},
      {"data": {"task": "feed the cat"}, "extras": {"when": "today", "type": "task"}}
  )


  flake_create(
      {"user": "john"},
      {"data": {"task": "buy food"}, "extras": {"when": "tomorrow", "type": "task"}}
  )
  flake_create(
      {"user": "john"},
      {"data": {"task": "update documentation"}, "extras": {"when": "tomorrow", "type": "task"}}
  )


  flake_list(
      {"user": "john"},
      {"extras": {"type": "task"}}
  )


  flake_list(
      {"user": "john"},
      {"extras": {"type": "task", "when": "today"}}
  )


  flake_list(
      {"user": "john"},
      {"extras": {"type": "task", "when": "tomorrow"}}
  )
  ```



  Scenario: each user can set a theme of application and this theme will be applied only for the current user

  Flakes are created for the user from the `context`. Flakes of the user A are
  visible only to the user A, flakes of the user B exist in the different
  namespace and are visible only to the user B.

  Each flake **can** have a name. Name must be unique among the flakes of the
  user. But different users can use the same names for their flakes, because
  every user has its own namespace for flakes.

  Flakes can be created either via `flakes_flake_create` action(accepts
  **optional** name and raises exception if name is not unique) or
  `flakes_flake_override`(requires a name and creates a new flake if name is not
  taken or updates existing flake if name already used by some flake)

  In order to get the flake use `flakes_flake_show` with the `id` of the flake or
  `flakes_flake_lookup` with the `name`.

  ```python

  tk.get_action("flakes_flake_override")(
      {"user": "john"},
      {"name": "application:theme", "data": {"theme": "dark"}}
  )


  tk.get_action("flakes_flake_override")(
      {"user": "mary"},
      {"name": "application:theme", "data": {"theme": "light"}}
  )



  john_theme = tk.get_action("flakes_flake_lookup")(
      {"user": "john"},
      {"name": "application:theme"}
  )["data"]["theme"]

  mary_theme = tk.get_action("flakes_flake_lookup")(
      {"user": "mary"},
      {"name": "application:theme"}
  )["data"]["theme"]

  assert john_theme == "dark"
  assert mary_theme == "light"
  ```



  Scenario: application requires global option, that can be changed in runtime

  By default flakes are created in the "namespace" of the current user. Only the
  author can see and modify his own flakes.

  Global values should not be owned by someone, so here we need "unowned" flake -
  the flake that is not connected to the particular user. Only sysadmin can
  create such flakes, so we are going to use `ignore_auth=True` attribute of the
  context.

  We'll use `flakes_flake_override` action, that accepts a `name` of the flake
  and either updates existing flakes with this name or creates a new one if this
  name is free. In this way we'll avoid duplicates of the global flake.


  ```python

  tk.get_action("flakes_flake_override")(
      {"ignore_auth": True}, # only syadmin allowed to create unowned flakes with empty author id
      {"name": "global:config:value", "data": {"value": 1}, "author_id": None}
  )


  value = tk.get_action("flakes_flake_lookup")(
      {"ignore_auth": True},
      {"name": "global:config:value", "author_id": None}
  )["data"]["value"]
  ```




  These plugins implement basic features that can be used as a real-life example
  of `ckanext-flakes` usage.



  User can rate a package via API action. Add
  `ckanext.flakes_rating.show_package_widget = true` to the config and default
  widget will be added to the sidebar on `dataset.read` page.



  User can leave a feedback for package via API action. Add
  `ckanext.flakes_feedback.enable_views = true` to the config and default page
  will be added to navigation tabs on `dataset.read` page.



  Requires python v3.7 or greater. Python v2 support doesn't require much effort,
  but it neither worth the time you'll spend on it.


  Compatibility with core CKAN versions:

  | CKAN version | Compatible? |
  |--------------|-------------|
  | 2.9          | yes         |
  | 2.10         | yes         |




  To install ckanext-flakes:

  1. Install it via **pip**:
     ```sh
     pip install ckanext-flakes
     ```
  1. Add `flakes` to the `ckan.plugins` setting in your CKAN config file.
  1. Run DB migrations:
     ```sh
     ckan db upgrade -p flakes
     ```



  ```ini


  ckanext.flakes.creation.allowed = false



  ckanext.flakes.validation.allowed = true
  ```



  Provides `ckanext.flakes.interfaces.IFlakes` interface. Always use
  `inherit=True` when implementing it, because it may change in the future.

  Currently it provides the following hooks:

  ```python
  class IFlakes(Interface):
      """Extend functionality of ckanext-flakes"""

      def get_flake_schemas(self) -> dict[str, dict[str, Any]]:
          """Register named validation schemas.

          Used by `flakes_flake_validate` and `flakes_data_validate` actions.

          Returns:
              Mapping of names and corresponding validation schemas.

          Example:
              def get_flake_schemas(self) -> dict[str, dict[str, Any]]:
                  return {
                      "schema-that-requires-name": {"name": [not_missing]}
                  }
          """
          return {}

      def get_flake_factories(self) -> dict[str, Callable[[dict[str, Any]], dict[str, Any]]]:
          """Register named example factories.

          Used by `flakes_data_example` action.

          Returns:
              Mapping of names and corresponding example factories.

          Example:
              def get_flake_factories(self) -> dict[str, dict[str, Any]]:
                  def factory(payload: dict[str, Any]):
                      return {"field": "value"}

                  return {
                      "test-factory": factory
                  }
          """
          return {}
  ```






  Create a flake.

  Args:

      name (str, optional): name of the flake
      data (dict): flake's data
      parent_id (str, optional): ID of flake to extend
      author_id (str, optional): author ID(can be set only by sysadmin)
      extras (dict): flake's extra details



  Display existing flake

  Args:

      id (str): ID of flake to display
      expand (bool, optional): Extend flake using data from the parent flakes




  Display all flakes of the user.

  If `extras` dictionary passed, show only flakes that contains given extras. Example:

      first_flake = Flake(extras={"xxx": {"yyy": "hello"}})
      second_flake = Flake(extras={"xxx": {"yyy": "world"}})

      flake_list(context, {"extras": {"xxx": {"yyy": "hello"}})
      >>> first_flake

  Args:

      expand (bool, optional): Extend flake using data from the parent flakes
      extras (dict, optional): Show only flakes whose extras contains passed dict
      author_id (str, optional): author ID(can be set only by sysadmin)



  Update existing flake

  Args:

      id (str): ID of flake to update
      data (dict): flake's data
      parent_id (str, optional): ID of flake to extend
      extras (dict): flake's extra details



  Update existing flake by name or create a new one.

  Args:

      name (str): Name flake to override
      data (dict): template itself
      parent_id (str, optional): ID of flake to extend
      author_id (str, optional): author ID(can be set only by sysadmin if flake does not exist)
      extras (dict): flake's extra details



  Delete existing flake

  Args:

      id (str): ID of flake to delete



  Display flake using its name.

  Args:

      name (str): Name of the flake
      expand (bool, optional): Extend flake using data from the parent flakes
      author_id (str, optional): author ID(can be set only by sysadmin)



  Validate existing flake

  Schemas must be registered via `IFlakes` interface.

  Args:

      id (str): ID of flake to validate
      expand (bool, optional): Extend flake using data from the parent flakes
      schema(str): validation schema for the flake's data




  Validate arbitrary data against the named schema(registered via IFlakes).

  Args:

      data (dict): data that needs to be validated
      schema(str): validation schema for the data



  Generate an example of the flake's data using named factory(registered via IFlakes).

  Factories must be registered via `IFlakes` interface.

  Args:

      factory(str): example factory
      data (dict, optional): payload for the example factory



  Send flake's data to API action.

  Args:

      id (str): ID of flake to materialize
      expand (bool, optional): Extend flake using data from the parent flakes
      remove (bool, optional): Remove flake after materialization
      action (str): API action to use for materialization



  Combine data from multiple flakes

  `id` argument specifies all the flakes that must be combined. All of the flakes
  must exist, otherwise `NotFound` error raised. IDs at the start of the list have
  higher priority(override matching keys). IDs at the end of the list have lower
  priority(can be shadowed by former flakes).

  `expand` must be a `dict[str, bool]`. Keys are IDs of the flakes, values are
  expand flags for the corresponding flake.

  Args:

      id (list): IDs of flakes.
      expand (dict, optional): Extend flake using data from the parent flakes



  Combine multiple flakes and save the result.

  Args:

      id (list): IDs of flakes.
      expand (dict, optional): Extend flake using data from the parent flakes
      remove (bool, optional): Remove flakes after the operation.
      destination (str, optional): Save data into the specified flake instead of a new one



  Partially overrides data leaving other fields intact.

  Args:

      id (str): ID of flake
      data (dict): patch for data




  Partially overrides extras leaving other fields intact.

  Args:

      id (str): ID of flake
      extras (dict): patch for extras



  To install ckanext-flakes for development, activate your CKAN virtualenv and
  do:

      git clone https://github.com/DataShades/ckanext-flakes.git
      cd ckanext-flakes
      python setup.py develop




  To run the tests, do:

      pytest



  [AGPL](https://www.gnu.org/licenses/agpl-3.0.en.html)


pkgId: e5372bb9866b263e9be8b434d00b87f071959592103f04c9eb51d4b0eca4ac1b
name: python-ckanext-fpx
arch: src
version: 0.6.4.post1
epoch: 0
release: 1
summary: please add a summary manually as the author left a blank one
url: https://github.com/DataShades/ckanext-fpx
rpm_license: AGPL
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-fpx-0.6.4.post1-1.src.rpm
checksum_type: sha256
description:
  CKAN adapter for FPX service



  - Configured and running FPX



  To install ckanext-fpx:

  1. Activate your CKAN virtual environment

  1. Install the ckanext-fpx Python package:

  		pip install ckanext-fpx

  1. Add ``fpx`` to the ``ckan.plugins`` setting in your CKAN config file

  1. Add ``fpx.client.secret`` and ``fpx.service.url`` config options



      
      
  	fpx.client.secret = 123abc

      
      
  	fpx.client.secret = client-name-for-123abc-secret


      
      
      fpx.service.url = http://0.0.0.0:8000


pkgId: 0aa099dcf07c0d96a58d1dc6bc834bdd52d21525f645fe94dad4028d0efa9e36
name: python-ckanext-gallery
arch: src
version: 3.0.3
epoch: 0
release: 1
summary: A CKAN extension for a dataset gallery view.
url: https://pypi.org/project/ckanext-gallery/
rpm_license: GPL-3.0-or-later
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-gallery-3.0.3-1.src.rpm
checksum_type: sha256
description:
  <!--header-start-->
  <picture>
    <source media="(prefers-color-scheme: dark)" srcset="https://data.nhm.ac.uk/images/nhm_logo.svg">
    <source media="(prefers-color-scheme: light)" srcset="https://data.nhm.ac.uk/images/nhm_logo_black.svg">
    <img alt="The Natural History Museum logo." src="https://data.nhm.ac.uk/images/nhm_logo_black.svg" align="left" width="150px" height="100px" hspace="40">
  </picture>



  [![Tests](https://img.shields.io/github/actions/workflow/status/NaturalHistoryMuseum/ckanext-gallery/tests.yml?style=flat-square)](https://github.com/NaturalHistoryMuseum/ckanext-gallery/actions/workflows/tests.yml)
  [![Coveralls](https://img.shields.io/coveralls/github/NaturalHistoryMuseum/ckanext-gallery/main?style=flat-square)](https://coveralls.io/github/NaturalHistoryMuseum/ckanext-gallery)
  [![CKAN](https://img.shields.io/badge/ckan-2.9.7-orange.svg?style=flat-square)](https://github.com/ckan/ckan)
  [![Python](https://img.shields.io/badge/python-3.6%20%7C%203.7%20%7C%203.8-blue.svg?style=flat-square)](https://www.python.org/)
  [![Docs](https://img.shields.io/readthedocs/ckanext-gallery?style=flat-square)](https://ckanext-gallery.readthedocs.io)

  _A CKAN extension for a dataset gallery view._

  <!--header-end-->



  <!--overview-start-->
  Adds a gallery view for resources on a CKAN instance. Three plugins are included in this extension: the main plugin (`gallery`) and two view plugins for specific image/data types (`gallery_image` and `gallery_iiif`).

  Based on [blueimp Gallery](https://blueimp.github.io/Gallery).

  <!--overview-end-->



  <!--installation-start-->
  Path variables used below:
  - `$INSTALL_FOLDER` (i.e. where CKAN is installed), e.g. `/usr/lib/ckan/default`
  - `$CONFIG_FILE`, e.g. `/etc/ckan/default/development.ini`



  ```shell
  pip install ckanext-gallery
  ```



  1. Clone the repository into the `src` folder:
     ```shell
     cd $INSTALL_FOLDER/src
     git clone https://github.com/NaturalHistoryMuseum/ckanext-gallery.git
     ```

  2. Activate the virtual env:
     ```shell
     . $INSTALL_FOLDER/bin/activate
     ```

  3. Install via pip:
     ```shell
     pip install $INSTALL_FOLDER/src/ckanext-gallery
     ```



  Installing from a `pyproject.toml` in editable mode (i.e. `pip install -e`) requires `setuptools>=64`; however, CKAN 2.9 requires `setuptools==44.1.0`. See [our CKAN fork](https://github.com/NaturalHistoryMuseum/ckan) for a version of v2.9 that uses an updated setuptools if this functionality is something you need.



  1. Add 'gallery' to the list of plugins in your `$CONFIG_FILE`:
     ```ini
     ckan.plugins = ... gallery
     ```

  2. Install `lessc` globally:
     ```shell
     npm install -g "less@~4.1"
     ```

  <!--installation-end-->



  <!--configuration-start-->
  There's only one option that can be specified in the `.ini` file:

  | Name                               | Description                           | Default |
  |------------------------------------|---------------------------------------|---------|
  | `ckanext.gallery.records_per_page` | Number of images to display on a page | 32      |

  <!--configuration-end-->



  <!--usage-start-->
  To use as a view, no further setup is needed; the 'Gallery' type should be available for resources
  after installing the plugin.



  The `IGalleryImage` interface allows plugins to override settings.

  ```python
  from ckan.plugins import SingletonPlugin, implements
  from ckanext.gallery.plugins.interfaces import IGalleryImage

  class YourPlugin(SingletonPlugin):
    implements(IGalleryImage)


    def image_info(self):
      '''
      Return info for this plugin. If resource type is set,
      only datasets of that type will be available.
      '''
      return {u'title': u'Text',
              u'resource_type': [u'csv', u'tsv'],
              u'field_type': [u'text']}


    def get_images(self, field_value, record, data_dict):
      '''
      Process images from a single record to return custom metadata.
      The field_value depends on the image field you choose.
      '''
      images = [{
        u'href': field_value[u'url'],
        u'thumbnail': field_value[u'url'].replace(u'preview', u'thumbnail'),
        u'record_id': record[u'_id']
      } for img in field_value]
      return image
  ```




  ```html+jinja
  {% snippet 'gallery/snippets/gallery.html', images=g.images, resource_id=res.id %}
  ```

  <!--usage-end-->



  <!--testing-start-->
  There is a Docker compose configuration available in this repository to make it easier to run tests. The ckan image uses the Dockerfile in the `docker/` folder.

  To run the tests against ckan 2.9.x on Python3:

  1. Build the required images:
     ```shell
     docker compose build
     ```

  2. Then run the tests.
     The root of the repository is mounted into the ckan container as a volume by the Docker compose
     configuration, so you should only need to rebuild the ckan image if you change the extension's
     dependencies.
     ```shell
     docker compose run ckan
     ```

  <!--testing-end-->


pkgId: 4e7556e50cd3a6722f71bcbe4ddc18893fe51a260dbea64bf984fa3a63b57477
name: python-ckanext-gbif
arch: src
version: 2.1.11
epoch: 0
release: 1
summary: A CKAN extension that that connects with the GBIF API.
url: https://pypi.org/project/ckanext-gbif/
rpm_license: GPL-3.0-or-later
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-gbif-2.1.11-1.src.rpm
checksum_type: sha256
description:
  <!--header-start-->
  <picture>
    <source media="(prefers-color-scheme: dark)" srcset="https://data.nhm.ac.uk/images/nhm_logo.svg">
    <source media="(prefers-color-scheme: light)" srcset="https://data.nhm.ac.uk/images/nhm_logo_black.svg">
    <img alt="The Natural History Museum logo." src="https://data.nhm.ac.uk/images/nhm_logo_black.svg" align="left" width="150px" height="100px" hspace="40">
  </picture>



  [![Tests](https://img.shields.io/github/actions/workflow/status/NaturalHistoryMuseum/ckanext-gbif/tests.yml?style=flat-square)](https://github.com/NaturalHistoryMuseum/ckanext-gbif/actions/workflows/tests.yml)
  [![Coveralls](https://img.shields.io/coveralls/github/NaturalHistoryMuseum/ckanext-gbif/main?style=flat-square)](https://coveralls.io/github/NaturalHistoryMuseum/ckanext-gbif)
  [![CKAN](https://img.shields.io/badge/ckan-2.9.7-orange.svg?style=flat-square)](https://github.com/ckan/ckan)
  [![Python](https://img.shields.io/badge/python-3.6%20%7C%203.7%20%7C%203.8-blue.svg?style=flat-square)](https://www.python.org/)
  [![Docs](https://img.shields.io/readthedocs/ckanext-gbif?style=flat-square)](https://ckanext-gbif.readthedocs.io)

  _A CKAN extension that that connects with the GBIF API._

  <!--header-end-->



  <!--overview-start-->
  This extension retrieves additional data (e.g. DQIs) from the [GBIF](https://gbif.org) API for a record with an associated GBIF ID.

  This extension also provides some templates for displaying these data.

  <!--overview-end-->



  <!--installation-start-->
  Path variables used below:
  - `$INSTALL_FOLDER` (i.e. where CKAN is installed), e.g. `/usr/lib/ckan/default`
  - `$CONFIG_FILE`, e.g. `/etc/ckan/default/development.ini`



  ```shell
  pip install ckanext-gbif
  ```



  1. Clone the repository into the `src` folder:
     ```shell
     cd $INSTALL_FOLDER/src
     git clone https://github.com/NaturalHistoryMuseum/ckanext-gbif.git
     ```

  2. Activate the virtual env:
     ```shell
     . $INSTALL_FOLDER/bin/activate
     ```

  3. Install via pip:
     ```shell
     pip install $INSTALL_FOLDER/src/ckanext-gbif
     ```



  Installing from a `pyproject.toml` in editable mode (i.e. `pip install -e`) requires `setuptools>=64`; however, CKAN 2.9 requires `setuptools==44.1.0`. See [our CKAN fork](https://github.com/NaturalHistoryMuseum/ckan) for a version of v2.9 that uses an updated setuptools if this functionality is something you need.



  1. Add 'gbif' to the list of plugins in your `$CONFIG_FILE`:
     ```ini
     ckan.plugins = ... gbif
     ```

  2. Install `lessc` globally:
     ```shell
     npm install -g "less@~4.1"
     ```

  <!--installation-end-->



  <!--configuration-start-->
  These are the options that can be specified in your .ini config file.



  | Name                            | Description                                                                    |
  |---------------------------------|--------------------------------------------------------------------------------|
  | `ckanext.gbif.organisation_key` | For linking to the dataset publisher (i.e. https://gbif.org/publisher/ORG_KEY) |
  | `ckanext.gbif.dataset_key`      | For linking to the dataset itself (i.e. https://gbif.org/dataset/DATA_KEY)     |

  <!--configuration-end-->



  <!--usage-start-->



  Get the associated GBIF data for a record.

  ```python
  from ckan.plugins import toolkit

  gbif_record = toolkit.get_action(u'gbif_record_show')(context, {
      u'occurrence_id': record_gbif_occurrence_id
      })
  ```



  The templates inherit from `record/specimen.html` and `record/dwc.html` and will insert a link to the GBIF view in the `content_primary_nav` block.

  <!--usage-end-->



  <!--testing-start-->
  There is a Docker compose configuration available in this repository to make it easier to run tests. The ckan image uses the Dockerfile in the `docker/` folder.

  To run the tests against ckan 2.9.x on Python3:

  1. Build the required images:
     ```shell
     docker compose build
     ```

  2. Then run the tests.
     The root of the repository is mounted into the ckan container as a volume by the Docker compose
     configuration, so you should only need to rebuild the ckan image if you change the extension's
     dependencies.
     ```shell
     docker compose run ckan
     ```

  <!--testing-end-->


pkgId: d352695920adb6936ca38290a1d0683d03343fc04e17118c135ca460aad2a1f1
name: python-ckanext-geodatagov
arch: src
version: 0.2.9
epoch: 0
release: 1
summary: please add a summary manually as the author left a blank one
url: https://github.com/GSA/ckanext-geodatagov
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-geodatagov-0.2.9-1.src.rpm
checksum_type: sha256
description:
  [ckanext-harvest](https://github.com/ckan/ckanext-harvest/)            | --
  [ckanext-spatial](https://github.com/ckan/ckanext-spatial)             | --
  [PyZ3950](https://github.com/asl2/PyZ3950)                             | --
  [werkzeug](https://github.com/nickumia-reisys/werkzeug)                | This only effects the tests.  For all intents and purposes, this should be tracking [upstream](https://github.com/pallets/werkzeug)
  This extension is compatible with these versions of CKAN.


pkgId: 81ff237e9306c313f4f4a8046bc8fed146071b9e5a5f2505a9e43b7971042ac5
name: python-ckanext-googleanalyticsbasic
arch: src
version: 0.2.1
epoch: 0
release: 1
summary: Basic extension to add google analytics tracking code in page header
url: https://github.com/GSA/ckanext-googleanalyticsbasic
rpm_license: UNKNOWN
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-googleanalyticsbasic-0.2.1-1.src.rpm
checksum_type: sha256
description:
  Puts the Google Analytics asynchronous tracking code into your page headers for basic Google Analytics page tracking.


pkgId: 72c4f0f50eb0c79ae8d0ada5b5a4de2f25a2712562df88bdf7c89fe249746c63
name: python-ckanext-graph
arch: src
version: 2.1.10
epoch: 0
release: 1
summary: A CKAN extension that adds a graph view for resources.
url: https://pypi.org/project/ckanext-graph/
rpm_license: GPL-3.0-or-later
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-graph-2.1.10-1.src.rpm
checksum_type: sha256
description:
  <!--header-start-->
  <picture>
    <source media="(prefers-color-scheme: dark)" srcset="https://data.nhm.ac.uk/images/nhm_logo.svg">
    <source media="(prefers-color-scheme: light)" srcset="https://data.nhm.ac.uk/images/nhm_logo_black.svg">
    <img alt="The Natural History Museum logo." src="https://data.nhm.ac.uk/images/nhm_logo_black.svg" align="left" width="150px" height="100px" hspace="40">
  </picture>



  [![Tests](https://img.shields.io/github/actions/workflow/status/NaturalHistoryMuseum/ckanext-graph/tests.yml?style=flat-square)](https://github.com/NaturalHistoryMuseum/ckanext-graph/actions/workflows/tests.yml)
  [![Coveralls](https://img.shields.io/coveralls/github/NaturalHistoryMuseum/ckanext-graph/main?style=flat-square)](https://coveralls.io/github/NaturalHistoryMuseum/ckanext-graph)
  [![CKAN](https://img.shields.io/badge/ckan-2.9.7-orange.svg?style=flat-square)](https://github.com/ckan/ckan)
  [![Python](https://img.shields.io/badge/python-3.6%20%7C%203.7%20%7C%203.8-blue.svg?style=flat-square)](https://www.python.org/)
  [![Docs](https://img.shields.io/readthedocs/ckanext-graph?style=flat-square)](https://ckanext-graph.readthedocs.io)

  _A CKAN extension that adds a graph view for resources._

  <!--header-end-->



  <!--overview-start-->
  Adds graph views for resources on a CKAN instance. Two types of graph are available: temporal (a line graph showing count over time based on a specified date field), and categorical (a bar chart showing counts for various values in a specified field).


  **NB**: the current version of this extension only works with the Natural History Museum's [ElasticSearch datastore CKAN backend](https://github.com/NaturalHistoryMuseum/ckanext-versioned-datastore). _However_, it is designed to be extensible, so if you would like to use this extension with a different backend (e.g. the standard PostgreSQL datastore), please see the [Extending](#extending) section.

  <!--overview-end-->



  <!--installation-start-->
  Path variables used below:
  - `$INSTALL_FOLDER` (i.e. where CKAN is installed), e.g. `/usr/lib/ckan/default`
  - `$CONFIG_FILE`, e.g. `/etc/ckan/default/development.ini`



  ```shell
  pip install ckanext-graph
  ```



  1. Clone the repository into the `src` folder:
     ```shell
     cd $INSTALL_FOLDER/src
     git clone https://github.com/NaturalHistoryMuseum/ckanext-graph.git
     ```

  2. Activate the virtual env:
     ```shell
     . $INSTALL_FOLDER/bin/activate
     ```

  3. Install via pip:
     ```shell
     pip install $INSTALL_FOLDER/src/ckanext-graph
     ```



  Installing from a `pyproject.toml` in editable mode (i.e. `pip install -e`) requires `setuptools>=64`; however, CKAN 2.9 requires `setuptools==44.1.0`. See [our CKAN fork](https://github.com/NaturalHistoryMuseum/ckan) for a version of v2.9 that uses an updated setuptools if this functionality is something you need.



  1. Add 'graph' to the list of plugins in your `$CONFIG_FILE`:
     ```ini
     ckan.plugins = ... graph
     ```

  2. Install `lessc` globally:
     ```shell
     npm install -g "less@~4.1"
     ```

  <!--installation-end-->



  <!--configuration-start-->
  These are the options that can be specified in your .ini config file.

  | Name                    | Description                                                                    | Options            | Default       |
  |-------------------------|--------------------------------------------------------------------------------|--------------------|---------------|
  | `ckanext.graph.backend` | The name of the backend to use (currently only `elasticsearch` is implemented) | elasticsearch, sql | elasticsearch |

  <!--configuration-end-->



  <!--usage-start-->


  The view will be added as an option with no further configuration necessary. However, if you wish to override or add content to the template, you can extend `templates/graph/view.html`:

  ```html+jinja
  {% ckan_extends %}

  {% block my_new_block %}
    <p>Look, some exciting new content.</p>
  {% endblock %}
  ```




  To use this extension with a datastore backend other than the ElasticSearch backend already implemented, you'll have to subclass from `Query` in `ckanext-graph/ckanext/graph/db.py`.

  An unimplemented class for SQL queries is already in the file as an example:

  ```python
  class SqlQuery(Query):
      @property
      def _date_query(self):
          raise NotImplementedError()

      @property
      def _count_query(self):
          raise NotImplementedError()

      def run(self):
          raise NotImplementedError()
  ```

  If you add a new class, you'll have to add it to the dictionary in `Query.new()` method to make it available as a configurable option.

  If you do this, please submit a pull request! Contributions are always welcome.

  <!--usage-end-->



  <!--testing-start-->
  There is a Docker compose configuration available in this repository to make it easier to run tests. The ckan image uses the Dockerfile in the `docker/` folder.

  To run the tests against ckan 2.9.x on Python3:

  1. Build the required images:
     ```shell
     docker compose build
     ```

  2. Then run the tests.
     The root of the repository is mounted into the ckan container as a volume by the Docker compose
     configuration, so you should only need to rebuild the ckan image if you change the extension's
     dependencies.
     ```shell
     docker compose run ckan
     ```

  <!--testing-end-->


pkgId: 948a7bdcd5b4515a3ec1e73178386de3806972ad7b243e24cb28571dcef542ac
name: python-ckanext-harvest-basket
arch: src
version: 1.3.73
epoch: 0
release: 1
summary: A bunch of custom harvesters for ckanext-harvest
url: https://github.com/DataShades/ckanext-harvest-basket
rpm_license: AGPL
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-harvest-basket-1.3.73-1.src.rpm
checksum_type: sha256
description:
  The `harvest_basket` extension comes with a few custom **harvesters** for different data portals.
  The list of available harvesters, that must be enabled with `ckan.plugins` in your config:
  - `dkan_harvester`
  - `junar_harvester`
  - `socrata_harvester`
  - `arcgis_harvester`

  This extension also adds some features to extend the basic harvester:
  1. Source checkup preview. During the source creation stage the harvester will try to access the remote portal and harvest one dataset to check if it's accessible or not. (TODO: the source checkup interface will be documented soon).
  2. Restriction for anonymous users to visit harveser pages




  To install ckanext-harvest-basket:

  1. Activate your CKAN virtual environment, for example:

       . /usr/lib/ckan/default/bin/activate

  2. Clone the source and install it on the virtualenv

      git clone https://github.com/DataShades/ckanext-harvest-basket.git
      cd ckanext-harvest-basket
      pip install -e .
  	pip install -r requirements.txt

  3. Add `harvest_basket` to the `ckan.plugins` setting in your CKAN
     config file (by default the config file is located at
     `/etc/ckan/default/ckan.ini`).

  4. Restart CKAN. For example if you've deployed CKAN with Apache on Ubuntu:

       sudo service apache2 reload



  Available config options:

  	
  	
  	ckanext.harvest_basket.allow_anonymous = 0




  To install ckanext-harvest-basket for development, activate your CKAN virtualenv and
  do:

      git clone https://github.com/DataShades/ckanext-harvest-basket.git
      cd ckanext-harvest-basket
      python setup.py develop
      pip install -r requirements.txt




  To run the tests, do:

      pytest --ckan-ini=test.ini



  [AGPL](https://www.gnu.org/licenses/agpl-3.0.en.html)


pkgId: ba982ad74a35868a30c9bfebfecfe8b06bc5512bd211fccbd400b4990a1ee541
name: python-ckanext-ids
arch: src
version: 1.1.0
epoch: 0
release: 1
summary: IDS data model extension for CKAN
url: https://github.com/semantic-web-company/ckanext-ids
rpm_license: AGPL
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-ids-1.1.0-1.src.rpm
checksum_type: sha256
description:
  [![Tests](https://github.com/semantic-web-company/ckanext-ids/workflows/Tests/badge.svg?branch=main)](https://github.com/semantic-web-company/ckanext-ids/actions)



  **TODO:** Put a description of your extension here:  What does it do? What features does it have? Consider including some screenshots or embedding a video!




  **TODO:** For example, you might want to mention here which versions of CKAN this
  extension works with.

  If your extension works across different versions you can add the following table:

  Compatibility with core CKAN versions:

  | CKAN version    | Compatible? |
  | --------------- |-------------|
  | 2.6 and earlier | not tested  |
  | 2.7             | not tested  |
  | 2.8             | not tested  |
  | 2.9             | tested      |

  Suggested values:

  * "yes"
  * "not tested" - I can't think of a reason why it wouldn't work
  * "not yet" - there is an intention to get it working
  * "no"




  **TODO:** Add any additional install steps to the list below.
     For example installing any non-Python dependencies or adding any required
     config settings.

  To install ckanext-ids:

  1. Activate your CKAN virtual environment, for example:

       . /usr/lib/ckan/default/bin/activate


  2. Clone the source and install it on the virtualenv

      git clone https://github.com/semantic-web-company/ckanext-ids.git
      cd ckanext-ids
      pip install -e .
      pip install -r requirements.txt



  3. Add `ids` and `ids_dummy to the `ckan.plugins` setting in your CKAN
     config file (by default the config file is located at
     `/etc/ckan/default/ckan.ini`).

  4. Restart CKAN. For example if you've deployed CKAN with Apache on Ubuntu:

       sudo service apache2 reload




      
      ckanext.ids.trusts_local_dataspace_connector_url = http://localhost:8089
      
      ckanext.ids.trusts_local_dataspace_connector_username = admin
      
      ckanext.ids.trusts_local_dataspace_connector_password = password




  To install ckanext-ids for development, activate your CKAN virtualenv and
  do:

      git clone https://github.com/semantic-web-company/ckanext-ids.git
      cd ckanext-ids
      python setup.py develop
      pip install -r dev-requirements.txt




  To run the tests, do:

      pytest --ckan-ini=test.ini




  If ckanext-ids should be available on PyPI you can follow these steps to publish a new version:

  1. Update the version number in the `setup.py` file. See [PEP 440](http://legacy.python.org/dev/peps/pep-0440/#public-version-identifiers) for how to choose version numbers.

  2. Make sure you have the latest version of necessary packages:

      pip install --upgrade setuptools wheel twine

  3. Create a source and binary distributions of the new version:

         python setup.py sdist bdist_wheel && twine check dist/*

     Fix any errors you get.

  4. Upload the source distribution to PyPI:

          twine upload dist/*

  5. Commit any outstanding changes:

         git commit -a
         git push

  6. Tag the new release of the project on GitHub with the version number from
     the `setup.py` file. For example if the version number in `setup.py` is
     0.0.1 then do:

         git tag 0.0.1
         git push --tags



  [AGPL](https://www.gnu.org/licenses/agpl-3.0.en.html)


  This code was created as part of project TRUSTS: Trusted secure data sharing space.

  This project has received funding from the European Union's Horizon 2020 research and innovation programme under grant agreement [No 871481](https://cordis.europa.eu/project/id/871481).


pkgId: ba9ef77cb4a5e41a545a37b668e52162582fd31d4add3d1fb6b23ec73f16bf43
name: python-ckanext-iiif
arch: src
version: 3.0.12
epoch: 0
release: 1
summary: IIIF for CKAN
url: https://pypi.org/project/ckanext-iiif/
rpm_license: GPL-3.0-or-later
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-iiif-3.0.12-1.src.rpm
checksum_type: sha256
description:
  <!--header-start-->
  <picture>
    <source media="(prefers-color-scheme: dark)" srcset="https://data.nhm.ac.uk/images/nhm_logo.svg">
    <source media="(prefers-color-scheme: light)" srcset="https://data.nhm.ac.uk/images/nhm_logo_black.svg">
    <img alt="The Natural History Museum logo." src="https://data.nhm.ac.uk/images/nhm_logo_black.svg" align="left" width="150px" height="100px" hspace="40">
  </picture>



  [![Tests](https://img.shields.io/github/actions/workflow/status/NaturalHistoryMuseum/ckanext-iiif/tests.yml?style=flat-square)](https://github.com/NaturalHistoryMuseum/ckanext-iiif/actions/workflows/tests.yml)
  [![Coveralls](https://img.shields.io/coveralls/github/NaturalHistoryMuseum/ckanext-iiif/main?style=flat-square)](https://coveralls.io/github/NaturalHistoryMuseum/ckanext-iiif)
  [![CKAN](https://img.shields.io/badge/ckan-2.9.7-orange.svg?style=flat-square)](https://github.com/ckan/ckan)
  [![Python](https://img.shields.io/badge/python-3.6%20%7C%203.7%20%7C%203.8-blue.svg?style=flat-square)](https://www.python.org/)
  [![Docs](https://img.shields.io/readthedocs/ckanext-iiif?style=flat-square)](https://ckanext-iiif.readthedocs.io)

  _IIIF for CKAN_

  <!--header-end-->



  <!--overview-start-->
  This extension enables IIIF functionality for CKAN by implementing the Presentation API.
  Currently, this includes a single manifest builder for records, but through the `IIIIF`
  interface you can extend the builders to include other IIIF resources.

  <!--overview-end-->



  <!--installation-start-->
  Path variables used below:
  - `$INSTALL_FOLDER` (i.e. where CKAN is installed), e.g. `/usr/lib/ckan/default`
  - `$CONFIG_FILE`, e.g. `/etc/ckan/default/development.ini`



  ```shell
  pip install ckanext-iiif
  ```



  1. Clone the repository into the `src` folder:
     ```shell
     cd $INSTALL_FOLDER/src
     git clone https://github.com/NaturalHistoryMuseum/ckanext-iiif.git
     ```

  2. Activate the virtual env:
     ```shell
     . $INSTALL_FOLDER/bin/activate
     ```

  3. Install via pip:
     ```shell
     pip install $INSTALL_FOLDER/src/ckanext-iiif
     ```



  Installing from a `pyproject.toml` in editable mode (i.e. `pip install -e`) requires `setuptools>=64`; however, CKAN 2.9 requires `setuptools==44.1.0`. See [our CKAN fork](https://github.com/NaturalHistoryMuseum/ckan) for a version of v2.9 that uses an updated setuptools if this functionality is something you need.



  1. Add 'iiif' to the list of plugins in your `$CONFIG_FILE`:
     ```ini
     ckan.plugins = ... iiif
     ```

  <!--installation-end-->



  <!--configuration-start-->
  There are no configuration options for this extension.

  <!--configuration-end-->



  <!--usage-start-->
  This extension's main function is provide a standard endpoint and action to create IIIF
  resources.
  These IIIF resources could be based on whatever you like - a record, a resource, a whole
  dataset etc.

  Presentation API IIIF resources can be accessed via either the `/iiif/<identifier>`
  endpoint or the `build_iiif_resource` action where the identifier is passed in the data
  dict in the key `"identifier"`.
  When this occurs the identifier is matched against any of the registered IIIF resource
  builders and if a match is found, the resource is returned.
  Identifiers can be built if the builder ID is known along with the necessary parameters
  by using the `build_iiif_identifier` action.



  By default, the only IIIF resource this extension can build is record manifests.
  This requires the `record_show` action to be available from the `ckanext-nhm` extension
  (there is
  an [open issue](https://github.com/NaturalHistoryMuseum/ckanext-nhm/issues/602) to move
  this action to a different extension, most likely
  [ckanext-versioned-datastore](https://github.com/NaturalHistoryMuseum/ckanext-versioned-datastore))
  .

  To build a record manifest you must provide the appropriate identifier, which must be of
  the format `resource/<resource_id>/record/<record_id>`, for example:
  `resource/afea211d-1b3d-49ad-9d15-17f0de368967/record/429`.
  This example identifies the record with ID `429` from the resource with ID
  `afea211d-1b3d-49ad-9d15-17f0de368967`.
  If the record and the resource can be found, and images can be found on the record, then
  a manifest is returned.
  If any of these conditions fail, the action returns `None` and the endpoint returns 404.

  The images are detected in the record by looking for the `_image_field` extra on the
  resource.
  This should define the field name in the record where images can be found.
  The value associated with this image field in the record can be:

  - a string (should be a URL)
  - a list of strings (each element should be a URL)
  - a string containing several URLs separated by a delimiter (this should be defined on
    the resource using the `_image_delimiter` extra)
  - a list of dicts (the URL is extracted by looking for an `identifier` field within
    each dict)

  To fill out the values in the manifest, the builder pulls out fields as specified by
  more resource level extras or by falling back to a default value.
  These are:

  - `"label"` - attempts to use `_title_field` extra but falls back to record ID
  - `"rights"` - attempts to use `_image_licence` extra but falls back
    to [cc-by](https://creativecommons.org/licenses/by/4.0/)

  The `"metadata"` field in the manifest is populated using the fields and values in the
  record data itself.



  To add a custom builder all you have to do is implement the `IIIIF` interface in your
  extension plugin.
  For example:

  ```python
  import ckan.plugins as plugins
  from typing import Optional, Callable
  from typing import OrderedDict

  from ckanext.iiif.builders.abc import IIIFResourceBuilder
  from ckanext.iiif.interfaces import IIIIF


  class MyBuilder(IIIFResourceBuilder):

      def match_and_build(self, identifier: str) -> Optional[dict]:
          ...

      def build_identifier(self, *args, **kwargs) -> str:
          ...


  class MyExtension(plugins.SingletonPlugin):
      plugins.implements(IIIIF)

      def register_iiif_builders(self, builders: OrderedDict[str, IIIFResourceBuilder]):
          builders["my_builder"]: MyBuilder()
  ```

  When a request is made to build a IIIF resource, each of the registered builders is
  called in turn with the identifier.
  This means that the builders need to both match the identifier to confirm it matches its
  pattern or meets its criteria, and generate the manifest.

  The builders should:

  - Return `None` if the identifier doesn't match the builders requirements. When this
    happens, the logic continues and tries the next registered builder function.
  - Raise a `ckanext.iiif.builders.utils.IIIFBuildError` if the identifier matched but the
    manifest couldn't be generated for any reason. This will stop the logic from checking
    any other builders for matches and return `None` to the caller.
  - Raise any other type of `Exception` if an unexpected error occurred during matching or
    processing. This will be propagated to the caller.

  <!--usage-end-->



  <!--testing-start-->
  There is a Docker compose configuration available in this repository to make it easier to run tests. The ckan image uses the Dockerfile in the `docker/` folder.

  To run the tests against ckan 2.9.x on Python3:

  1. Build the required images:
     ```shell
     docker compose build
     ```

  2. Then run the tests.
     The root of the repository is mounted into the ckan container as a volume by the Docker compose
     configuration, so you should only need to rebuild the ckan image if you change the extension's
     dependencies.
     ```shell
     docker compose run ckan
     ```

  <!--testing-end-->


pkgId: 50a9854c8d8364bf2ef01158bb54b337de328bafe96de823f626c3e3908c4c9d
name: python-ckanext-ingest
arch: src
version: 1.4.2.post1
epoch: 0
release: 1
summary: please add a summary manually as the author left a blank one
url: https://github.com/DataShades/ckanext-ingest
rpm_license: AGPL
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-ingest-1.4.2.post1-1.src.rpm
checksum_type: sha256
description:
  [![Tests](https://github.com/DataShades/ckanext-ingest/workflows/Tests/badge.svg)](https://github.com/DataShades/ckanext-ingest/actions/workflows/test.yml)



  Framework for transforming data stream into tasks.

  This extension provides tools for reading user-provided file-like object and
  producing tasks based on the input. Use it if you need to read records from
  CSV/JSON/XLSX/etc. file and:

  * create or update datasets using information from these records
  * remove users/organizations/datasets based on record details
  * send email to user specified by every record
  * collect some sort of statistics
  * perform any type of work that can be described as a series of steps



  Compatibility with core CKAN versions:

  | CKAN version | Compatible? |
  |--------------|-------------|
  | 2.9          | no          |
  | 2.10         | yes         |
  | 2.11         | yes         |
  | master       | yes         |




  To install ckanext-ingest:

  1. Install it via **pip**:
     ```sh
     pip install ckanext-ingest

     
     
     ```
  1. Add `ingest` to the `ckan.plugins` setting in your CKAN config file.



  Data can be ingested into CKAN via `ingest_import_records` API action. It
  requires a `source` with the data, and it's recommended to pass an extraction
  `strategy`, to get a full control over the process.

  ```sh
  ckanapi action ingest_import_records source@path/to/data.zip strategy="myext:extract_archive"
  ```

  But before anything can be ingested you have to regiser a `strategy` that
  produces `records`. `strategy` defines how source is parsed and divided into
  data chunks, and `record` wraps single data chunk and perform actions using
  information from the chunk.

  `strategy` is registered via `IIngest` interface. It has to be a subclass of
  `ckanext.ingest.shared.ExtractionStrategy`. The only requirement for
  `strategy` is to return iterable of `records` from its `extract` method.

  `record` is created by `strategy` and it has to be a subclass of
  `ckanext.ingest.shared.Record`. Its `ingest` method is responsible for
  ingestion: depending on the record purpose, it can create/update/delete data or
  perform any other task that has sense.






  ```python

  import ckan.plugins as p

  from ckanext.ingest.interfaces import IIngest

  class MyPlugin(p.SingletonPlugin):
      p.implements(IIngest)

      def get_ingest_strategies(self):
          return {
            "my:custom_strategy": CustomStrategy,
          }

  ```


  ```python
  import ckan.plugins.toolkit as tk
  from ckanext.ingest.shared import ExtractionStrategy, Storage, Record, IngestionResult

  class SingleJsonStrategy(ExtractionStrategy):

      def extract(self, source: Storage, options):
          
          data = json.load(source)

          
          
          
          yield SimplePackageRecord(data, {})

  class SimplePackageRecord(Record):
      def ingest(self, context: ckan.types.Context) -> IngestionResult:

          dataset = tk.get_action("package_create")(context, self.data)

          
          return {
              "success": True,
              "result": dataset,
              "details": {}
          }

  ```



  ```python
  import csv
  import ckan.plugins.toolkit as tk
  from ckanext.ingest.shared import ExtractionStrategy, Record

  class DropOrganizationsUsingCsvStrategy(ExtractionStrategy):

      def extract(self, source, options):
          
          str_stream = StringIO(source.read().decode())
          rows = csv.DictReader(st_stream)

          for row in rows:
              
              
              yield DropOrganiationRecord(row, {})

  class DropOrganizationRecord(Record):
      def ingest(self, context: ckan.types.Context):
          try:
              tk.get_action("organization_delete")(context, {"id": self.data["name"]})
          except tk.ObjectNotFound:
              success = False
          else:
              success = True

          return {
              "success": success,
              "result": None,
              "details": {}
          }

  ```



  ```python
  import json
  from datetime import datetime
  from ckanapi import RemoteCKAN
  import ckan.plugins.toolkit as tk
  from ckanext.ingest.shared import ExtractionStrategy, Record

  class HarvestStrategy(ExtractionStrategy):

      def extract(self, source, options):
          details = json.load(source)
          client = RemoteCKAN(**details)

          now = datetime.utcnow()

          
          for dataset in client.action.package_search()["results"]:
              yield SimpleDatasetRecord(row, {})

          
          
          
          yield DeleteStaleDatasetsRecord({"before": now}, {})

  class SimplePackageRecord(Record):
      def ingest(self, context: ckan.types.Context) -> IngestionResult:

          dataset = tk.get_action("package_create")(context, self.data)

          return {
              "success": True,
              "result": dataset,
              "details": {"remote_id": self.data["id"]}
          }


  class DeleteStaleDatasetsRecord(Record):
      def ingest(self, context: ckan.types.Context) -> IngestionResult:
          before = self.data["before"].isoformat()
          result = tk.get_action("package_search")(
              context,
              {"fq": f"metadata_modified:[* TO {before}]", "fl": "id"}
          )

          deleted = []
          for dataset in result["results"]
              tk.get_action("package_delete")(context, {"id": dataset["id"]})
              deleted.append(id)

          return {
              "success": True,
              "result": deleted,
              "details": {"count": len(deleted), "before": before}
          }

  ```



  To get the most from ingestion workflows, try writing reusable strategies and
  records using details below



  `strategy` argument for actions is optional. When it missing, the plugins
  chooses the most appropriate strategy for the ingested source. This feature
  relies on `can_handle` and `must_handle` methods of the extraction
  strategy. Both methods receive the mimetype of the source and the source itself
  and return `True`/`False`.

  Among all strategies that return `True` from `can_handle`, plugin selects the
  first strategy that returns `True` from `must_handle` as well. If there is no
  such strategy, the first `can_handle` wins.

  `ckanext.ingest.shared.ExtractionStrategy` defines both these
  methods. `must_handle` always returns `False`. `can_handle` return `True` if
  source's mimetype is listed in `mimetypes` property of the handler:

  ```python
  class ExtractionStrategy:
      mimetypes: ClassVar[set[str]] = set()

      @classmethod
      def can_handle(cls, mime: str | None, source) -> bool:
          return mime in cls.mimetypes

      @classmethod
      def must_handle(cls, mime, source) -> bool:
          return False

  ```

  If you want to register strategy that can handle JSON sources, just register
  strategy with an appropriate `mimetypes`:

  ```python
  class JsonStrategy(ExtractionStrategy):
      mimetypes = {"application/json"}
  ```

  If there are more than one strategy that supports JSON mimetype, the first
  registered strategy is selected. If you want to register strategy that always
  handles JSON sources with specific name(`DRINK_ME.json`), disregarding the
  order, you can use `must_handle`.

  Note, that `must_handle` is checked only when `can_handle` returns `True`, so
  we still using default `mimetypes` logic:

  ```python
  class DrinkMeJsonStrategy(ExtractionStrategy):
      mimetypes = {"application/json"}

      @classmethod
      def must_handle(cls, mime, source: Storage) -> bool:
          return source.filename == "DRINK_ME.json"
  ```



  `ExtractionStrategy` has a default implementation of `extract`. This default
  implementation calls `chunks` method to parse the source and get ingestable
  data fragments. Then, for every data chunk `chunk_into_record` method is
  called, to transform arbitrary data into a `Record`. Finally, `extract` yields
  whatever is produced by `chunk_into_record`.

  Default implementation of `chunks` ignores the source and returns an empty
  list. As result, by default any source produce zero records and nothing happens.

  The first thing you can do to produce a data is overriding `chunks`.

  If you are working with CSV file, `chunks` can return rows from the file:

  ```python
  class CsvRowsStrategy(ExtractionStrategy):
      mimetypes = {"text/csv"}

      def chunks(self, source, options) -> Iterable[Any]:
          str_stream = StringIO(source.read().decode())
          rows = csv.reader(str_stream)

          yield from rows
  ```

  Such strategy will produce `ckanext.ingest.shared.Record` for every row of the
  source CSV. But base `Record` class doesn't do much, so you need to replace it
  with your own `Record` subclass.

  As mentioned before, data chunk converted into a record via `chunk_into_record`
  method. You can either override it, or use default implemmentation, which
  creates instances of the class stored under `record_factory` attribute of the
  strategy. Default value of this attribute is `ckanext.ingest.shared.Record` and
  if you want to use a different record implementation, do the following:

  ```python
  class CsvRowsStrategy(ExtractionStrategy):
      record_factory = MyCustomRecord
      ...
  ```



  `ExtractionStrategy.extract` method is responsible for producing records. But
  it doesn't mean that strategy have to generate records itself. Instead,
  strategy can do some preparations and use another strategy in order to make records.

  Let's imagine `UrlStrategy` that accepts file with a single line - URL of the
  remote portal - and pulls data from this portal. As we don't know the
  type of the data, we cannot tell, how records can be created from it. So, when
  data is fetched, we can use its mimetype to select the most suitable strategy
  and delegate record generation to its `extract` method:

  ```python
  import requests
  import magic
  from io import BytesIO
  from ckanext.ingest import shared

  class UrlStrategy(ExtractionStrategy):

      def extract(self, source, options) -> Iterable[Any]:
          
          url = source.read()
          resp = requests.get(url)

          
          sub_source = shared.make_storage(BytesIO(resp.content))

          
          mime = magic.from_buffer(sub_source.read(1024))
          sub_source.seek(0)

          
          handler = shared.get_handler_for_mimetype(mime, sub_source)

          
          if handler:
              yield from handler.extract(source, options)
  ```



  `ExtractionStrategy.extract` and `Record.ingest` accept second argument
  `options`. In both cases it's a dictionary that can be used to modify the logic
  inside corresponding methods. Strategy options described by
  `ckanext.ingest.shared.StrategyOptions`, and record options described by
  `ckanext.ingest.shared.RecordOptions`.

  Keys defined on the top-level, have sense for every strategy/record. For
  example, `RecordOptions` defines `update_existing` flag. If record that creates
  data detects existing conflicting entity, `update_existing` flag should be
  taken into account when the record is considering what to do in such case. It's
  only a recomendation and this flag can be ignored or you can use a different
  option. But using common options simplify understanding of the workflow.

  For strategy there are 3 common keys:

  * `record_options`: these options should be passed into every record produced
    by the strategy(`RecordOptions`)
  * `nested_strategy`: if strategy delegates record creation to a different
    strategy, `nested_strategy` should be prefered over auto-detected
    strategy(mimetype detection)
  * `locator`: if source is represented by some kind of collection, `locator` is
    a callable that returns specific members of collection. It can be used when
    parsing archives, so that strategy can extract package's metadata from one
    file and upload resources returned by `locator` into it. Or, when parsing
    XLSX, `locator` can return sheets by title to simplify processing of multiple
    sheets.

  For any options that can be used only by a specific strategy, there is an
  `extras` option inside both `StrategyOptions` and `RecordOptions`. This
  dictionary can hold any data and there are no expectations to its structure.

  Keys that are used often inside `extras` may eventually be added as recommended
  options to the top-level. But, as these are only recomendations, you can just
  ignore them and pass whatever data you need as options.



  `ckanext.ingest.shared.Record` class requires two parameters for
  initialization: `raw` data and `options` for the record. When record is
  created, it calls its `trasform` method, that copies `raw` data into `data`
  property. This is the best place for data mapping, before record's `ingest`
  method is called. If you want to remove all empty members from record's `data`,
  it can be done in the following way:

  ```python
  class DenseRecord(Record):
      def transform(self, raw: Any):
          self.data = {
              key: value
              for key, value in raw.items()
              if value is not None
          }

  ```



  Record usually calls one of CKAN API actions during ingestion. In order to do
  it properly, record needs action `context`, which is passed as as single
  argument into `ingest` method. But this is only the most common workflow, so if
  you don't use any action, just ignore the `context`. What is more important, is
  the output of the `ingest`. It must be a dictionary described by
  `ckanext.ingest.shared.IngestionResult`. It has three members:

  * `success`: flag that indicates whether ingestion succeeded or failed
  * `result`: data produced by ingestion(package, resource, organization, etc.)
  * `details`: any other details that may be useful. For example, how many
    entities were modified during ingestion, which API action was used, what were
    the errors if ingestion failed.

  These details are not required by ingestion, but they may be used for building
  ingestion report.



  `ckanext.ingest.record` module contains `PackageRecord` and `ResourceRecord`
  classes that create package/resource. But their `trasform` method is much more
  interesting. It maps `raw` into `data` using field configuration from metadata
  schema defined by ckanext-scheming.

  In order to configure mapping, add `ingest_options` attribute to the field defition:
  ```yaml
  - field_name: title
    label: Title
    ingest_options: {}
  ```

  During transformation, every key in `raw` is checked agains the schema. If
  schema contains field with `ingest_options` whose `field_name` or `label`
  matches the key from `raw`, this key is copied into `data` and mapped to the
  corresponding `field_name`. I.e, for the field definition above, both `raw`
  versions - `{"title": "hello"}` and `{"Title": "hello"}` will turn into `data`
  with value `{"title": "hello"}`.

  If you have completely different names in `raw`, use `aliases`(`list[str]`)
  attribute of `ingest_options`:

  ```yaml
  - field_name: title
    label: Title
    ingest_options:
        aliasses: [TITLE, "name of the dataset"]
  ```

  In this case, `{"name of the dataset": "hello"}` and `{"TITLE": "hello"}` will
  turn into `{"title": "hello"}`.

  If value requires additional processing before it can be used as a field
  values, specify all applied validators as `convert` attribute of the
  `ingest_options`:

  ```yaml
  - field_name: title
    label: Title
    ingest_options:
        convert: conver_to_lowercase json_list_or_string
  ```

  `convert` uses the same syntax as `validators` attribute of the field
  definition. You can use any registered validator inside this field. But, unlike
  validators, if `Invalid` error raised during transformation, field is silently
  ignored and ingestion continues.

  Any field from `raw` that has no corresponding field in schema(detected by
  `field_name`/`label` or `ingest_options.aiases`), is not added to the `data`
  and won't be used for package/resource creation.



  There are a number of strategies available out-of-the box. You probably won't
  use them as-is, but creating a subclass of these strategies may simplify the
  process and solve a couple of common problems.



  Defined by `ckanext.ingest.strategy.csv.CsvStrategy`.



  Defined by `ckanext.ingest.strategy.zip.CsvStrategy`.



  Defined by `ckanext.ingest.strategy.xlsx.XlsxStrategy`.



  ```ini



  ckanext.ingest.strategy.allowed = ingest:recursive_zip



  ckanext.ingest.strategy.disabled = ingest:scheming_csv



  ckanext.ingest.base_template = admin/index.html



  ckanext.ingest.allow_resource_transfer = true




  ckanext.ingest.strategy.name_mapping = {"ckanext.ingest.strategy.zip:ZipStrategy": "zip"}
  ```



  `ckanext.ingest.interfaces.IIngest` interface implementations can regiser
  custom extraction strategies via `get_ingest_strategies` method::

  ```python
  def get_ingest_strategies() -> dict[str, type[ckanext.ingest.shared.ExtractionStrategy]]:
      """Return extraction strategies."""
      return {
          "my_plugin:xlsx_datasets": MyXlsxStrategy,
      }
  ```





  Extract records from the source.

  This method mainly exists for debugging. It doesn't create anything, just
  parses the source, produces records and return record's data as a
  list. Because it aggregates all extracted records into a single list, it
  can consume a lot of memory. If you want to iterate over, consider using
  `iter_records` function that produces an iterable over records.

  Args:

      source: str|FileStorage - data source for records

      strategy: str|None - record extraction strategy. If missing, strategy
      is guessed depending on source's mimetype

      options: SourceOptions - dictionary with configuration for strategy and
      records. Consumed by strategies so heavily depends on the chosen
      strategy.




  Ingest records extracted from source.

  Parse the source, convert it into Records using selected strategy, and call
  `Record.ingest`, potentially creating/updating data.

  Args:

      source: str|FileStorage - data source for records

      strategy: str|None - record extraction strategy. If missing, strategy
      is guessed depending on source's mimetype

      options: SourceOptions - dictionary with configuration for strategy and
      records. Consumed by strategies so heavily depends on the chosen
      strategy.

      defaults: dict[str, Any] - default data added to every record(if missing)

      overrides: dict[str, Any] - data that unconditionally overrides record details

      skip: int - number of records that are skipped without ingestion

      take: int - max number of records that will be ingested


pkgId: 3a07aeb969b343acf833eb82db4b28638ca4ef2a0a814cfebb764095ed2000dc
name: python-ckanext-iso19115
arch: src
version: 0.1.1.post1
epoch: 0
release: 1
summary: please add a summary manually as the author left a blank one
url: https://github.com/DataShades/ckanext-iso19115
rpm_license: AGPL
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-iso19115-0.1.1.post1-1.src.rpm
checksum_type: sha256
description:
  [![Tests](https://github.com/DataShades/ckanext-iso19115/workflows/Tests/badge.svg?branch=main)](https://github.com/DataShades/ckanext-iso19115/actions)



  Export dataset into ISO 19115 XML.




  Compatibility with core CKAN versions:

  | CKAN version | Compatible? |
  |--------------|-------------|
  | 2.9          | yes         |
  | 2.10         | yes         |




  To install ckanext-iso19115:

  1. Install it into virtualenv:
     ```sh
     pip install ckanext-iso19115
     ```

  1. Add `iso19115` to the `ckan.plugins`.



  None at present

  ```ini


  ckanext.iso19115.misc.cache_dir = /var/data/iso19115_cache
  ```



  Customize the way of mapping dataset into ISO 19115 by implementing `IIso18115` interface.

  ```python
  from ckanext.iso19115.interfaces import IIso19115

  class Iso19115(p.SingletonPlugin):
      p.implements(IIso19115, inherit=True)

      def iso19115_metadata_converter(self, data_dict: dict[str, Any]):
          return Converter(data_dict)
  ```

  `Converter` must be defined as a sub-class of
  `ckanext.iso19115.converter.Converter`. It already contains some basic logic
  that can be used as a starting point for extension.





  Export dataset into ISO 19115 JsonML.

  Format can be changed using `format` parameter of the action. Possible alternatives:

  * xml



  Check if the dataset can be rendered as a valid ISO 19115 document



  To run the tests, do:

      pytest





  [AGPL](https://www.gnu.org/licenses/agpl-3.0.en.html)


pkgId: 6c05a993b5fc1dee2678927e332b185a5eb24ddd37fedeb7dbd02b5896bfad64
name: python-ckanext-ldap
arch: src
version: 3.3.3
epoch: 0
release: 1
summary: A CKAN extension that provides LDAP authentication.
url: https://pypi.org/project/ckanext-ldap/
rpm_license: GPL-3.0-or-later
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-ldap-3.3.3-1.src.rpm
checksum_type: sha256
description:
  <!--header-start-->
  <picture>
    <source media="(prefers-color-scheme: dark)" srcset="https://data.nhm.ac.uk/images/nhm_logo.svg">
    <source media="(prefers-color-scheme: light)" srcset="https://data.nhm.ac.uk/images/nhm_logo_black.svg">
    <img alt="The Natural History Museum logo." src="https://data.nhm.ac.uk/images/nhm_logo_black.svg" align="left" width="150px" height="100px" hspace="40">
  </picture>



  [![Tests](https://img.shields.io/github/actions/workflow/status/NaturalHistoryMuseum/ckanext-ldap/tests.yml?style=flat-square)](https://github.com/NaturalHistoryMuseum/ckanext-ldap/actions/workflows/tests.yml)
  [![Coveralls](https://img.shields.io/coveralls/github/NaturalHistoryMuseum/ckanext-ldap/main?style=flat-square)](https://coveralls.io/github/NaturalHistoryMuseum/ckanext-ldap)
  [![CKAN](https://img.shields.io/badge/ckan-2.9.7+%20%7C%202.10-orange.svg?style=flat-square)](https://github.com/ckan/ckan)
  [![Python](https://img.shields.io/badge/python-3.6%20%7C%203.7%20%7C%203.8-blue.svg?style=flat-square)](https://www.python.org/)
  [![Docs](https://img.shields.io/readthedocs/ckanext-ldap?style=flat-square)](https://ckanext-ldap.readthedocs.io)

  _A CKAN extension that provides LDAP authentication._

  <!--header-end-->



  <!--overview-start-->
  This plugin provides LDAP authentication for CKAN.

  Features include:

  - Imports username, full name, email and description;
  - Can match against several LDAP fields (eg. username or full name);
  - Allows to have LDAP only authentication, or combine LDAP and basic CKAN
    authentication;
  - Can add LDAP users to a given organization automatically;
  - Works with Active Directory.

  <!--overview-end-->



  <!--installation-start-->
  Path variables used below:

  - `$INSTALL_FOLDER` (i.e. where CKAN is installed), e.g. `/usr/lib/ckan/default`
  - `$CONFIG_FILE`, e.g. `/etc/ckan/default/development.ini`



  ```shell
  pip install ckanext-ldap
  ```



  1. Clone the repository into the `src` folder:
     ```shell
     cd $INSTALL_FOLDER/src
     git clone https://github.com/NaturalHistoryMuseum/ckanext-ldap.git
     ```

  2. Activate the virtual env:
     ```shell
     . $INSTALL_FOLDER/bin/activate
     ```

  3. Install via pip:
     ```shell
     pip install $INSTALL_FOLDER/src/ckanext-ldap
     ```



  Installing from a `pyproject.toml` in editable mode (i.e. `pip install -e`)
  requires `setuptools>=64`; however, CKAN 2.9 requires `setuptools==44.1.0`.
  See [our CKAN fork](https://github.com/NaturalHistoryMuseum/ckan) for a version of v2.9
  that uses an updated setuptools if this functionality is something you need.



  1. Add 'ldap' to the list of plugins in your `$CONFIG_FILE`:
     ```ini
     ckan.plugins = ... ldap
     ```

  <!--installation-end-->



  <!--configuration-start-->
  These are the options that can be specified in your .ini config file.



  | Name                         | Description                                                                                                                                                                                                                         | Options    |
  |------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|
  | `ckanext.ldap.uri`           | The URI of the LDAP server, of the form _ldap://example.com_. You can use the URI to specify TLS (use 'ldaps' protocol), and the port number (suffix ':port').                                                                      | True/False |
  | `ckanext.ldap.base_dn`       | The base dn in which to perform the search. Example: 'ou=USERS,dc=example,dc=com'.                                                                                                                                                  |            |
  | `ckanext.ldap.search.filter` | This is the search string that is sent to the LDAP server, in which '{login}' is replaced by the user name provided by the user. Example: 'sAMAccountName={login}'. The search performed here **must** return exactly 0 or 1 entry. |            |
  | `ckanext.ldap.username`      | The LDAP attribute that will be used as the CKAN username. This **must** be unique.                                                                                                                                                 |            |
  | `ckanext.ldap.email`         | The LDAP attribute to map to the user's email address. This **must** be unique.                                                                                                                                                     |            |



  | Name                                | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | Options                         | Default  |
  |-------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------|----------|
  | `ckanext.ldap.ckan_fallback`        | If true this will attempt to log in against the CKAN user database when no LDAP user exists.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | True/False                      | False    |
  | `ckanext.ldap.prevent_edits`        | If true, this will prevent LDAP users from editing their profile. Note that there is no problem in allowing users to change their details - even their user name can be changed. But you may prefer to keep things centralized in your LDAP server. **Important**: while this prevents the operation from happening, it won't actually remove the 'edit settings' button from the dashboard. You need to do this in your own template.                                                                                                                                                                                                                                                                                                                                                                                                                                  | True/False                      | False    |
  | `ckanext.ldap.auth.dn`              | DN to use if LDAP server requires authentication.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |                                 |          |
  | `ckanext.ldap.auth.password`        | Password to use if LDAP server requires authentication.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |                                 |          |
  | `ckanext.ldap.auth.method`          | Authentication method                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | SIMPLE, SASL                    |          |
  | `ckanext.ldap.auth.mechanism`       | SASL mechanism to use, if auth.method is set to SASL.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |                                 |          |
  | `ckanext.ldap.fullname`             | The LDAP attribute to map to the user's full name.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |                                 |          |
  | `ckanext.ldap.about`                | The LDAP attribute to map to the user's description.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                 |          |
  | `ckanext.ldap.organization.id`      | If this is set, users that log in using LDAP will automatically get added to the given organization. **Warning**: Changing this parameter will only affect users that have not yet logged on. It will not modify the organization of users who have already logged on. **Warning**: The organization to which to add LDAP users must already exist; the first user logging in will not automatically create it and instead you will see a "500 Server Error" returned.                                                                                                                                                                                                                                                                                                                                                                                                  |                                 |          |
  | `ckanext.ldap.organization.role`    | The role given to users added in the given organization ('admin', 'editor' or 'member'). **Warning**: Changing this parameter will only affect users that have not yet logged on. It will not modify the role of users who have already logged on. This is only used if `ckanext.ldap.organization.id` is set. There is currently no functionality for mapping LDAP groups to CKAN roles, so this just assigns the same role to _every_ new LDAP user.                                                                                                                                                                                                                                                                                                                                                                                                                  | member, editor, admin           | 'member' |
  | `ckanext.ldap.search.alt`           | An alternative search string for the LDAP filter. If this is present and the search using `ckanext.ldap.search.filter` returns exactly 0 results, then a search using this filter will be performed. If this search returns exactly one result, then it will be accepted. You can use this for example in Active Directory to match against both username and fullname by setting `ckanext.ldap.search.filter` to  'sAMAccountName={login}' and `ckanext.ldap.search.alt` to 'name={login}'. The approach of using two separate filter strings (rather than one with an or statement) ensures that priority will always be given to the unique id match. `ckanext.ldap.search.alt` however can  be used to match against more than one field. For example you could match against either the full name or the email address by setting `ckanext.ldap.search.alt` to '(\ | (name={login})(mail={login}))'. |          |
  | `ckanext.ldap.search.alt_msg`       | A message that is output to the user when the search on `ckanext.ldap.search.filter` returns 0 results, and the search on `ckanext.ldap.search.alt` returns more than one result. Example: 'Please use your short account name instead'.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |                                 |          |
  | `ckanext.ldap.migrate`              | If true this will change an existing CKAN user with the same username to an LDAP user. Otherwise, an exception `UserConflictError`is raised if LDAP-login with an already existing local CKAN username is attempted. This option provides a migration path from local CKAN authentication to LDAP authentication: Rename all users to their LDAP usernames and instruct them to login with their LDAP credentials. Migration then happens transparently.                                                                                                                                                                                                                                                                                                                                                                                                                | True/False                      | False    |
  | `ckanext.ldap.debug_level`          | [python-ldap debug level](https://www.python-ldap.org/en/python-ldap-3.0.0b1/reference/ldap.html?highlight=debug_level#ldap.OPT_DEBUG_LEVEL). **Security warning**: it is strongly recommended to keep this parameter set to 0 (zero) on production systems, otherwise [plaintext passwords will be logged by `python-ldap`](https://github.com/python-ldap/python-ldap/issues/384)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | 0-9                             | 0        |
  | `ckanext.ldap.trace_level`          | [python-ldap trace level](https://www.python-ldap.org/en/python-ldap-3.0.0b1/reference/ldap.html?highlight=trace_level#ldap.initialize). **Security warning**: it is strongly recommended to keep this parameter set to 0 (zero) on production systems, otherwise [plaintext passwords will be logged by `python-ldap`](https://github.com/python-ldap/python-ldap/issues/384)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | 0-9                             | 0        |
  | `ckanext.ldap.allow_password_reset` | If true, allows LDAP users to reset their passwords, if false, disallows this functionality. Note that if this is true, the password that is reset is the CKAN user password, not the LDAP one. If set to false, the request to reset will be denied only if the user is an LDAP user, if not they will be allowed to reset regardless of the value of this option.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | True/False                      | true     |
  | `ckanext.ldap.ignore_referrals`     | If true, The plugin will ignore referral query results sent by the LDAP server. This might be necessary if your base_dn is at the domain level, but the LDAP server searches in multiple paths for the user, resulting in queries containing more than one result.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | True/False                      | false    |

  <!--configuration-end-->



  <!--usage-start-->



  To test that the extension is working correctly without having to set up an LDAP service
  yourself, you can try this config snippet:

  ```ini
  ckanext.ldap.uri = ldap://ldap.forumsys.com:389
  ckanext.ldap.base_dn = dc=example,dc=com
  ckanext.ldap.search.filter = cn=*{login}*
  ckanext.ldap.username = cn
  ckanext.ldap.auth.dn = cn=read-only-admin,dc=example,dc=com
  ckanext.ldap.email = mail
  ckanext.ldap.auth.password = password
  ckanext.ldap.auth.method = SIMPLE
  ```

  See [here](https://www.forumsys.com/tutorials/integration-how-to/ldap/online-ldap-test-server/)
  for more information.
  Then just login with `tesla` or `gauss` for example with `password` as the password.





  1. `setup-org`: create the organisation specified in `ckanext.ldap.organization.id`.
      ```bash
      ckan -c $CONFIG_FILE ldap setup-org
      ```

  2. `initdb`: ensure the tables needed by this extension exist.
      ```bash
      ckan -c $CONFIG_FILE ldap initdb
      ```



  This extension overrides `templates/user/login.html` and sets the form action to the
  LDAP login handler.

  To use it elsewhere:

  ```html+jinja
  {% set ldap_action = h.get_login_action() %}
  {% snippet "user/snippets/login_form.html", action=ldap_action, error_summary=error_summary %}
  ```

  The helper function `h.is_ldap_user()` is also provided for templates.

  <!--usage-end-->



  <!--testing-start-->
  There is a Docker compose configuration available in this repository to make it easier
  to run tests. The ckan image uses the Dockerfile in the `docker/` folder.

  To run the tests can be run against ckan 2.9.x and 2.10.x on Python3:

  1. Build the required images:
     ```shell
     docker compose build
     ```

  2. Then run the tests.
     The root of the repository is mounted into the ckan container as a volume by the
     Docker compose configuration, so you should only need to rebuild the ckan image if
     you change the extension's dependencies.
     ```shell
     
     docker compose run latest

     
     docker compose run next
     ```

  <!--testing-end-->


pkgId: 5a4ba6b409d0073d2d03c808bf91b6943aa2ae63e0b8e9c13af8f19139c3199e
name: python-ckanext-metrics-dashboard
arch: src
version: 0.1.6
epoch: 0
release: 1
summary: A CKAN extension to display metrics about datasets.
url: https://github.com/GSA/ckanext-metrics_dashboard/
rpm_license: Public Domain
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-metrics-dashboard-0.1.6-1.src.rpm
checksum_type: sha256
description:
  <=2.8        | ???
  2.9          | yes (with ckanext-datagovtheme==0.1.*)
  2.10         | yes (with ckanext-datagovtheme>=0.2.1)


  These extensions are required for metrics_dashboard:
  -   [ckanext-report](https://github.com/ckan/ckanext-report/)


  -   GNU Make
  -   Docker Compose

  Build the docker containers. You'll want to do this anytime the dependencies
  change (requirements.txt, dev-requirements.txt).
      $ make build
  Start the containers.
      $ make up
  CKAN will start at [localhost:5000](http://localhost:5000).
  Start the containers, but don't start ckan. More debugging instructions [here](#Debugging)
      $ make debug
  Open a shell to run commands in the container.
      $ docker-compose exec app bash
  If you're unfamiliar with docker-compose, see our
  [cheatsheet](https://github.com/GSA/datagov-deploy/wiki/Docker-Best-Practices#cheatsheet)
  and the [official docs](https://docs.docker.com/compose/reference/).
  Clean the containers and remove the data.
      $ make clean
  For additional make targets, see the help.
      $ make help

  They follow the guidelines for [testing CKAN extensions](https://docs.ckan.org/en/2.8/extensions/testing-extensions.html#testing-extensions).
  To run the extension tests:
      $ make test
  Lint your code.
      $ make lint

  We have not determined a good way for most IDE native debugging, however you can use the built in Python pdb debugger. Simply run `make debug`, which will run docker with an interactive shell. Add import pdb; pdb.set_trace() anywhere you want to start debugging, and if the code is triggered you should see a command prompt waiting in the shell. Use a pdb cheat sheet when starting to learn like this.
  When you edit/add/remove code, the server is smart enough to restart. If you are editing logic that is not part of the webserver (ckan command, etc) then you should be able to run the command after edits and get the same debugger prompt.
  1. Launch the containers with `make debug`
  2. Start the CKAN process by running `./start_ckan_development.sh`
  3. Add `import ibdb; ipdb.set_trace()` at the point you wish to debug.
  4. Invoke that code to hit that breakpoint.


pkgId: ee03c1b2b4922e371dd635629fee86a6fff8d4af88247db244b28c4aeebc6f39
name: python-ckanext-nhm
arch: src
version: 6.9.6
epoch: 0
release: 1
summary: A CKAN extension for the Natural History Museum's Data Portal.
url: https://pypi.org/project/ckanext-nhm/
rpm_license: GPL-3.0-or-later
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-nhm-6.9.6-1.src.rpm
checksum_type: sha256
description:
  <!--header-start-->
  <img src="https://data.nhm.ac.uk/images/nhm_logo.svg" align="left" width="150px" height="100px" hspace="40"/>



  [![Tests](https://img.shields.io/github/actions/workflow/status/NaturalHistoryMuseum/ckanext-nhm/main.yml?style=flat-square)](https://github.com/NaturalHistoryMuseum/ckanext-nhm/actions/workflows/main.yml)
  [![Coveralls](https://img.shields.io/coveralls/github/NaturalHistoryMuseum/ckanext-nhm/main?style=flat-square)](https://coveralls.io/github/NaturalHistoryMuseum/ckanext-nhm)
  [![CKAN](https://img.shields.io/badge/ckan-2.9.7-orange.svg?style=flat-square)](https://github.com/ckan/ckan)
  [![Python](https://img.shields.io/badge/python-3.6%20%7C%203.7%20%7C%203.8-blue.svg?style=flat-square)](https://www.python.org/)
  [![Docs](https://img.shields.io/readthedocs/ckanext-nhm?style=flat-square)](https://ckanext-nhm.readthedocs.io)
  [![Specimen records](https://img.shields.io/badge/dynamic/json.svg?color=brightgreen&label=specimens&query=%24.result.total&suffix=%20records&url=https%3A%2F%2Fdata.nhm.ac.uk%2Fapi%2F3%2Faction%2Fdatastore_search%3Fresource_id%3D05ff2255-c38a-40c9-b657-4ccb55ab2feb&style=flat-square)](https://data.nhm.ac.uk/dataset/collection-specimens/resource/05ff2255-c38a-40c9-b657-4ccb55ab2feb)

  _A CKAN extension for the Natural History Museum's [Data Portal](https://data.nhm.ac.uk)._

  <!--header-end-->



  <!--overview-start-->
  This extension provides theming and specific functionality for the Natural History Museum's [Data Portal](https://data.nhm.ac.uk).

  The codebase shows how to implement various plugins created by the Museum's developers; notably our new [ElasticSearch datastore](https://github.com/NaturalHistoryMuseum/ckanext-versioned-datastore) with versioned records.

  <!--overview-end-->



  <!--installation-start-->
  Path variables used below:
  - `$INSTALL_FOLDER` (i.e. where CKAN is installed), e.g. `/usr/lib/ckan/default`
  - `$CONFIG_FILE`, e.g. `/etc/ckan/default/development.ini`



  This package depends on `ckanext-dcat==1.3.0`, but since that isn't available on PyPI it's not listed in the package dependencies.

  Install it with:
  ```shell
  pip install git+https://github.com/ckan/ckanext-dcat@v1.3.0#egg=ckanext-dcat
  ```



  ```shell
  pip install ckanext-nhm
  ```



  1. Clone the repository into the `src` folder:
     ```shell
     cd $INSTALL_FOLDER/src
     git clone https://github.com/NaturalHistoryMuseum/ckanext-nhm.git
     ```

  2. Activate the virtual env:
     ```shell
     . $INSTALL_FOLDER/bin/activate
     ```

  3. Install via pip:
     ```shell
     pip install $INSTALL_FOLDER/src/ckanext-nhm
     ```



  Installing from a `pyproject.toml` in editable mode (i.e. `pip install -e`) requires `setuptools>=64`; however, CKAN 2.9 requires `setuptools==44.1.0`. See [our CKAN fork](https://github.com/NaturalHistoryMuseum/ckan) for a version of v2.9 that uses an updated setuptools if this functionality is something you need.



  1. Add 'nhm' to the list of plugins in your `$CONFIG_FILE`:
     ```ini
     ckan.plugins = ... nhm
     ```

  2. Install `lessc` globally:
     ```shell
     npm install -g "less@~4.1"
     ```

  <!--installation-end-->



  <!--configuration-start-->


  <!--configuration-end-->



  <!--usage-start-->



  Retrieve an individual record.

  ```python
  from ckan.plugins import toolkit

  data_dict = {
                  'resource_id': RESOURCE_ID,
                  'record_id': RECORD_ID,
                  'version': OPTIONAL_RECORD_VERSION
              }

  toolkit.get_action('record_show')(
      context,
      data_dict
  )
  ```


  Get record RDF from its occurrence ID.

  ```python
  from ckan.plugins import toolkit

  data_dict = {
                  'uuid': OCCURRENCE_ID,
                  'version': OPTIONAL_RECORD_VERSION
              }

  toolkit.get_action('object_rdf')(
      context,
      data_dict
  )
  ```




  Ensures the default dataset vocabulary and categories exists.

  ```bash
  ckan -c $CONFIG_FILE nhm create-dataset-vocabulary
  ```


  Adds the given category to the dataset category vocabulary.

  ```bash
  ckan -c $CONFIG_FILE nhm delete-dataset-category $NAME
  ```


  Deletes the given dataset category from the vocabulary.

  ```bash
  ckan -c $CONFIG_FILE nhm create-dataset-vocabulary $NAME
  ```


  Replaces the file associated with `$RESOURCE_ID` with `$PATH`, e.g. to replace a small dummy file
  with a large one that was too big to upload initially.

  ```bash
  ckan -c $CONFIG_FILE nhm replace-resource-file $RESOURCE_ID $PATH
  ```

  <!--usage-end-->



  <!--testing-start-->
  There is a Docker compose configuration available in this repository to make it easier to run tests. The ckan image uses the Dockerfile in the `docker/` folder.

  To run the tests against ckan 2.9.x on Python3:

  1. Build the required images:
     ```shell
     docker compose build
     ```

  2. Then run the tests.
     The root of the repository is mounted into the ckan container as a volume by the Docker compose
     configuration, so you should only need to rebuild the ckan image if you change the extension's
     dependencies.
     ```shell
     docker compose run ckan
     ```

  <!--testing-end-->


pkgId: b897909c473b8fe0af44b5d19da18fee6dcb705903c8ae1fc676830bae785882
name: python-ckanext-passwordless_api
arch: src
version: 1.1.8
epoch: 0
release: 1
summary: Extension to allow paswordless login to the CKAN API
url: https://pypi.org/project/ckanext-passwordless_api/
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-passwordless_api-1.1.8-1.src.rpm
checksum_type: sha256
description:
  **Documentation**: <a href="https://envidat.gitlab-pages.wsl.ch/ckanext-passwordless_api/" target="_blank">https://envidat.gitlab-pages.wsl.ch/ckanext-passwordless_api/</a>


pkgId: 08bd9ff005715efe1ad4f911110ad9d5ce6008b8fff8e8b3e0d1d89e0ab9d921
name: python-ckanext-pygments
arch: src
version: 1.2.1
epoch: 0
release: 1
summary: Provides previews with syntax highlight for multiple formats
url: https://github.com/DataShades/ckanext-pygments
rpm_license: AGPL
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-pygments-1.2.1-1.src.rpm
checksum_type: sha256
description:
  [![Tests](https://github.com/mutantsan/ckanext-pygments/workflows/Tests/badge.svg?branch=main)](https://github.com/mutantsan/ckanext-pygments/actions)



  This extension provides a preview with syntax highlight for multiple text resources formats.


  There is a caching mechanism implemented in this extension. It is disabled by default. To enable it, set `ckanext.pygments.cache.enable` to `True`. You can also set the time to live for the cache in seconds with `ckanext.pygments.cache.ttl`. The default is 7200 seconds (2 hours). You can also set the maximum size of the resource to cache in bytes with `ckanext.pygments.cache.resouce_max_size`. The default is 20MB.


  We use Redis for caching and it uses memory. If you have a lot of resources and they are big, you can run out of memory. That's why it is disabled by default.
  It's still debatable if we need cache at all. Big resource processed with pygments will be even bigger. So we can have a lot of memory usage. But if we have a lot of resources and many users access it, we can save a lot of time on processing.


  If you're using the [ckanext-admin-panel](https://github.com/mutantsan/ckanext-admin-panel) extension, you can configure the pygments settings from the admin panel.

  ![Configuration page](doc/config.png)

  Otherwise, you can configure it in the `ckan.ini` file.



  Supported config options:

  ```yaml
  - key: ckanext.pygments.supported_formats
    type: list
    description: Specify a list of supported formats
    default: sql html xhtml htm xslt py pyw pyi jy sage sc rs rs.in rst rest md markdown xml xsl rss xslt xsd wsdl wsf json jsonld yaml yml dtd php inc rdf ttl js

  - key: ckanext.pygments.max_size
    type: int
    description: Specify how many bytes we are going to render from file. Default to 1MB
    default: 1048576

  - key: ckanext.pygments.include_htmx_asset
    description: Include HTMX asset
    default: true
    type: bool

  - key: ckanext.pygments.default_theme
    description: Default theme for preview
    default: default

  - key: ckanext.pygments.cache.enable
    description: Enable cache
    default: false
    type: bool

  - key: ckanext.pygments.cache.preview_max_size
    description: Specify what is the maximum size of a preview we are going to cache
    default: 20971520 # 20MB
    type: int

  - key: ckanext.pygments.cache.ttl
    description: Specify the time to live of the cache
    default: 7200 # 2 hours
    type: int
  ```



  To run the tests, do:

      pytest --ckan-ini=test.ini



  [AGPL](https://www.gnu.org/licenses/agpl-3.0.en.html)


pkgId: 7f03d941a968b42238e9a8f40cb0b7ea51b4751c9b87a056a9da112cd6bd34db
name: python-ckanext-query-dois
arch: src
version: 4.1.1
epoch: 0
release: 1
summary: A CKAN extension that creates DOIs for queries on resources.
url: https://pypi.org/project/ckanext-query-dois/
rpm_license: GPL-3.0-or-later
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-query-dois-4.1.1-1.src.rpm
checksum_type: sha256
description:
  <!--header-start-->
  <img src="https://data.nhm.ac.uk/images/nhm_logo.svg" align="left" width="150px" height="100px" hspace="40"/>



  [![Tests](https://img.shields.io/github/actions/workflow/status/NaturalHistoryMuseum/ckanext-query-dois/main.yml?style=flat-square)](https://github.com/NaturalHistoryMuseum/ckanext-query-dois/actions/workflows/main.yml)
  [![Coveralls](https://img.shields.io/coveralls/github/NaturalHistoryMuseum/ckanext-query-dois/main?style=flat-square)](https://coveralls.io/github/NaturalHistoryMuseum/ckanext-query-dois)
  [![CKAN](https://img.shields.io/badge/ckan-2.9.7-orange.svg?style=flat-square)](https://github.com/ckan/ckan)
  [![Python](https://img.shields.io/badge/python-3.6%20%7C%203.7%20%7C%203.8-blue.svg?style=flat-square)](https://www.python.org/)
  [![Docs](https://img.shields.io/readthedocs/ckanext-query-dois?style=flat-square)](https://ckanext-query-dois.readthedocs.io)

  _A CKAN extension that creates DOIs for queries on resources._

  <!--header-end-->



  <!--overview-start-->
  This extension creates (mints) digital object identifiers (DOIs) for queries on resources. By recording the query parameters used and the exact version of the data at the time of the query, this allows precise retrieval of the data as it looked when the DOI was minted.

  Can be used in conjunction with **v5.2+** of [ckanext-versioned-datastore](https://github.com/NaturalHistoryMuseum/ckanext-versioned-datastore).

  You will need an account with a DataCite DOI service provider to use this extension.

  <!--overview-end-->



  <!--installation-start-->
  Path variables used below:
  - `$INSTALL_FOLDER` (i.e. where CKAN is installed), e.g. `/usr/lib/ckan/default`
  - `$CONFIG_FILE`, e.g. `/etc/ckan/default/development.ini`



  ```shell
  pip install ckanext-query-dois
  ```



  1. Clone the repository into the `src` folder:
     ```shell
     cd $INSTALL_FOLDER/src
     git clone https://github.com/NaturalHistoryMuseum/ckanext-query-dois.git
     ```

  2. Activate the virtual env:
     ```shell
     . $INSTALL_FOLDER/bin/activate
     ```

  3. Install via pip:
     ```shell
     pip install $INSTALL_FOLDER/src/ckanext-query-dois
     ```



  Installing from a `pyproject.toml` in editable mode (i.e. `pip install -e`) requires `setuptools>=64`; however, CKAN 2.9 requires `setuptools==44.1.0`. See [our CKAN fork](https://github.com/NaturalHistoryMuseum/ckan) for a version of v2.9 that uses an updated setuptools if this functionality is something you need.



  1. Add 'query_dois' to the list of plugins in your `$CONFIG_FILE`:
     ```ini
     ckan.plugins = ... query_dois
     ```

  2. Install `lessc` globally:
     ```shell
     npm install -g "less@~4.1"
     ```

  3. Initialise database tables:
     ```shell
     ckan -c $CONFIG_FILE query-dois initdb
     ```

  4. Sign up for an account with [DataCite](https://datacite.org) and provide the credentials in your configuration.

  <!--installation-end-->



  <!--configuration-start-->
  These are the options that can be specified in your .ini config file.



  | Name                                   | Description                                                           | Options |
  |----------------------------------------|-----------------------------------------------------------------------|---------|
  | `ckanext.query_dois.prefix`            | Prefix to use for the new DOIs                                        |         |
  | `ckanext.query_dois.datacite_username` | Datacite account username                                             |         |
  | `ckanext.query_dois.datacite_password` | Datacite account password                                             |         |
  | `ckanext.query_dois.doi_title`         | Template string for the DOI title: takes `count` as a format argument |         |
  | `ckanext.query_dois.publisher`         | DOI publisher name                                                    |         |



  | Name                           | Description                                                  | Options    | Default |
  |--------------------------------|--------------------------------------------------------------|------------|---------|
  | `ckanext.query_dois.test_mode` | Enable/disable using test DOIs (i.e. not creating real DOIs) | True/False | True    |

  <!--configuration-end-->



  <!--usage-start-->



  Initialises the database table.

  1. `initdb`: initialise the database model
      ```bash
      ckan -c $CONFIG_FILE query-dois initdb
      ```

  <!--usage-end-->



  <!--testing-start-->
  There is a Docker compose configuration available in this repository to make it easier to run tests. The ckan image uses the Dockerfile in the `docker/` folder.

  To run the tests against ckan 2.9.x on Python3:

  1. Build the required images:
     ```shell
     docker compose build
     ```

  2. Then run the tests.
     The root of the repository is mounted into the ckan container as a volume by the Docker compose
     configuration, so you should only need to rebuild the ckan image if you change the extension's
     dependencies.
     ```shell
     docker compose run ckan
     ```

  <!--testing-end-->


pkgId: 054def9980d9f03ab68a5b9cd397d6fae74874d9383fbf6476c21f760f846842
name: python-ckanext-resource-indexer
arch: src
version: 0.4.2.post1
epoch: 0
release: 1
summary: please add a summary manually as the author left a blank one
url: https://github.com/DataShades/ckanext-resource_indexer
rpm_license: AGPL
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-ckanext-resource-indexer-0.4.2.post1-1.src.rpm
checksum_type: sha256
description:
  Discover more results in the Dataset search by searching through the content of resources.

  This extension indexes the content of files attached to resources. In this way
  user has more chances to find the relevant results when using site search.

  The process if indexation can be customized for each file format via [resource
  indexers](#indexers). The following formats are supported out of the box:
  * Plain text
  * PDF
  * JSON


  * [Installation](#installation)
  * [Configuration](#configuration)
  * [Indexers](#indexers)
    * [Register own indexer](#register-own-indexer)
    * [Built-in indexers](#built-in-indexers)



  1. Install the package as a CKAN extension
     ```sh
     pip install ckanext-resource-indexer
     ```
  1. Add `resource_indexer` to the list of enabled plugins
  1. **Optional**. Enable built-in indexers by adding the following items to the list of enabled plugins:
     * [`plain_resource_indexer`](#plain-indexer)
     * [`pdf_resource_indexer`](#pdf-indexer)
     * [`json_resource_indexer`](#json-indexer)



  ```ini



  ckanext.resource_indexer.allow_remote = 1



  ckanext.resource_indexer.remote_timeout = 10



  ckanext.resource_indexer.max_remote_size = 4




  ckanext.resource_indexer.indexable_formats = txt pdf




  ckanext.resoruce_indexer.index_field = extras_res_attachment






  ckanext.resoruce_indexer.search_boost = 0.5






  ckanext.resource_indexer.plain.indexable_formats = xml txt csv




  ckanext.resoruce_indexer.pdf.page_processor = custom.module:value_processor




  ckanext.resoruce_indexer.json.add_as_plain = true



  ckanext.resoruce_indexer.json.key_processor = custom.module:key_processor



  ckanext.resoruce_indexer.json.value_processor = custom.module:value_processor
  ```



  In order to extract the data from resources, this extension uses
  **Indexers**. These are CKAN plugins implementing `IResourceIndexer` interface.

  For every resource with the format specified by
  `ckanext.resource_indexer.indexable_formats` config option, an appropriate
  indexer is searched. If no indexers were found(or resource format is missing
  from the `ckanext.resource_indexer.indexable_formats` config option), the
  resource is skipped.

  :information_source: Indexation can be temporarily disabled using one of the
  following approaches:
  * Set environment variable `CKANEXT_RESOURCE_INDEXER_BYPASS`(any non-empty
  value), and the plugin won't interfer into standard dataset indexation
  process.
  * Use `ckanext.resource_indexer.utils.disabled_indexation` context manager:
    ```python
    with disabled_indexation():
        here_indexation_does_not_happen()

    here_indexation_happens()
    ```


  Every indexer has weight(priority). Indexer with the highest weight will be
  used to index the resource.

  Indexation consists of two steps:

  * meaningful data segments extracted from the resource
  * these data segments are merged into the package dictionary consumed by the
    search engine(Solr) for indexing

  It means, that the format of extracted segments must be compatible with the
  merging logic from the second step. But other than that, there are no
  particular requirements for the format of extracted data.

  Data extraction happens locally. If the resource was uploaded to the local
  filesystem, data is extracted directly from the resource's file. If the
  resource is stored remotely(either uploaded to the cloud or linked via remote
  URL), it can be temporarily downloaded to the local filesystem and removed
  after processing. By default, non-local resources are ignored, but this can be
  changed via `ckanext.resource_indexer.allow_remote` config option.



  Implement `ckanext.resource_indexer.interface.IResourceIndexer` by providing following methods:

  ```python
  class CustomIndexerPlugin(plugins.SingletonPlugin):
      plugins.implements(IResourceIndexer)

      def get_resource_indexer_weight(self, resource: dict[str, Any]) -> int:
          """Define priority of the indexer

          Args:
              resource: resource's details

          Returns:
              the weight of the indexer
              Expected values:
                 0: skip handler
                 10: use handler if no other handlers found
                 20: use handler as a default one for the resource
                 30: use handler as an optimal one for the resource
                 40: use handler as a special-case handler for the resource
                 50: ignore all the other handlers and use this one instead
          """
          return Weight.fallback

      def extract_indexable_chunks(self, path: str) -> Any:
          """Extract indexable data from the resource

          The result can have any form as long as it can be merged into the
          package dictionary by implementation of `merge_chunk_into_index`.

          Args:
              path: path to resource file

          Returns:
              all meaningfuld pieces of data with no type assumption

          """
          return []

      def merge_chunks_into_index(self, pkg_dict: dict[str, Any], chunks: Any):
          """Merge data into the package dictionary.


          Args:
              pkg_dict: package that is going to be indexed
              chunks: collection of data fragments extracted from resource

          Returns:
              all meaningfuld pieces of data with no type assumption
          """
          pass
  ```




  Index formats specified by `ckanext.resource_indexer.indexable_formats` if they fall into the value of `ckanext.resource_indexer.plain.indexable_formats` config option, unless other handler with a non-fallback weight(>10) found.

  Resources are indexed as-is. File is read and sent to the index without any additional changes.

  Enable it by adding `plain_resource_indexer` to the list of enabled plugins.




  Extract and index text from the PDF file.

  In order to enable it:
  * install current extension with the `pdf` extra:
    ```sh
    pip install 'ckanext-resource-indexer[pdf]'
    ```
    or, if you've already installed the extension itself, just install `pdftotext`:
    ```sh
    pip install pdftotext
    ```
  * add `pdf_resource_indexer` to the list of enabled plugins and
  * install system packages for PDF processing. This will be different depending on your system. Examples:
    * CentOS
       ```sh
       yum install -y pulseaudio-libs-devel \
          gcc-c++ pkgconfig \
          python3-devel \
          libxml2-devel libxslt-devel \
          poppler poppler-utils poppler-cpp-devel
       ```

    * Debian
      ```sh
      apt install build-essential libpoppler-cpp-dev pkg-config python3-dev
      ```

    * macOS
      ```sh
      brew install pkg-config poppler python
      ```

  If PDF content requires preprocessing, specify function that converts text from
  a every separate as a `ckanext.resoruce_indexer.pdf.page_processor`. It uses
  standard import-string format: `module.import.path:function`



  Read a dictionary from the JSON file, convert all non-string values into
  strings(i.e, no nested values allowed), and apply it as a patch to the indexed
  dataset.

  Optionally, if `ckanext.resoruce_indexer.json.add_as_plain` flag enabled, index
  the content of the file as a plain-text(similar to the [plain
  indexer](#plain-indexer))

  If key or value requires preprocessing, specify function that converts data as
  a `ckanext.resoruce_indexer.json.key_processor` or
  `ckanext.resoruce_indexer.json.value_processor`. It uses standard import-string
  format: `module.import.path:function`


  Enable it by adding `json_resource_indexer` to the list of enabled plugins.


